summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Greenwood <tcdgreenwood@hotmail.com>2013-10-22 18:49:22 +0100
committerSebastian Dröge <sebastian@centricular.com>2014-09-02 09:12:30 +0300
commit18b99670587fec120d97389ae4d476a15d6ff049 (patch)
tree52417a84b8274692749ee4d667a2777bd40997c7
parentb48adf4e6ceafa38dc59a53970b960ea07e3ac1c (diff)
vp8dec: Fix for handling resolution changes when decoding VP8
If the resolution changes in the bitstream without the input caps changing we would previously output corrupted video or crash. https://bugzilla.gnome.org/show_bug.cgi?id=719359
-rw-r--r--ext/vpx/gstvp8dec.c23
1 files changed, 22 insertions, 1 deletions
diff --git a/ext/vpx/gstvp8dec.c b/ext/vpx/gstvp8dec.c
index 6f3d7d7fc..fc022c78f 100644
--- a/ext/vpx/gstvp8dec.c
+++ b/ext/vpx/gstvp8dec.c
@@ -497,8 +497,10 @@ gst_vp8_dec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
long decoder_deadline = 0;
GstClockTimeDiff deadline;
GstMapInfo minfo;
+ GstVideoInfo *info;
+ GstVideoCodecState *new_output_state;
- GST_DEBUG_OBJECT (decoder, "handle_frame");
+ GST_LOG_OBJECT (decoder, "handle_frame");
dec = GST_VP8_DEC (decoder);
@@ -550,6 +552,25 @@ gst_vp8_dec_handle_frame (GstVideoDecoder * decoder, GstVideoCodecFrame * frame)
(double) -deadline / GST_SECOND);
gst_video_decoder_drop_frame (decoder, frame);
} else {
+ info = &dec->output_state->info;
+ if (GST_VIDEO_INFO_WIDTH (info) != img->d_w
+ || GST_VIDEO_INFO_HEIGHT (info) != img->d_h) {
+ GST_DEBUG_OBJECT (dec,
+ "Changed output resolution was %d x %d now is got %u x %u (display %u x %u)",
+ GST_VIDEO_INFO_WIDTH (info), GST_VIDEO_INFO_HEIGHT (info), img->w,
+ img->h, img->d_w, img->d_h);
+
+ new_output_state =
+ gst_video_decoder_set_output_state (GST_VIDEO_DECODER (dec),
+ GST_VIDEO_FORMAT_I420, img->d_w, img->d_h, dec->output_state);
+ if (dec->output_state) {
+ gst_video_codec_state_unref (dec->output_state);
+ }
+ dec->output_state = new_output_state;
+ /* No need to call negotiate() here, it will be automatically called
+ * by allocate_output_frame() below */
+ }
+
ret = gst_video_decoder_allocate_output_frame (decoder, frame);
if (ret == GST_FLOW_OK) {