2011/4/13 Kostya <[email protected]>:
> I've seen display information used for cropping - e.g. adjust picture
> dimensions for odd dimensions.

The wording on the spec isn't very clear, but it sounds to me like it is
not intended to crop.

In any case, mpegvideo does not currently support arbitrary cropping, so
the options are:

* Use it for aspect ratio only (as in the patch)
* Use it for limited cropping (less than 16 pixels)
* Ignore it completely

Here's an updated patch that also checks the entry point dimensions not
to be larger than the ones specified in the sequence header. The spec
says they can't be larger, and they can cause a crash too (uploaded
sample to incoming/VC1_EPH_crash.wmv)
From df8c9ad4c7789712b8eba60cbd183b8cfc912b83 Mon Sep 17 00:00:00 2001
From: Alberto Delmas <[email protected]>
Date: Wed, 13 Apr 2011 19:10:51 +0200
Subject: [PATCH] Prevent crashes with bogus VC-1 entry point or display 
extension info

---
 libavcodec/vc1.c |   24 +++++++++++++++++++-----
 1 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/libavcodec/vc1.c b/libavcodec/vc1.c
index b058a38..c9bc1c4 100644
--- a/libavcodec/vc1.c
+++ b/libavcodec/vc1.c
@@ -503,10 +503,10 @@ static int decode_sequence_header_adv(VC1Context *v, 
GetBitContext *gb)
     if(get_bits1(gb)) { //Display Info - decoding is not affected by it
         int w, h, ar = 0;
         av_log(v->s.avctx, AV_LOG_DEBUG, "Display extended info:\n");
-        v->s.avctx->width  = w = get_bits(gb, 14) + 1;
-        v->s.avctx->height = h = get_bits(gb, 14) + 1;
+        w = get_bits(gb, 14) + 1;
+        h = get_bits(gb, 14) + 1;
         av_log(v->s.avctx, AV_LOG_DEBUG, "Display dimensions: %ix%i\n", w, h);
-        if(get_bits1(gb))
+        if(get_bits1(gb)){
             ar = get_bits(gb, 4);
         if(ar && ar < 14){
             v->s.avctx->sample_aspect_ratio = ff_vc1_pixel_aspect[ar];
@@ -515,6 +515,13 @@ static int decode_sequence_header_adv(VC1Context *v, 
GetBitContext *gb)
             h = get_bits(gb, 8);
             v->s.avctx->sample_aspect_ratio = (AVRational){w, h};
         }
+        }else{
+            av_reduce(&v->s.avctx->sample_aspect_ratio.num,
+                      &v->s.avctx->sample_aspect_ratio.den,
+                      v->s.avctx->height * w,
+                      v->s.avctx->width * h,
+                      1<<30);
+        }
         av_log(v->s.avctx, AV_LOG_DEBUG, "Aspect: %i:%i\n", 
v->s.avctx->sample_aspect_ratio.num, v->s.avctx->sample_aspect_ratio.den);
 
         if(get_bits1(gb)){ //framerate stuff
@@ -577,8 +584,15 @@ int vc1_decode_entry_point(AVCodecContext *avctx, 
VC1Context *v, GetBitContext *
     }
 
     if(get_bits1(gb)){
-        avctx->coded_width = (get_bits(gb, 12)+1)<<1;
-        avctx->coded_height = (get_bits(gb, 12)+1)<<1;
+        int w, h;
+        w = (get_bits(gb, 12)+1)<<1;
+        h = (get_bits(gb, 12)+1)<<1;
+        if(w <= avctx->width && h <= avctx->height){
+            avctx->coded_width = w;
+            avctx->coded_height = h;
+        }else{
+            av_log(avctx, AV_LOG_ERROR, "Entry point coded frame size too 
large\n");
+        }
     }
     if(v->extended_mv)
         v->extended_dmv = get_bits1(gb);
-- 
1.7.3.3

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to