diff options
author | Hyunjun Ko <zzoon@igalia.com> | 2017-03-07 18:33:12 +0900 |
---|---|---|
committer | Sebastian Dröge <sebastian@centricular.com> | 2017-03-07 13:27:33 +0200 |
commit | 201e71c3aacd4c61771fd6ac20dc39e43e42bb0c (patch) | |
tree | 39a83341d50a3929d279fdcf62a6fbd5cab81e53 /gst | |
parent | 08c52c931e5145a569da1efcd53d77e0090ec898 (diff) | |
download | gstreamer-plugins-bad-201e71c3aacd4c61771fd6ac20dc39e43e42bb0c.tar.gz |
h264parse: insert AU delimiter only in case of byte-stream
Inserts AU delimeter by default if missing au delimeter from upstream.
This should be done only in case of byte-stream format.
Note that:
We have to compensate for the new bytes added for the AU, otherwise
insertion of PPS/SPS will use wrong offsets and overwrite wrong data.
Also mark the AU delimiter blob const, and use frame->out_buffer for
storing the output to keep baseparse assumptions valid.
Original-Patch-By: Michal Lazo <michal.lazo@mdragon.org>
Helped by Sebastian Dröge <sebastian@centricular.com>
https://bugzilla.gnome.org/show_bug.cgi?id=736213
Diffstat (limited to 'gst')
-rw-r--r-- | gst/videoparsers/gsth264parse.c | 55 | ||||
-rw-r--r-- | gst/videoparsers/gsth264parse.h | 4 |
2 files changed, 54 insertions, 5 deletions
diff --git a/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c index aaf4c39ac..6aeb4e16f 100644 --- a/gst/videoparsers/gsth264parse.c +++ b/gst/videoparsers/gsth264parse.c @@ -164,6 +164,9 @@ gst_h264_parse_init (GstH264Parse * h264parse) gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (h264parse), FALSE); GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (h264parse)); GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (h264parse)); + + h264parse->aud_needed = TRUE; + h264parse->aud_insert = TRUE; } @@ -192,6 +195,7 @@ gst_h264_parse_reset_frame (GstH264Parse * h264parse) h264parse->keyframe = FALSE; h264parse->header = FALSE; h264parse->frame_start = FALSE; + h264parse->aud_insert = TRUE; gst_adapter_clear (h264parse->frame_out); } @@ -868,6 +872,7 @@ gst_h264_parse_process_nal (GstH264Parse * h264parse, GstH264NalUnit * nalu) pres = gst_h264_parser_parse_nal (nalparser, nalu); if (pres != GST_H264_PARSER_OK) return FALSE; + h264parse->aud_insert = FALSE; break; default: /* drop anything before the initial SPS */ @@ -943,6 +948,11 @@ gst_h264_parse_collect_nal (GstH264Parse * h264parse, const guint8 * data, return complete; } +static guint8 au_delim[6] = { + 0x00, 0x00, 0x00, 0x01, /* nal prefix */ + 0x09, /* nal unit type = access unit delimiter */ + 0xf0 /* allow any slice type */ +}; static GstFlowReturn gst_h264_parse_handle_frame_packetized (GstBaseParse * parse, @@ -1054,6 +1064,7 @@ gst_h264_parse_handle_frame (GstBaseParse * parse, GstH264ParserResult pres; gint framesize; GstFlowReturn ret; + gboolean au_complete; if (G_UNLIKELY (GST_BUFFER_FLAG_IS_SET (frame->buffer, GST_BUFFER_FLAG_DISCONT))) { @@ -1204,9 +1215,6 @@ gst_h264_parse_handle_frame (GstBaseParse * parse, GST_DEBUG_OBJECT (h264parse, "%p complete nal found. Off: %u, Size: %u", data, nalu.offset, nalu.size); - /* simulate no next nal if none needed */ - nonext = nonext || (h264parse->align == GST_H264_PARSE_ALIGN_NAL); - if (!nonext) { if (nalu.offset + nalu.size + 4 + 2 > size) { GST_DEBUG_OBJECT (h264parse, "not enough data for next NALU"); @@ -1231,7 +1239,18 @@ gst_h264_parse_handle_frame (GstBaseParse * parse, break; /* if no next nal, we know it's complete here */ - if (gst_h264_parse_collect_nal (h264parse, data, size, &nalu)) + au_complete = gst_h264_parse_collect_nal (h264parse, data, size, &nalu); + + /* Judge whether or not to insert AU Delimiter in case of byte-stream */ + if (h264parse->align == GST_H264_PARSE_ALIGN_NAL) { + if (!h264parse->aud_needed) + h264parse->aud_insert = FALSE; + + h264parse->aud_needed = au_complete; + break; + } + + if (au_complete) break; GST_DEBUG_OBJECT (h264parse, "Looking for more"); @@ -2364,7 +2383,33 @@ gst_h264_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) h264parse->sent_codec_tag = TRUE; } - buffer = frame->buffer; + /* In case of byte-stream, insert au delimeter by default + * if it doesn't exist */ + if (frame->buffer != NULL && h264parse->aud_insert + && h264parse->format == GST_H264_PARSE_FORMAT_BYTE) { + if (h264parse->align == GST_H264_PARSE_ALIGN_AU) { + GstMemory *mem = + gst_memory_new_wrapped (GST_MEMORY_FLAG_READONLY, (guint8 *) au_delim, + sizeof (au_delim), 0, sizeof (au_delim), NULL, NULL); + + frame->out_buffer = gst_buffer_copy (frame->buffer); + gst_buffer_prepend_memory (frame->out_buffer, mem); + if (h264parse->idr_pos >= 0) + h264parse->idr_pos += sizeof (au_delim); + + buffer = frame->out_buffer; + } else { + GstBuffer *aud_buffer = gst_buffer_new_allocate (NULL, 2, NULL); + gst_buffer_fill (aud_buffer, 0, (guint8 *) (au_delim + 4), 2); + + buffer = frame->buffer; + gst_h264_parse_push_codec_buffer (h264parse, aud_buffer, + GST_BUFFER_TIMESTAMP (buffer)); + gst_buffer_unref (aud_buffer); + } + } else { + buffer = frame->buffer; + } if ((event = check_pending_key_unit_event (h264parse->force_key_unit_event, &parse->segment, GST_BUFFER_TIMESTAMP (buffer), diff --git a/gst/videoparsers/gsth264parse.h b/gst/videoparsers/gsth264parse.h index c71990b12..137c2cdc7 100644 --- a/gst/videoparsers/gsth264parse.h +++ b/gst/videoparsers/gsth264parse.h @@ -128,6 +128,10 @@ struct _GstH264Parse GstVideoMultiviewMode multiview_mode; GstVideoMultiviewFlags multiview_flags; gboolean first_in_bundle; + + /* For insertion of AU Delimiter */ + gboolean aud_needed; + gboolean aud_insert; }; struct _GstH264ParseClass |