From 650dee63c8b1e6693c6cf5983f4a5ed3f571379f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Wed, 18 Jun 2014 10:59:37 +0200 Subject: dv: get rid of global non-const tables Instead, store them in the context and compute on each parameter change. --- libavcodec/dv.c | 14 +++++--------- libavcodec/dv.h | 9 ++++++++- libavcodec/dv_profile.c | 34 ---------------------------------- libavcodec/dv_profile.h | 7 ------- libavcodec/dvdec.c | 20 +++++++++++++++----- libavcodec/dvenc.c | 4 ++-- 6 files changed, 30 insertions(+), 58 deletions(-) (limited to 'libavcodec') diff --git a/libavcodec/dv.c b/libavcodec/dv.c index 1a54c4efa8..143a5ccebb 100644 --- a/libavcodec/dv.c +++ b/libavcodec/dv.c @@ -175,13 +175,12 @@ static const uint8_t dv100_qstep[16] = { static const uint8_t dv_quant_areas[4] = { 6, 21, 43, 64 }; -int ff_dv_init_dynamic_tables(const DVprofile *d) +int ff_dv_init_dynamic_tables(DVVideoContext *ctx, const DVprofile *d) { int j,i,c,s,p; uint32_t *factor1, *factor2; const int *iweight1, *iweight2; - if (!d->work_chunks[dv_work_pool_size(d)-1].buf_offset) { p = i = 0; for (c=0; cn_difchan; c++) { for (s=0; sdifseg_size; s++) { @@ -190,18 +189,16 @@ int ff_dv_init_dynamic_tables(const DVprofile *d) p += !(j%3); if (!(DV_PROFILE_IS_1080i50(d) && c != 0 && s == 11) && !(DV_PROFILE_IS_720p50(d) && s > 9)) { - dv_calc_mb_coordinates(d, c, s, j, &d->work_chunks[i].mb_coordinates[0]); - d->work_chunks[i++].buf_offset = p; + dv_calc_mb_coordinates(d, c, s, j, &ctx->work_chunks[i].mb_coordinates[0]); + ctx->work_chunks[i++].buf_offset = p; } p += 5; } } } - } - if (!d->idct_factor[DV_PROFILE_IS_HD(d)?8191:5631]) { - factor1 = &d->idct_factor[0]; - factor2 = &d->idct_factor[DV_PROFILE_IS_HD(d)?4096:2816]; + factor1 = &ctx->idct_factor[0]; + factor2 = &ctx->idct_factor[DV_PROFILE_IS_HD(d) ? 4096 : 2816]; if (d->height == 720) { iweight1 = &ff_dv_iweight_720_y[0]; iweight2 = &ff_dv_iweight_720_c[0]; @@ -231,7 +228,6 @@ int ff_dv_init_dynamic_tables(const DVprofile *d) } } } - } return 0; } diff --git a/libavcodec/dv.h b/libavcodec/dv.h index 01a4eec49a..f4047a41cc 100644 --- a/libavcodec/dv.h +++ b/libavcodec/dv.h @@ -32,6 +32,11 @@ #include "get_bits.h" #include "dv_profile.h" +typedef struct DVwork_chunk { + uint16_t buf_offset; + uint16_t mb_coordinates[5]; +} DVwork_chunk; + typedef struct DVVideoContext { const DVprofile *sys; AVFrame *frame; @@ -44,6 +49,8 @@ typedef struct DVVideoContext { void (*fdct[2])(int16_t *block); void (*idct_put[2])(uint8_t *dest, int line_size, int16_t *block); me_cmp_func ildct_cmp; + DVwork_chunk work_chunks[4 * 12 * 27]; + uint32_t idct_factor[2 * 4 * 16 * 64]; } DVVideoContext; enum dv_section_type { @@ -91,7 +98,7 @@ enum dv_pack_type { extern RL_VLC_ELEM ff_dv_rl_vlc[1184]; -int ff_dv_init_dynamic_tables(const DVprofile *d); +int ff_dv_init_dynamic_tables(DVVideoContext *s, const DVprofile *d); int ff_dvvideo_init(AVCodecContext *avctx); static inline int dv_work_pool_size(const DVprofile *d) diff --git a/libavcodec/dv_profile.c b/libavcodec/dv_profile.c index be392bbcaa..7ceffa4a51 100644 --- a/libavcodec/dv_profile.c +++ b/libavcodec/dv_profile.c @@ -24,20 +24,6 @@ #include "avcodec.h" #include "dv_profile.h" -static DVwork_chunk work_chunks_dv25pal [1*12*27]; -static DVwork_chunk work_chunks_dv25pal411[1*12*27]; -static DVwork_chunk work_chunks_dv25ntsc [1*10*27]; -static DVwork_chunk work_chunks_dv50pal [2*12*27]; -static DVwork_chunk work_chunks_dv50ntsc [2*10*27]; -static DVwork_chunk work_chunks_dv100palp [2*12*27]; -static DVwork_chunk work_chunks_dv100ntscp[2*10*27]; -static DVwork_chunk work_chunks_dv100pali [4*12*27]; -static DVwork_chunk work_chunks_dv100ntsci[4*10*27]; - -static uint32_t dv_idct_factor_sd [2*2*22*64]; -static uint32_t dv_idct_factor_hd1080[2*4*16*64]; -static uint32_t dv_idct_factor_hd720 [2*4*16*64]; - static const uint8_t dv_audio_shuffle525[10][9] = { { 0, 30, 60, 20, 50, 80, 10, 40, 70 }, /* 1st channel */ { 6, 36, 66, 26, 56, 86, 16, 46, 76 }, @@ -88,8 +74,6 @@ static const DVprofile dv_profiles[] = { .height = 480, .width = 720, .sar = {{8, 9}, {32, 27}}, - .work_chunks = &work_chunks_dv25ntsc[0], - .idct_factor = &dv_idct_factor_sd[0], .pix_fmt = AV_PIX_FMT_YUV411P, .bpm = 6, .block_sizes = block_sizes_dv2550, @@ -108,8 +92,6 @@ static const DVprofile dv_profiles[] = { .height = 576, .width = 720, .sar = {{16, 15}, {64, 45}}, - .work_chunks = &work_chunks_dv25pal[0], - .idct_factor = &dv_idct_factor_sd[0], .pix_fmt = AV_PIX_FMT_YUV420P, .bpm = 6, .block_sizes = block_sizes_dv2550, @@ -128,8 +110,6 @@ static const DVprofile dv_profiles[] = { .height = 576, .width = 720, .sar = {{16, 15}, {64, 45}}, - .work_chunks = &work_chunks_dv25pal411[0], - .idct_factor = &dv_idct_factor_sd[0], .pix_fmt = AV_PIX_FMT_YUV411P, .bpm = 6, .block_sizes = block_sizes_dv2550, @@ -148,8 +128,6 @@ static const DVprofile dv_profiles[] = { .height = 480, .width = 720, .sar = {{8, 9}, {32, 27}}, - .work_chunks = &work_chunks_dv50ntsc[0], - .idct_factor = &dv_idct_factor_sd[0], .pix_fmt = AV_PIX_FMT_YUV422P, .bpm = 6, .block_sizes = block_sizes_dv2550, @@ -168,8 +146,6 @@ static const DVprofile dv_profiles[] = { .height = 576, .width = 720, .sar = {{16, 15}, {64, 45}}, - .work_chunks = &work_chunks_dv50pal[0], - .idct_factor = &dv_idct_factor_sd[0], .pix_fmt = AV_PIX_FMT_YUV422P, .bpm = 6, .block_sizes = block_sizes_dv2550, @@ -188,8 +164,6 @@ static const DVprofile dv_profiles[] = { .height = 1080, .width = 1280, .sar = {{1, 1}, {3, 2}}, - .work_chunks = &work_chunks_dv100ntsci[0], - .idct_factor = &dv_idct_factor_hd1080[0], .pix_fmt = AV_PIX_FMT_YUV422P, .bpm = 8, .block_sizes = block_sizes_dv100, @@ -208,8 +182,6 @@ static const DVprofile dv_profiles[] = { .height = 1080, .width = 1440, .sar = {{1, 1}, {4, 3}}, - .work_chunks = &work_chunks_dv100pali[0], - .idct_factor = &dv_idct_factor_hd1080[0], .pix_fmt = AV_PIX_FMT_YUV422P, .bpm = 8, .block_sizes = block_sizes_dv100, @@ -228,8 +200,6 @@ static const DVprofile dv_profiles[] = { .height = 720, .width = 960, .sar = {{1, 1}, {4, 3}}, - .work_chunks = &work_chunks_dv100ntscp[0], - .idct_factor = &dv_idct_factor_hd720[0], .pix_fmt = AV_PIX_FMT_YUV422P, .bpm = 8, .block_sizes = block_sizes_dv100, @@ -248,8 +218,6 @@ static const DVprofile dv_profiles[] = { .height = 720, .width = 960, .sar = {{1, 1}, {4, 3}}, - .work_chunks = &work_chunks_dv100palp[0], - .idct_factor = &dv_idct_factor_hd720[0], .pix_fmt = AV_PIX_FMT_YUV422P, .bpm = 8, .block_sizes = block_sizes_dv100, @@ -268,8 +236,6 @@ static const DVprofile dv_profiles[] = { .height = 576, .width = 720, .sar = {{16, 15}, {64, 45}}, - .work_chunks = &work_chunks_dv25pal[0], - .idct_factor = &dv_idct_factor_sd[0], .pix_fmt = AV_PIX_FMT_YUV420P, .bpm = 6, .block_sizes = block_sizes_dv2550, diff --git a/libavcodec/dv_profile.h b/libavcodec/dv_profile.h index c6d2278b0d..9cf58a0bb5 100644 --- a/libavcodec/dv_profile.h +++ b/libavcodec/dv_profile.h @@ -25,11 +25,6 @@ #include "libavutil/rational.h" #include "avcodec.h" -typedef struct DVwork_chunk { - uint16_t buf_offset; - uint16_t mb_coordinates[5]; -} DVwork_chunk; - /* * DVprofile is used to express the differences between various * DV flavors. For now it's primarily used for differentiating @@ -47,8 +42,6 @@ typedef struct DVprofile { int height; /* picture height in pixels */ int width; /* picture width in pixels */ AVRational sar[2]; /* sample aspect ratios for 4:3 and 16:9 */ - DVwork_chunk *work_chunks; /* each thread gets its own chunk of frame to work on */ - uint32_t *idct_factor; /* set of iDCT factor tables */ enum AVPixelFormat pix_fmt; /* picture pixel format */ int bpm; /* blocks per macroblock */ const uint8_t *block_sizes; /* AC block sizes, in bits */ diff --git a/libavcodec/dvdec.c b/libavcodec/dvdec.c index ef9ba4cd1c..f354b9e0e8 100644 --- a/libavcodec/dvdec.c +++ b/libavcodec/dvdec.c @@ -178,12 +178,12 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg) if (DV_PROFILE_IS_HD(s->sys)) { mb->idct_put = s->idct_put[0]; mb->scan_table = s->dv_zigzag[0]; - mb->factor_table = &s->sys->idct_factor[(j >= 4)*4*16*64 + class1*16*64 + quant*64]; + mb->factor_table = &s->idct_factor[(j >= 4)*4*16*64 + class1*16*64 + quant*64]; is_field_mode[mb_index] |= !j && dct_mode; } else { mb->idct_put = s->idct_put[dct_mode && log2_blocksize == 3]; mb->scan_table = s->dv_zigzag[dct_mode]; - mb->factor_table = &s->sys->idct_factor[(class1 == 3)*2*22*64 + dct_mode*22*64 + + mb->factor_table = &s->idct_factor[(class1 == 3)*2*22*64 + dct_mode*22*64 + (quant + ff_dv_quant_offset[class1])*64]; } dc = dc << 2; @@ -320,13 +320,23 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, DVVideoContext *s = avctx->priv_data; const uint8_t* vsc_pack; int apt, is16_9, ret; + const DVprofile *sys; - s->sys = avpriv_dv_frame_profile(s->sys, buf, buf_size); - if (!s->sys || buf_size < s->sys->frame_size || ff_dv_init_dynamic_tables(s->sys)) { + sys = avpriv_dv_frame_profile(s->sys, buf, buf_size); + if (!sys || buf_size < sys->frame_size) { av_log(avctx, AV_LOG_ERROR, "could not find dv frame profile\n"); return -1; /* NOTE: we only accept several full frames */ } + if (sys != s->sys) { + ret = ff_dv_init_dynamic_tables(s, sys); + if (ret < 0) { + av_log(avctx, AV_LOG_ERROR, "Error initializing the work tables.\n"); + return ret; + } + s->sys = sys; + } + s->frame = data; s->frame->key_frame = 1; s->frame->pict_type = AV_PICTURE_TYPE_I; @@ -345,7 +355,7 @@ static int dvvideo_decode_frame(AVCodecContext *avctx, s->frame->top_field_first = 0; s->buf = buf; - avctx->execute(avctx, dv_decode_video_segment, s->sys->work_chunks, NULL, + avctx->execute(avctx, dv_decode_video_segment, s->work_chunks, NULL, dv_work_pool_size(s->sys), sizeof(DVwork_chunk)); emms_c(); diff --git a/libavcodec/dvenc.c b/libavcodec/dvenc.c index 552f6912d0..94fb7eaf6f 100644 --- a/libavcodec/dvenc.c +++ b/libavcodec/dvenc.c @@ -46,7 +46,7 @@ static av_cold int dvvideo_encode_init(AVCodecContext *avctx) ff_dv_print_profiles(avctx, AV_LOG_ERROR); return AVERROR(EINVAL); } - ret = ff_dv_init_dynamic_tables(s->sys); + ret = ff_dv_init_dynamic_tables(s, s->sys); if (ret < 0) { av_log(avctx, AV_LOG_ERROR, "Error initializing work tables.\n"); return ret; @@ -680,7 +680,7 @@ static int dvvideo_encode_frame(AVCodecContext *c, AVPacket *pkt, c->coded_frame->pict_type = AV_PICTURE_TYPE_I; s->buf = pkt->data; - c->execute(c, dv_encode_video_segment, s->sys->work_chunks, NULL, + c->execute(c, dv_encode_video_segment, s->work_chunks, NULL, dv_work_pool_size(s->sys), sizeof(DVwork_chunk)); emms_c(); -- cgit v1.2.3