Hello everyone,
this is my first patch for Libav that I think is worth publishing :)
I have to handle a lot of stereoscopic content and as I was using Libav decoders, I noticed a strange behavior: final resolution of videos were always different from the initial one. Jason made me notice it was because I was using "unusual" cropping values inside my videos and that Libav doesn't fully handle cropping. So my long term plan is to provide full h264 cropping feature inside Libav, but for the meantime I fixed the issue I encountered. Here are a more technical description of what my patch does:

/As you know in h264 videos you can specify any crop values in any direction; normally only the bottom part is used because 1080 is not multiple of 16, however Libav supports cropping only partially. Currently it ignores the left and top values but completely misses the bottom and right values, introducing additional values that modify the final resolution of the video (usually I get a 1906x1074 frame). This patch makes Libav ignore the right cropping values and handle correctly the bottom ones, that is crop 8 lower lines for progressive and 4 for interlaced video, so that the output resolution is preserved for 1920x1080 content./

I can provide copyleft samples to evaluate this patch if needed. I hope the community finds this useful and that the patch can be safely committed :)
Best,
Vittorio
>From 52392ec84ec0e62d18afa17a6f05ca85016d2220 Mon Sep 17 00:00:00 2001
From: Vittorio Giovara <[email protected]>
Date: Fri, 22 Apr 2011 16:48:57 +0200
Subject: [PATCH] this patch makes the h264 decoder discard "unusal" cropping values in a consistent way

---
 libavcodec/h264.c    |    6 +++---
 libavcodec/h264_ps.c |    7 ++-----
 2 files changed, 5 insertions(+), 8 deletions(-)

diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index cd7dccc..19c04f7 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -1797,11 +1797,11 @@ static int decode_slice_header(H264Context *h, H264Context *h0){
 
     h->b_stride=  s->mb_width*4;
 
-    s->width = 16*s->mb_width - 2*FFMIN(h->sps.crop_right, 7);
+    s->width = 16*s->mb_width;
     if(h->sps.frame_mbs_only_flag)
-        s->height= 16*s->mb_height - 2*FFMIN(h->sps.crop_bottom, 7);
+        s->height= 16*s->mb_height - 2*FFMIN(h->sps.crop_bottom, 4);
     else
-        s->height= 16*s->mb_height - 4*FFMIN(h->sps.crop_bottom, 7);
+        s->height= 16*s->mb_height - 4*FFMIN(h->sps.crop_bottom, 2);
 
     if (s->context_initialized
         && (   s->width != s->avctx->width || s->height != s->avctx->height
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
index 44b8381..0bdcb9c 100644
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -371,11 +371,8 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){
         sps->crop_right = get_ue_golomb(&s->gb);
         sps->crop_top   = get_ue_golomb(&s->gb);
         sps->crop_bottom= get_ue_golomb(&s->gb);
-        if(sps->crop_left || sps->crop_top){
-            av_log(h->s.avctx, AV_LOG_ERROR, "insane cropping not completely supported, this could look slightly wrong ...\n");
-        }
-        if(sps->crop_right >= 8 || sps->crop_bottom >= 8){
-            av_log(h->s.avctx, AV_LOG_ERROR, "brainfart cropping not supported, this could look slightly wrong ...\n");
+        if(sps->crop_left || sps->crop_top || sps->crop_right || sps->crop_bottom > 4){
+            av_log(h->s.avctx, AV_LOG_ERROR, "cropping not completely supported, this could look slightly wrong ...\n");
         }
     }else{
         sps->crop_left  =
-- 
1.7.1

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

Reply via email to