dv: get rid of global non-const tables

Instead, store them in the context and compute on each parameter change.
pull/76/merge
Anton Khirnov 11 years ago
parent 778111592b
commit 650dee63c8
  1. 14
      libavcodec/dv.c
  2. 9
      libavcodec/dv.h
  3. 34
      libavcodec/dv_profile.c
  4. 7
      libavcodec/dv_profile.h
  5. 20
      libavcodec/dvdec.c
  6. 4
      libavcodec/dvenc.c

@ -175,13 +175,12 @@ static const uint8_t dv100_qstep[16] = {
static const uint8_t dv_quant_areas[4] = { 6, 21, 43, 64 }; 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; int j,i,c,s,p;
uint32_t *factor1, *factor2; uint32_t *factor1, *factor2;
const int *iweight1, *iweight2; const int *iweight1, *iweight2;
if (!d->work_chunks[dv_work_pool_size(d)-1].buf_offset) {
p = i = 0; p = i = 0;
for (c=0; c<d->n_difchan; c++) { for (c=0; c<d->n_difchan; c++) {
for (s=0; s<d->difseg_size; s++) { for (s=0; s<d->difseg_size; s++) {
@ -190,18 +189,16 @@ int ff_dv_init_dynamic_tables(const DVprofile *d)
p += !(j%3); p += !(j%3);
if (!(DV_PROFILE_IS_1080i50(d) && c != 0 && s == 11) && if (!(DV_PROFILE_IS_1080i50(d) && c != 0 && s == 11) &&
!(DV_PROFILE_IS_720p50(d) && s > 9)) { !(DV_PROFILE_IS_720p50(d) && s > 9)) {
dv_calc_mb_coordinates(d, c, s, j, &d->work_chunks[i].mb_coordinates[0]); dv_calc_mb_coordinates(d, c, s, j, &ctx->work_chunks[i].mb_coordinates[0]);
d->work_chunks[i++].buf_offset = p; ctx->work_chunks[i++].buf_offset = p;
} }
p += 5; p += 5;
} }
} }
} }
}
if (!d->idct_factor[DV_PROFILE_IS_HD(d)?8191:5631]) { factor1 = &ctx->idct_factor[0];
factor1 = &d->idct_factor[0]; factor2 = &ctx->idct_factor[DV_PROFILE_IS_HD(d) ? 4096 : 2816];
factor2 = &d->idct_factor[DV_PROFILE_IS_HD(d)?4096:2816];
if (d->height == 720) { if (d->height == 720) {
iweight1 = &ff_dv_iweight_720_y[0]; iweight1 = &ff_dv_iweight_720_y[0];
iweight2 = &ff_dv_iweight_720_c[0]; iweight2 = &ff_dv_iweight_720_c[0];
@ -231,7 +228,6 @@ int ff_dv_init_dynamic_tables(const DVprofile *d)
} }
} }
} }
}
return 0; return 0;
} }

@ -32,6 +32,11 @@
#include "get_bits.h" #include "get_bits.h"
#include "dv_profile.h" #include "dv_profile.h"
typedef struct DVwork_chunk {
uint16_t buf_offset;
uint16_t mb_coordinates[5];
} DVwork_chunk;
typedef struct DVVideoContext { typedef struct DVVideoContext {
const DVprofile *sys; const DVprofile *sys;
AVFrame *frame; AVFrame *frame;
@ -44,6 +49,8 @@ typedef struct DVVideoContext {
void (*fdct[2])(int16_t *block); void (*fdct[2])(int16_t *block);
void (*idct_put[2])(uint8_t *dest, int line_size, int16_t *block); void (*idct_put[2])(uint8_t *dest, int line_size, int16_t *block);
me_cmp_func ildct_cmp; me_cmp_func ildct_cmp;
DVwork_chunk work_chunks[4 * 12 * 27];
uint32_t idct_factor[2 * 4 * 16 * 64];
} DVVideoContext; } DVVideoContext;
enum dv_section_type { enum dv_section_type {
@ -91,7 +98,7 @@ enum dv_pack_type {
extern RL_VLC_ELEM ff_dv_rl_vlc[1184]; 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); int ff_dvvideo_init(AVCodecContext *avctx);
static inline int dv_work_pool_size(const DVprofile *d) static inline int dv_work_pool_size(const DVprofile *d)

@ -24,20 +24,6 @@
#include "avcodec.h" #include "avcodec.h"
#include "dv_profile.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] = { static const uint8_t dv_audio_shuffle525[10][9] = {
{ 0, 30, 60, 20, 50, 80, 10, 40, 70 }, /* 1st channel */ { 0, 30, 60, 20, 50, 80, 10, 40, 70 }, /* 1st channel */
{ 6, 36, 66, 26, 56, 86, 16, 46, 76 }, { 6, 36, 66, 26, 56, 86, 16, 46, 76 },
@ -88,8 +74,6 @@ static const DVprofile dv_profiles[] = {
.height = 480, .height = 480,
.width = 720, .width = 720,
.sar = {{8, 9}, {32, 27}}, .sar = {{8, 9}, {32, 27}},
.work_chunks = &work_chunks_dv25ntsc[0],
.idct_factor = &dv_idct_factor_sd[0],
.pix_fmt = AV_PIX_FMT_YUV411P, .pix_fmt = AV_PIX_FMT_YUV411P,
.bpm = 6, .bpm = 6,
.block_sizes = block_sizes_dv2550, .block_sizes = block_sizes_dv2550,
@ -108,8 +92,6 @@ static const DVprofile dv_profiles[] = {
.height = 576, .height = 576,
.width = 720, .width = 720,
.sar = {{16, 15}, {64, 45}}, .sar = {{16, 15}, {64, 45}},
.work_chunks = &work_chunks_dv25pal[0],
.idct_factor = &dv_idct_factor_sd[0],
.pix_fmt = AV_PIX_FMT_YUV420P, .pix_fmt = AV_PIX_FMT_YUV420P,
.bpm = 6, .bpm = 6,
.block_sizes = block_sizes_dv2550, .block_sizes = block_sizes_dv2550,
@ -128,8 +110,6 @@ static const DVprofile dv_profiles[] = {
.height = 576, .height = 576,
.width = 720, .width = 720,
.sar = {{16, 15}, {64, 45}}, .sar = {{16, 15}, {64, 45}},
.work_chunks = &work_chunks_dv25pal411[0],
.idct_factor = &dv_idct_factor_sd[0],
.pix_fmt = AV_PIX_FMT_YUV411P, .pix_fmt = AV_PIX_FMT_YUV411P,
.bpm = 6, .bpm = 6,
.block_sizes = block_sizes_dv2550, .block_sizes = block_sizes_dv2550,
@ -148,8 +128,6 @@ static const DVprofile dv_profiles[] = {
.height = 480, .height = 480,
.width = 720, .width = 720,
.sar = {{8, 9}, {32, 27}}, .sar = {{8, 9}, {32, 27}},
.work_chunks = &work_chunks_dv50ntsc[0],
.idct_factor = &dv_idct_factor_sd[0],
.pix_fmt = AV_PIX_FMT_YUV422P, .pix_fmt = AV_PIX_FMT_YUV422P,
.bpm = 6, .bpm = 6,
.block_sizes = block_sizes_dv2550, .block_sizes = block_sizes_dv2550,
@ -168,8 +146,6 @@ static const DVprofile dv_profiles[] = {
.height = 576, .height = 576,
.width = 720, .width = 720,
.sar = {{16, 15}, {64, 45}}, .sar = {{16, 15}, {64, 45}},
.work_chunks = &work_chunks_dv50pal[0],
.idct_factor = &dv_idct_factor_sd[0],
.pix_fmt = AV_PIX_FMT_YUV422P, .pix_fmt = AV_PIX_FMT_YUV422P,
.bpm = 6, .bpm = 6,
.block_sizes = block_sizes_dv2550, .block_sizes = block_sizes_dv2550,
@ -188,8 +164,6 @@ static const DVprofile dv_profiles[] = {
.height = 1080, .height = 1080,
.width = 1280, .width = 1280,
.sar = {{1, 1}, {3, 2}}, .sar = {{1, 1}, {3, 2}},
.work_chunks = &work_chunks_dv100ntsci[0],
.idct_factor = &dv_idct_factor_hd1080[0],
.pix_fmt = AV_PIX_FMT_YUV422P, .pix_fmt = AV_PIX_FMT_YUV422P,
.bpm = 8, .bpm = 8,
.block_sizes = block_sizes_dv100, .block_sizes = block_sizes_dv100,
@ -208,8 +182,6 @@ static const DVprofile dv_profiles[] = {
.height = 1080, .height = 1080,
.width = 1440, .width = 1440,
.sar = {{1, 1}, {4, 3}}, .sar = {{1, 1}, {4, 3}},
.work_chunks = &work_chunks_dv100pali[0],
.idct_factor = &dv_idct_factor_hd1080[0],
.pix_fmt = AV_PIX_FMT_YUV422P, .pix_fmt = AV_PIX_FMT_YUV422P,
.bpm = 8, .bpm = 8,
.block_sizes = block_sizes_dv100, .block_sizes = block_sizes_dv100,
@ -228,8 +200,6 @@ static const DVprofile dv_profiles[] = {
.height = 720, .height = 720,
.width = 960, .width = 960,
.sar = {{1, 1}, {4, 3}}, .sar = {{1, 1}, {4, 3}},
.work_chunks = &work_chunks_dv100ntscp[0],
.idct_factor = &dv_idct_factor_hd720[0],
.pix_fmt = AV_PIX_FMT_YUV422P, .pix_fmt = AV_PIX_FMT_YUV422P,
.bpm = 8, .bpm = 8,
.block_sizes = block_sizes_dv100, .block_sizes = block_sizes_dv100,
@ -248,8 +218,6 @@ static const DVprofile dv_profiles[] = {
.height = 720, .height = 720,
.width = 960, .width = 960,
.sar = {{1, 1}, {4, 3}}, .sar = {{1, 1}, {4, 3}},
.work_chunks = &work_chunks_dv100palp[0],
.idct_factor = &dv_idct_factor_hd720[0],
.pix_fmt = AV_PIX_FMT_YUV422P, .pix_fmt = AV_PIX_FMT_YUV422P,
.bpm = 8, .bpm = 8,
.block_sizes = block_sizes_dv100, .block_sizes = block_sizes_dv100,
@ -268,8 +236,6 @@ static const DVprofile dv_profiles[] = {
.height = 576, .height = 576,
.width = 720, .width = 720,
.sar = {{16, 15}, {64, 45}}, .sar = {{16, 15}, {64, 45}},
.work_chunks = &work_chunks_dv25pal[0],
.idct_factor = &dv_idct_factor_sd[0],
.pix_fmt = AV_PIX_FMT_YUV420P, .pix_fmt = AV_PIX_FMT_YUV420P,
.bpm = 6, .bpm = 6,
.block_sizes = block_sizes_dv2550, .block_sizes = block_sizes_dv2550,

@ -25,11 +25,6 @@
#include "libavutil/rational.h" #include "libavutil/rational.h"
#include "avcodec.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 * DVprofile is used to express the differences between various
* DV flavors. For now it's primarily used for differentiating * DV flavors. For now it's primarily used for differentiating
@ -47,8 +42,6 @@ typedef struct DVprofile {
int height; /* picture height in pixels */ int height; /* picture height in pixels */
int width; /* picture width in pixels */ int width; /* picture width in pixels */
AVRational sar[2]; /* sample aspect ratios for 4:3 and 16:9 */ 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 */ enum AVPixelFormat pix_fmt; /* picture pixel format */
int bpm; /* blocks per macroblock */ int bpm; /* blocks per macroblock */
const uint8_t *block_sizes; /* AC block sizes, in bits */ const uint8_t *block_sizes; /* AC block sizes, in bits */

@ -178,12 +178,12 @@ static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
if (DV_PROFILE_IS_HD(s->sys)) { if (DV_PROFILE_IS_HD(s->sys)) {
mb->idct_put = s->idct_put[0]; mb->idct_put = s->idct_put[0];
mb->scan_table = s->dv_zigzag[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; is_field_mode[mb_index] |= !j && dct_mode;
} else { } else {
mb->idct_put = s->idct_put[dct_mode && log2_blocksize == 3]; mb->idct_put = s->idct_put[dct_mode && log2_blocksize == 3];
mb->scan_table = s->dv_zigzag[dct_mode]; 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]; (quant + ff_dv_quant_offset[class1])*64];
} }
dc = dc << 2; dc = dc << 2;
@ -320,13 +320,23 @@ static int dvvideo_decode_frame(AVCodecContext *avctx,
DVVideoContext *s = avctx->priv_data; DVVideoContext *s = avctx->priv_data;
const uint8_t* vsc_pack; const uint8_t* vsc_pack;
int apt, is16_9, ret; int apt, is16_9, ret;
const DVprofile *sys;
s->sys = avpriv_dv_frame_profile(s->sys, buf, buf_size); 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)) { if (!sys || buf_size < sys->frame_size) {
av_log(avctx, AV_LOG_ERROR, "could not find dv frame profile\n"); av_log(avctx, AV_LOG_ERROR, "could not find dv frame profile\n");
return -1; /* NOTE: we only accept several full frames */ 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 = data;
s->frame->key_frame = 1; s->frame->key_frame = 1;
s->frame->pict_type = AV_PICTURE_TYPE_I; 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->frame->top_field_first = 0;
s->buf = buf; 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)); dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
emms_c(); emms_c();

@ -46,7 +46,7 @@ static av_cold int dvvideo_encode_init(AVCodecContext *avctx)
ff_dv_print_profiles(avctx, AV_LOG_ERROR); ff_dv_print_profiles(avctx, AV_LOG_ERROR);
return AVERROR(EINVAL); return AVERROR(EINVAL);
} }
ret = ff_dv_init_dynamic_tables(s->sys); ret = ff_dv_init_dynamic_tables(s, s->sys);
if (ret < 0) { if (ret < 0) {
av_log(avctx, AV_LOG_ERROR, "Error initializing work tables.\n"); av_log(avctx, AV_LOG_ERROR, "Error initializing work tables.\n");
return ret; return ret;
@ -680,7 +680,7 @@ static int dvvideo_encode_frame(AVCodecContext *c, AVPacket *pkt,
c->coded_frame->pict_type = AV_PICTURE_TYPE_I; c->coded_frame->pict_type = AV_PICTURE_TYPE_I;
s->buf = pkt->data; 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)); dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
emms_c(); emms_c();

Loading…
Cancel
Save