commit 8cdda132cf0e29c21b17edcbca925c2c843853bb
Author: Gwenole Beauchesne <gbeauchesne@splitted-desktop.com>
Date:   Tue Apr 13 09:04:31 2010 +0200

    Fix MPEG-4 decoding of video clips with B-frames.

diff --git a/libavcodec/h263dec.c b/libavcodec/h263dec.c
index f85f15a..4a19b7a 100644
--- a/libavcodec/h263dec.c
+++ b/libavcodec/h263dec.c
@@ -160,13 +160,6 @@ static int decode_slice(MpegEncContext *s){
 
     ff_set_qscale(s, s->qscale);
 
-    if (s->avctx->hwaccel) {
-        const uint8_t *start= s->gb.buffer + get_bits_count(&s->gb)/8;
-        const uint8_t *end  = ff_h263_find_resync_marker(start + 1, s->gb.buffer_end);
-        skip_bits_long(&s->gb, 8*(end - start));
-        return s->avctx->hwaccel->decode_slice(s->avctx, start, end - start);
-    }
-
     if(s->partitioned_frame){
         const int qscale= s->qscale;
 
@@ -623,8 +616,15 @@ retry:
     }
 
     if (avctx->hwaccel) {
-        if (avctx->hwaccel->start_frame(avctx, s->gb.buffer, s->gb.buffer_end - s->gb.buffer) < 0)
+        const uint8_t * const buf   = s->gb.buffer;
+        const uint32_t buf_size     = s->gb.buffer_end - buf;
+        const uint8_t * const slice = s->gb.buffer + get_bits_count(&s->gb)/8;
+        const uint32_t slice_size   = s->gb.buffer_end - slice;
+        if (avctx->hwaccel->start_frame(avctx, buf, buf_size) < 0)
             return -1;
+        if (avctx->hwaccel->decode_slice(avctx, slice, slice_size) < 0)
+            return -1;
+        goto frame_end;
     }
 
     ff_er_frame_start(s);
diff --git a/libavcodec/vaapi.c b/libavcodec/vaapi.c
index 10f9054..1d7dc36 100644
--- a/libavcodec/vaapi.c
+++ b/libavcodec/vaapi.c
@@ -77,7 +77,7 @@ static int render_picture(struct vaapi_context *vactx, VASurfaceID surface)
     return 0;
 }
 
-static int commit_slices(struct vaapi_context *vactx)
+int ff_vaapi_commit_slice_data(struct vaapi_context *vactx)
 {
     VABufferID *slice_buf_ids;
     VABufferID slice_param_buf_id, slice_data_buf_id;
@@ -152,7 +152,7 @@ VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, co
     if (!vactx->slice_data)
         vactx->slice_data = buffer;
     if (vactx->slice_data + vactx->slice_data_size != buffer) {
-        if (commit_slices(vactx) < 0)
+        if (ff_vaapi_commit_slice_data(vactx) < 0)
             return NULL;
         vactx->slice_data = buffer;
     }
@@ -182,7 +182,7 @@ int ff_vaapi_common_end_frame(MpegEncContext *s)
 
     dprintf(s->avctx, "ff_vaapi_common_end_frame()\n");
 
-    if (commit_slices(vactx) < 0)
+    if (ff_vaapi_commit_slice_data(vactx) < 0)
         goto done;
     if (vactx->n_slice_buf_ids > 0) {
         if (render_picture(vactx, ff_vaapi_get_surface_id(s->current_picture_ptr)) < 0)
diff --git a/libavcodec/vaapi_internal.h b/libavcodec/vaapi_internal.h
index 2c0fdf9..8471260 100644
--- a/libavcodec/vaapi_internal.h
+++ b/libavcodec/vaapi_internal.h
@@ -63,6 +63,15 @@ uint8_t *ff_vaapi_alloc_bitplane(struct vaapi_context *vactx, uint32_t size);
  */
 VASliceParameterBufferBase *ff_vaapi_alloc_slice(struct vaapi_context *vactx, const uint8_t *buffer, uint32_t size);
 
+/**
+ * Commits slice data immediately. i.e. don't try to pack all slice
+ * data in a single VA buffer.
+ *
+ * @pram vactx the VA API context
+ * @return zero on success
+ */
+int ff_vaapi_commit_slice_data(struct vaapi_context *vactx);
+
 /* @} */
 
 #endif /* AVCODEC_VAAPI_INTERNAL_H */
diff --git a/libavcodec/vaapi_mpeg4.c b/libavcodec/vaapi_mpeg4.c
index 466ce2f..3a695cc 100644
--- a/libavcodec/vaapi_mpeg4.c
+++ b/libavcodec/vaapi_mpeg4.c
@@ -126,14 +126,6 @@ static int vaapi_mpeg4_decode_slice(AVCodecContext *avctx, const uint8_t *buffer
 
     dprintf(avctx, "vaapi_mpeg4_decode_slice(): buffer %p, size %d\n", buffer, size);
 
-    /* video_plane_with_short_video_header() contains all GOBs
-     * in-order, and this is what VA API (Intel backend) expects: only
-     * a single slice param. So fake macroblock_number for FFmpeg so
-     * that we don't call vaapi_mpeg4_decode_slice() again
-     */
-    if (avctx->codec->id == CODEC_ID_H263)
-        size = s->gb.buffer_end - buffer;
-
     /* Fill in VASliceParameterBufferMPEG4 */
     slice_param = (VASliceParameterBufferMPEG4 *)ff_vaapi_alloc_slice(avctx->hwaccel_context, buffer, size);
     if (!slice_param)
@@ -142,10 +134,7 @@ static int vaapi_mpeg4_decode_slice(AVCodecContext *avctx, const uint8_t *buffer
     slice_param->macroblock_number      = s->mb_y * s->mb_width + s->mb_x;
     slice_param->quant_scale            = s->qscale;
 
-    if (avctx->codec->id == CODEC_ID_H263)
-        s->mb_y = s->mb_height;
-
-    return 0;
+    return ff_vaapi_commit_slice_data(avctx->hwaccel_context);
 }
 
 #if CONFIG_MPEG4_VAAPI_HWACCEL
