| From 41476a48b06f2b2285659844e88f3e7ffa71b1ec Mon Sep 17 00:00:00 2001 |
| From: Yuan Fang <yuan.fang@mediatek.com> |
| Date: Wed, 14 Aug 2019 16:18:17 +0800 |
| Subject: [PATCH] upgrade-gst-bad-to-1-14-4 |
| |
| --- |
| ext/resindvd/gstmpegdemux.c | 17 ++++ |
| gst-libs/gst/wayland/Makefile.am | 3 + |
| gst-libs/gst/wayland/Makefile.in | 58 ++++++++--- |
| gst/adpcmdec/adpcmdec.c | 4 + |
| gst/ivfparse/gstivfparse.c | 3 +- |
| gst/jpegformat/gstjpegformat.c | 2 +- |
| gst/jpegformat/gstjpegparse.c | 2 +- |
| gst/mpegtsdemux/tsdemux.c | 178 ++++++++++++++++++++++++++++++++++ |
| gst/videoparsers/gsth264parse.c | 26 +++-- |
| gst/videoparsers/gsth264parse.h | 1 + |
| gst/videoparsers/gsth265parse.c | 8 +- |
| gst/videoparsers/gsth265parse.h | 1 + |
| gst/videoparsers/gstmpeg4videoparse.c | 9 +- |
| gst/videoparsers/gstmpeg4videoparse.h | 1 + |
| gst/videoparsers/gstmpegvideoparse.c | 91 ++++++++++++++--- |
| 15 files changed, 361 insertions(+), 43 deletions(-) |
| |
| diff --git a/ext/resindvd/gstmpegdemux.c b/ext/resindvd/gstmpegdemux.c |
| index a35a6a4..562f3bb 100644 |
| --- a/ext/resindvd/gstmpegdemux.c |
| +++ b/ext/resindvd/gstmpegdemux.c |
| @@ -1932,6 +1932,23 @@ gst_flups_demux_data_cb (GstPESFilter * filter, gboolean first, |
| } |
| if (stream_type == -1) |
| goto unknown_stream_type; |
| + } else if (stream_type == ST_GST_VIDEO_MPEG1_OR_2) { |
| + if (datalen >= 4) { |
| + if (!memcmp("\x00\x00\x01\xB0", map.data, 4)) { |
| + stream_type = ST_VIDEO_MPEG4; |
| + } |
| + } |
| + if (datalen >= 5) { |
| + if (!memcmp("\x00\x00\x01\x00\x00", map.data, 5)) { |
| + stream_type = ST_VIDEO_MPEG4; |
| + } |
| + } |
| + } else if (stream_type == ST_AUDIO_MPEG1) { |
| + if (datalen >= 4) { |
| + if (!memcmp("\xFF\xF1\x50\x80", map.data, 4)) { |
| + stream_type = ST_AUDIO_AAC_ADTS; |
| + } |
| + } |
| } |
| if (filter->pts != -1) { |
| demux->next_pts = filter->pts + demux->scr_adjust; |
| diff --git a/gst-libs/gst/wayland/Makefile.am b/gst-libs/gst/wayland/Makefile.am |
| index 743a489..d2e4f6e 100644 |
| --- a/gst-libs/gst/wayland/Makefile.am |
| +++ b/gst-libs/gst/wayland/Makefile.am |
| @@ -22,6 +22,9 @@ libgstwayland_@GST_API_VERSION@_la_LDFLAGS = \ |
| $(GST_ALL_LDFLAGS) \ |
| $(GST_LT_LDFLAGS) |
| |
| +libgstwayland_@GST_API_VERSION@include_HEADERS = \ |
| + wayland.h |
| + |
| noinst_HEADERS = \ |
| wayland.h |
| |
| diff --git a/gst/adpcmdec/adpcmdec.c b/gst/adpcmdec/adpcmdec.c |
| index 3cfa820..4412d85 100644 |
| --- a/gst/adpcmdec/adpcmdec.c |
| +++ b/gst/adpcmdec/adpcmdec.c |
| @@ -424,6 +424,10 @@ adpcmdec_handle_frame (GstAudioDecoder * bdec, GstBuffer * buffer) |
| ("frame decode failed"), ret); |
| } |
| |
| + if (bdec->ts_none) { |
| + bdec->sub_ts_none = FALSE; |
| + } |
| + |
| if (ret == GST_FLOW_OK) |
| ret = gst_audio_decoder_finish_frame (bdec, outbuf, 1); |
| |
| diff --git a/gst/ivfparse/gstivfparse.c b/gst/ivfparse/gstivfparse.c |
| index e0e8401..df6a915 100644 |
| --- a/gst/ivfparse/gstivfparse.c |
| +++ b/gst/ivfparse/gstivfparse.c |
| @@ -331,7 +331,8 @@ gst_ivf_parse_handle_frame_data (GstIvfParse * ivf, GstBaseParseFrame * frame, |
| if (gst_buffer_map (frame->out_buffer, &map, GST_MAP_READ)) { |
| guint32 width, height; |
| |
| - if (ivf->fourcc == GST_MAKE_FOURCC ('V', 'P', '8', '0')) { |
| + if ((ivf->fourcc == GST_MAKE_FOURCC ('V', 'P', '8', '0')) || |
| + (ivf->fourcc == GST_MAKE_FOURCC ('V', 'P', '9', '0'))) { |
| guint32 frame_tag; |
| frame_tag = GST_READ_UINT24_LE (map.data); |
| if (!(frame_tag & 0x01) && map.size >= 10) { /* key frame */ |
| diff --git a/gst/jpegformat/gstjpegformat.c b/gst/jpegformat/gstjpegformat.c |
| index b410466..1faf1ce 100644 |
| --- a/gst/jpegformat/gstjpegformat.c |
| +++ b/gst/jpegformat/gstjpegformat.c |
| @@ -30,7 +30,7 @@ |
| static gboolean |
| plugin_init (GstPlugin * plugin) |
| { |
| - if (!gst_element_register (plugin, "jpegparse", GST_RANK_NONE, |
| + if (!gst_element_register (plugin, "jpegparse", GST_RANK_PRIMARY, |
| GST_TYPE_JPEG_PARSE)) |
| return FALSE; |
| if (!gst_element_register (plugin, "jifmux", GST_RANK_SECONDARY, |
| diff --git a/gst/jpegformat/gstjpegparse.c b/gst/jpegformat/gstjpegparse.c |
| index 0bfdc80..b9f1853 100644 |
| --- a/gst/jpegformat/gstjpegparse.c |
| +++ b/gst/jpegformat/gstjpegparse.c |
| @@ -151,7 +151,7 @@ gst_jpeg_parse_class_init (GstJpegParseClass * klass) |
| |
| gst_element_class_set_static_metadata (gstelement_class, |
| "JPEG stream parser", |
| - "Video/Parser", |
| + "Video/Parser/Codec", |
| "Parse JPEG images into single-frame buffers", |
| "Arnout Vandecappelle (Essensium/Mind) <arnout@mind.be>"); |
| |
| diff --git a/gst/mpegtsdemux/tsdemux.c b/gst/mpegtsdemux/tsdemux.c |
| index e5c78e7..49a426f 100644 |
| --- a/gst/mpegtsdemux/tsdemux.c |
| +++ b/gst/mpegtsdemux/tsdemux.c |
| @@ -39,6 +39,9 @@ |
| #include <gst/pbutils/pbutils.h> |
| #include <gst/base/base.h> |
| #include <gst/audio/audio.h> |
| +#include <gst/riff/riff-read.h> |
| +#include <gst/riff/riff-ids.h> |
| +#include <gst/riff/riff-media.h> |
| |
| #include "mpegtsbase.h" |
| #include "tsdemux.h" |
| @@ -1067,6 +1070,168 @@ gst_ts_demux_create_tags (TSDemuxStream * stream) |
| } |
| } |
| |
| +static GstFlowReturn |
| +gst_ts_demux_scan_vc1_wh (MpegTSBase * base, guint * w, guint * h) |
| +{ |
| + const guint cacheSize = 64 * 1024; |
| + const guint cacheCount = 32; |
| + const guint gapCount = 4 + 2 + 3; |
| + guint cacheStart = 0; |
| + GstFlowReturn ret = GST_FLOW_ERROR; |
| + gboolean done = FALSE; |
| + GstBuffer *buffer = NULL; |
| + guint i = 0; |
| + guint offset = 0; |
| + GstMapInfo map; |
| + guint8 *data = NULL; |
| + size_t size = 0; |
| + |
| + if (G_UNLIKELY (base == NULL)) { |
| + GST_DEBUG ("base is NULL"); |
| + return ret; |
| + } |
| + |
| + if (w == NULL || h == NULL) { |
| + GST_DEBUG ("w or h is NULL"); |
| + return ret; |
| + } |
| + |
| + GST_DEBUG ("Scanning for width and height"); |
| + |
| + for (i = 0; (i < cacheCount) && !done; i++) { |
| + if (i == 0) { |
| + cacheStart = 0; |
| + } else { |
| + cacheStart = i * (cacheSize - gapCount); |
| + } |
| + |
| + GST_DEBUG ("Grabbing %d => %d", cacheStart, cacheStart + cacheSize); |
| + ret = gst_pad_pull_range (base->sinkpad, cacheStart, cacheSize, &buffer); |
| + if (G_UNLIKELY (ret == GST_FLOW_EOS)) { |
| + break; |
| + } |
| + if (G_UNLIKELY (ret != GST_FLOW_OK)) { |
| + break; |
| + } |
| + |
| + gst_buffer_map (buffer, &map, GST_MAP_READ); |
| + |
| + data=map.data; |
| + size=map.size; |
| + |
| + for (offset = 0; offset <= (size - gapCount); offset++) { |
| + if (memcmp("\x00\x00\x01\x0F", data + offset, 4)) { |
| + offset++; |
| + } else { |
| + offset +=4; |
| + offset +=2; |
| + |
| + *w = (((data[offset] << 4) + (data[offset+1] >> 4)) << 1) + 2; |
| + *h = ((((data[offset+1] & 0x0F) << 8) + data[offset+2]) << 1) + 2; |
| + done = TRUE; |
| + ret = GST_FLOW_OK; |
| + break; |
| + } |
| + } |
| + |
| + gst_buffer_unmap (buffer, &map); |
| + gst_buffer_unref(buffer); |
| + buffer = NULL; |
| + } |
| + |
| + return ret; |
| +} |
| + |
| +static GstFlowReturn |
| +gst_ts_demux_separate_vc1_header (GstTSDemux * demux, TSDemuxStream * stream, GstBuffer ** buffer) |
| +{ |
| + static gboolean headerPushed = FALSE; |
| + GstFlowReturn res = GST_FLOW_OK; |
| + |
| + if (memcmp("\x00\x00\x01\x0F", stream->data, 4)) { |
| + if (!headerPushed) { |
| + gst_buffer_unref (*buffer); |
| + GST_DEBUG ("This frame should be dropped!"); |
| + res = GST_FLOW_ERROR; |
| + return res; |
| + } |
| + } else { |
| + GstBuffer *bufLeft = NULL; |
| + const guint8 *data = stream->data; |
| + size_t offset = 0; |
| + |
| + while (offset + 3 < stream->current_size) { |
| + if (memcmp(data+offset, "\x00\x00\x01", 3)) { |
| + offset++; |
| + continue; |
| + } else { |
| + guint currentStartCode = data[offset+3]; |
| + |
| + if (currentStartCode == 0x0F || currentStartCode == 0x0E) { |
| + offset++; |
| + continue; |
| + } else { |
| + //found data |
| + break; |
| + } |
| + } |
| + } |
| + |
| + if (!headerPushed) { |
| + GstCaps *caps = NULL; |
| + GstStructure *str = NULL; |
| + GstBuffer *bufVids = NULL; |
| + GstBuffer *bufSeq = NULL; |
| + GstBuffer *bufMerged = NULL; |
| + guint width = 0; |
| + guint height = 0; |
| + gst_riff_strf_vids *pVids; |
| + const guint sizeVids = sizeof (gst_riff_strf_vids); |
| + |
| + pVids = g_new (gst_riff_strf_vids, 1); |
| + memset (pVids, 0, sizeVids); |
| + |
| + caps = gst_pad_get_current_caps (stream->pad); |
| + if (caps) { |
| + str = gst_caps_get_structure (caps, 0); |
| + |
| + gst_structure_get_int (str, "width", &width); |
| + gst_structure_get_int (str, "height", &height); |
| + } |
| + |
| + pVids->size = sizeVids + offset; |
| + pVids->width = width; |
| + pVids->height = height; |
| + |
| + pVids->size = GUINT32_FROM_LE (pVids->size); |
| + pVids->width = GUINT32_FROM_LE (pVids->width); |
| + pVids->height = GUINT32_FROM_LE (pVids->height); |
| + pVids->compression = GST_MAKE_FOURCC ('W', 'V', 'C', '1'); |
| + |
| + bufVids = gst_buffer_new_wrapped (g_memdup ((guint8 *) pVids, |
| + sizeVids), sizeVids); |
| + bufSeq = gst_buffer_new_wrapped (g_memdup ((guint8 *) data, |
| + offset), offset); |
| + bufMerged = gst_buffer_append (bufVids, bufSeq); |
| + |
| + gst_pad_push (stream->pad, bufMerged); |
| + headerPushed = TRUE; |
| + |
| + if (pVids) { |
| + g_free (pVids); |
| + } |
| + } |
| + |
| + bufLeft = gst_buffer_copy_region (*buffer, GST_BUFFER_COPY_ALL, offset, stream->current_size-offset); |
| + stream->current_size -= offset; |
| + gst_buffer_unref (*buffer); |
| + *buffer = bufLeft; |
| + res = GST_FLOW_OK; |
| + } |
| + |
| + return res; |
| +} |
| + |
| static GstPad * |
| create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream, |
| MpegTSBaseProgram * program) |
| @@ -1081,6 +1246,8 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream, |
| gboolean sparse = FALSE; |
| gboolean is_audio = FALSE, is_video = FALSE, is_subpicture = FALSE, |
| is_private = FALSE; |
| + guint width = 0; |
| + guint height = 0; |
| |
| gst_ts_demux_create_tags (stream); |
| |
| @@ -1565,6 +1732,10 @@ create_pad_for_stream (MpegTSBase * base, MpegTSBaseStream * bstream, |
| is_video = TRUE; |
| caps = gst_caps_new_simple ("video/x-wmv", |
| "wmvversion", G_TYPE_INT, 3, "format", G_TYPE_STRING, "WVC1", NULL); |
| + |
| + gst_ts_demux_scan_vc1_wh (base, &width, &height); |
| + gst_caps_set_simple (caps, "width", G_TYPE_INT, width, NULL); |
| + gst_caps_set_simple (caps, "height", G_TYPE_INT, height, NULL); |
| |
| break; |
| } |
| @@ -2945,6 +3116,13 @@ gst_ts_demux_push_pending_data (GstTSDemux * demux, TSDemuxStream * stream, |
| } |
| } |
| |
| + if (bs->stream_type == ST_PRIVATE_EA) { |
| + if (G_UNLIKELY (gst_ts_demux_separate_vc1_header (demux, stream, &buffer) |
| + != GST_FLOW_OK)) { |
| + goto beach; |
| + } |
| + } |
| + |
| if (G_UNLIKELY (stream->need_newsegment)) |
| calculate_and_push_newsegment (demux, stream, target_program); |
| |
| diff --git a/gst/videoparsers/gsth264parse.c b/gst/videoparsers/gsth264parse.c |
| index 7751ea2..ceb2f58 100644 |
| --- a/gst/videoparsers/gsth264parse.c |
| +++ b/gst/videoparsers/gsth264parse.c |
| @@ -167,6 +167,7 @@ gst_h264_parse_init (GstH264Parse * h264parse) |
| |
| h264parse->aud_needed = TRUE; |
| h264parse->aud_insert = TRUE; |
| + h264parse->caps_flag = FALSE; |
| } |
| |
| |
| @@ -1835,13 +1836,21 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps) |
| caps = gst_caps_copy (sink_caps); |
| |
| /* sps should give this but upstream overrides */ |
| - if (s && gst_structure_has_field (s, "width")) |
| - gst_structure_get_int (s, "width", &width); |
| + if (s && gst_structure_has_field (s, "width")) { |
| + gst_structure_get_int (s, "width", &width); |
| + if (width != h264parse->width) { |
| + width = h264parse->width; |
| + } |
| + } |
| else |
| width = h264parse->width; |
| |
| - if (s && gst_structure_has_field (s, "height")) |
| - gst_structure_get_int (s, "height", &height); |
| + if (s && gst_structure_has_field (s, "height")) { |
| + gst_structure_get_int (s, "height", &height); |
| + if (height != h264parse->height) { |
| + height = h264parse->height; |
| + } |
| + } |
| else |
| height = h264parse->height; |
| |
| @@ -1988,7 +1997,10 @@ gst_h264_parse_update_src_caps (GstH264Parse * h264parse, GstCaps * caps) |
| gst_buffer_replace (&h264parse->codec_data, NULL); |
| } |
| |
| - gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (h264parse), caps); |
| + if (sps && !h264parse->caps_flag) { |
| + h264parse->caps_flag = TRUE; |
| + gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (h264parse), caps); |
| + } |
| } |
| |
| if (src_caps) |
| @@ -2581,11 +2593,11 @@ gst_h264_parse_set_caps (GstBaseParse * parse, GstCaps * caps) |
| if (format == GST_H264_PARSE_FORMAT_NONE) { |
| /* codec_data implies avc */ |
| if (codec_data_value != NULL) { |
| - GST_ERROR ("video/x-h264 caps with codec_data but no stream-format=avc"); |
| + GST_LOG ("video/x-h264 caps with codec_data but no stream-format=avc"); |
| format = GST_H264_PARSE_FORMAT_AVC; |
| } else { |
| /* otherwise assume bytestream input */ |
| - GST_ERROR ("video/x-h264 caps without codec_data or stream-format"); |
| + GST_LOG ("video/x-h264 caps without codec_data or stream-format"); |
| format = GST_H264_PARSE_FORMAT_BYTE; |
| } |
| } |
| diff --git a/gst/videoparsers/gsth264parse.h b/gst/videoparsers/gsth264parse.h |
| index 137c2cd..997c0e3 100644 |
| --- a/gst/videoparsers/gsth264parse.h |
| +++ b/gst/videoparsers/gsth264parse.h |
| @@ -132,6 +132,7 @@ struct _GstH264Parse |
| /* For insertion of AU Delimiter */ |
| gboolean aud_needed; |
| gboolean aud_insert; |
| + gboolean caps_flag; |
| }; |
| |
| struct _GstH264ParseClass |
| diff --git a/gst/videoparsers/gsth265parse.c b/gst/videoparsers/gsth265parse.c |
| index 775cd24..13c93ea 100644 |
| --- a/gst/videoparsers/gsth265parse.c |
| +++ b/gst/videoparsers/gsth265parse.c |
| @@ -154,6 +154,7 @@ static void |
| gst_h265_parse_init (GstH265Parse * h265parse) |
| { |
| h265parse->frame_out = gst_adapter_new (); |
| + h265parse->has_caps_flag = FALSE; |
| gst_base_parse_set_pts_interpolation (GST_BASE_PARSE (h265parse), FALSE); |
| GST_PAD_SET_ACCEPT_INTERSECT (GST_BASE_PARSE_SINK_PAD (h265parse)); |
| GST_PAD_SET_ACCEPT_TEMPLATE (GST_BASE_PARSE_SINK_PAD (h265parse)); |
| @@ -1761,7 +1762,12 @@ gst_h265_parse_update_src_caps (GstH265Parse * h265parse, GstCaps * caps) |
| gst_buffer_replace (&h265parse->codec_data, NULL); |
| } |
| |
| - gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (h265parse), caps); |
| + if (h265parse->has_caps_flag == FALSE) { |
| + GST_INFO_OBJECT (h265parse, "h265parse->has_caps_flag=FALSE"); |
| + gst_pad_set_caps (GST_BASE_PARSE_SRC_PAD (h265parse), caps); |
| + h265parse->has_caps_flag = TRUE; |
| + } |
| + |
| } |
| |
| if (src_caps) |
| diff --git a/gst/videoparsers/gsth265parse.h b/gst/videoparsers/gsth265parse.h |
| index eb82f6f..0d6be87 100644 |
| --- a/gst/videoparsers/gsth265parse.h |
| +++ b/gst/videoparsers/gsth265parse.h |
| @@ -86,6 +86,7 @@ struct _GstH265Parse |
| /* frame parsing */ |
| gint idr_pos, sei_pos; |
| gboolean update_caps; |
| + gboolean has_caps_flag; |
| GstAdapter *frame_out; |
| gboolean keyframe; |
| gboolean header; |
| diff --git a/gst/videoparsers/gstmpeg4videoparse.c b/gst/videoparsers/gstmpeg4videoparse.c |
| index 38e1f45..990f0db 100644 |
| --- a/gst/videoparsers/gstmpeg4videoparse.c |
| +++ b/gst/videoparsers/gstmpeg4videoparse.c |
| @@ -210,6 +210,7 @@ gst_mpeg4vparse_reset (GstMpeg4VParse * mp4vparse) |
| mp4vparse->pending_key_unit_ts = GST_CLOCK_TIME_NONE; |
| mp4vparse->force_key_unit_event = NULL; |
| mp4vparse->discont = FALSE; |
| + mp4vparse->vop_flag = FALSE; |
| |
| gst_buffer_replace (&mp4vparse->config, NULL); |
| memset (&mp4vparse->vol, 0, sizeof (mp4vparse->vol)); |
| @@ -338,6 +339,7 @@ gst_mpeg4vparse_process_sc (GstMpeg4VParse * mp4vparse, GstMpeg4Packet * packet, |
| if (packet->type == GST_MPEG4_VIDEO_OBJ_PLANE) { |
| GST_LOG_OBJECT (mp4vparse, "startcode is VOP"); |
| mp4vparse->vop_offset = packet->offset; |
| + mp4vparse->vop_flag = TRUE; |
| } else if (packet->type == GST_MPEG4_GROUP_OF_VOP) { |
| GST_LOG_OBJECT (mp4vparse, "startcode is GOP"); |
| } else { |
| @@ -527,6 +529,7 @@ out: |
| GST_BUFFER_FLAG_SET (frame->buffer, GST_BUFFER_FLAG_DISCONT); |
| mp4vparse->discont = FALSE; |
| } |
| + mp4vparse->vop_flag = FALSE; |
| return gst_base_parse_finish_frame (parse, frame, framesize); |
| } |
| |
| @@ -540,8 +543,8 @@ gst_mpeg4vparse_update_src_caps (GstMpeg4VParse * mp4vparse) |
| GstStructure *s = NULL; |
| |
| /* only update if no src caps yet or explicitly triggered */ |
| - if (G_LIKELY (gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD (mp4vparse)) && |
| - !mp4vparse->update_caps)) |
| + if (G_LIKELY (gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD (mp4vparse)) || |
| + !mp4vparse->update_caps || (mp4vparse->vop_flag == FALSE))) |
| return; |
| |
| GST_LOG_OBJECT (mp4vparse, "Updating caps"); |
| @@ -641,7 +644,7 @@ gst_mpeg4vparse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame) |
| else |
| GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT); |
| |
| - if (G_UNLIKELY (mp4vparse->drop && !mp4vparse->config)) { |
| + if (G_UNLIKELY (mp4vparse->drop && !mp4vparse->config && (mp4vparse->vop_flag == FALSE))) { |
| GST_LOG_OBJECT (mp4vparse, "dropping frame as no config yet"); |
| return GST_BASE_PARSE_FLOW_DROPPED; |
| } else |
| diff --git a/gst/videoparsers/gstmpeg4videoparse.h b/gst/videoparsers/gstmpeg4videoparse.h |
| index 149289a..73e4407 100644 |
| --- a/gst/videoparsers/gstmpeg4videoparse.h |
| +++ b/gst/videoparsers/gstmpeg4videoparse.h |
| @@ -54,6 +54,7 @@ struct _GstMpeg4VParse { |
| gboolean config_found; |
| gboolean update_caps; |
| gboolean sent_codec_tag; |
| + gboolean vop_flag; |
| |
| GstMpeg4VisualObject vo; |
| gint vo_offset; |
| diff --git a/gst/videoparsers/gstmpegvideoparse.c b/gst/videoparsers/gstmpegvideoparse.c |
| index 6896339..6547517 100644 |
| --- a/gst/videoparsers/gstmpegvideoparse.c |
| +++ b/gst/videoparsers/gstmpegvideoparse.c |
| @@ -561,10 +561,10 @@ gst_mpegv_parse_process_sc (GstMpegvParse * mpvparse, |
| ret = FALSE; |
| } else { |
| /* TSN is stored in first 10 bits */ |
| - int tsn = info->data[off] << 2 | (info->data[off + 1] & 0xC0) >> 6; |
| + //int tsn = info->data[off] << 2 | (info->data[off + 1] & 0xC0) >> 6; |
| |
| - if (tsn == mpvparse->pichdr.tsn) /* prevent termination if TSN is same */ |
| - ret = FALSE; |
| + //if (tsn == mpvparse->pichdr.tsn) /* prevent termination if TSN is same */ |
| + // ret = FALSE; |
| } |
| } |
| } |
| @@ -731,12 +731,18 @@ gst_mpegv_parse_update_src_caps (GstMpegvParse * mpvparse) |
| { |
| GstCaps *caps = NULL; |
| GstStructure *s = NULL; |
| + static gboolean is_first_in=TRUE; |
| |
| /* only update if no src caps yet or explicitly triggered */ |
| if (G_LIKELY (gst_pad_has_current_caps (GST_BASE_PARSE_SRC_PAD (mpvparse)) && |
| !mpvparse->update_caps)) |
| return; |
| |
| + if (!is_first_in) { |
| + return; |
| + } |
| + is_first_in = FALSE; |
| + |
| /* carry over input caps as much as possible; override with our own stuff */ |
| caps = gst_pad_get_current_caps (GST_BASE_PARSE_SINK_PAD (mpvparse)); |
| if (caps) { |
| @@ -758,24 +764,12 @@ gst_mpegv_parse_update_src_caps (GstMpegvParse * mpvparse) |
| "parsed", G_TYPE_BOOLEAN, TRUE, NULL); |
| |
| if (mpvparse->sequencehdr.width > 0 && mpvparse->sequencehdr.height > 0) { |
| - GstMpegVideoSequenceDisplayExt *seqdispext; |
| + |
| gint width, height; |
| |
| width = mpvparse->sequencehdr.width; |
| height = mpvparse->sequencehdr.height; |
| |
| - if (mpvparse->config_flags & FLAG_SEQUENCE_DISPLAY_EXT) { |
| - seqdispext = &mpvparse->sequencedispext; |
| - |
| - if (seqdispext->display_horizontal_size <= width |
| - && seqdispext->display_vertical_size <= height) { |
| - width = seqdispext->display_horizontal_size; |
| - height = seqdispext->display_vertical_size; |
| - GST_INFO_OBJECT (mpvparse, |
| - "stream has display extension: display_width=%d display_height=%d", |
| - width, height); |
| - } |
| - } |
| gst_caps_set_simple (caps, "width", G_TYPE_INT, width, |
| "height", G_TYPE_INT, height, NULL); |
| } |
| @@ -927,6 +921,61 @@ gst_mpegv_parse_parse_frame (GstBaseParse * parse, GstBaseParseFrame * frame) |
| } |
| |
| static GstFlowReturn |
| +gst_mpegv_parse_frame_max_slice_no (const GstBuffer * buf, guint * max_slice_no) |
| +{ |
| + GstFlowReturn ret = GST_FLOW_OK; |
| + GstBuffer *buffer = buf; |
| + GstMapInfo map; |
| + guint8 *data = NULL; |
| + size_t size = 0; |
| + size_t offset = 0; |
| + guint max_no = 0; |
| + |
| + gst_buffer_map (buffer, &map, GST_MAP_READ); |
| + data = map.data; |
| + size = map.size; |
| + |
| + for (offset=0; offset + 3 < size; offset++) { |
| + if (!memcmp(data+offset, "\x00\x00\x01", 3)) { |
| + guint currentStartCode = data[offset+3]; |
| + |
| + if ((currentStartCode <= GST_MPEG_VIDEO_PACKET_SLICE_MAX) && (currentStartCode > max_no)) { |
| + max_no = currentStartCode; |
| + } |
| + } |
| + } |
| + |
| + gst_buffer_unmap (buffer, &map); |
| + |
| + *max_slice_no = max_no; |
| + return ret; |
| +} |
| + |
| +static gboolean |
| +gst_mpegv_parse_frame_is_invalid (GstBaseParse * parse, GstBaseParseFrame * frame) |
| +{ |
| + GstMpegvParse *mpvparse = GST_MPEGVIDEO_PARSE (parse); |
| + GstBuffer *buffer = frame->buffer; |
| + static guint preFrameMaxSliceNo = 0; |
| + guint curFrameMaxSliceNo = 0; |
| + static gboolean shouldDrop = FALSE; |
| + |
| + if (G_UNLIKELY (mpvparse->pichdr.pic_type != GST_MPEG_VIDEO_PICTURE_TYPE_I)) { |
| + return shouldDrop; |
| + } |
| + |
| + gst_mpegv_parse_frame_max_slice_no (buffer, &curFrameMaxSliceNo); |
| + if ((curFrameMaxSliceNo + 13) <= preFrameMaxSliceNo) { |
| + shouldDrop = TRUE; |
| + } else { |
| + shouldDrop = FALSE; |
| + } |
| + |
| + preFrameMaxSliceNo = curFrameMaxSliceNo; |
| + return shouldDrop; |
| +} |
| + |
| +static GstFlowReturn |
| gst_mpegv_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) |
| { |
| GstMpegvParse *mpvparse = GST_MPEGVIDEO_PARSE (parse); |
| @@ -939,6 +988,16 @@ gst_mpegv_parse_pre_push_frame (GstBaseParse * parse, GstBaseParseFrame * frame) |
| GstMpegVideoPictureExt *pic_ext = NULL; |
| GstMpegVideoQuantMatrixExt *quant_ext = NULL; |
| |
| + if (gst_mpegv_parse_frame_is_invalid (parse, frame)) { |
| + frame->flags |= GST_BASE_PARSE_FRAME_FLAG_DROP; |
| + return GST_FLOW_OK; |
| + } |
| + |
| + GstBuffer *buffer = frame->buffer; |
| + if (!GST_BUFFER_PTS_IS_VALID (buffer)) { |
| + GST_BUFFER_PTS (buffer) = GST_BUFFER_DTS (buffer); |
| + } |
| + |
| /* tag sending done late enough in hook to ensure pending events |
| * have already been sent */ |
| |
| -- |
| 1.9.1 |
| |