aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/mpeg12.c
diff options
context:
space:
mode:
authorAlexander Strange <astrange@ithinksw.com>2011-06-02 10:15:58 -0700
committerRonald S. Bultje <rsbultje@gmail.com>2011-06-02 10:16:20 -0700
commit6a9c85944427e3c4355bce67d7f677ec69527bff (patch)
treedf4bb83f820a5c0295485ca8b7751c4063d5165f /libavcodec/mpeg12.c
parent53be7b23e9d7074d1aeee77407b008411d034e9e (diff)
downloadffmpeg-6a9c85944427e3c4355bce67d7f677ec69527bff.tar.gz
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.c36
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;