mirror of
https://gitlab.freedesktop.org/gstreamer/gstreamer.git
synced 2024-12-19 06:46:38 +00:00
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:
parent
22eb18f828
commit
91a5e5138f
1 changed files with 39 additions and 32 deletions
|
@ -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 >=
|
||||||
|
|
Loading…
Reference in a new issue