mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-02 14:36:41 +00:00
qtdemux: Add handling for stps atoms
stps atoms contain "partial sync" information, which means that it's a sync point where pts != dts. This is needed to properly handle MPEG2, H.264, Dirac, etc., in quicktime.
This commit is contained in:
parent
db0b8755e0
commit
40bd377230
5 changed files with 44 additions and 0 deletions
|
@ -2956,6 +2956,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream,
|
||||||
GNode *co64;
|
GNode *co64;
|
||||||
GNode *stts;
|
GNode *stts;
|
||||||
GNode *stss;
|
GNode *stss;
|
||||||
|
GNode *stps;
|
||||||
GNode *ctts;
|
GNode *ctts;
|
||||||
const guint8 *stsc_data, *stsz_data, *stco_data;
|
const guint8 *stsc_data, *stsz_data, *stco_data;
|
||||||
int sample_size;
|
int sample_size;
|
||||||
|
@ -2992,6 +2993,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream,
|
||||||
|
|
||||||
/* sample sync, can be NULL */
|
/* sample sync, can be NULL */
|
||||||
stss = qtdemux_tree_get_child_by_type (stbl, FOURCC_stss);
|
stss = qtdemux_tree_get_child_by_type (stbl, FOURCC_stss);
|
||||||
|
stps = qtdemux_tree_get_child_by_type (stbl, FOURCC_stps);
|
||||||
|
|
||||||
sample_size = QT_UINT32 (stsz_data + 12);
|
sample_size = QT_UINT32 (stsz_data + 12);
|
||||||
if (sample_size == 0 || stream->sampled) {
|
if (sample_size == 0 || stream->sampled) {
|
||||||
|
@ -3093,6 +3095,25 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (stps) {
|
||||||
|
/* mark keyframes */
|
||||||
|
guint32 n_sample_syncs;
|
||||||
|
|
||||||
|
n_sample_syncs = QT_UINT32 ((guint8 *) stps->data + 12);
|
||||||
|
if (n_sample_syncs == 0) {
|
||||||
|
//stream->all_keyframe = TRUE;
|
||||||
|
} else {
|
||||||
|
offset = 16;
|
||||||
|
for (i = 0; i < n_sample_syncs; i++) {
|
||||||
|
/* note that the first sample is index 1, not 0 */
|
||||||
|
index = QT_UINT32 ((guint8 *) stps->data + offset);
|
||||||
|
if (index > 0 && index <= stream->n_samples) {
|
||||||
|
samples[index - 1].keyframe = TRUE;
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
/* no stss, all samples are keyframes */
|
/* no stss, all samples are keyframes */
|
||||||
stream->all_keyframe = TRUE;
|
stream->all_keyframe = TRUE;
|
||||||
|
|
|
@ -232,6 +232,25 @@ qtdemux_dump_stts (GstQTDemux * qtdemux, guint8 * buffer, int depth)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
qtdemux_dump_stps (GstQTDemux * qtdemux, guint8 * buffer, int depth)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int n;
|
||||||
|
int offset;
|
||||||
|
|
||||||
|
GST_LOG ("%*s version/flags: %08x", depth, "", QT_UINT32 (buffer + 8));
|
||||||
|
GST_LOG ("%*s n entries: %d", depth, "", QT_UINT32 (buffer + 12));
|
||||||
|
n = QT_UINT32 (buffer + 12);
|
||||||
|
offset = 16;
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
GST_LOG ("%*s sample: %u", depth, "",
|
||||||
|
QT_UINT32 (buffer + offset));
|
||||||
|
|
||||||
|
offset += 4;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
qtdemux_dump_stss (GstQTDemux * qtdemux, guint8 * buffer, int depth)
|
qtdemux_dump_stss (GstQTDemux * qtdemux, guint8 * buffer, int depth)
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,6 +35,7 @@ void qtdemux_dump_dref (GstQTDemux * qtdemux, guint8 * buffer, int depth);
|
||||||
void qtdemux_dump_stsd (GstQTDemux * qtdemux, guint8 * buffer, int depth);
|
void qtdemux_dump_stsd (GstQTDemux * qtdemux, guint8 * buffer, int depth);
|
||||||
void qtdemux_dump_stts (GstQTDemux * qtdemux, guint8 * buffer, int depth);
|
void qtdemux_dump_stts (GstQTDemux * qtdemux, guint8 * buffer, int depth);
|
||||||
void qtdemux_dump_stss (GstQTDemux * qtdemux, guint8 * buffer, int depth);
|
void qtdemux_dump_stss (GstQTDemux * qtdemux, guint8 * buffer, int depth);
|
||||||
|
void qtdemux_dump_stps (GstQTDemux * qtdemux, guint8 * buffer, int depth);
|
||||||
void qtdemux_dump_stsc (GstQTDemux * qtdemux, guint8 * buffer, int depth);
|
void qtdemux_dump_stsc (GstQTDemux * qtdemux, guint8 * buffer, int depth);
|
||||||
void qtdemux_dump_stsz (GstQTDemux * qtdemux, guint8 * buffer, int depth);
|
void qtdemux_dump_stsz (GstQTDemux * qtdemux, guint8 * buffer, int depth);
|
||||||
void qtdemux_dump_stco (GstQTDemux * qtdemux, guint8 * buffer, int depth);
|
void qtdemux_dump_stco (GstQTDemux * qtdemux, guint8 * buffer, int depth);
|
||||||
|
|
|
@ -56,6 +56,7 @@ G_BEGIN_DECLS
|
||||||
#define FOURCC_stsd GST_MAKE_FOURCC('s','t','s','d')
|
#define FOURCC_stsd GST_MAKE_FOURCC('s','t','s','d')
|
||||||
#define FOURCC_stts GST_MAKE_FOURCC('s','t','t','s')
|
#define FOURCC_stts GST_MAKE_FOURCC('s','t','t','s')
|
||||||
#define FOURCC_stss GST_MAKE_FOURCC('s','t','s','s')
|
#define FOURCC_stss GST_MAKE_FOURCC('s','t','s','s')
|
||||||
|
#define FOURCC_stps GST_MAKE_FOURCC('s','t','p','s')
|
||||||
#define FOURCC_stsc GST_MAKE_FOURCC('s','t','s','c')
|
#define FOURCC_stsc GST_MAKE_FOURCC('s','t','s','c')
|
||||||
#define FOURCC_stsz GST_MAKE_FOURCC('s','t','s','z')
|
#define FOURCC_stsz GST_MAKE_FOURCC('s','t','s','z')
|
||||||
#define FOURCC_stco GST_MAKE_FOURCC('s','t','c','o')
|
#define FOURCC_stco GST_MAKE_FOURCC('s','t','c','o')
|
||||||
|
|
|
@ -61,6 +61,8 @@ static const QtNodeType qt_node_types[] = {
|
||||||
qtdemux_dump_stsd},
|
qtdemux_dump_stsd},
|
||||||
{FOURCC_stts, "time-to-sample", 0,
|
{FOURCC_stts, "time-to-sample", 0,
|
||||||
qtdemux_dump_stts},
|
qtdemux_dump_stts},
|
||||||
|
{FOURCC_stps, "partial sync sample", 0,
|
||||||
|
qtdemux_dump_stps},
|
||||||
{FOURCC_stss, "sync sample", 0,
|
{FOURCC_stss, "sync sample", 0,
|
||||||
qtdemux_dump_stss},
|
qtdemux_dump_stss},
|
||||||
{FOURCC_stsc, "sample-to-chunk", 0,
|
{FOURCC_stsc, "sample-to-chunk", 0,
|
||||||
|
|
Loading…
Reference in a new issue