mpeg4dec: Ensure data is not clobbered too early.
[ffmpeg.git] / libavcodec / h263dec.c
index cc87bc7..52ab779 100644 (file)
@@ -41,9 +41,6 @@
 #include "flv.h"
 #include "mpeg4video.h"
 
-//#define DEBUG
-//#define PRINT_FRAME_TIME
-
 av_cold int ff_h263_decode_init(AVCodecContext *avctx)
 {
     MpegEncContext *s = avctx->priv_data;
@@ -64,7 +61,7 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx)
     if (avctx->codec->id == AV_CODEC_ID_MSS2)
         avctx->pix_fmt = AV_PIX_FMT_YUV420P;
     else
-        avctx->pix_fmt = ff_thread_get_format(avctx, avctx->codec->pix_fmts);
+        avctx->pix_fmt = avctx->get_format(avctx, avctx->codec->pix_fmts);
     s->unrestricted_mv= 1;
 
     /* select sub codec */
@@ -116,6 +113,9 @@ av_cold int ff_h263_decode_init(AVCodecContext *avctx)
     s->codec_id= avctx->codec->id;
     avctx->hwaccel= ff_find_hwaccel(avctx->codec->id, avctx->pix_fmt);
 
+    if (avctx->stream_codec_tag == AV_RL32("l263") && avctx->extradata_size == 56 && avctx->extradata[0] == 1)
+        s->ehc_mode = 1;
+
     /* for h263, we allocate the images after having read the header */
     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)
@@ -355,9 +355,6 @@ int ff_h263_decode_frame(AVCodecContext *avctx,
     int ret;
     AVFrame *pict = data;
 
-#ifdef PRINT_FRAME_TIME
-uint64_t time= rdtsc();
-#endif
     s->flags= avctx->flags;
     s->flags2= avctx->flags2;
 
@@ -675,7 +672,7 @@ retry:
     if (CONFIG_WMV2_DECODER && s->msmpeg4_version==5){
         ret = ff_wmv2_decode_secondary_picture_header(s);
         if(ret<0) return ret;
-        if(ret==1) goto intrax8_decoded;
+        if(ret==1) goto frame_end;
     }
 
     /* decode each macroblock */
@@ -708,7 +705,18 @@ retry:
 
     av_assert1(s->bitstream_buffer_size==0);
 frame_end:
+    ff_er_frame_end(&s->er);
+
+    if (avctx->hwaccel) {
+        if ((ret = avctx->hwaccel->end_frame(avctx)) < 0)
+            return ret;
+    }
+
+    ff_MPV_frame_end(s);
+
     /* divx 5.01+ bitstream reorder stuff */
+    /* Since this clobbers the input buffer and hwaccel codecs still need the
+     * data during hwaccel->end_frame we should not do this any earlier */
     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;
@@ -735,16 +743,6 @@ frame_end:
         }
     }
 
-intrax8_decoded:
-    ff_er_frame_end(&s->er);
-
-    if (avctx->hwaccel) {
-        if ((ret = avctx->hwaccel->end_frame(avctx)) < 0)
-            return ret;
-    }
-
-    ff_MPV_frame_end(s);
-
     if (!s->divx_packed && avctx->hwaccel)
         ff_thread_finish_setup(avctx);
 
@@ -763,13 +761,24 @@ intrax8_decoded:
     }
 
     if(s->last_picture_ptr || s->low_delay){
+        if (   pict->format == AV_PIX_FMT_YUV420P
+            && (s->codec_tag == AV_RL32("GEOV") || s->codec_tag == AV_RL32("GEOX"))) {
+            int x, y, p;
+            av_frame_make_writable(pict);
+            for (p=0; p<3; p++) {
+                int w = FF_CEIL_RSHIFT(pict-> width, !!p);
+                int h = FF_CEIL_RSHIFT(pict->height, !!p);
+                int linesize = pict->linesize[p];
+                for (y=0; y<(h>>1); y++)
+                    for (x=0; x<w; x++)
+                        FFSWAP(int,
+                               pict->data[p][x + y*linesize],
+                               pict->data[p][x + (h-1-y)*linesize]);
+            }
+        }
         *got_frame = 1;
     }
 
-#ifdef PRINT_FRAME_TIME
-av_log(avctx, AV_LOG_DEBUG, "%"PRId64"\n", rdtsc()-time);
-#endif
-
     return (ret && (avctx->err_recognition & AV_EF_EXPLODE))?ret:get_consumed_bytes(s, buf_size);
 }