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:
David Schleef 2009-02-06 16:16:05 -08:00
parent db0b8755e0
commit 40bd377230
5 changed files with 44 additions and 0 deletions

View file

@ -2956,6 +2956,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream,
GNode *co64;
GNode *stts;
GNode *stss;
GNode *stps;
GNode *ctts;
const guint8 *stsc_data, *stsz_data, *stco_data;
int sample_size;
@ -2992,6 +2993,7 @@ qtdemux_parse_samples (GstQTDemux * qtdemux, QtDemuxStream * stream,
/* sample sync, can be NULL */
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);
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 {
/* no stss, all samples are keyframes */
stream->all_keyframe = TRUE;

View file

@ -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
qtdemux_dump_stss (GstQTDemux * qtdemux, guint8 * buffer, int depth)
{

View file

@ -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_stts (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_stsz (GstQTDemux * qtdemux, guint8 * buffer, int depth);
void qtdemux_dump_stco (GstQTDemux * qtdemux, guint8 * buffer, int depth);

View file

@ -56,6 +56,7 @@ G_BEGIN_DECLS
#define FOURCC_stsd GST_MAKE_FOURCC('s','t','s','d')
#define FOURCC_stts GST_MAKE_FOURCC('s','t','t','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_stsz GST_MAKE_FOURCC('s','t','s','z')
#define FOURCC_stco GST_MAKE_FOURCC('s','t','c','o')

View file

@ -61,6 +61,8 @@ static const QtNodeType qt_node_types[] = {
qtdemux_dump_stsd},
{FOURCC_stts, "time-to-sample", 0,
qtdemux_dump_stts},
{FOURCC_stps, "partial sync sample", 0,
qtdemux_dump_stps},
{FOURCC_stss, "sync sample", 0,
qtdemux_dump_stss},
{FOURCC_stsc, "sample-to-chunk", 0,