diff options
author | Alexander Strange <astrange@ithinksw.com> | 2011-06-02 21:15:58 +0400 |
---|---|---|
committer | Ronald S. Bultje <rsbultje@gmail.com> | 2011-06-02 21:16:20 +0400 |
commit | 6a9c85944427e3c4355bce67d7f677ec69527bff (patch) | |
tree | df4bb83f820a5c0295485ca8b7751c4063d5165f /libavcodec/mpeg12.c | |
parent | 53be7b23e9d7074d1aeee77407b008411d034e9e (diff) |
H264/MPEG frame-level multi-threading.
Signed-off-by: Ronald S. Bultje <rsbultje@gmail.com>
Diffstat (limited to 'libavcodec/mpeg12.c')
-rw-r--r-- | libavcodec/mpeg12.c | 36 |
1 files changed, 32 insertions, 4 deletions
diff --git a/libavcodec/mpeg12.c b/libavcodec/mpeg12.c index 88ed5332ae..82c2987b90 100644 --- a/libavcodec/mpeg12.c +++ b/libavcodec/mpeg12.c @@ -37,6 +37,7 @@ #include "bytestream.h" #include "vdpau_internal.h" #include "xvmc_internal.h" +#include "thread.h" //#undef NDEBUG //#include <assert.h> @@ -1179,6 +1180,27 @@ static av_cold int mpeg_decode_init(AVCodecContext *avctx) return 0; } +static int mpeg_decode_update_thread_context(AVCodecContext *avctx, const AVCodecContext *avctx_from) +{ + Mpeg1Context *ctx = avctx->priv_data, *ctx_from = avctx_from->priv_data; + MpegEncContext *s = &ctx->mpeg_enc_ctx, *s1 = &ctx_from->mpeg_enc_ctx; + int err; + + if(avctx == avctx_from || !ctx_from->mpeg_enc_ctx_allocated || !s1->context_initialized) + return 0; + + err = ff_mpeg_update_thread_context(avctx, avctx_from); + if(err) return err; + + if(!ctx->mpeg_enc_ctx_allocated) + memcpy(s + 1, s1 + 1, sizeof(Mpeg1Context) - sizeof(MpegEncContext)); + + if(!(s->pict_type == FF_B_TYPE || s->low_delay)) + s->picture_number++; + + return 0; +} + static void quant_matrix_rebuild(uint16_t *matrix, const uint8_t *old_perm, const uint8_t *new_perm){ uint16_t temp_matrix[64]; @@ -1595,6 +1617,9 @@ static int mpeg_field_start(MpegEncContext *s, const uint8_t *buf, int buf_size) } *s->current_picture_ptr->pan_scan= s1->pan_scan; + + if (HAVE_PTHREADS && (avctx->active_thread_type & FF_THREAD_FRAME)) + ff_thread_finish_setup(avctx); }else{ //second field int i; @@ -1769,6 +1794,7 @@ static int mpeg_decode_slice(Mpeg1Context *s1, int mb_y, const int mb_size= 16>>s->avctx->lowres; ff_draw_horiz_band(s, mb_size*(s->mb_y>>field_pic), mb_size); + MPV_report_decode_progress(s); s->mb_x = 0; s->mb_y += 1<<field_pic; @@ -1926,7 +1952,8 @@ static int slice_end(AVCodecContext *avctx, AVFrame *pict) *pict= *(AVFrame*)s->current_picture_ptr; ff_print_debug_info(s, pict); } else { - s->picture_number++; + if (avctx->active_thread_type & FF_THREAD_FRAME) + s->picture_number++; /* latency of 1 frame for I- and P-frames */ /* XXX: use another variable than picture_number */ if (s->last_picture_ptr != NULL) { @@ -2262,7 +2289,7 @@ static int decode_chunks(AVCodecContext *avctx, buf_ptr = ff_find_start_code(buf_ptr,buf_end, &start_code); if (start_code > 0x1ff){ if(s2->pict_type != AV_PICTURE_TYPE_B || avctx->skip_frame <= AVDISCARD_DEFAULT){ - if((avctx->active_thread_type & FF_THREAD_SLICE) && avctx->thread_count > 1){ + if(HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)){ int i; avctx->execute(avctx, slice_decode_thread, &s2->thread_context[0], NULL, s->slice_count, sizeof(void*)); @@ -2430,7 +2457,7 @@ static int decode_chunks(AVCodecContext *avctx, break; } - if((avctx->active_thread_type & FF_THREAD_SLICE) && avctx->thread_count > 1){ + if(HAVE_THREADS && (avctx->active_thread_type & FF_THREAD_SLICE)){ int threshold= (s2->mb_height*s->slice_count + avctx->thread_count/2) / avctx->thread_count; if(threshold <= mb_y){ MpegEncContext *thread_context= s2->thread_context[s->slice_count]; @@ -2505,6 +2532,7 @@ AVCodec ff_mpeg1video_decoder = { .flush= flush, .max_lowres= 3, .long_name= NULL_IF_CONFIG_SMALL("MPEG-1 video"), + .update_thread_context= ONLY_IF_THREADS_ENABLED(mpeg_decode_update_thread_context) }; AVCodec ff_mpeg2video_decoder = { @@ -2541,7 +2569,7 @@ AVCodec ff_mpegvideo_decoder = { #if CONFIG_MPEG_XVMC_DECODER static av_cold int mpeg_mc_decode_init(AVCodecContext *avctx){ - if((avctx->active_thread_type & FF_THREAD_SLICE) && avctx->thread_count > 1) + if( avctx->active_thread_type & FF_THREAD_SLICE ) return -1; if( !(avctx->slice_flags & SLICE_FLAG_CODED_ORDER) ) return -1; |