[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