From: Zaheer Abbas Merali Date: Fri, 21 May 2010 13:35:34 +0000 (+0100) Subject: matroskamux: set delta unit on all buffers except cluster start ones X-Git-Tag: RELEASE-0.10.24~160 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ec23b22d298112f7a1a2b62f11c63a59263354f6;p=platform%2Fupstream%2Fgst-plugins-good.git matroskamux: set delta unit on all buffers except cluster start ones --- diff --git a/gst/matroska/ebml-write.c b/gst/matroska/ebml-write.c index 6bcc3e4..0691d5d 100644 --- a/gst/matroska/ebml-write.c +++ b/gst/matroska/ebml-write.c @@ -212,7 +212,7 @@ gst_ebml_write_set_cache (GstEbmlWrite * ebml, guint size) * Flush the cache. */ void -gst_ebml_write_flush_cache (GstEbmlWrite * ebml) +gst_ebml_write_flush_cache (GstEbmlWrite * ebml, gboolean is_keyframe) { GstBuffer *buffer; @@ -226,7 +226,7 @@ gst_ebml_write_flush_cache (GstEbmlWrite * ebml) if (ebml->last_write_result == GST_FLOW_OK) { if (ebml->need_newsegment) { GstEvent *ev; - + GST_WARNING ("new segment being sent"); ev = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, 0, -1, 0); if (gst_pad_push_event (ebml->srcpad, ev)) ebml->need_newsegment = FALSE; @@ -234,6 +234,9 @@ gst_ebml_write_flush_cache (GstEbmlWrite * ebml) if (ebml->writing_streamheader) { GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_IN_CAPS); } + if (!is_keyframe) { + GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT); + } ebml->last_write_result = gst_pad_push (ebml->srcpad, buffer); } else { gst_buffer_unref (buffer); @@ -403,6 +406,7 @@ gst_ebml_write_element_push (GstEbmlWrite * ebml, GstBuffer * buf) if (ebml->writing_streamheader) { GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_IN_CAPS); } + GST_BUFFER_FLAG_SET (buf, GST_BUFFER_FLAG_DELTA_UNIT); ebml->last_write_result = gst_pad_push (ebml->srcpad, buf); } else { gst_buffer_unref (buf); @@ -446,13 +450,14 @@ gst_ebml_write_seek (GstEbmlWrite * ebml, guint64 pos) return; } else { GST_LOG ("Seek outside cache range. Clearing..."); - gst_ebml_write_flush_cache (ebml); + gst_ebml_write_flush_cache (ebml, FALSE); } } event = gst_event_new_new_segment (FALSE, 1.0, GST_FORMAT_BYTES, pos, -1, 0); if (gst_pad_push_event (ebml->srcpad, event)) { - GST_DEBUG ("Seek'd to offset %" G_GUINT64_FORMAT, pos); + GST_DEBUG ("Seek'd to offset %" G_GUINT64_FORMAT " from %" G_GUINT64_FORMAT, + pos, ebml->pos); } else { GST_WARNING ("Seek to offset %" G_GUINT64_FORMAT " failed", pos); } @@ -773,6 +778,7 @@ gst_ebml_replace_uint (GstEbmlWrite * ebml, guint64 pos, guint64 num) guint64 oldpos = ebml->pos; GstBuffer *buf = gst_buffer_new_and_alloc (8); + GST_DEBUG ("replace_uint"); gst_ebml_write_seek (ebml, pos); GST_BUFFER_SIZE (buf) = 0; gst_ebml_write_set_uint (buf, num, 8); @@ -810,5 +816,5 @@ gst_ebml_write_header (GstEbmlWrite * ebml, const gchar * doctype, gst_ebml_write_uint (ebml, GST_EBML_ID_DOCTYPEVERSION, version); gst_ebml_write_uint (ebml, GST_EBML_ID_DOCTYPEREADVERSION, version); gst_ebml_write_master_finish (ebml, pos); - gst_ebml_write_flush_cache (ebml); + gst_ebml_write_flush_cache (ebml, FALSE); } diff --git a/gst/matroska/ebml-write.h b/gst/matroska/ebml-write.h index 38f0766..2240f4f 100644 --- a/gst/matroska/ebml-write.h +++ b/gst/matroska/ebml-write.h @@ -84,7 +84,8 @@ GstBuffer* gst_ebml_stop_streamheader (GstEbmlWrite *ebml); */ void gst_ebml_write_set_cache (GstEbmlWrite *ebml, guint size); -void gst_ebml_write_flush_cache (GstEbmlWrite *ebml); +void gst_ebml_write_flush_cache (GstEbmlWrite *ebml, + gboolean is_keyframe); /* * Seeking. diff --git a/gst/matroska/matroska-mux.c b/gst/matroska/matroska-mux.c index f0244c4..feaff36 100644 --- a/gst/matroska/matroska-mux.c +++ b/gst/matroska/matroska-mux.c @@ -2005,7 +2005,6 @@ gst_matroska_mux_start (GstMatroskaMux * mux) GstClockTime duration = 0; guint32 segment_uid[4]; GTimeVal time = { 0, 0 }; - GstBuffer *streamheader_buffer; if (!strcmp (mux->doctype, GST_MATROSKA_DOCTYPE_WEBM)) { ebml->caps = gst_caps_from_string ("video/webm"); @@ -2016,7 +2015,6 @@ gst_matroska_mux_start (GstMatroskaMux * mux) doctype = mux->doctype; GST_INFO_OBJECT (ebml, "DocType: %s, Version: %d", doctype, mux->doctype_version); - gst_ebml_start_streamheader (ebml); gst_ebml_write_header (ebml, doctype, mux->doctype_version); /* the rest of the header is cached */ @@ -2108,30 +2106,7 @@ gst_matroska_mux_start (GstMatroskaMux * mux) gst_ebml_write_master_finish (ebml, master); /* lastly, flush the cache */ - gst_ebml_write_flush_cache (ebml); - streamheader_buffer = gst_ebml_stop_streamheader (ebml); - /* lets set the pad caps, which is how the buffer caps is set currently :( */ - { - GstCaps *caps; - GstStructure *s; - GValue streamheader = { 0 }; - GValue bufval = { 0 }; - if (!strcmp (mux->doctype, GST_MATROSKA_DOCTYPE_WEBM)) { - caps = gst_caps_from_string ("video/webm"); - } else { - caps = gst_caps_from_string ("video/x-matroska"); - } - s = gst_caps_get_structure (caps, 0); - g_value_init (&streamheader, GST_TYPE_ARRAY); - g_value_init (&bufval, GST_TYPE_BUFFER); - gst_value_set_buffer (&bufval, streamheader_buffer); - gst_value_array_append_value (&streamheader, &bufval); - g_value_unset (&bufval); - gst_structure_set_value (s, "streamheader", &streamheader); - g_value_unset (&streamheader); - gst_caps_unref (ebml->caps); - ebml->caps = caps; - } + gst_ebml_write_flush_cache (ebml, FALSE); } static void @@ -2240,7 +2215,7 @@ gst_matroska_mux_finish (GstMatroskaMux * mux) } gst_ebml_write_master_finish (ebml, master); - gst_ebml_write_flush_cache (ebml); + gst_ebml_write_flush_cache (ebml, FALSE); } /* tags */ @@ -2271,6 +2246,7 @@ gst_matroska_mux_finish (GstMatroskaMux * mux) * - all entries are local to the segment (so pos - segment_master). * - so each entry is at 12 + 20 + num * 28. */ if (!mux->is_live) { + GST_DEBUG_OBJECT (mux, "not live"); gst_ebml_replace_uint (ebml, mux->seekhead_pos + 32, mux->info_pos - mux->segment_master); gst_ebml_replace_uint (ebml, mux->seekhead_pos + 60, @@ -2348,6 +2324,7 @@ gst_matroska_mux_finish (GstMatroskaMux * mux) gst_ebml_write_seek (ebml, my_pos); } } + GST_DEBUG_OBJECT (mux, "finishing segment"); /* finish segment - this also writes element length */ gst_ebml_write_master_finish (ebml, mux->segment_pos); } @@ -2496,6 +2473,34 @@ gst_matroska_mux_handle_dirac_packet (GstMatroskaMux * mux, return ret; } +static void +gst_matroska_mux_stop_streamheader (GstMatroskaMux * mux) +{ + GstCaps *caps; + GstStructure *s; + GValue streamheader = { 0 }; + GValue bufval = { 0 }; + GstBuffer *streamheader_buffer; + GstEbmlWrite *ebml = mux->ebml_write; + + streamheader_buffer = gst_ebml_stop_streamheader (ebml); + if (!strcmp (mux->doctype, GST_MATROSKA_DOCTYPE_WEBM)) { + caps = gst_caps_from_string ("video/webm"); + } else { + caps = gst_caps_from_string ("video/x-matroska"); + } + s = gst_caps_get_structure (caps, 0); + g_value_init (&streamheader, GST_TYPE_ARRAY); + g_value_init (&bufval, GST_TYPE_BUFFER); + gst_value_set_buffer (&bufval, streamheader_buffer); + gst_value_array_append_value (&streamheader, &bufval); + g_value_unset (&bufval); + gst_structure_set_value (s, "streamheader", &streamheader); + g_value_unset (&streamheader); + gst_caps_unref (ebml->caps); + ebml->caps = caps; +} + /** * gst_matroska_mux_write_data: * @mux: #GstMatroskaMux @@ -2563,8 +2568,8 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad) /* start a new cluster every two seconds or at keyframe */ if (mux->cluster_time + GST_SECOND * 2 < GST_BUFFER_TIMESTAMP (buf) || is_video_keyframe) { - - gst_ebml_write_master_finish (ebml, mux->cluster); + if (!mux->is_live) + gst_ebml_write_master_finish (ebml, mux->cluster); mux->prev_cluster_size = ebml->pos - mux->cluster_pos; mux->cluster_pos = ebml->pos; gst_ebml_write_set_cache (ebml, 0x20); @@ -2572,7 +2577,7 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad) gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CLUSTER); gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CLUSTERTIMECODE, GST_BUFFER_TIMESTAMP (buf) / mux->time_scale); - gst_ebml_write_flush_cache (ebml); + gst_ebml_write_flush_cache (ebml, TRUE); mux->cluster_time = GST_BUFFER_TIMESTAMP (buf); gst_ebml_write_uint (ebml, GST_MATROSKA_ID_PREVSIZE, mux->prev_cluster_size); @@ -2585,7 +2590,7 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad) mux->cluster = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_CLUSTER); gst_ebml_write_uint (ebml, GST_MATROSKA_ID_CLUSTERTIMECODE, GST_BUFFER_TIMESTAMP (buf) / mux->time_scale); - gst_ebml_write_flush_cache (ebml); + gst_ebml_write_flush_cache (ebml, TRUE); mux->cluster_time = GST_BUFFER_TIMESTAMP (buf); } @@ -2662,12 +2667,12 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad) gst_ebml_write_buffer_header (ebml, GST_MATROSKA_ID_SIMPLEBLOCK, GST_BUFFER_SIZE (buf) + GST_BUFFER_SIZE (hdr)); gst_ebml_write_buffer (ebml, hdr); - gst_ebml_write_flush_cache (ebml); + gst_ebml_write_flush_cache (ebml, FALSE); gst_ebml_write_buffer (ebml, buf); return gst_ebml_last_write_result (ebml); } else { - gst_ebml_write_set_cache (ebml, 0x40); + gst_ebml_write_set_cache (ebml, GST_BUFFER_SIZE (buf) * 2); /* write and call order slightly unnatural, * but avoids seek and minizes pushing */ blockgroup = gst_ebml_write_master_start (ebml, GST_MATROSKA_ID_BLOCKGROUP); @@ -2682,7 +2687,7 @@ gst_matroska_mux_write_data (GstMatroskaMux * mux, GstMatroskaPad * collect_pad) GST_BUFFER_SIZE (buf) + GST_BUFFER_SIZE (hdr)); gst_ebml_write_buffer (ebml, hdr); gst_ebml_write_master_finish_full (ebml, blockgroup, GST_BUFFER_SIZE (buf)); - gst_ebml_write_flush_cache (ebml); + gst_ebml_write_flush_cache (ebml, FALSE); gst_ebml_write_buffer (ebml, buf); return gst_ebml_last_write_result (ebml); } @@ -2702,6 +2707,7 @@ static GstFlowReturn gst_matroska_mux_collected (GstCollectPads * pads, gpointer user_data) { GstMatroskaMux *mux = GST_MATROSKA_MUX (user_data); + GstEbmlWrite *ebml = mux->ebml_write; GstMatroskaPad *best; gboolean popped; GstFlowReturn ret; @@ -2716,7 +2722,9 @@ gst_matroska_mux_collected (GstCollectPads * pads, gpointer user_data) return GST_FLOW_ERROR; } mux->state = GST_MATROSKA_MUX_STATE_HEADER; + gst_ebml_start_streamheader (ebml); gst_matroska_mux_start (mux); + gst_matroska_mux_stop_streamheader (mux); mux->state = GST_MATROSKA_MUX_STATE_DATA; }