From c54144cc16849907dc5a73b0e671d3c272c5c7ae Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Tue, 3 Jan 2012 20:21:51 +0100 Subject: [PATCH 01/27] h264parse: some more proper parse state reset --- gst/videoparsers/gsth264parse.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c index 840cfb2d08..38561bf09a 100644 --- a/gst/videoparsers/gsth264parse.c +++ b/gst/videoparsers/gsth264parse.c @@ -179,6 +179,7 @@ gst_h264_parse_reset_frame (GstH264Parse * h264parse) /* done parsing; reset state */ h264parse->nalu.valid = FALSE; h264parse->nalu.offset = 0; + h264parse->nalu.sc_offset = 0; h264parse->nalu.size = 0; h264parse->current_off = 0; @@ -617,7 +618,7 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse, guint size, current_off = 0; gboolean drain; GstH264NalParser *nalparser = h264parse->nalparser; - GstH264NalUnit nalu = h264parse->nalu; + GstH264NalUnit nalu; /* expect at least 3 bytes startcode == sc, and 2 bytes NALU payload */ if (G_UNLIKELY (GST_BUFFER_SIZE (buffer) < 5)) @@ -640,6 +641,7 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse, size = GST_BUFFER_SIZE (buffer); drain = FALSE; + nalu = h264parse->nalu; current_off = h264parse->current_off; GST_DEBUG_OBJECT (h264parse, "last parse position %u", current_off); From 75b8ddb6cf440d71d939722da6ff43f3bcd44f9b Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Tue, 3 Jan 2012 20:23:16 +0100 Subject: [PATCH 02/27] h264parse: properly determine skip amount when no NAL start found yet --- gst/videoparsers/gsth264parse.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c index 38561bf09a..e9ea858c2a 100644 --- a/gst/videoparsers/gsth264parse.c +++ b/gst/videoparsers/gsth264parse.c @@ -686,7 +686,9 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse, current_off = size - 3; goto parsing_error; case GST_H264_PARSER_NO_NAL: - current_off = size - 3; + /* don't expect to have found any NAL so far */ + g_assert (h264parse->nalu.size == 0); + current_off = h264parse->nalu.sc_offset = size - 3; goto more; case GST_H264_PARSER_BROKEN_DATA: GST_WARNING_OBJECT (h264parse, "input stream is corrupt; " From dcd2ee421a90cba280b5c8abfb0f1c39bd4d8780 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Tue, 3 Jan 2012 21:59:32 +0100 Subject: [PATCH 03/27] h264parse: mark byte-stream AU frame with inserted codec NALs as keyframe --- gst/videoparsers/gsth264parse.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c index e9ea858c2a..e1f92ee9ea 100644 --- a/gst/videoparsers/gsth264parse.c +++ b/gst/videoparsers/gsth264parse.c @@ -1463,6 +1463,9 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) /* collect result and push */ new_buf = gst_byte_writer_reset_and_get_buffer (&bw); gst_buffer_copy_metadata (new_buf, buffer, GST_BUFFER_COPY_ALL); + /* should already be keyframe/IDR, but it may not have been, + * so mark it as such to avoid being discarded by picky decoder */ + GST_BUFFER_FLAG_UNSET (new_buf, GST_BUFFER_FLAG_DELTA_UNIT); gst_buffer_replace (&frame->buffer, new_buf); gst_buffer_unref (new_buf); } From 9d0c7d054eafc6b92402d283a2e6cdd8cfa5cb1f Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Tue, 3 Jan 2012 22:09:04 +0100 Subject: [PATCH 04/27] h264parse: prefer negotiating pass-through --- gst/videoparsers/gsth264parse.c | 33 +++++++++++++++++++++++++++------ 1 file changed, 27 insertions(+), 6 deletions(-) diff --git a/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c index e1f92ee9ea..5ac459970d 100644 --- a/gst/videoparsers/gsth264parse.c +++ b/gst/videoparsers/gsth264parse.c @@ -321,7 +321,7 @@ gst_h264_parse_format_from_caps (GstCaps * caps, guint * format, guint * align) /* check downstream caps to configure format and alignment */ static void -gst_h264_parse_negotiate (GstH264Parse * h264parse) +gst_h264_parse_negotiate (GstH264Parse * h264parse, GstCaps * in_caps) { GstCaps *caps; guint format = GST_H264_PARSE_FORMAT_NONE; @@ -330,10 +330,19 @@ gst_h264_parse_negotiate (GstH264Parse * h264parse) caps = gst_pad_get_allowed_caps (GST_BASE_PARSE_SRC_PAD (h264parse)); GST_DEBUG_OBJECT (h264parse, "allowed caps: %" GST_PTR_FORMAT, caps); - gst_h264_parse_format_from_caps (caps, &format, &align); + if (in_caps && caps) { + if (gst_caps_can_intersect (in_caps, caps)) { + GST_DEBUG_OBJECT (h264parse, "downstream accepts upstream caps"); + gst_h264_parse_format_from_caps (in_caps, &format, &align); + gst_caps_unref (caps); + caps = NULL; + } + } - if (caps) + if (caps) { + gst_h264_parse_format_from_caps (caps, &format, &align); gst_caps_unref (caps); + } /* default */ if (!format) @@ -626,7 +635,7 @@ gst_h264_parse_check_valid_frame (GstBaseParse * parse, /* need to configure aggregation */ if (G_UNLIKELY (h264parse->format == GST_H264_PARSE_FORMAT_NONE)) - gst_h264_parse_negotiate (h264parse); + gst_h264_parse_negotiate (h264parse, NULL); /* avoid stale cached parsing state */ if (!(frame->flags & GST_BASE_PARSE_FRAME_FLAG_PARSING)) { @@ -1595,8 +1604,20 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps) } } - /* negotiate with downstream, sets ->format and ->align */ - gst_h264_parse_negotiate (h264parse); + { + GstCaps *in_caps; + + /* prefer input type determined above */ + in_caps = gst_caps_new_simple ("video/x-h264", + "parsed", G_TYPE_BOOLEAN, TRUE, + "stream-format", G_TYPE_STRING, + gst_h264_parse_get_string (h264parse, TRUE, format), + "alignment", G_TYPE_STRING, + gst_h264_parse_get_string (h264parse, FALSE, align), NULL); + /* negotiate with downstream, sets ->format and ->align */ + gst_h264_parse_negotiate (h264parse, in_caps); + gst_caps_unref (in_caps); + } if (format == h264parse->format && align == h264parse->align) { gst_base_parse_set_passthrough (parse, TRUE); From c4abaf1428c5fdd9b30b20ee982ee04722cd5a87 Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Wed, 4 Jan 2012 10:56:51 +0100 Subject: [PATCH 05/27] h264parse: fix and tweak frame timestamping ... to run with properly init'ed variables, and to only perform interpolation in safe cases. --- gst/videoparsers/gsth264parse.c | 31 ++++++++++++++++++++++++++++--- gst/videoparsers/gsth264parse.h | 1 + 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c index 5ac459970d..505def9a69 100644 --- a/gst/videoparsers/gsth264parse.c +++ b/gst/videoparsers/gsth264parse.c @@ -215,6 +215,10 @@ gst_h264_parse_reset (GstH264Parse * h264parse) h264parse->have_pps = FALSE; h264parse->have_sps = FALSE; + h264parse->dts = GST_CLOCK_TIME_NONE; + h264parse->ts_trn_nb = GST_CLOCK_TIME_NONE; + h264parse->do_ts = TRUE; + h264parse->pending_key_unit_ts = GST_CLOCK_TIME_NONE; h264parse->force_key_unit_event = NULL; @@ -1238,9 +1242,12 @@ gst_h264_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame) gst_h264_parse_update_src_caps (h264parse, NULL); - gst_h264_parse_get_timestamp (h264parse, - &GST_BUFFER_TIMESTAMP (buffer), &GST_BUFFER_DURATION (buffer), - h264parse->frame_start); + /* don't mess with timestamps if provided by upstream, + * particularly since our ts not that good they handle seeking etc */ + if (h264parse->do_ts) + gst_h264_parse_get_timestamp (h264parse, + &GST_BUFFER_TIMESTAMP (buffer), &GST_BUFFER_DURATION (buffer), + h264parse->frame_start); if (h264parse->keyframe) GST_BUFFER_FLAG_UNSET (buffer, GST_BUFFER_FLAG_DELTA_UNIT); @@ -1728,6 +1735,24 @@ gst_h264_parse_event (GstBaseParse * parse, GstEvent * event) gst_event_replace (&h264parse->force_key_unit_event, event); break; } + case GST_EVENT_FLUSH_STOP: + h264parse->dts = GST_CLOCK_TIME_NONE; + h264parse->ts_trn_nb = GST_CLOCK_TIME_NONE; + break; + case GST_EVENT_NEWSEGMENT: + { + gdouble rate, applied_rate; + GstFormat format; + gint64 start; + + gst_event_parse_new_segment_full (event, NULL, &rate, &applied_rate, + &format, &start, NULL, NULL); + /* don't try to mess with more subtle cases (e.g. seek) */ + if (format == GST_FORMAT_TIME && + (start != 0 || rate != 1.0 || applied_rate != 1.0)) + h264parse->do_ts = FALSE; + break; + } default: break; } diff --git a/gst/videoparsers/gsth264parse.h b/gst/videoparsers/gsth264parse.h index 4800092b39..1064ff8bba 100644 --- a/gst/videoparsers/gsth264parse.h +++ b/gst/videoparsers/gsth264parse.h @@ -92,6 +92,7 @@ struct _GstH264Parse GstClockTime dts; /* dts at start of last buffering period */ GstClockTime ts_trn_nb; + gboolean do_ts; /* frame parsing */ /*guint last_nal_pos;*/ From 3c69286db9711db590670fbd9db2a4a9a19035b8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tim-Philipp=20M=C3=BCller?= Date: Wed, 4 Jan 2012 18:42:57 +0000 Subject: [PATCH 06/27] tests: remove temporary files when done in camerabin, camerabin2 and jifmux tests --- tests/check/elements/camerabin.c | 20 ++++++++++++++++++++ tests/check/elements/camerabin2.c | 28 +++++++++++++++++++++++++++- tests/check/elements/jifmux.c | 3 +++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/tests/check/elements/camerabin.c b/tests/check/elements/camerabin.c index 53a82e9f5b..ce17ac3e3a 100644 --- a/tests/check/elements/camerabin.c +++ b/tests/check/elements/camerabin.c @@ -26,6 +26,7 @@ #include #include +#include #include #include #include @@ -501,6 +502,16 @@ check_file_validity (const gchar * filename, gint num, GstTagList * taglist) return TRUE; } +static void +remove_file (const gchar * fn_template, guint num) +{ + const gchar *fn; + + fn = make_test_file_name (fn_template, num); + GST_INFO ("removing %s", fn); + g_unlink (fn); +} + GST_START_TEST (test_single_image_capture) { gboolean ready = FALSE; @@ -544,6 +555,7 @@ GST_START_TEST (test_single_image_capture) gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); check_file_validity (SINGLE_IMAGE_FILENAME, 0, NULL); + remove_file (SINGLE_IMAGE_FILENAME, 0); } GST_END_TEST; @@ -568,6 +580,7 @@ GST_START_TEST (test_single_image_capture_with_flags) gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); check_file_validity (SINGLE_IMAGE_WITH_FLAGS_FILENAME, 0, NULL); + remove_file (SINGLE_IMAGE_WITH_FLAGS_FILENAME, 0); } GST_END_TEST; @@ -617,6 +630,7 @@ GST_START_TEST (test_video_recording) gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); check_file_validity (VIDEO_WITH_FLAGS_FILENAME, 0, NULL); + remove_file (VIDEO_WITH_FLAGS_FILENAME, 0); } GST_END_TEST; @@ -653,6 +667,7 @@ GST_START_TEST (test_video_recording_with_flags) gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); check_file_validity (VIDEO_FILENAME, 0, NULL); + remove_file (VIDEO_FILENAME, 0); } GST_END_TEST; @@ -704,6 +719,7 @@ GST_START_TEST (test_video_recording_pause) gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); check_file_validity (VIDEO_PAUSE_FILENAME, 0, NULL); + remove_file (VIDEO_PAUSE_FILENAME, 0); } GST_END_TEST; @@ -740,6 +756,7 @@ GST_START_TEST (test_video_recording_no_audio) gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); check_file_validity (VIDEO_NOAUDIO_FILENAME, 0, NULL); + remove_file (VIDEO_NOAUDIO_FILENAME, 0); } GST_END_TEST; @@ -767,7 +784,9 @@ GST_START_TEST (test_image_video_cycle) /* validate all the files */ for (i = 2; i > 0; i--) { check_file_validity (CYCLE_IMAGE_FILENAME, i, NULL); + remove_file (CYCLE_IMAGE_FILENAME, i); check_file_validity (CYCLE_VIDEO_FILENAME, i, NULL); + remove_file (CYCLE_VIDEO_FILENAME, i); } } @@ -796,6 +815,7 @@ GST_START_TEST (test_image_tags_setting) for (i = 0; i < SEQUENTIAL_IMAGES_COUNT; i++) { check_file_validity (SEQUENTIAL_IMAGES_FILENAME, i, taglists[i % TAGLISTS_COUNT]); + remove_file (SEQUENTIAL_IMAGES_FILENAME, i); } } diff --git a/tests/check/elements/camerabin2.c b/tests/check/elements/camerabin2.c index f39e4aaaf0..9ae219a150 100644 --- a/tests/check/elements/camerabin2.c +++ b/tests/check/elements/camerabin2.c @@ -27,6 +27,7 @@ #include #include +#include #include #include #include @@ -434,8 +435,9 @@ teardown (void) tags_found = NULL; g_free (video_filename); - g_free (image_filename); video_filename = NULL; + + g_free (image_filename); image_filename = NULL; GST_INFO ("done"); @@ -569,6 +571,16 @@ check_file_validity (const gchar * filename, gint num, GstTagList * taglist, return TRUE; } +static void +remove_file (const gchar * fn_template, guint num) +{ + const gchar *fn; + + fn = make_const_file_name (fn_template, num); + GST_INFO ("removing %s", fn); + g_unlink (fn); +} + static gboolean filter_buffer_count (GstPad * pad, GstMiniObject * obj, gpointer data) { @@ -676,6 +688,7 @@ GST_START_TEST (test_single_image_capture) wait_for_idle_state (); gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); check_file_validity (image_filename, 0, NULL, 0, 0, NO_AUDIO); + remove_file (image_filename, 0); } GST_END_TEST; @@ -730,6 +743,7 @@ GST_START_TEST (test_multiple_image_captures) for (i = 0; i < 3; i++) { check_file_validity (image_filename, i, NULL, widths[i], heights[i], NO_AUDIO); + remove_file (image_filename, i); } } @@ -779,6 +793,8 @@ GST_START_TEST (test_single_video_recording) gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); check_file_validity (video_filename, 0, NULL, 0, 0, WITH_AUDIO); + remove_file (video_filename, 0); + } GST_END_TEST; @@ -850,6 +866,7 @@ GST_START_TEST (test_multiple_video_recordings) for (i = 0; i < 3; i++) { check_file_validity (video_filename, i, NULL, widths[i], heights[i], WITH_AUDIO); + remove_file (video_filename, i); } } @@ -914,7 +931,9 @@ GST_START_TEST (test_image_video_cycle) /* validate all the files */ for (i = 0; i < 2; i++) { check_file_validity (image_filename, i, NULL, 0, 0, NO_AUDIO); + remove_file (image_filename, i); check_file_validity (video_filename, i, NULL, 0, 0, WITH_AUDIO); + remove_file (video_filename, i); } } @@ -961,6 +980,7 @@ GST_START_TEST (test_image_capture_previews) gst_message_unref (msg); check_preview_image (camera, image_filename, i); + remove_file (image_filename, i); if (preview_buffer) gst_buffer_unref (preview_buffer); @@ -1040,6 +1060,7 @@ GST_START_TEST (test_image_capture_with_tags) for (i = 0; i < 3; i++) { check_file_validity (image_filename, i, taglists[i], 0, 0, NO_AUDIO); gst_tag_list_free (taglists[i]); + remove_file (image_filename, i); } } @@ -1117,6 +1138,7 @@ GST_START_TEST (test_video_capture_with_tags) for (i = 0; i < 3; i++) { check_file_validity (video_filename, i, taglists[i], 0, 0, NO_AUDIO); gst_tag_list_free (taglists[i]); + remove_file (video_filename, i); } } @@ -1218,6 +1240,7 @@ GST_START_TEST (test_idle_property) gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); check_file_validity (video_filename, 0, NULL, 0, 0, WITH_AUDIO); + remove_file (video_filename, 0); } GST_END_TEST; @@ -1284,6 +1307,7 @@ GST_START_TEST (test_image_custom_filter) gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); check_file_validity (image_filename, 0, NULL, 0, 0, NO_AUDIO); + remove_file (image_filename, 0); fail_unless (vf_probe_counter > 0); fail_unless (image_probe_counter == 1); @@ -1365,6 +1389,7 @@ GST_START_TEST (test_video_custom_filter) gst_element_set_state (GST_ELEMENT (camera), GST_STATE_NULL); check_file_validity (video_filename, 0, NULL, 0, 0, WITH_AUDIO); + remove_file (video_filename, 0); fail_unless (vf_probe_counter > 0); fail_unless (video_probe_counter > 0); @@ -1467,6 +1492,7 @@ GST_START_TEST (test_image_location_switching) } for (i = 0; i < LOCATION_SWITCHING_FILENAMES_COUNT; i++) { + g_unlink (filenames[i]); g_free (filenames[i]); } g_signal_handler_disconnect (src, notify_id); diff --git a/tests/check/elements/jifmux.c b/tests/check/elements/jifmux.c index 9e21d1a5b0..05e67561f0 100644 --- a/tests/check/elements/jifmux.c +++ b/tests/check/elements/jifmux.c @@ -27,6 +27,8 @@ #include #include +#include + #include #include @@ -1200,6 +1202,7 @@ GST_START_TEST (test_jifmux_tags) tmpfile); libexif_check_tags (FILE_SOURCE_TAG ("transparent-scanner"), tmpfile); + g_unlink (tmpfile); g_free (tmpfile); } From 74952a15bf1db09711681cf7238981e03fd2608d Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Thu, 5 Jan 2012 11:01:01 +0000 Subject: [PATCH 07/27] tests: test for GTK 2.24 for new symbols used in camerabin2 tests The whole tree is likely to switch to GTK 3.0 at some point, but we might as well continue building with slightly less new versions if it's not hard to do. --- tests/examples/camerabin2/gst-camera2.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/tests/examples/camerabin2/gst-camera2.c b/tests/examples/camerabin2/gst-camera2.c index 13299eac57..8f34501fb9 100644 --- a/tests/examples/camerabin2/gst-camera2.c +++ b/tests/examples/camerabin2/gst-camera2.c @@ -257,9 +257,10 @@ bus_callback (GstBus * bus, GstMessage * message, gpointer data) return TRUE; } -static void +static gboolean init_gtkwidgets_data (void) { +#if GTK_CHECK_VERSION(2,24,0) gint i; GtkComboBoxText *combobox = GTK_COMBO_BOX_TEXT (gtk_builder_get_object (builder, "formatComboBox")); @@ -273,6 +274,11 @@ init_gtkwidgets_data (void) /* default to the first one -> ogg */ gtk_combo_box_set_active (GTK_COMBO_BOX (combobox), 0); + return TRUE; +#else + g_warning ("This needs a newer version of GTK (2.24 at least)"); + return FALSE; +#endif } int @@ -298,7 +304,9 @@ main (int argc, char *argv[]) gst_bus_set_sync_handler (bus, bus_sync_callback, NULL); gst_object_unref (bus); - init_gtkwidgets_data (); + if (!init_gtkwidgets_data ()) { + goto error; + } ui_main_window = GTK_WIDGET (gtk_builder_get_object (builder, "mainWindow")); gtk_builder_connect_signals (builder, NULL); @@ -308,6 +316,7 @@ main (int argc, char *argv[]) gtk_main (); +error: gst_element_set_state (camera, GST_STATE_NULL); gst_object_unref (camera); return ret; From 70390ad8462cc33685d5f956e2a20038c69ca974 Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Thu, 8 Dec 2011 11:27:56 +0800 Subject: [PATCH 08/27] codecparsers: fix mask pattern for h263 start marker --- gst-libs/gst/codecparsers/gstmpeg4parser.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst-libs/gst/codecparsers/gstmpeg4parser.c b/gst-libs/gst/codecparsers/gstmpeg4parser.c index 302219fc13..658f678586 100644 --- a/gst-libs/gst/codecparsers/gstmpeg4parser.c +++ b/gst-libs/gst/codecparsers/gstmpeg4parser.c @@ -273,7 +273,7 @@ find_psc (GstByteReader * br) /* Scan for the picture start code (22 bits - 0x0020) */ while ((gst_byte_reader_get_remaining (br) >= 3)) { if (gst_byte_reader_peek_uint24_be (br, &psc) && - ((psc & 0xffffc0) == 0x000080)) { + ((psc & 0xfffffc) == 0x000080)) { psc_pos = gst_byte_reader_get_pos (br); break; } else From 052d1ace5e617015af99663b1bcd9f13d462b41d Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Thu, 8 Dec 2011 12:07:42 +0800 Subject: [PATCH 09/27] codecparsers: fix offset issue in h263 parse --- gst-libs/gst/codecparsers/gstmpeg4parser.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst-libs/gst/codecparsers/gstmpeg4parser.c b/gst-libs/gst/codecparsers/gstmpeg4parser.c index 658f678586..686ae9336a 100644 --- a/gst-libs/gst/codecparsers/gstmpeg4parser.c +++ b/gst-libs/gst/codecparsers/gstmpeg4parser.c @@ -524,7 +524,7 @@ gst_h263_parse (GstMpeg4Packet * packet, gint off1, off2; GstByteReader br; - gst_byte_reader_init (&br, data, size); + gst_byte_reader_init (&br, data + offset, size - offset); g_return_val_if_fail (packet != NULL, GST_MPEG4_PARSER_ERROR); @@ -541,9 +541,10 @@ gst_h263_parse (GstMpeg4Packet * packet, return GST_MPEG4_PARSER_NO_PACKET; } - packet->offset = off1; + packet->offset = off1 + offset; packet->data = data; + gst_byte_reader_skip (&br, 3); off2 = find_psc (&br); if (off2 == -1) { From 1138aab1db5d359dade2585c83dc4e61501677a9 Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Thu, 8 Dec 2011 12:12:21 +0800 Subject: [PATCH 10/27] codecparsers: includes start_marker in h263 header for parsing --- gst-libs/gst/codecparsers/gstmpeg4parser.c | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/codecparsers/gstmpeg4parser.c b/gst-libs/gst/codecparsers/gstmpeg4parser.c index 686ae9336a..ad7fcb6382 100644 --- a/gst-libs/gst/codecparsers/gstmpeg4parser.c +++ b/gst-libs/gst/codecparsers/gstmpeg4parser.c @@ -1497,7 +1497,10 @@ gst_mpeg4_parse_video_plane_short_header (GstMpeg4VideoPlaneShortHdr * g_return_val_if_fail (shorthdr != NULL, GST_MPEG4_PARSER_ERROR); - if (gst_bit_reader_get_remaining (&br) < 26) + if (gst_bit_reader_get_remaining (&br) < 48) + goto failed; + + if (gst_bit_reader_get_bits_uint32_unchecked (&br, 22) != 0x20) goto failed; shorthdr->temporal_reference = @@ -1518,26 +1521,31 @@ gst_mpeg4_parse_video_plane_short_header (GstMpeg4VideoPlaneShortHdr * shorthdr->vop_height = 96; shorthdr->num_macroblocks_in_gob = 8; shorthdr->num_gobs_in_vop = 6; + break; case 0x02: shorthdr->vop_width = 176; shorthdr->vop_height = 144; shorthdr->num_macroblocks_in_gob = 11; shorthdr->num_gobs_in_vop = 9; + break; case 0x03: shorthdr->vop_width = 352; shorthdr->vop_height = 288; shorthdr->num_macroblocks_in_gob = 22; shorthdr->num_gobs_in_vop = 18; + break; case 0x04: shorthdr->vop_width = 704; shorthdr->vop_height = 576; shorthdr->num_macroblocks_in_gob = 88; shorthdr->num_gobs_in_vop = 18; + break; case 0x05: shorthdr->vop_width = 1408; shorthdr->vop_height = 1152; shorthdr->num_macroblocks_in_gob = 352; shorthdr->num_gobs_in_vop = 18; + break; default: shorthdr->vop_width = 0; shorthdr->vop_height = 0; From bb52df5e24a7271f310eebe16a47719262285a79 Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Thu, 8 Dec 2011 12:13:38 +0800 Subject: [PATCH 11/27] codecparsers: add missing zero_bits in h263 parsing --- gst-libs/gst/codecparsers/gstmpeg4parser.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gst-libs/gst/codecparsers/gstmpeg4parser.c b/gst-libs/gst/codecparsers/gstmpeg4parser.c index ad7fcb6382..461196a762 100644 --- a/gst-libs/gst/codecparsers/gstmpeg4parser.c +++ b/gst-libs/gst/codecparsers/gstmpeg4parser.c @@ -1506,6 +1506,10 @@ gst_mpeg4_parse_video_plane_short_header (GstMpeg4VideoPlaneShortHdr * shorthdr->temporal_reference = gst_bit_reader_get_bits_uint8_unchecked (&br, 8); CHECK_MARKER (&br); + zero_bits = gst_bit_reader_get_bits_uint8_unchecked (&br, 1); + if (zero_bits != 0x00) + goto failed; + shorthdr->split_screen_indicator = gst_bit_reader_get_bits_uint8_unchecked (&br, 1); shorthdr->document_camera_indicator = From 5676ff5bf4d3e2501875c4684e8370185d78bdef Mon Sep 17 00:00:00 2001 From: Zhao Halley Date: Thu, 8 Dec 2011 12:15:39 +0800 Subject: [PATCH 12/27] codecparsers: remove h263 gob parsing, since there is no gob immediate after svh --- gst-libs/gst/codecparsers/gstmpeg4parser.c | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/gst-libs/gst/codecparsers/gstmpeg4parser.c b/gst-libs/gst/codecparsers/gstmpeg4parser.c index 461196a762..fcaa4195e0 100644 --- a/gst-libs/gst/codecparsers/gstmpeg4parser.c +++ b/gst-libs/gst/codecparsers/gstmpeg4parser.c @@ -1491,7 +1491,6 @@ gst_mpeg4_parse_video_plane_short_header (GstMpeg4VideoPlaneShortHdr * shorthdr, const guint8 * data, gsize size) { guint8 zero_bits; - guint32 gob_resync; GstBitReader br = GST_BIT_READER_INIT (data, size); @@ -1578,26 +1577,6 @@ gst_mpeg4_parse_video_plane_short_header (GstMpeg4VideoPlaneShortHdr * } while (shorthdr->pei == 1); - if (!gst_bit_reader_peek_bits_uint32 (&br, &gob_resync, 17)) - goto failed; - - /* gob_layer() */ - - /* Setting default values */ - shorthdr->gob_header_empty = 1; - shorthdr->gob_number = 0; - shorthdr->gob_frame_id = 0; - shorthdr->quant_scale = 0; - - if (gob_resync == 0x01) { - shorthdr->gob_header_empty = 0; - - gst_bit_reader_skip_unchecked (&br, 17); - READ_UINT8 (&br, shorthdr->gob_number, 5); - READ_UINT8 (&br, shorthdr->gob_frame_id, 2); - READ_UINT8 (&br, shorthdr->quant_scale, 5); - } - shorthdr->size = gst_bit_reader_get_pos (&br); return GST_MPEG4_PARSER_OK; From 53735eaa72c4dd1c9714a9fed58ea13738969189 Mon Sep 17 00:00:00 2001 From: "Oleksij Rempel (Alexey Fisher)" Date: Mon, 2 Jan 2012 08:28:13 +0100 Subject: [PATCH 13/27] vp8: add initial preset file This is initial preset file, currently with only one profile for realtime encoding. Signed-off-by: Oleksij Rempel (Alexey Fisher) --- ext/vp8/GstVP8Enc.prs | 7 +++++++ ext/vp8/Makefile.am | 5 +++++ 2 files changed, 12 insertions(+) create mode 100644 ext/vp8/GstVP8Enc.prs diff --git a/ext/vp8/GstVP8Enc.prs b/ext/vp8/GstVP8Enc.prs new file mode 100644 index 0000000000..6e1d13d9b2 --- /dev/null +++ b/ext/vp8/GstVP8Enc.prs @@ -0,0 +1,7 @@ +[_presets_] +version=0.10 +element-name=GstVP8Enc + +[Profile Realtime] +max-latency=1 +speed=2 diff --git a/ext/vp8/Makefile.am b/ext/vp8/Makefile.am index d839666fda..312966c6a5 100644 --- a/ext/vp8/Makefile.am +++ b/ext/vp8/Makefile.am @@ -24,3 +24,8 @@ noinst_HEADERS = \ gstvp8dec.h \ gstvp8enc.h \ gstvp8utils.h + +presetdir = $(datadir)/gstreamer-$(GST_MAJORMINOR)/presets +preset_DATA = GstVP8Enc.prs + +EXTRA_DIST = $(preset_DATA) From 1c25aab906041c1aa9bd38db3c9c958ad65a2c05 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Fri, 6 Jan 2012 10:39:07 +0000 Subject: [PATCH 14/27] interlace: avoid dividing by zero on unkbown framerate If the framerate is unknown, we cannot generate meaningful buffer timestamps/durations, so set them to _NONE instead of calculating something wrong and dividing by 0. --- gst/interlace/gstinterlace.c | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/gst/interlace/gstinterlace.c b/gst/interlace/gstinterlace.c index 0e86f85704..1665ed791c 100644 --- a/gst/interlace/gstinterlace.c +++ b/gst/interlace/gstinterlace.c @@ -328,13 +328,19 @@ gst_interlace_decorate_buffer (GstInterlace * interlace, GstBuffer * buf, int n_fields) { /* field duration = src_fps_d / (2 * src_fps_n) */ - GST_BUFFER_TIMESTAMP (buf) = interlace->timebase + - gst_util_uint64_scale (GST_SECOND, - interlace->src_fps_d * interlace->fields_since_timebase, - interlace->src_fps_n * 2); - GST_BUFFER_DURATION (buf) = - gst_util_uint64_scale (GST_SECOND, interlace->src_fps_d * n_fields, - interlace->src_fps_n * 2); + if (interlace->src_fps_n == 0) { + /* If we don't know the fps, we can't generate timestamps/durations */ + GST_BUFFER_TIMESTAMP (buf) = GST_CLOCK_TIME_NONE; + GST_BUFFER_DURATION (buf) = GST_CLOCK_TIME_NONE; + } else { + GST_BUFFER_TIMESTAMP (buf) = interlace->timebase + + gst_util_uint64_scale (GST_SECOND, + interlace->src_fps_d * interlace->fields_since_timebase, + interlace->src_fps_n * 2); + GST_BUFFER_DURATION (buf) = + gst_util_uint64_scale (GST_SECOND, interlace->src_fps_d * n_fields, + interlace->src_fps_n * 2); + } /* increment the buffer timestamp by duration for the next buffer */ gst_buffer_set_caps (buf, interlace->srccaps); From 4f27b2b4fe7ece1ce47106ef55ccc0d9dbc0cedd Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Fri, 6 Jan 2012 10:52:36 +0000 Subject: [PATCH 15/27] h264parse: fix test and set not using the same input This fixes H.264 output not having a set framerate, and confusing some of the elements downstream (such as interlace). --- gst/videoparsers/gsth264parse.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c index 505def9a69..05a5bab2ad 100644 --- a/gst/videoparsers/gsth264parse.c +++ b/gst/videoparsers/gsth264parse.c @@ -1060,7 +1060,7 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps) gst_caps_set_simple (caps, "width", G_TYPE_INT, sps->width, "height", G_TYPE_INT, sps->height, NULL); /* but not necessarily or reliably this */ - if (h264parse->fps_num > 0 && h264parse->fps_den > 0) + if (sps->fps_num > 0 && sps->fps_den > 0) gst_caps_set_simple (caps, "framerate", GST_TYPE_FRACTION, sps->fps_num, sps->fps_den, NULL); } From 36c496b8f144f6441a46cca86987671f7cddca74 Mon Sep 17 00:00:00 2001 From: David Biomech360 Date: Mon, 19 Dec 2011 11:24:31 -0500 Subject: [PATCH 16/27] coloreffects: added support for a visual magnifier color filter to be used in gnome-video-effects https://bugzilla.gnome.org/show_bug.cgi?id=666542 --- gst/coloreffects/gstcoloreffects.c | 37 ++++++++++++++++++++++++++++++ gst/coloreffects/gstcoloreffects.h | 4 +++- 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/gst/coloreffects/gstcoloreffects.c b/gst/coloreffects/gstcoloreffects.c index 0941df1952..35af8a27bb 100644 --- a/gst/coloreffects/gstcoloreffects.c +++ b/gst/coloreffects/gstcoloreffects.c @@ -86,6 +86,7 @@ gst_color_effects_preset_get_type (void) {GST_COLOR_EFFECTS_PRESET_XRAY, "Invert and slightly shade to blue", "xray"}, {GST_COLOR_EFFECTS_PRESET_XPRO, "Cross processing toning", "xpro"}, + {GST_COLOR_EFFECTS_PRESET_YELLOWBLUE, "Yellow foreground Blue background color filter", "yellowblue"}, {0, NULL, NULL}, }; @@ -253,6 +254,38 @@ static const guint8 xpro_table[768] = "\376\365\377\377\365\377\377\366\377\377\366\377\377\366\377\377\367\377" "\377\367\377\377\367\377\377\370"; +/*Used for a video magnifer emulator in gnome-video-effects*/ +static const guint8 yellowblue_table[768] = + "\0\0\377\1\1\376\2\2\375\3\3\374\4\4\373\5\5\372\6\6\371\7\7\370\10\10\367" + "\11\11\367\12\12\365\13\13\364\14\14\363\15\14\362\16\16\361\17\17\360\20" + "\20\357\20\21\356\22\22\355\23\23\354\24\24\354\24\25\352\26\26\351\27\27" + "\350\27\30\347\31\31\346\32\32\345\33\32\344\34\34\343\34\34\342\36\36\341" + "\37\36\340\40\40\337!!\336!!\335##\334$#\334%%\332&%\331'&\330((\327()\326" + "*)\325++\324,,\323--\322..\321//\320/0\31711\31722\31522\31444\31445\313" + "55\31276\31188\30799\3069:\305;;\305<<\304==\302>>\301>>\300@@\300@A\276" + "AB\275BC\274CD\273DE\272EE\272FF\270HH\270HI\266IJ\265KK\264KL\263MM\262" + "NN\262NN\261OO\257QP\256RQ\256RR\254TT\253UU\253VU\251VW\250XX\247XY\246" + "YZ\245[[\245[[\243]]\243^^\242^_\240_`\237`a\236aa\235bb\235dc\233de\233" + "ff\232gf\231hg\230hi\227ji\226kj\225lk\223lm\223nm\222nn\221op\217qq\216" + "rr\215ss\214st\213uu\213uu\211wv\210ww\207xx\207yz\205z{\205{{\204||\203" + "}}\202\177~\201\177\200\177\200\201\177\202\202~\203\202|\204\203|\204\204" + "{\205\206z\207\206x\207\207w\211\210w\211\211v\212\212u\213\214s\214\214" + "r\215\215r\216\217q\217\217p\221\220o\221\222n\223\222l\224\223k\224\224" + "k\225\225j\226\226i\227\227h\230\231f\231\231f\233\232e\233\233c\234\234" + "c\235\235b\236\236a\237\237`\241\240_\242\241^\242\242]\243\244\\\244\244" + "[\245\245Y\246\246Y\250\247X\250\250W\251\251V\252\252T\253\253T\254\255" + "S\256\255R\257\256Q\257\260P\260\261O\261\261N\262\262M\263\263L\264\265" + "K\265\265J\266\266I\267\270H\270\270G\271\271F\272\272E\273\273C\274\274" + "B\275\275B\276\276A\277\277@\300\300?\301\301>\302\302=\303\303<\304\304" + ";\305\305:\306\3069\307\3078\310\3107\311\3116\312\3125\313\3134\314\314" + "3\315\3152\316\3161\317\3170\320\320/\321\321.\322\322-\323\323,\323\324" + "+\325\325*\326\326)\327\327(\330\330'\331\331&\332\331%\333\332$\334\334" + "#\334\335\"\336\336!\337\337\40\340\340\37\341\341\36\342\342\35\343\343" + "\34\344\344\33\345\345\32\345\346\31\347\347\30\350\350\27\351\351\26\352" + "\352\25\353\353\24\354\354\23\354\355\22\356\356\21\357\357\20\360\360\17" + "\361\361\16\362\362\15\363\362\14\364\364\13\365\365\12\365\366\11\367\367" + "\11\370\370\7\371\371\6\372\371\5\373\373\4\374\374\4\375\375\3\375\376\1"; + static const int cog_ycbcr_to_rgb_matrix_8bit_sdtv[] = { 298, 0, 409, -57068, 298, -100, -208, 34707, @@ -543,6 +576,10 @@ gst_color_effects_set_property (GObject * object, guint prop_id, filter->table = xpro_table; filter->map_luma = FALSE; break; + case GST_COLOR_EFFECTS_PRESET_YELLOWBLUE: + filter->table = yellowblue_table; + filter->map_luma = FALSE; + break; default: g_assert_not_reached (); diff --git a/gst/coloreffects/gstcoloreffects.h b/gst/coloreffects/gstcoloreffects.h index 04e52a9038..e2ae65f946 100644 --- a/gst/coloreffects/gstcoloreffects.h +++ b/gst/coloreffects/gstcoloreffects.h @@ -45,6 +45,7 @@ typedef struct _GstColorEffectsClass GstColorEffectsClass; * @GST_CLUT_PRESET_SEPIA: Sepia toning filter * @GST_CLUT_PRESET_XRAY: Invert colors and slightly shade to cyan * @GST_CLUT_PRESET_XPRO: Cross Processing filter + * @GST_CLUT_PRESET_YELLOWBLUE: Visual magnifier high-contrast color filter. Since: 0.10.24 * * The lookup table to use to convert input colors */ @@ -54,7 +55,8 @@ typedef enum GST_COLOR_EFFECTS_PRESET_HEAT, GST_COLOR_EFFECTS_PRESET_SEPIA, GST_COLOR_EFFECTS_PRESET_XRAY, - GST_COLOR_EFFECTS_PRESET_XPRO + GST_COLOR_EFFECTS_PRESET_XPRO, + GST_COLOR_EFFECTS_PRESET_YELLOWBLUE, } GstColorEffectsPreset; /** From e81ecb250af9adc7041c82f2f0986e7e6d59a148 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Mon, 9 Jan 2012 10:58:56 +0000 Subject: [PATCH 17/27] mpegvideoparse: add a couple consts on string literal arrays --- gst/videoparsers/gstmpegvideoparse.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gst/videoparsers/gstmpegvideoparse.c b/gst/videoparsers/gstmpegvideoparse.c index 4f8eb3a37d..4170996aea 100644 --- a/gst/videoparsers/gstmpegvideoparse.c +++ b/gst/videoparsers/gstmpegvideoparse.c @@ -624,12 +624,13 @@ gst_mpegv_parse_update_src_caps (GstMpegvParse * mpvparse) * 3 => SNR Scalable, 4 => Main, 5 => Simple * 4:2:2 and Multi-view have profile = 0, with the escape bit set to 1 */ - const gchar *profiles[] = { "high", "spatial", "snr", "main", "simple" }; + const gchar *const profiles[] = + { "high", "spatial", "snr", "main", "simple" }; /* * Level indication - 4 => High, 6 => High-1440, 8 => Main, 10 => Low, * except in the case of profile = 0 */ - const gchar *levels[] = { "high", "high-1440", "main", "low" }; + const gchar *const levels[] = { "high", "high-1440", "main", "low" }; if (profile_c > 0 && profile_c < 6) profile = profiles[profile_c - 1]; From 2dc41db862ec8fe6ab361b0a066cd71e1c71b44d Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Mon, 9 Jan 2012 11:03:24 +0000 Subject: [PATCH 18/27] h264parse: use the framerate that was copied a few lines above --- gst/videoparsers/gsth264parse.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c index 05a5bab2ad..2e4da486ad 100644 --- a/gst/videoparsers/gsth264parse.c +++ b/gst/videoparsers/gsth264parse.c @@ -1060,9 +1060,9 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps) gst_caps_set_simple (caps, "width", G_TYPE_INT, sps->width, "height", G_TYPE_INT, sps->height, NULL); /* but not necessarily or reliably this */ - if (sps->fps_num > 0 && sps->fps_den > 0) + if (h264parse->fps_num > 0 && h264parse->fps_den > 0) gst_caps_set_simple (caps, "framerate", - GST_TYPE_FRACTION, sps->fps_num, sps->fps_den, NULL); + GST_TYPE_FRACTION, h264parse->fps_num, h264parse->fps_den, NULL); } } From 360cbaa46c4949a8ce3c53a70147d297c089d3de Mon Sep 17 00:00:00 2001 From: Mark Nauwelaerts Date: Mon, 9 Jan 2012 14:56:29 +0100 Subject: [PATCH 19/27] codecparsers: mpeg4: fix parsing when recursively skipping user data --- gst-libs/gst/codecparsers/gstmpeg4parser.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/gst-libs/gst/codecparsers/gstmpeg4parser.c b/gst-libs/gst/codecparsers/gstmpeg4parser.c index fcaa4195e0..4b0acb6b59 100644 --- a/gst-libs/gst/codecparsers/gstmpeg4parser.c +++ b/gst-libs/gst/codecparsers/gstmpeg4parser.c @@ -473,8 +473,7 @@ gst_mpeg4_parse (GstMpeg4Packet * packet, gboolean skip_user_data, if (skip_user_data && data[off1 + 3] == GST_MPEG4_USER_DATA) /* If we are here, we know no resync code has been found the first time, so we * don't look for it this time */ - return gst_mpeg4_parse (packet, skip_user_data, NULL, data, off1 + 3, - size - off1 - 3); + return gst_mpeg4_parse (packet, skip_user_data, NULL, data, off1 + 3, size); packet->offset = off1 + 3; packet->data = data; From 1d0507af896ca76d4629ce1a83ae8da356d4808a Mon Sep 17 00:00:00 2001 From: "Oleksij Rempel (Alexey Fisher)" Date: Wed, 4 Jan 2012 11:09:23 +0100 Subject: [PATCH 20/27] basevideodecoder: add option to hande alt frame data altref/invisible 'frame' do not describe some frame directly, so it can't be displayed and timestamps should not be updated. Fix bug: https://bugzilla.gnome.org/show_bug.cgi?id=655245 Signed-off-by: Oleksij Rempel (Alexey Fisher) --- gst-libs/gst/video/gstbasevideocodec.h | 4 ++++ gst-libs/gst/video/gstbasevideodecoder.c | 7 ++++++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/gst-libs/gst/video/gstbasevideocodec.h b/gst-libs/gst/video/gstbasevideocodec.h index 41c2282a6e..7a76f9d12a 100644 --- a/gst-libs/gst/video/gstbasevideocodec.h +++ b/gst-libs/gst/video/gstbasevideocodec.h @@ -124,6 +124,10 @@ struct _GstVideoFrame gboolean is_sync_point; gboolean is_eos; + /* Frames that should not be pushed downstream and are + * not meant for display */ + gboolean decode_only; + GstBuffer *sink_buffer; GstBuffer *src_buffer; diff --git a/gst-libs/gst/video/gstbasevideodecoder.c b/gst-libs/gst/video/gstbasevideodecoder.c index 6a5554ea31..83255f4141 100644 --- a/gst-libs/gst/video/gstbasevideodecoder.c +++ b/gst-libs/gst/video/gstbasevideodecoder.c @@ -1411,6 +1411,11 @@ gst_base_video_decoder_prepare_finish_frame (GstBaseVideoDecoder * } g_list_free (events); + /* Check if the data should not be displayed. For example altref/invisible + * frame in vp8. In this case we should not update the timestamps. */ + if (frame->decode_only) + return; + if (GST_CLOCK_TIME_IS_VALID (frame->presentation_timestamp)) { if (frame->presentation_timestamp != base_video_decoder->timestamp_offset) { GST_DEBUG_OBJECT (base_video_decoder, @@ -1564,7 +1569,7 @@ gst_base_video_decoder_finish_frame (GstBaseVideoDecoder * base_video_decoder, base_video_decoder->processed++; /* no buffer data means this frame is skipped */ - if (!frame->src_buffer) { + if (!frame->src_buffer || frame->decode_only) { GST_DEBUG_OBJECT (base_video_decoder, "skipping frame %" GST_TIME_FORMAT, GST_TIME_ARGS (frame->presentation_timestamp)); goto done; From 3d34779e2401598ac7f49fedda75d852e98c7bd6 Mon Sep 17 00:00:00 2001 From: "Oleksij Rempel (Alexey Fisher)" Date: Wed, 4 Jan 2012 11:05:48 +0100 Subject: [PATCH 21/27] vp8dec: use is_alt_data option to prevent timestamp collisions altref/invisible frames usually stored in container with same timestamp as dependet frame. This make basevideodecoder to update timestamp for dependet frame and couse TS colision on next frame: ^- here is altref time : 1 2 3 4 5 6 7 8 9 webm ts : 1 3 5 5 7 9 vp8dec ts: 1 3 7 7 9 Fix bug: https://bugzilla.gnome.org/show_bug.cgi?id=655245 Signed-off-by: Oleksij Rempel (Alexey Fisher) --- ext/vp8/gstvp8dec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/vp8/gstvp8dec.c b/ext/vp8/gstvp8dec.c index e3a2fd9bdc..68abfece18 100644 --- a/ext/vp8/gstvp8dec.c +++ b/ext/vp8/gstvp8dec.c @@ -495,6 +495,7 @@ gst_vp8_dec_handle_frame (GstBaseVideoDecoder * decoder, GstVideoFrame * frame) } } else { /* Invisible frame */ + frame->decode_only = 1; gst_base_video_decoder_finish_frame (decoder, frame); } From 24408bce96e85a4788e551d250fc2aa66537cdd2 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Tue, 10 Jan 2012 11:37:13 +0100 Subject: [PATCH 22/27] tsdemux: Handle rollover in PTS and DTS Also hands back-rollover which can happen with PTS --- gst/mpegtsdemux/tsdemux.c | 88 +++++++++++++++++++++++++++++++++------ 1 file changed, 75 insertions(+), 13 deletions(-) diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c index 118ffb598a..58f3a82743 100644 --- a/gst/mpegtsdemux/tsdemux.c +++ b/gst/mpegtsdemux/tsdemux.c @@ -63,6 +63,7 @@ #define PCR_SMALL 17775000 /* maximal PCR time */ #define PCR_MAX_VALUE (((((guint64)1)<<33) * 300) + 298) +#define PTS_DTS_MAX_VALUE (((guint64)1) << 33) /* seek to SEEK_TIMESTAMP_OFFSET before the desired offset and search then * either accurately or for the next timestamp @@ -72,6 +73,8 @@ GST_DEBUG_CATEGORY_STATIC (ts_demux_debug); #define GST_CAT_DEFAULT ts_demux_debug +#define ABSDIFF(a,b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a))) + static GQuark QUARK_TSDEMUX; static GQuark QUARK_PID; static GQuark QUARK_PCR; @@ -116,8 +119,15 @@ struct _TSDemuxStream GstBufferListIterator *currentit; GList *currentlist; - /* Current PTS for this stream */ + /* Current PTS/DTS for this stream */ GstClockTime pts; + GstClockTime dts; + /* Raw value of current PTS/DTS */ + guint64 raw_pts; + guint64 raw_dts; + /* Number of rollover seen for PTS/DTS (default:0) */ + guint nb_pts_rollover; + guint nb_dts_rollover; }; #define VIDEO_CAPS \ @@ -1229,7 +1239,13 @@ gst_ts_demux_stream_added (MpegTSBase * base, MpegTSBaseStream * bstream, /* Create the pad */ if (bstream->stream_type != 0xff) stream->pad = create_pad_for_stream (base, bstream, program); + stream->pts = GST_CLOCK_TIME_NONE; + stream->dts = GST_CLOCK_TIME_NONE; + stream->raw_pts = 0; + stream->raw_dts = 0; + stream->nb_pts_rollover = 0; + stream->nb_dts_rollover = 0; } stream->flow_return = GST_FLOW_OK; } @@ -1865,9 +1881,33 @@ gst_ts_demux_record_pts (GstTSDemux * demux, TSDemuxStream * stream, { MpegTSBaseStream *bs = (MpegTSBaseStream *) stream; - GST_LOG ("pid 0x%04x pts:%" GST_TIME_FORMAT " at offset %" - G_GUINT64_FORMAT, bs->pid, - GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (pts)), offset); + GST_LOG ("pid 0x%04x pts:%" G_GUINT64_FORMAT " at offset %" + G_GUINT64_FORMAT, bs->pid, pts, offset); + + if (G_UNLIKELY (GST_CLOCK_TIME_IS_VALID (stream->pts) && + ABSDIFF (stream->raw_pts, pts) > 900000)) { + /* Detect rollover if diff > 10s */ + GST_LOG ("Detected rollover (previous:%" G_GUINT64_FORMAT " new:%" + G_GUINT64_FORMAT ")", stream->raw_pts, pts); + if (pts < stream->raw_pts) { + /* Forward rollover */ + GST_LOG ("Forward rollover, incrementing nb_pts_rollover"); + stream->nb_pts_rollover++; + } else { + /* Reverse rollover */ + GST_LOG ("Reverse rollover, decrementing nb_pts_rollover"); + stream->nb_pts_rollover--; + } + } + + /* Compute PTS in GstClockTime */ + stream->raw_pts = pts; + stream->pts = + MPEGTIME_TO_GSTTIME (pts + stream->nb_pts_rollover * PTS_DTS_MAX_VALUE); + + GST_LOG ("pid 0x%04x Stored PTS %" G_GUINT64_FORMAT " (%" GST_TIME_FORMAT ")", + bs->pid, stream->raw_pts, GST_TIME_ARGS (stream->pts)); + if (G_UNLIKELY (demux->emit_statistics)) { GstStructure *st; @@ -1887,9 +1927,32 @@ gst_ts_demux_record_dts (GstTSDemux * demux, TSDemuxStream * stream, { MpegTSBaseStream *bs = (MpegTSBaseStream *) stream; - GST_LOG ("pid 0x%04x dts:%" GST_TIME_FORMAT " at offset %" - G_GUINT64_FORMAT, bs->pid, - GST_TIME_ARGS (MPEGTIME_TO_GSTTIME (dts)), offset); + GST_LOG ("pid 0x%04x dts:%" G_GUINT64_FORMAT " at offset %" + G_GUINT64_FORMAT, bs->pid, dts, offset); + + if (G_UNLIKELY (GST_CLOCK_TIME_IS_VALID (stream->dts) && + ABSDIFF (stream->raw_dts, dts) > 900000)) { + /* Detect rollover if diff > 10s */ + GST_LOG ("Detected rollover (previous:%" G_GUINT64_FORMAT " new:%" + G_GUINT64_FORMAT ")", stream->raw_dts, dts); + if (dts < stream->raw_dts) { + /* Forward rollover */ + GST_LOG ("Forward rollover, incrementing nb_dts_rollover"); + stream->nb_dts_rollover++; + } else { + /* Reverse rollover */ + GST_LOG ("Reverse rollover, decrementing nb_dts_rollover"); + stream->nb_dts_rollover--; + } + } + + /* Compute DTS in GstClockTime */ + stream->raw_dts = dts; + stream->dts = + MPEGTIME_TO_GSTTIME (dts + stream->nb_dts_rollover * PTS_DTS_MAX_VALUE); + + GST_LOG ("pid 0x%04x Stored DTS %" G_GUINT64_FORMAT " (%" GST_TIME_FORMAT ")", + bs->pid, stream->raw_dts, GST_TIME_ARGS (stream->dts)); if (G_UNLIKELY (demux->emit_statistics)) { GstStructure *st; @@ -1939,7 +2002,6 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream) guint8 *data; guint32 length; guint64 bufferoffset; - GstClockTime time; PESParsingResult parseres; data = GST_BUFFER_DATA (stream->pendingbuffers[0]); @@ -1957,6 +2019,9 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream) goto discont; } + if (header.DTS != -1) + gst_ts_demux_record_dts (demux, stream, header.DTS, bufferoffset); + if (header.PTS != -1) { gst_ts_demux_record_pts (demux, stream, header.PTS, bufferoffset); @@ -1980,7 +2045,6 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream) time = calc_gsttime_from_pts (&demux->index_pcr, pts); #endif - stream->pts = time = MPEGTIME_TO_GSTTIME (header.PTS); GST_DEBUG_OBJECT (base, "stream PTS %" GST_TIME_FORMAT, GST_TIME_ARGS (stream->pts)); @@ -2012,12 +2076,10 @@ gst_ts_demux_parse_pes_header (GstTSDemux * demux, TSDemuxStream * stream) if (!GST_CLOCK_TIME_IS_VALID (base->in_gap)) base->in_gap = 0; - GST_BUFFER_TIMESTAMP (stream->pendingbuffers[0]) = time + base->in_gap; + GST_BUFFER_TIMESTAMP (stream->pendingbuffers[0]) = + stream->pts + base->in_gap; } - if (header.DTS != -1) - gst_ts_demux_record_dts (demux, stream, header.DTS, bufferoffset); - /* Remove PES headers */ GST_DEBUG ("Moving data forward by %d bytes", header.header_size); GST_BUFFER_DATA (stream->pendingbuffers[0]) += header.header_size; From fcf511aa8f4ebc375e4d76d8eb9cd946b05e1b37 Mon Sep 17 00:00:00 2001 From: Edward Hervey Date: Tue, 10 Jan 2012 11:41:34 +0100 Subject: [PATCH 23/27] tsdemux: Don't provide bogus values in non-TIME push-mode Only take the upstream segment values in GST_FORMAT_TIME --- gst/mpegtsdemux/tsdemux.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c index 58f3a82743..c2ebe1700a 100644 --- a/gst/mpegtsdemux/tsdemux.c +++ b/gst/mpegtsdemux/tsdemux.c @@ -2168,7 +2168,7 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream) { MpegTSBase *base = (MpegTSBase *) demux; GstEvent *newsegmentevent; - gint64 start, stop, position; + gint64 start = 0, stop = GST_CLOCK_TIME_NONE, position = 0; GstClockTime firstpts = GST_CLOCK_TIME_NONE; GList *tmp; @@ -2196,21 +2196,24 @@ calculate_and_push_newsegment (GstTSDemux * demux, TSDemuxStream * stream) /* FIXME : We should use base->segment.format and a upstream latency query * to decide if we need to use live values or not */ GST_DEBUG ("push-based. base Segment start:%" GST_TIME_FORMAT " duration:%" - GST_TIME_FORMAT ", time:%" GST_TIME_FORMAT, + GST_TIME_FORMAT ", stop:%" GST_TIME_FORMAT ", time:%" GST_TIME_FORMAT, GST_TIME_ARGS (base->segment.start), GST_TIME_ARGS (base->segment.duration), - GST_TIME_ARGS (base->segment.time)); + GST_TIME_ARGS (base->segment.stop), GST_TIME_ARGS (base->segment.time)); GST_DEBUG ("push-based. demux Segment start:%" GST_TIME_FORMAT " duration:%" - GST_TIME_FORMAT ", time:%" GST_TIME_FORMAT, + GST_TIME_FORMAT ", stop:%" GST_TIME_FORMAT ", time:%" GST_TIME_FORMAT, GST_TIME_ARGS (demux->segment.start), GST_TIME_ARGS (demux->segment.duration), + GST_TIME_ARGS (demux->segment.stop), GST_TIME_ARGS (demux->segment.time)); GST_DEBUG ("stream pts: %" GST_TIME_FORMAT " first pts: %" GST_TIME_FORMAT, GST_TIME_ARGS (stream->pts), GST_TIME_ARGS (firstpts)); - start = base->segment.start; - stop = base->segment.stop; + if (base->segment.format == GST_FORMAT_TIME) { + start = base->segment.start; + stop = base->segment.stop; + } /* Shift the start depending on our position in the stream */ start += firstpts + base->in_gap - base->first_buf_ts; position = start; From 5ea1601dd9b0054592df57cd51653e706e398f57 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Tue, 10 Jan 2012 13:24:22 +0000 Subject: [PATCH 24/27] interlace: fix ref leak --- gst/interlace/gstinterlace.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gst/interlace/gstinterlace.c b/gst/interlace/gstinterlace.c index 1665ed791c..4e224be7b1 100644 --- a/gst/interlace/gstinterlace.c +++ b/gst/interlace/gstinterlace.c @@ -463,6 +463,8 @@ gst_interlace_getcaps (GstPad * pad) gst_caps_set_simple (icaps, "interlaced", G_TYPE_BOOLEAN, pad == interlace->srcpad ? TRUE : FALSE, NULL); + gst_object_unref (interlace); + return icaps; } From 6cf84a0348d49e2906451b251d1e09387b1199a6 Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Tue, 10 Jan 2012 13:25:05 +0000 Subject: [PATCH 25/27] interlace: fix caps leaks --- gst/interlace/gstinterlace.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/gst/interlace/gstinterlace.c b/gst/interlace/gstinterlace.c index 4e224be7b1..96455f1a24 100644 --- a/gst/interlace/gstinterlace.c +++ b/gst/interlace/gstinterlace.c @@ -187,6 +187,7 @@ static gboolean gst_interlace_setcaps (GstPad * pad, GstCaps * caps); static GstCaps *gst_interlace_getcaps (GstPad * pad); static GstStateChangeReturn gst_interlace_change_state (GstElement * element, GstStateChange transition); +static void gst_interlace_finalize (GObject * obj); static GstElementClass *parent_class = NULL; @@ -242,6 +243,7 @@ gst_interlace_class_init (GstInterlaceClass * klass) object_class->set_property = gst_interlace_set_property; object_class->get_property = gst_interlace_get_property; + object_class->finalize = gst_interlace_finalize; element_class->change_state = gst_interlace_change_state; @@ -268,6 +270,16 @@ gst_interlace_class_init (GstInterlaceClass * klass) } +static void +gst_interlace_finalize (GObject * obj) +{ + GstInterlace *interlace = GST_INTERLACE (obj); + + gst_caps_replace (&interlace->srccaps, NULL); + + G_OBJECT_CLASS (parent_class)->finalize (obj); +} + static void gst_interlace_reset (GstInterlace * interlace) { @@ -478,7 +490,7 @@ gst_interlace_setcaps (GstPad * pad, GstCaps * caps) gboolean interlaced = TRUE; int fps_n, fps_d; GstPad *otherpad; - GstCaps *othercaps; + GstCaps *othercaps = NULL; const PulldownFormat *pdformat; interlace = GST_INTERLACE (gst_pad_get_parent (pad)); @@ -527,6 +539,8 @@ gst_interlace_setcaps (GstPad * pad, GstCaps * caps) } error: + if (othercaps) + gst_caps_unref (othercaps); g_object_unref (interlace); return ret; From 9d675bfa8ddeb87ecdd1a5506e8a78791fa5447a Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Tue, 10 Jan 2012 13:38:42 +0000 Subject: [PATCH 26/27] opusenc: fix caps leak --- ext/opus/gstopusenc.c | 1 + 1 file changed, 1 insertion(+) diff --git a/ext/opus/gstopusenc.c b/ext/opus/gstopusenc.c index 0ccbbebc5f..016b891c81 100644 --- a/ext/opus/gstopusenc.c +++ b/ext/opus/gstopusenc.c @@ -897,6 +897,7 @@ gst_opus_enc_handle_frame (GstAudioEncoder * benc, GstBuffer * buf) GST_DEBUG_OBJECT (enc, "here are the caps: %" GST_PTR_FORMAT, caps); gst_pad_set_caps (GST_AUDIO_ENCODER_SRC_PAD (enc), caps); + gst_caps_unref (caps); enc->header_sent = TRUE; } From 1f543ec0ada7849a25a6451679eeb3cd3f605c1f Mon Sep 17 00:00:00 2001 From: Vincent Penquerc'h Date: Tue, 10 Jan 2012 13:38:50 +0000 Subject: [PATCH 27/27] opusenc: fix slist leak --- ext/opus/gstopusenc.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ext/opus/gstopusenc.c b/ext/opus/gstopusenc.c index 016b891c81..9b475cf8c7 100644 --- a/ext/opus/gstopusenc.c +++ b/ext/opus/gstopusenc.c @@ -360,6 +360,7 @@ gst_opus_enc_stop (GstAudioEncoder * benc) gst_tag_list_free (enc->tags); enc->tags = NULL; g_slist_foreach (enc->headers, (GFunc) gst_buffer_unref, NULL); + g_slist_free (enc->headers); enc->headers = NULL; gst_tag_setter_reset_tags (GST_TAG_SETTER (enc)); @@ -885,6 +886,7 @@ gst_opus_enc_handle_frame (GstAudioEncoder * benc, GstBuffer * buf) GstCaps *caps; g_slist_foreach (enc->headers, (GFunc) gst_buffer_unref, NULL); + g_slist_free (enc->headers); enc->headers = NULL; gst_opus_header_create_caps (&caps, &enc->headers, enc->n_channels,