factoring code into dv_init_enc_block

Originally committed as revision 16875 to svn://svn.ffmpeg.org/ffmpeg/trunk
pull/126/head
Roman Shaposhnik 16 years ago
parent 5c2a9dd64e
commit 9b8390bfbe
  1. 78
      libavcodec/dv.c

@ -830,10 +830,11 @@ static av_always_inline int dv_guess_dct_mode(DCTELEM *blk) {
return (score88 - score248 > -10);
}
static av_always_inline void dv_set_class_number(DCTELEM* blk, EncBlockInfo* bi,
const uint8_t* zigzag_scan,
const int *weight, int bias)
static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, int linesize, DVVideoContext *s, int bias)
{
const int *weight;
const uint8_t* zigzag_scan;
DECLARE_ALIGNED_16(DCTELEM, blk[64]);
int i, area;
/* We offer two different methods for class number assignment: the
method suggested in SMPTE 314M Table 22, and an improved
@ -853,8 +854,28 @@ static av_always_inline void dv_set_class_number(DCTELEM* blk, EncBlockInfo* bi,
int max = classes[0];
int prev = 0;
assert((((int)blk) & 15) == 0);
bi->area_q[0] = bi->area_q[1] = bi->area_q[2] = bi->area_q[3] = 0;
bi->partial_bit_count = 0;
bi->partial_bit_buffer = 0;
bi->cur_ac = 0;
if (data) {
s->get_pixels(blk, data, linesize);
bi->dct_mode = (s->avctx->flags & CODEC_FLAG_INTERLACED_DCT) &&
dv_guess_dct_mode(blk);
s->fdct[bi->dct_mode](blk);
} else {
/* We rely on the fact that encoding all zeros leads to an immediate EOB,
which is precisely what the spec calls for in the "dummy" blocks. */
memset(blk, 0, sizeof(blk));
bi->dct_mode = 0;
}
bi->mb[0] = blk[0];
zigzag_scan = bi->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct;
weight = bi->dct_mode ? dv_weight_248 : dv_weight_88;
for (area = 0; area < 4; area++) {
bi->prev[area] = prev;
bi->bit_size[area] = 1; // 4 areas 4 bits for EOB :)
@ -900,6 +921,8 @@ static av_always_inline void dv_set_class_number(DCTELEM* blk, EncBlockInfo* bi,
}
bi->next[prev]= i;
}
return bi->bit_size[0] + bi->bit_size[1] + bi->bit_size[2] + bi->bit_size[3];
}
static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos)
@ -980,8 +1003,7 @@ static int dv_encode_video_segment(AVCodecContext *avctx, DVwork_chunk *work_chu
uint8_t* data;
uint8_t* ptr;
uint8_t* dif;
int do_edge_wrap;
DECLARE_ALIGNED_16(DCTELEM, block[64]);
uint8_t scratch[64];
EncBlockInfo enc_blks[5*DV_MAX_BPM];
PutBitContext pbs[5*DV_MAX_BPM];
PutBitContext* pb;
@ -989,8 +1011,6 @@ static int dv_encode_video_segment(AVCodecContext *avctx, DVwork_chunk *work_chu
int vs_bit_size = 0;
int qnos[5];
assert((((int)block) & 15) == 0);
dif = &s->buf[work_chunk->buf_offset*80];
enc_blk = &enc_blks[0];
pb = &pbs[0];
@ -999,11 +1019,9 @@ static int dv_encode_video_segment(AVCodecContext *avctx, DVwork_chunk *work_chu
y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << 3);
c_offset = (((mb_y >> (s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] +
(mb_x >> ((s->sys->pix_fmt == PIX_FMT_YUV411P) ? 2 : 1))) << 3);
do_edge_wrap = 0;
qnos[mb_index] = 15; /* No quantization */
ptr = dif + mb_index*80 + 4;
for (j = 0; j < 6; j++) {
int dummy = 0;
if (s->sys->pix_fmt == PIX_FMT_YUV422P) { /* 4:2:2 */
if (j == 0 || j == 2) {
/* Y0 Y1 */
@ -1017,7 +1035,6 @@ static int dv_encode_video_segment(AVCodecContext *avctx, DVwork_chunk *work_chu
/* j=1 and j=3 are "dummy" blocks, used for AC data only */
data = NULL;
linesize = 0;
dummy = 1;
}
} else { /* 4:1:1 or 4:2:0 */
if (j < 4) { /* Four Y blocks */
@ -1032,15 +1049,9 @@ static int dv_encode_video_segment(AVCodecContext *avctx, DVwork_chunk *work_chu
/* don't ask Fabrice why they inverted Cb and Cr ! */
data = s->picture.data [6 - j] + c_offset;
linesize = s->picture.linesize[6 - j];
if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8))
do_edge_wrap = 1;
}
}
/* Everything is set up -- now just copy data -> DCT block */
if (do_edge_wrap) { /* Edge wrap copy: 4x16 -> 8x8 */
if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
uint8_t* d;
DCTELEM *b = block;
uint8_t* b = scratch;
for (i = 0; i < 8; i++) {
d = data + 8 * linesize;
b[0] = data[0]; b[1] = data[1]; b[2] = data[2]; b[3] = data[3];
@ -1048,40 +1059,19 @@ static int dv_encode_video_segment(AVCodecContext *avctx, DVwork_chunk *work_chu
data += linesize;
b += 8;
}
} else { /* Simple copy: 8x8 -> 8x8 */
if (!dummy)
s->get_pixels(block, data, linesize);
}
if (s->avctx->flags & CODEC_FLAG_INTERLACED_DCT)
enc_blk->dct_mode = dv_guess_dct_mode(block);
else
enc_blk->dct_mode = 0;
enc_blk->area_q[0] = enc_blk->area_q[1] = enc_blk->area_q[2] = enc_blk->area_q[3] = 0;
enc_blk->partial_bit_count = 0;
enc_blk->partial_bit_buffer = 0;
enc_blk->cur_ac = 0;
if (dummy) {
/* We rely on the fact that encoding all zeros leads to an immediate EOB,
which is precisely what the spec calls for in the "dummy" blocks. */
memset(block, 0, sizeof(block));
} else {
s->fdct[enc_blk->dct_mode](block);
data = scratch;
linesize = 8;
}
}
}
dv_set_class_number(block, enc_blk,
enc_blk->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct,
enc_blk->dct_mode ? dv_weight_248 : dv_weight_88,
j/4);
vs_bit_size += dv_init_enc_block(enc_blk, data, linesize, s, j>>2);
init_put_bits(pb, ptr, s->sys->block_sizes[j]/8);
put_bits(pb, 9, (uint16_t)(((enc_blk->mb[0] >> 3) - 1024 + 2) >> 2));
put_bits(pb, 1, enc_blk->dct_mode);
put_bits(pb, 2, enc_blk->cno);
vs_bit_size += enc_blk->bit_size[0] + enc_blk->bit_size[1] +
enc_blk->bit_size[2] + enc_blk->bit_size[3];
++enc_blk;
++pb;
ptr += s->sys->block_sizes[j]/8;

Loading…
Cancel
Save