[FFmpeg-devel] [PATCH] Fix threaded mpeg*video encoding

Mans Rullgard mans
Wed Jun 30 16:49:34 CEST 2010


This allocates per-thread copies of some buffers which are updated
concurrently from the encoding threads.
---
 libavcodec/mpegvideo.c |   49 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/libavcodec/mpegvideo.c b/libavcodec/mpegvideo.c
index 624419a..600d337 100644
--- a/libavcodec/mpegvideo.c
+++ b/libavcodec/mpegvideo.c
@@ -356,6 +356,10 @@ static void free_picture(MpegEncContext *s, Picture *pic){
 }
 
 static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base){
+    int mb_array_size= s->mb_height * s->mb_stride;
+    int y_size = s->b8_stride * (2 * s->mb_height + 1);
+    int c_size = s->mb_stride * (s->mb_height + 1);
+    int yc_size = y_size + 2 * c_size;
     int i;
 
     // edge emu needs blocksize + filter length - 1 (=17x17 for halfpel / 21x21 for h264)
@@ -381,6 +385,34 @@ static int init_duplicate_context(MpegEncContext *s, MpegEncContext *base){
     for(i=0;i<12;i++){
         s->pblocks[i] = &s->block[i];
     }
+
+    if (s->ac_val_base) {
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->ac_val_base, yc_size * sizeof(int16_t) * 16, fail);
+        s->ac_val[0] = s->ac_val_base + s->b8_stride + 1;
+        s->ac_val[1] = s->ac_val_base + y_size + s->mb_stride + 1;
+        s->ac_val[2] = s->ac_val[1] + c_size;
+    }
+
+    if (s->coded_block_base) {
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->coded_block_base, y_size, fail);
+        s->coded_block= s->coded_block_base + s->b8_stride + 1;
+    }
+
+    if (s->cbp_table)
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->cbp_table, mb_array_size, fail);
+
+    if (s->pred_dir_table)
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->pred_dir_table, mb_array_size, fail);
+
+    if (s->dc_val_base) {
+        FF_ALLOCZ_OR_GOTO(s->avctx, s->dc_val_base, yc_size * sizeof(int16_t), fail);
+        s->dc_val[0] = s->dc_val_base + s->b8_stride + 1;
+        s->dc_val[1] = s->dc_val_base + y_size + s->mb_stride + 1;
+        s->dc_val[2] = s->dc_val[1] + c_size;
+        for(i=0;i<yc_size;i++)
+            s->dc_val_base[i] = 1024;
+    }
+
     return 0;
 fail:
     return -1; //free() through MPV_common_end()
@@ -400,6 +432,11 @@ static void free_duplicate_context(MpegEncContext *s){
     av_freep(&s->me.map);
     av_freep(&s->me.score_map);
     av_freep(&s->blocks);
+    av_freep(&s->ac_val_base);
+    av_freep(&s->dc_val_base);
+    av_freep(&s->coded_block_base);
+    av_freep(&s->cbp_table);
+    av_freep(&s->pred_dir_table);
     s->block= NULL;
 }
 
@@ -423,6 +460,18 @@ static void backup_duplicate_context(MpegEncContext *bak, MpegEncContext *src){
     COPY(dct_error_sum);
     COPY(dct_count[0]);
     COPY(dct_count[1]);
+    COPY(ac_val_base);
+    COPY(ac_val[0]);
+    COPY(ac_val[1]);
+    COPY(ac_val[2]);
+    COPY(dc_val_base);
+    COPY(dc_val[0]);
+    COPY(dc_val[1]);
+    COPY(dc_val[2]);
+    COPY(coded_block_base);
+    COPY(coded_block);
+    COPY(cbp_table);
+    COPY(pred_dir_table);
 #undef COPY
 }
 
-- 
1.7.1.1




More information about the ffmpeg-devel mailing list