diff options
author | Mark Nauwelaerts <manauw@skynet.be> | 2006-05-03 14:51:50 +0000 |
---|---|---|
committer | Tim-Philipp Müller <tim@centricular.net> | 2006-05-03 14:51:50 +0000 |
commit | fcd464ea306af49f48793107774ae10f3511e29e (patch) | |
tree | bf1dfa21c96173bd1c0a4314363e94ee19fdfcd8 /gst/matroska/matroska-mux.c | |
parent | e73a19cb48797674ecd261293c6197c8bca0d573 (diff) |
gst/matroska/matroska-mux.c: Don't misinterpret GST_CLOCK_TIME_NONE as very high timestamp value and then dead-lock w...
Original commit message from CVS:
Patch by: Mark Nauwelaerts <manauw at skynet be>
* gst/matroska/matroska-mux.c: (gst_matroska_mux_best_pad),
(gst_matroska_mux_stream_is_vorbis_header),
(gst_matroska_mux_write_data):
Don't misinterpret GST_CLOCK_TIME_NONE as very high timestamp
value and then dead-lock when muxing vorbis audio streams
(the three vorbis header buffers carry no timestamp, and it
would try to mux these after all video buffers). Fixes #340346.
Improve clustering: start a new cluster also whenever we get
a keyframe.
Diffstat (limited to 'gst/matroska/matroska-mux.c')
-rw-r--r-- | gst/matroska/matroska-mux.c | 54 |
1 files changed, 49 insertions, 5 deletions
diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c index 6e17588a..20d5cfaf 100644 --- a/gst/matroska/matroska-mux.c +++ b/gst/matroska/matroska-mux.c @@ -1292,9 +1292,10 @@ gst_matroska_mux_best_pad (GstMatroskaMux * mux, gboolean * popped) /* if we have a buffer check if it is better then the current best one */ if (collect_pad->buffer != NULL) { - if (best == NULL - || GST_BUFFER_TIMESTAMP (collect_pad->buffer) < - GST_BUFFER_TIMESTAMP (best->buffer)) { + if (best == NULL || !GST_BUFFER_TIMESTAMP_IS_VALID (collect_pad->buffer) + || (GST_BUFFER_TIMESTAMP_IS_VALID (best->buffer) + && GST_BUFFER_TIMESTAMP (collect_pad->buffer) < + GST_BUFFER_TIMESTAMP (best->buffer))) { best = collect_pad; } } @@ -1303,6 +1304,33 @@ gst_matroska_mux_best_pad (GstMatroskaMux * mux, gboolean * popped) return best; } +static gboolean +gst_matroska_mux_stream_is_vorbis_header (GstMatroskaMux * mux, + GstMatroskaPad * collect_pad) +{ + GstMatroskaTrackAudioContext *audio_ctx; + + audio_ctx = (GstMatroskaTrackAudioContext *) collect_pad->track; + + if (collect_pad->track->type != GST_MATROSKA_TRACK_TYPE_AUDIO) + return FALSE; + + if (audio_ctx->first_frame != FALSE) + return FALSE; + + if (strcmp (collect_pad->track->codec_id, GST_MATROSKA_CODEC_ID_AUDIO_VORBIS)) + return FALSE; + + /* HACK: three frame headers are counted using pos */ + if (++collect_pad->track->pos <= 3) + return TRUE; + + /* 4th vorbis packet => skipped all headers */ + collect_pad->track->pos = 0; + audio_ctx->first_frame = TRUE; + return FALSE; +} + /** * gst_matroska_mux_buffer_header: @@ -1356,12 +1384,28 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad) buf = collect_pad->buffer; collect_pad->buffer = NULL; + /* vorbis header are retrieved from caps and placed in CodecPrivate */ + if (gst_matroska_mux_stream_is_vorbis_header (mux, collect_pad)) { + gst_buffer_unref (buf); + return GST_FLOW_OK; + } + + /* hm, invalid timestamp (due to --to be fixed--- element upstream); + * this would wreak havoc with time stored in matroska file */ + if (!GST_BUFFER_TIMESTAMP_IS_VALID (buf)) { + GST_WARNING_OBJECT (collect_pad->collect.pad, + "Invalid buffer timestamp; dropping buffer"); + gst_buffer_unref (buf); + return GST_FLOW_OK; + } + /* set the timestamp for outgoing buffers */ ebml->timestamp = GST_BUFFER_TIMESTAMP (buf); if (mux->cluster) { - /* start a new cluster every two seconds */ - if (mux->cluster_time + GST_SECOND * 2 < GST_BUFFER_TIMESTAMP (buf)) { + /* start a new cluster every two seconds or at keyframe */ + if (mux->cluster_time + GST_SECOND * 2 < GST_BUFFER_TIMESTAMP (buf) + || !GST_BUFFER_FLAG_IS_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT)) { GstMatroskaMetaSeekIndex *idx; gst_ebml_write_master_finish (ebml, mux->cluster); |