]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/h263dec.c
h263dec: disable coded dimensions = 0 handling
[ffmpeg] / libavcodec / h263dec.c
index b0b2baa8ede1887dbcc8089d3458cca7630638a3..ef1b6ed62c682cd9c3de249b583f9ccd5e51caf1 100644 (file)
@@ -47,6 +47,7 @@
 av_cold int ff_h263_decode_init(AVCodecContext *avctx)
 {
     MpegEncContext *s = avctx->priv_data;
+    int ret;
 
     s->avctx = avctx;
     s->out_format = FMT_H263;
@@ -60,61 +61,65 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx)
     s->quant_precision=5;
     s->decode_mb= ff_h263_decode_mb;
     s->low_delay= 1;
-    avctx->pix_fmt= avctx->get_format(avctx, avctx->codec->pix_fmts);
+    if (avctx->codec->id == AV_CODEC_ID_MSS2)
+        avctx->pix_fmt = PIX_FMT_YUV420P;
+    else
+        avctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts);
     s->unrestricted_mv= 1;
 
     /* select sub codec */
     switch(avctx->codec->id) {
-    case CODEC_ID_H263:
-    case CODEC_ID_H263P:
+    case AV_CODEC_ID_H263:
+    case AV_CODEC_ID_H263P:
         s->unrestricted_mv= 0;
         avctx->chroma_sample_location = AVCHROMA_LOC_CENTER;
         break;
-    case CODEC_ID_MPEG4:
+    case AV_CODEC_ID_MPEG4:
         break;
-    case CODEC_ID_MSMPEG4V1:
+    case AV_CODEC_ID_MSMPEG4V1:
         s->h263_pred = 1;
         s->msmpeg4_version=1;
         break;
-    case CODEC_ID_MSMPEG4V2:
+    case AV_CODEC_ID_MSMPEG4V2:
         s->h263_pred = 1;
         s->msmpeg4_version=2;
         break;
-    case CODEC_ID_MSMPEG4V3:
+    case AV_CODEC_ID_MSMPEG4V3:
         s->h263_pred = 1;
         s->msmpeg4_version=3;
         break;
-    case CODEC_ID_WMV1:
+    case AV_CODEC_ID_WMV1:
         s->h263_pred = 1;
         s->msmpeg4_version=4;
         break;
-    case CODEC_ID_WMV2:
+    case AV_CODEC_ID_WMV2:
         s->h263_pred = 1;
         s->msmpeg4_version=5;
         break;
-    case CODEC_ID_VC1:
-    case CODEC_ID_WMV3:
-    case CODEC_ID_VC1IMAGE:
-    case CODEC_ID_WMV3IMAGE:
+    case AV_CODEC_ID_VC1:
+    case AV_CODEC_ID_WMV3:
+    case AV_CODEC_ID_VC1IMAGE:
+    case AV_CODEC_ID_WMV3IMAGE:
+    case AV_CODEC_ID_MSS2:
         s->h263_pred = 1;
         s->msmpeg4_version=6;
         avctx->chroma_sample_location = AVCHROMA_LOC_LEFT;
         break;
-    case CODEC_ID_H263I:
+    case AV_CODEC_ID_H263I:
         break;
-    case CODEC_ID_FLV1:
+    case AV_CODEC_ID_FLV1:
         s->h263_flv = 1;
         break;
     default:
-        return -1;
+        return AVERROR(EINVAL);
     }
     s->codec_id= avctx->codec->id;
     avctx->hwaccel= ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
 
     /* for h263, we allocate the images after having read the header */
-    if (avctx->codec->id != CODEC_ID_H263 && avctx->codec->id != CODEC_ID_H263P && avctx->codec->id != CODEC_ID_MPEG4)
-        if (ff_MPV_common_init(s) < 0)
-            return -1;
+    if (avctx->codec->id != AV_CODEC_ID_H263 && avctx->codec->id != AV_CODEC_ID_H263P && avctx->codec->id != AV_CODEC_ID_MPEG4)
+        if ((ret = ff_MPV_common_init(s)) < 0)
+            return ret;
 
         ff_h263_decode_init_vlc(s);
 
@@ -153,6 +158,8 @@ static int get_consumed_bytes(MpegEncContext *s, int buf_size){
 static int decode_slice(MpegEncContext *s){
     const int part_mask= s->partitioned_frame ? (ER_AC_END|ER_AC_ERROR) : 0x7F;
     const int mb_size= 16>>s->avctx->lowres;
+    int ret;
+
     s->last_resync_gb= s->gb;
     s->first_slice_line= 1;
 
@@ -171,9 +178,9 @@ static int decode_slice(MpegEncContext *s){
     if(s->partitioned_frame){
         const int qscale= s->qscale;
 
-        if(CONFIG_MPEG4_DECODER && s->codec_id==CODEC_ID_MPEG4){
-            if(ff_mpeg4_decode_partitions(s) < 0)
-                return -1;
+        if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4){
+            if ((ret = ff_mpeg4_decode_partitions(s)) < 0)
+                return ret;
         }
 
         /* restore variables which were modified */
@@ -242,12 +249,12 @@ static int decode_slice(MpegEncContext *s){
                 }else if(ret==SLICE_NOEND){
                     av_log(s->avctx, AV_LOG_ERROR, "Slice mismatch at MB: %d\n", xy);
                     ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x+1, s->mb_y, ER_MB_END&part_mask);
-                    return -1;
+                    return AVERROR_INVALIDDATA;
                 }
                 av_log(s->avctx, AV_LOG_ERROR, "Error at MB: %d\n", xy);
                 ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_ERROR&part_mask);
 
-                return -1;
+                return AVERROR_INVALIDDATA;
             }
 
             ff_MPV_decode_mb(s, s->block);
@@ -263,7 +270,7 @@ static int decode_slice(MpegEncContext *s){
 
     assert(s->mb_x==0 && s->mb_y==s->mb_height);
 
-    if(s->codec_id==CODEC_ID_MPEG4
+    if(s->codec_id==AV_CODEC_ID_MPEG4
        && (s->workaround_bugs&FF_BUG_AUTODETECT)
        && get_bits_left(&s->gb) >= 48
        && show_bits(&s->gb, 24)==0x4010
@@ -271,7 +278,7 @@ static int decode_slice(MpegEncContext *s){
         s->padding_bug_score+=32;
 
     /* try to detect the padding bug */
-    if(      s->codec_id==CODEC_ID_MPEG4
+    if(      s->codec_id==AV_CODEC_ID_MPEG4
        &&   (s->workaround_bugs&FF_BUG_AUTODETECT)
        &&    get_bits_left(&s->gb) >=0
        &&    get_bits_left(&s->gb) < 137
@@ -335,7 +342,7 @@ static int decode_slice(MpegEncContext *s){
 
     ff_er_add_slice(s, s->resync_mb_x, s->resync_mb_y, s->mb_x, s->mb_y, ER_MB_END&part_mask);
 
-    return -1;
+    return AVERROR_INVALIDDATA;
 }
 
 int ff_h263_decode_frame(AVCodecContext *avctx,
@@ -370,15 +377,15 @@ uint64_t time= rdtsc();
     if(s->flags&CODEC_FLAG_TRUNCATED){
         int next;
 
-        if(CONFIG_MPEG4_DECODER && s->codec_id==CODEC_ID_MPEG4){
+        if(CONFIG_MPEG4_DECODER && s->codec_id==AV_CODEC_ID_MPEG4){
             next= ff_mpeg4_find_frame_end(&s->parse_context, buf, buf_size);
-        }else if(CONFIG_H263_DECODER && s->codec_id==CODEC_ID_H263){
+        }else if(CONFIG_H263_DECODER && s->codec_id==AV_CODEC_ID_H263){
             next= ff_h263_find_frame_end(&s->parse_context, buf, buf_size);
-        }else if(CONFIG_H263P_DECODER && s->codec_id==CODEC_ID_H263P){
+        }else if(CONFIG_H263P_DECODER && s->codec_id==AV_CODEC_ID_H263P){
             next= ff_h263_find_frame_end(&s->parse_context, buf, buf_size);
         }else{
             av_log(s->avctx, AV_LOG_ERROR, "this codec does not support truncated bitstreams\n");
-            return -1;
+            return AVERROR(EINVAL);
         }
 
         if( ff_combine_frame(&s->parse_context, next, (const uint8_t **)&buf, &buf_size) < 0 )
@@ -407,8 +414,8 @@ retry:
     s->bitstream_buffer_size=0;
 
     if (!s->context_initialized) {
-        if (ff_MPV_common_init(s) < 0) //we need the idct permutaton for reading a custom matrix
-            return -1;
+        if ((ret = ff_MPV_common_init(s)) < 0) //we need the idct permutaton for reading a custom matrix
+            return ret;
     }
 
     /* We need to set current_picture_ptr before reading the header,
@@ -433,7 +440,7 @@ retry:
             ret = ff_mpeg4_decode_picture_header(s, &gb);
         }
         ret = ff_mpeg4_decode_picture_header(s, &s->gb);
-    } else if (CONFIG_H263I_DECODER && s->codec_id == CODEC_ID_H263I) {
+    } else if (CONFIG_H263I_DECODER && s->codec_id == AV_CODEC_ID_H263I) {
         ret = ff_intel_h263_decode_picture_header(s);
     } else if (CONFIG_FLV_DECODER && s->h263_flv) {
         ret = ff_flv_decode_picture_header(s);
@@ -454,16 +461,7 @@ retry:
     /* skip if the header was thrashed */
     if (ret < 0){
         av_log(s->avctx, AV_LOG_ERROR, "header damaged\n");
-        return -1;
-    } else if ((s->width  != avctx->coded_width  ||
-                s->height != avctx->coded_height ||
-                (s->width  + 15) >> 4 != s->mb_width ||
-                (s->height + 15) >> 4 != s->mb_height) &&
-               (HAVE_THREADS && (s->avctx->active_thread_type & FF_THREAD_FRAME))) {
-        av_log_missing_feature(s->avctx, "Width/height/bit depth/chroma idc changing with threads is", 0);
-        s->width = avctx->coded_width;
-        s->height= avctx->coded_height;
-        return AVERROR_PATCHWELCOME;   // width / height changed during parallelized decoding
+        return ret;
     }
 
     avctx->has_b_frames= !s->low_delay;
@@ -558,7 +556,7 @@ retry:
          * Let us hope this at least works.
          */
         if(   s->resync_marker==0 && s->data_partitioning==0 && s->divx_version==-1
-           && s->codec_id==CODEC_ID_MPEG4 && s->vo_type==0)
+           && s->codec_id==AV_CODEC_ID_MPEG4 && s->vo_type==0)
             s->workaround_bugs|= FF_BUG_NO_PADDING;
 
         if(s->lavc_build<4609U) //FIXME not sure about the version num but a 4609 file seems ok
@@ -588,9 +586,10 @@ retry:
                s->divx_packed ? "p" : "");
 
 #if HAVE_MMX
-    if (s->codec_id == CODEC_ID_MPEG4 && s->xvid_build>=0 && avctx->idct_algo == FF_IDCT_AUTO && (av_get_cpu_flags() & AV_CPU_FLAG_MMX)) {
+    if (s->codec_id == AV_CODEC_ID_MPEG4 && s->xvid_build>=0 && avctx->idct_algo == FF_IDCT_AUTO && (av_get_cpu_flags() & AV_CPU_FLAG_MMX)) {
         avctx->idct_algo= FF_IDCT_XVIDMMX;
         ff_dct_common_init(s);
+        goto retry;
     }
 #endif
 
@@ -599,22 +598,30 @@ retry:
         /* FIXME: By the way H263 decoder is evolving it should have */
         /* an H263EncContext                                         */
 
-    if (   s->width  != avctx->coded_width
-        || s->height != avctx->coded_height) {
-        /* H.263 could change picture size any time */
+    if ((!avctx->coded_width || !avctx->coded_height) && 0) {
         ParseContext pc= s->parse_context; //FIXME move these demuxng hack to avformat
 
         s->parse_context.buffer=0;
         ff_MPV_common_end(s);
         s->parse_context= pc;
-    }
-    if (!s->context_initialized) {
         avcodec_set_dimensions(avctx, s->width, s->height);
 
         goto retry;
     }
 
-    if((s->codec_id==CODEC_ID_H263 || s->codec_id==CODEC_ID_H263P || s->codec_id == CODEC_ID_H263I))
+    if (s->width  != avctx->coded_width  ||
+        s->height != avctx->coded_height ||
+        s->context_reinit) {
+        /* H.263 could change picture size any time */
+        s->context_reinit = 0;
+
+        avcodec_set_dimensions(avctx, s->width, s->height);
+
+        if ((ret = ff_MPV_common_frame_size_change(s)))
+            return ret;
+    }
+
+    if((s->codec_id==AV_CODEC_ID_H263 || s->codec_id==AV_CODEC_ID_H263P || s->codec_id == AV_CODEC_ID_H263I))
         s->gob_index = ff_h263_get_gob_height(s);
 
     // for skipping the frame
@@ -646,8 +653,8 @@ retry:
         s->me.qpel_avg= s->dsp.avg_qpel_pixels_tab;
     }
 
-    if(ff_MPV_frame_start(s, avctx) < 0)
-        return -1;
+    if ((ret = ff_MPV_frame_start(s, avctx)) < 0)
+        return ret;
 
     if (!s->divx_packed) ff_thread_finish_setup(avctx);
 
@@ -657,8 +664,8 @@ retry:
     }
 
     if (avctx->hwaccel) {
-        if (avctx->hwaccel->start_frame(avctx, s->gb.buffer, s->gb.buffer_end - s->gb.buffer) < 0)
-            return -1;
+        if ((ret = avctx->hwaccel->start_frame(avctx, s->gb.buffer, s->gb.buffer_end - s->gb.buffer)) < 0)
+            return ret;
     }
 
     ff_er_frame_start(s);
@@ -702,7 +709,7 @@ retry:
     assert(s->bitstream_buffer_size==0);
 frame_end:
     /* divx 5.01+ bistream reorder stuff */
-    if(s->codec_id==CODEC_ID_MPEG4 && s->divx_packed){
+    if(s->codec_id==AV_CODEC_ID_MPEG4 && s->divx_packed){
         int current_pos= s->gb.buffer == s->bitstream_buffer ? 0 : (get_bits_count(&s->gb)>>3);
         int startcode_found=0;
 
@@ -732,8 +739,8 @@ intrax8_decoded:
     ff_er_frame_end(s);
 
     if (avctx->hwaccel) {
-        if (avctx->hwaccel->end_frame(avctx) < 0)
-            return -1;
+        if ((ret = avctx->hwaccel->end_frame(avctx)) < 0)
+            return ret;
     }
 
     ff_MPV_frame_end(s);
@@ -761,7 +768,7 @@ av_log(avctx, AV_LOG_DEBUG, "%"PRId64"\n", rdtsc()-time);
 AVCodec ff_h263_decoder = {
     .name           = "h263",
     .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = CODEC_ID_H263,
+    .id             = AV_CODEC_ID_H263,
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_h263_decode_init,
     .close          = ff_h263_decode_end,
@@ -777,7 +784,7 @@ AVCodec ff_h263_decoder = {
 AVCodec ff_h263p_decoder = {
     .name           = "h263p",
     .type           = AVMEDIA_TYPE_VIDEO,
-    .id             = CODEC_ID_H263P,
+    .id             = AV_CODEC_ID_H263P,
     .priv_data_size = sizeof(MpegEncContext),
     .init           = ff_h263_decode_init,
     .close          = ff_h263_decode_end,