summaryrefslogtreecommitdiffstats
path: root/gst/matroska/matroska-mux.c
diff options
context:
space:
mode:
authorMark Nauwelaerts <manauw@skynet.be>2006-05-03 14:51:50 +0000
committerTim-Philipp Müller <tim@centricular.net>2006-05-03 14:51:50 +0000
commitfcd464ea306af49f48793107774ae10f3511e29e (patch)
treebf1dfa21c96173bd1c0a4314363e94ee19fdfcd8 /gst/matroska/matroska-mux.c
parente73a19cb48797674ecd261293c6197c8bca0d573 (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.c54
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);