[FFmpeg-devel] [PATCH] H264: try to keep container-provided dimensions.

Reimar Döffinger Reimar.Doeffinger at gmx.de
Mon Aug 29 21:12:19 CEST 2011


Tries to see if the user/container provided dimensions match close
enough with the values in SPS and if so modifies the SPS crop
values to keep them.

This fixes ticket #156.

This is currently quite hackish, needs to be cleaned up a bit
if the approach seems sensible in principle.

Signed-off-by: Reimar Döffinger <Reimar.Doeffinger at gmx.de>
---
 libavcodec/h264.c    |   26 ++++++++++++++++++++++++++
 libavcodec/h264.h    |    1 +
 libavcodec/h264_ps.c |    1 +
 libavformat/mov.c    |    3 ---
 4 files changed, 28 insertions(+), 3 deletions(-)

diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index c3f279c..957384c 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -986,6 +986,8 @@ static av_cold void common_init(H264Context *h){
 int ff_h264_decode_extradata(H264Context *h)
 {
     AVCodecContext *avctx = h->s.avctx;
+    int container_w = avctx->width;
+    int container_h = avctx->height;
 
     if(avctx->extradata[0] == 1){
         int i, cnt, nalsize;
@@ -1028,6 +1030,30 @@ int ff_h264_decode_extradata(H264Context *h)
         if(decode_nal_units(h, avctx->extradata, avctx->extradata_size) < 0)
             return -1;
     }
+    if (container_w > 0 && container_h > 0 &&
+        h->sps.crop_left == 0 && h->sps.crop_top == 0) {
+        int sps_w = 16 * h->sps.mb_width;
+        int sps_h = 16 * h->sps.mb_height;
+        int crop_x = (sps_w - container_w) >> (CHROMA444 + 1);
+        int crop_y = (sps_h - container_h) >> ((h->sps.chroma_format_idc <= 1) + !h->sps.frame_mbs_only_flag);
+        if (crop_x < 0 || crop_x >= 16 ||
+            crop_y < 0 || crop_y >= 16) {
+            av_log(avctx, AV_LOG_WARNING, "Mismatch between container and "
+                   "extradata size info (%ix%i vs %ix%i)\n",
+                   container_w, container_h, sps_w, sps_h);
+        } else if (crop_x != h->sps.crop_right ||
+                   crop_y != h->sps.crop_bottom) {
+            av_log(avctx, AV_LOG_WARNING, "Replacing crop values to match "
+                   "container specified resolution (%ix%i to %ix%i)\n",
+                   h->sps.crop_right, h->sps.crop_bottom, crop_x, crop_y);
+            h->sps.crop_right  = crop_x;
+            h->sps.crop_bottom = crop_y;
+            if (h->sps_buffers[h->sps.sps_id]) {
+                h->sps_buffers[h->sps.sps_id]->crop_right   = crop_x;
+                h->sps_buffers[h->sps.sps_id]->crop_bottom  = crop_y;
+            }
+        }
+    }
     return 0;
 }
 
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index 2809e32..820c18d 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -151,6 +151,7 @@ typedef enum {
  */
 typedef struct SPS{
 
+    int sps_id;
     int profile_idc;
     int level_idc;
     int chroma_format_idc;
diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
index fa99372..fbf2ee3 100644
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -318,6 +318,7 @@ int ff_h264_decode_seq_parameter_set(H264Context *h){
     if(sps == NULL)
         return -1;
 
+    sps->sps_id = sps_id;
     sps->time_offset_length = 24;
     sps->profile_idc= profile_idc;
     sps->constraint_set_flags = constraint_set_flags;
diff --git a/libavformat/mov.c b/libavformat/mov.c
index 2663aa0..e11c0fe 100644
--- a/libavformat/mov.c
+++ b/libavformat/mov.c
@@ -1829,9 +1829,6 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom)
 #if CONFIG_H263_DECODER
     case CODEC_ID_H263:
 #endif
-#if CONFIG_H264_DECODER
-    case CODEC_ID_H264:
-#endif
 #if CONFIG_MPEG4_DECODER
     case CODEC_ID_MPEG4:
 #endif
-- 
1.7.5.4



More information about the ffmpeg-devel mailing list