qtdemux: cleanups and make duration more accurate

Make the QtDemuxSample struct smaller by keeping the duration and the pts_offset
as their 32 bit values.
Make some macros to calculate PTS, DTS and duration of a sample.
Deref the sample index less often by keeping a ref to the sample we're dealing
with.
This commit is contained in:
Wim Taymans 2010-01-04 16:33:30 +01:00
parent 22eb18f828
commit 91a5e5138f

View file

@ -88,13 +88,28 @@ typedef struct _QtDemuxSample QtDemuxSample;
struct _QtDemuxSample struct _QtDemuxSample
{ {
guint32 size; guint32 size;
gint32 pts_offset; /* Add this value to timestamp to get the pts */
guint64 offset; guint64 offset;
guint64 pts_offset; /* Add this value to timestamp to get the pts */ guint64 timestamp; /* DTS In mov time */
guint64 timestamp; /* In mov time */ guint32 duration; /* In mov time */
guint64 duration; /* In mov time */
gboolean keyframe; /* TRUE when this packet is a keyframe */ gboolean keyframe; /* TRUE when this packet is a keyframe */
}; };
/* timestamp is the DTS */
#define QTSAMPLE_DTS(stream,sample) gst_util_uint64_scale ((sample)->timestamp,\
GST_SECOND, (stream)->timescale)
/* timestamp + offset is the PTS */
#define QTSAMPLE_PTS(stream,sample) gst_util_uint64_scale ((sample)->timestamp + \
(sample)->pts_offset, GST_SECOND, (stream)->timescale)
/* timestamp + duration - dts is the duration */
#define QTSAMPLE_DUR_DTS(stream,sample,dts) (gst_util_uint64_scale ((sample)->timestamp + \
(sample)->duration, GST_SECOND, (stream)->timescale) - (dts));
/* timestamp + offset + duration - pts is the duration */
#define QTSAMPLE_DUR_PTS(stream,sample,pts) (gst_util_uint64_scale ((sample)->timestamp + \
(sample)->pts_offset + (sample)->duration, GST_SECOND, (stream)->timescale) - (pts));
#define QTSAMPLE_KEYFRAME(stream,sample) ((stream)->all_keyframe || (sample)->keyframe)
/* /*
* Quicktime has tracks and segments. A track is a continuous piece of * Quicktime has tracks and segments. A track is a continuous piece of
* multimedia content. The track is not always played from start to finish but * multimedia content. The track is not always played from start to finish but
@ -2098,21 +2113,21 @@ gst_qtdemux_activate_segment (GstQTDemux * qtdemux, QtDemuxStream * stream,
if (kf_index > stream->sample_index) { if (kf_index > stream->sample_index) {
GST_DEBUG_OBJECT (qtdemux, GST_DEBUG_OBJECT (qtdemux,
"moving forwards to keyframe at %u (pts %" GST_TIME_FORMAT, kf_index, "moving forwards to keyframe at %u (pts %" GST_TIME_FORMAT, kf_index,
GST_TIME_ARGS (gst_util_uint64_scale (stream->samples[kf_index]. GST_TIME_ARGS (gst_util_uint64_scale (stream->
timestamp, GST_SECOND, stream->timescale))); samples[kf_index].timestamp, GST_SECOND, stream->timescale)));
gst_qtdemux_move_stream (qtdemux, stream, kf_index); gst_qtdemux_move_stream (qtdemux, stream, kf_index);
} else { } else {
GST_DEBUG_OBJECT (qtdemux, GST_DEBUG_OBJECT (qtdemux,
"moving forwards, keyframe at %u (pts %" GST_TIME_FORMAT "moving forwards, keyframe at %u (pts %" GST_TIME_FORMAT
" already sent", kf_index, " already sent", kf_index,
GST_TIME_ARGS (gst_util_uint64_scale (stream->samples[kf_index]. GST_TIME_ARGS (gst_util_uint64_scale (stream->
timestamp, GST_SECOND, stream->timescale))); samples[kf_index].timestamp, GST_SECOND, stream->timescale)));
} }
} else { } else {
GST_DEBUG_OBJECT (qtdemux, GST_DEBUG_OBJECT (qtdemux,
"moving backwards to keyframe at %u (pts %" GST_TIME_FORMAT, kf_index, "moving backwards to keyframe at %u (pts %" GST_TIME_FORMAT, kf_index,
GST_TIME_ARGS (gst_util_uint64_scale (stream->samples[kf_index]. GST_TIME_ARGS (gst_util_uint64_scale (stream->
timestamp, GST_SECOND, stream->timescale))); samples[kf_index].timestamp, GST_SECOND, stream->timescale)));
gst_qtdemux_move_stream (qtdemux, stream, kf_index); gst_qtdemux_move_stream (qtdemux, stream, kf_index);
} }
@ -2170,14 +2185,11 @@ gst_qtdemux_prepare_current_sample (GstQTDemux * qtdemux,
return FALSE; return FALSE;
} }
*timestamp = *timestamp = QTSAMPLE_PTS (stream, sample);
gst_util_uint64_scale (sample->timestamp + sample->pts_offset,
GST_SECOND, stream->timescale);
*offset = sample->offset; *offset = sample->offset;
*size = sample->size; *size = sample->size;
*duration = *duration = QTSAMPLE_DUR_PTS (stream, sample, *timestamp);
gst_util_uint64_scale (sample->duration, GST_SECOND, stream->timescale); *keyframe = QTSAMPLE_KEYFRAME (stream, sample);
*keyframe = stream->all_keyframe || sample->keyframe;
/* update dummy segment duration */ /* update dummy segment duration */
if (stream->sample_index == stream->n_samples - 1 && stream->n_segments == 1) { if (stream->sample_index == stream->n_samples - 1 && stream->n_segments == 1) {
@ -3160,6 +3172,7 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
case QTDEMUX_STATE_MOVIE:{ case QTDEMUX_STATE_MOVIE:{
GstBuffer *outbuf; GstBuffer *outbuf;
QtDemuxStream *stream = NULL; QtDemuxStream *stream = NULL;
QtDemuxSample *sample;
int i = -1; int i = -1;
guint64 timestamp, duration, position; guint64 timestamp, duration, position;
gboolean keyframe; gboolean keyframe;
@ -3210,21 +3223,15 @@ gst_qtdemux_chain (GstPad * sinkpad, GstBuffer * inbuf)
GST_FOURCC_ARGS (stream->fourcc)); GST_FOURCC_ARGS (stream->fourcc));
g_return_val_if_fail (outbuf != NULL, GST_FLOW_ERROR); g_return_val_if_fail (outbuf != NULL, GST_FLOW_ERROR);
position =
gst_util_uint64_scale (stream->samples[stream-> sample = &stream->samples[stream->sample_index];
sample_index].timestamp, GST_SECOND, stream->timescale);
timestamp = position = QTSAMPLE_DTS (stream, sample);
gst_util_uint64_scale (stream->samples[stream-> timestamp = QTSAMPLE_PTS (stream, sample);
sample_index].timestamp + duration = QTSAMPLE_DUR_DTS (stream, sample, position);
stream->samples[stream->sample_index].pts_offset, GST_SECOND, keyframe = QTSAMPLE_KEYFRAME (stream, sample);
stream->timescale);
duration = ret = gst_qtdemux_decorate_and_push_buffer (demux, stream, outbuf,
gst_util_uint64_scale (stream->samples[stream->
sample_index].duration, GST_SECOND, stream->timescale);
keyframe = stream->all_keyframe
|| stream->samples[stream->sample_index].keyframe;
ret =
gst_qtdemux_decorate_and_push_buffer (demux, stream, outbuf,
timestamp, duration, keyframe, position, demux->offset); timestamp, duration, keyframe, position, demux->offset);
/* combine flows */ /* combine flows */
@ -4130,8 +4137,8 @@ qtdemux_stbl_init (GstQTDemux * qtdemux, QtDemuxStream * stream, GNode * stbl)
return FALSE; return FALSE;
} }
GST_DEBUG_OBJECT (qtdemux, "allocating n_samples %u (%u MB)", GST_DEBUG_OBJECT (qtdemux, "allocating n_samples %u * %d = (%u MB)",
stream->n_samples, stream->n_samples, sizeof (QtDemuxSample),
(guint) (stream->n_samples * sizeof (QtDemuxSample)) >> 20); (guint) (stream->n_samples * sizeof (QtDemuxSample)) >> 20);
if (stream->n_samples >= if (stream->n_samples >=