blob: 33c65bd1bde10de2bdf090e963436f39234ea7c6 [file] [log] [blame]
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