00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00041 #include "libavutil/pixdesc.h"
00042 #include "avcodec.h"
00043 #include "dsputil.h"
00044 #include "get_bits.h"
00045 #include "internal.h"
00046 #include "put_bits.h"
00047 #include "simple_idct.h"
00048 #include "dvdata.h"
00049 #include "dv_tablegen.h"
00050
00051
00052 RL_VLC_ELEM ff_dv_rl_vlc[1184];
00053
00054 static inline void dv_calc_mb_coordinates(const DVprofile *d, int chan, int seq, int slot,
00055 uint16_t *tbl)
00056 {
00057 static const uint8_t off[] = { 2, 6, 8, 0, 4 };
00058 static const uint8_t shuf1[] = { 36, 18, 54, 0, 72 };
00059 static const uint8_t shuf2[] = { 24, 12, 36, 0, 48 };
00060 static const uint8_t shuf3[] = { 18, 9, 27, 0, 36 };
00061
00062 static const uint8_t l_start[] = {0, 4, 9, 13, 18, 22, 27, 31, 36, 40};
00063 static const uint8_t l_start_shuffled[] = { 9, 4, 13, 0, 18 };
00064
00065 static const uint8_t serpent1[] = {0, 1, 2, 2, 1, 0,
00066 0, 1, 2, 2, 1, 0,
00067 0, 1, 2, 2, 1, 0,
00068 0, 1, 2, 2, 1, 0,
00069 0, 1, 2};
00070 static const uint8_t serpent2[] = {0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
00071 0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
00072 0, 1, 2, 3, 4, 5};
00073
00074 static const uint8_t remap[][2] = {{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
00075 { 0, 0}, { 0, 1}, { 0, 2}, { 0, 3}, {10, 0},
00076 {10, 1}, {10, 2}, {10, 3}, {20, 0}, {20, 1},
00077 {20, 2}, {20, 3}, {30, 0}, {30, 1}, {30, 2},
00078 {30, 3}, {40, 0}, {40, 1}, {40, 2}, {40, 3},
00079 {50, 0}, {50, 1}, {50, 2}, {50, 3}, {60, 0},
00080 {60, 1}, {60, 2}, {60, 3}, {70, 0}, {70, 1},
00081 {70, 2}, {70, 3}, { 0,64}, { 0,65}, { 0,66},
00082 {10,64}, {10,65}, {10,66}, {20,64}, {20,65},
00083 {20,66}, {30,64}, {30,65}, {30,66}, {40,64},
00084 {40,65}, {40,66}, {50,64}, {50,65}, {50,66},
00085 {60,64}, {60,65}, {60,66}, {70,64}, {70,65},
00086 {70,66}, { 0,67}, {20,67}, {40,67}, {60,67}};
00087
00088 int i, k, m;
00089 int x, y, blk;
00090
00091 for (m=0; m<5; m++) {
00092 switch (d->width) {
00093 case 1440:
00094 blk = (chan*11+seq)*27+slot;
00095
00096 if (chan == 0 && seq == 11) {
00097 x = m*27+slot;
00098 if (x<90) {
00099 y = 0;
00100 } else {
00101 x = (x - 90)*2;
00102 y = 67;
00103 }
00104 } else {
00105 i = (4*chan + blk + off[m])%11;
00106 k = (blk/11)%27;
00107
00108 x = shuf1[m] + (chan&1)*9 + k%9;
00109 y = (i*3+k/9)*2 + (chan>>1) + 1;
00110 }
00111 tbl[m] = (x<<1)|(y<<9);
00112 break;
00113 case 1280:
00114 blk = (chan*10+seq)*27+slot;
00115
00116 i = (4*chan + (seq/5) + 2*blk + off[m])%10;
00117 k = (blk/5)%27;
00118
00119 x = shuf1[m]+(chan&1)*9 + k%9;
00120 y = (i*3+k/9)*2 + (chan>>1) + 4;
00121
00122 if (x >= 80) {
00123 x = remap[y][0]+((x-80)<<(y>59));
00124 y = remap[y][1];
00125 }
00126 tbl[m] = (x<<1)|(y<<9);
00127 break;
00128 case 960:
00129 blk = (chan*10+seq)*27+slot;
00130
00131 i = (4*chan + (seq/5) + 2*blk + off[m])%10;
00132 k = (blk/5)%27 + (i&1)*3;
00133
00134 x = shuf2[m] + k%6 + 6*(chan&1);
00135 y = l_start[i] + k/6 + 45*(chan>>1);
00136 tbl[m] = (x<<1)|(y<<9);
00137 break;
00138 case 720:
00139 switch (d->pix_fmt) {
00140 case PIX_FMT_YUV422P:
00141 x = shuf3[m] + slot/3;
00142 y = serpent1[slot] +
00143 ((((seq + off[m]) % d->difseg_size)<<1) + chan)*3;
00144 tbl[m] = (x<<1)|(y<<8);
00145 break;
00146 case PIX_FMT_YUV420P:
00147 x = shuf3[m] + slot/3;
00148 y = serpent1[slot] +
00149 ((seq + off[m]) % d->difseg_size)*3;
00150 tbl[m] = (x<<1)|(y<<9);
00151 break;
00152 case PIX_FMT_YUV411P:
00153 i = (seq + off[m]) % d->difseg_size;
00154 k = slot + ((m==1||m==2)?3:0);
00155
00156 x = l_start_shuffled[m] + k/6;
00157 y = serpent2[k] + i*6;
00158 if (x>21)
00159 y = y*2 - i*6;
00160 tbl[m] = (x<<2)|(y<<8);
00161 break;
00162 }
00163 default:
00164 break;
00165 }
00166 }
00167 }
00168
00169
00170 static const uint8_t dv100_qstep[16] = {
00171 1,
00172 1,
00173 2, 3, 4, 5, 6, 7, 8, 16, 18, 20, 22, 24, 28, 52
00174 };
00175
00176 static const uint8_t dv_quant_areas[4] = { 6, 21, 43, 64 };
00177
00178 int ff_dv_init_dynamic_tables(const DVprofile *d)
00179 {
00180 int j,i,c,s,p;
00181 uint32_t *factor1, *factor2;
00182 const int *iweight1, *iweight2;
00183
00184 if (!d->work_chunks[dv_work_pool_size(d)-1].buf_offset) {
00185 p = i = 0;
00186 for (c=0; c<d->n_difchan; c++) {
00187 for (s=0; s<d->difseg_size; s++) {
00188 p += 6;
00189 for (j=0; j<27; j++) {
00190 p += !(j%3);
00191 if (!(DV_PROFILE_IS_1080i50(d) && c != 0 && s == 11) &&
00192 !(DV_PROFILE_IS_720p50(d) && s > 9)) {
00193 dv_calc_mb_coordinates(d, c, s, j, &d->work_chunks[i].mb_coordinates[0]);
00194 d->work_chunks[i++].buf_offset = p;
00195 }
00196 p += 5;
00197 }
00198 }
00199 }
00200 }
00201
00202 if (!d->idct_factor[DV_PROFILE_IS_HD(d)?8191:5631]) {
00203 factor1 = &d->idct_factor[0];
00204 factor2 = &d->idct_factor[DV_PROFILE_IS_HD(d)?4096:2816];
00205 if (d->height == 720) {
00206 iweight1 = &ff_dv_iweight_720_y[0];
00207 iweight2 = &ff_dv_iweight_720_c[0];
00208 } else {
00209 iweight1 = &ff_dv_iweight_1080_y[0];
00210 iweight2 = &ff_dv_iweight_1080_c[0];
00211 }
00212 if (DV_PROFILE_IS_HD(d)) {
00213 for (c = 0; c < 4; c++) {
00214 for (s = 0; s < 16; s++) {
00215 for (i = 0; i < 64; i++) {
00216 *factor1++ = (dv100_qstep[s] << (c + 9)) * iweight1[i];
00217 *factor2++ = (dv100_qstep[s] << (c + 9)) * iweight2[i];
00218 }
00219 }
00220 }
00221 } else {
00222 iweight1 = &ff_dv_iweight_88[0];
00223 for (j = 0; j < 2; j++, iweight1 = &ff_dv_iweight_248[0]) {
00224 for (s = 0; s < 22; s++) {
00225 for (i = c = 0; c < 4; c++) {
00226 for (; i < dv_quant_areas[c]; i++) {
00227 *factor1 = iweight1[i] << (ff_dv_quant_shifts[s][c] + 1);
00228 *factor2++ = (*factor1++) << 1;
00229 }
00230 }
00231 }
00232 }
00233 }
00234 }
00235
00236 return 0;
00237 }
00238
00239 av_cold int ff_dvvideo_init(AVCodecContext *avctx)
00240 {
00241 DVVideoContext *s = avctx->priv_data;
00242 DSPContext dsp;
00243 static int done = 0;
00244 int i, j;
00245
00246 if (!done) {
00247 VLC dv_vlc;
00248 uint16_t new_dv_vlc_bits[NB_DV_VLC*2];
00249 uint8_t new_dv_vlc_len[NB_DV_VLC*2];
00250 uint8_t new_dv_vlc_run[NB_DV_VLC*2];
00251 int16_t new_dv_vlc_level[NB_DV_VLC*2];
00252
00253 done = 1;
00254
00255
00256 for (i = 0, j = 0; i < NB_DV_VLC; i++, j++) {
00257 new_dv_vlc_bits[j] = dv_vlc_bits[i];
00258 new_dv_vlc_len[j] = dv_vlc_len[i];
00259 new_dv_vlc_run[j] = dv_vlc_run[i];
00260 new_dv_vlc_level[j] = dv_vlc_level[i];
00261
00262 if (dv_vlc_level[i]) {
00263 new_dv_vlc_bits[j] <<= 1;
00264 new_dv_vlc_len[j]++;
00265
00266 j++;
00267 new_dv_vlc_bits[j] = (dv_vlc_bits[i] << 1) | 1;
00268 new_dv_vlc_len[j] = dv_vlc_len[i] + 1;
00269 new_dv_vlc_run[j] = dv_vlc_run[i];
00270 new_dv_vlc_level[j] = -dv_vlc_level[i];
00271 }
00272 }
00273
00274
00275
00276 init_vlc(&dv_vlc, TEX_VLC_BITS, j,
00277 new_dv_vlc_len, 1, 1, new_dv_vlc_bits, 2, 2, 0);
00278 assert(dv_vlc.table_size == 1184);
00279
00280 for (i = 0; i < dv_vlc.table_size; i++){
00281 int code = dv_vlc.table[i][0];
00282 int len = dv_vlc.table[i][1];
00283 int level, run;
00284
00285 if (len < 0){
00286 run = 0;
00287 level = code;
00288 } else {
00289 run = new_dv_vlc_run [code] + 1;
00290 level = new_dv_vlc_level[code];
00291 }
00292 ff_dv_rl_vlc[i].len = len;
00293 ff_dv_rl_vlc[i].level = level;
00294 ff_dv_rl_vlc[i].run = run;
00295 }
00296 ff_free_vlc(&dv_vlc);
00297 }
00298
00299
00300 ff_dsputil_init(&dsp, avctx);
00301 ff_set_cmp(&dsp, dsp.ildct_cmp, avctx->ildct_cmp);
00302 s->get_pixels = dsp.get_pixels;
00303 s->ildct_cmp = dsp.ildct_cmp[5];
00304
00305
00306 s->fdct[0] = dsp.fdct;
00307 s->idct_put[0] = dsp.idct_put;
00308 for (i = 0; i < 64; i++)
00309 s->dv_zigzag[0][i] = dsp.idct_permutation[ff_zigzag_direct[i]];
00310
00311
00312 s->fdct[1] = dsp.fdct248;
00313 s->idct_put[1] = ff_simple_idct248_put;
00314 if (avctx->lowres){
00315 for (i = 0; i < 64; i++){
00316 int j = ff_zigzag248_direct[i];
00317 s->dv_zigzag[1][i] = dsp.idct_permutation[(j & 7) + (j & 8) * 4 + (j & 48) / 2];
00318 }
00319 }else
00320 memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64);
00321
00322 avctx->coded_frame = &s->picture;
00323 s->avctx = avctx;
00324 avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
00325
00326 return 0;
00327 }
00328
00329 static av_cold int dvvideo_init_encoder(AVCodecContext *avctx)
00330 {
00331 if (!avpriv_dv_codec_profile(avctx)) {
00332 av_log(avctx, AV_LOG_ERROR, "Found no DV profile for %ix%i %s video. "
00333 "Valid DV profiles are:\n",
00334 avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt));
00335 ff_dv_print_profiles(avctx, AV_LOG_ERROR);
00336 return AVERROR(EINVAL);
00337 }
00338 if (avctx->height > 576) {
00339 av_log(avctx, AV_LOG_ERROR, "DVCPRO HD encoding is not supported.\n");
00340 return AVERROR_PATCHWELCOME;
00341 }
00342
00343 dv_vlc_map_tableinit();
00344
00345 return ff_dvvideo_init(avctx);
00346 }
00347
00348
00349 static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5;
00350 static const int mb_area_start[5] = { 1, 6, 21, 43, 64 };
00351
00352 static inline int put_bits_left(PutBitContext* s)
00353 {
00354 return (s->buf_end - s->buf) * 8 - put_bits_count(s);
00355 }
00356
00357 #if CONFIG_SMALL
00358
00359 static av_always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc)
00360 {
00361 int size;
00362 if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
00363 *vlc = dv_vlc_map[run][level].vlc | sign;
00364 size = dv_vlc_map[run][level].size;
00365 }
00366 else {
00367 if (level < DV_VLC_MAP_LEV_SIZE) {
00368 *vlc = dv_vlc_map[0][level].vlc | sign;
00369 size = dv_vlc_map[0][level].size;
00370 } else {
00371 *vlc = 0xfe00 | (level << 1) | sign;
00372 size = 16;
00373 }
00374 if (run) {
00375 *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc :
00376 (0x1f80 | (run - 1))) << size;
00377 size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
00378 }
00379 }
00380
00381 return size;
00382 }
00383
00384 static av_always_inline int dv_rl2vlc_size(int run, int level)
00385 {
00386 int size;
00387
00388 if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
00389 size = dv_vlc_map[run][level].size;
00390 }
00391 else {
00392 size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16;
00393 if (run) {
00394 size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
00395 }
00396 }
00397 return size;
00398 }
00399 #else
00400 static av_always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc)
00401 {
00402 *vlc = dv_vlc_map[run][l].vlc | sign;
00403 return dv_vlc_map[run][l].size;
00404 }
00405
00406 static av_always_inline int dv_rl2vlc_size(int run, int l)
00407 {
00408 return dv_vlc_map[run][l].size;
00409 }
00410 #endif
00411
00412 typedef struct EncBlockInfo {
00413 int area_q[4];
00414 int bit_size[4];
00415 int prev[5];
00416 int cur_ac;
00417 int cno;
00418 int dct_mode;
00419 DCTELEM mb[64];
00420 uint8_t next[64];
00421 uint8_t sign[64];
00422 uint8_t partial_bit_count;
00423 uint32_t partial_bit_buffer;
00424 } EncBlockInfo;
00425
00426 static av_always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi,
00427 PutBitContext* pb_pool,
00428 PutBitContext* pb_end)
00429 {
00430 int prev, bits_left;
00431 PutBitContext* pb = pb_pool;
00432 int size = bi->partial_bit_count;
00433 uint32_t vlc = bi->partial_bit_buffer;
00434
00435 bi->partial_bit_count = bi->partial_bit_buffer = 0;
00436 for (;;){
00437
00438 for (; size > (bits_left = put_bits_left(pb)); pb++) {
00439 if (bits_left) {
00440 size -= bits_left;
00441 put_bits(pb, bits_left, vlc >> size);
00442 vlc = vlc & ((1 << size) - 1);
00443 }
00444 if (pb + 1 >= pb_end) {
00445 bi->partial_bit_count = size;
00446 bi->partial_bit_buffer = vlc;
00447 return pb;
00448 }
00449 }
00450
00451
00452 put_bits(pb, size, vlc);
00453
00454 if (bi->cur_ac >= 64)
00455 break;
00456
00457
00458 prev = bi->cur_ac;
00459 bi->cur_ac = bi->next[prev];
00460 if (bi->cur_ac < 64){
00461 size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc);
00462 } else {
00463 size = 4; vlc = 6;
00464 }
00465 }
00466 return pb;
00467 }
00468
00469 static av_always_inline int dv_guess_dct_mode(DVVideoContext *s, uint8_t *data, int linesize) {
00470 if (s->avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
00471 int ps = s->ildct_cmp(NULL, data, NULL, linesize, 8) - 400;
00472 if (ps > 0) {
00473 int is = s->ildct_cmp(NULL, data , NULL, linesize<<1, 4) +
00474 s->ildct_cmp(NULL, data + linesize, NULL, linesize<<1, 4);
00475 return ps > is;
00476 }
00477 }
00478
00479 return 0;
00480 }
00481
00482 static const int dv_weight_bits = 18;
00483 static const int dv_weight_88[64] = {
00484 131072, 257107, 257107, 242189, 252167, 242189, 235923, 237536,
00485 237536, 235923, 229376, 231390, 223754, 231390, 229376, 222935,
00486 224969, 217965, 217965, 224969, 222935, 200636, 218652, 211916,
00487 212325, 211916, 218652, 200636, 188995, 196781, 205965, 206433,
00488 206433, 205965, 196781, 188995, 185364, 185364, 200636, 200704,
00489 200636, 185364, 185364, 174609, 180568, 195068, 195068, 180568,
00490 174609, 170091, 175557, 189591, 175557, 170091, 165371, 170627,
00491 170627, 165371, 160727, 153560, 160727, 144651, 144651, 136258,
00492 };
00493 static const int dv_weight_248[64] = {
00494 131072, 242189, 257107, 237536, 229376, 200636, 242189, 223754,
00495 224969, 196781, 262144, 242189, 229376, 200636, 257107, 237536,
00496 211916, 185364, 235923, 217965, 229376, 211916, 206433, 180568,
00497 242189, 223754, 224969, 196781, 211916, 185364, 235923, 217965,
00498 200704, 175557, 222935, 205965, 200636, 185364, 195068, 170627,
00499 229376, 211916, 206433, 180568, 200704, 175557, 222935, 205965,
00500 175557, 153560, 188995, 174609, 165371, 144651, 200636, 185364,
00501 195068, 170627, 175557, 153560, 188995, 174609, 165371, 144651,
00502 };
00503
00504 static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, int linesize, DVVideoContext *s, int bias)
00505 {
00506 const int *weight;
00507 const uint8_t* zigzag_scan;
00508 LOCAL_ALIGNED_16(DCTELEM, blk, [64]);
00509 int i, area;
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520 #if 0
00521 static const int classes[] = {12, 24, 36, 0xffff};
00522 #else
00523 static const int classes[] = {-1, -1, 255, 0xffff};
00524 #endif
00525 int max = classes[0];
00526 int prev = 0;
00527
00528 assert((((int)blk) & 15) == 0);
00529
00530 bi->area_q[0] = bi->area_q[1] = bi->area_q[2] = bi->area_q[3] = 0;
00531 bi->partial_bit_count = 0;
00532 bi->partial_bit_buffer = 0;
00533 bi->cur_ac = 0;
00534 if (data) {
00535 bi->dct_mode = dv_guess_dct_mode(s, data, linesize);
00536 s->get_pixels(blk, data, linesize);
00537 s->fdct[bi->dct_mode](blk);
00538 } else {
00539
00540
00541 memset(blk, 0, 64*sizeof(*blk));
00542 bi->dct_mode = 0;
00543 }
00544 bi->mb[0] = blk[0];
00545
00546 zigzag_scan = bi->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct;
00547 weight = bi->dct_mode ? dv_weight_248 : dv_weight_88;
00548
00549 for (area = 0; area < 4; area++) {
00550 bi->prev[area] = prev;
00551 bi->bit_size[area] = 1;
00552 for (i = mb_area_start[area]; i < mb_area_start[area+1]; i++) {
00553 int level = blk[zigzag_scan[i]];
00554
00555 if (level + 15 > 30U) {
00556 bi->sign[i] = (level >> 31) & 1;
00557
00558
00559
00560 level = (FFABS(level) * weight[i] + (1 << (dv_weight_bits+3))) >> (dv_weight_bits+4);
00561 bi->mb[i] = level;
00562 if (level > max)
00563 max = level;
00564 bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, level);
00565 bi->next[prev]= i;
00566 prev = i;
00567 }
00568 }
00569 }
00570 bi->next[prev]= i;
00571 for (bi->cno = 0; max > classes[bi->cno]; bi->cno++);
00572
00573 bi->cno += bias;
00574
00575 if (bi->cno >= 3) {
00576 bi->cno = 3;
00577 prev = 0;
00578 i = bi->next[prev];
00579 for (area = 0; area < 4; area++) {
00580 bi->prev[area] = prev;
00581 bi->bit_size[area] = 1;
00582 for (; i < mb_area_start[area+1]; i = bi->next[i]) {
00583 bi->mb[i] >>= 1;
00584
00585 if (bi->mb[i]) {
00586 bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, bi->mb[i]);
00587 bi->next[prev]= i;
00588 prev = i;
00589 }
00590 }
00591 }
00592 bi->next[prev]= i;
00593 }
00594
00595 return bi->bit_size[0] + bi->bit_size[1] + bi->bit_size[2] + bi->bit_size[3];
00596 }
00597
00598 static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos)
00599 {
00600 int size[5];
00601 int i, j, k, a, prev, a2;
00602 EncBlockInfo* b;
00603
00604 size[0] = size[1] = size[2] = size[3] = size[4] = 1 << 24;
00605 do {
00606 b = blks;
00607 for (i = 0; i < 5; i++) {
00608 if (!qnos[i])
00609 continue;
00610
00611 qnos[i]--;
00612 size[i] = 0;
00613 for (j = 0; j < 6; j++, b++) {
00614 for (a = 0; a < 4; a++) {
00615 if (b->area_q[a] != ff_dv_quant_shifts[qnos[i] + ff_dv_quant_offset[b->cno]][a]) {
00616 b->bit_size[a] = 1;
00617 b->area_q[a]++;
00618 prev = b->prev[a];
00619 assert(b->next[prev] >= mb_area_start[a+1] || b->mb[prev]);
00620 for (k = b->next[prev] ; k < mb_area_start[a+1]; k = b->next[k]) {
00621 b->mb[k] >>= 1;
00622 if (b->mb[k]) {
00623 b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
00624 prev = k;
00625 } else {
00626 if (b->next[k] >= mb_area_start[a+1] && b->next[k]<64){
00627 for (a2 = a + 1; b->next[k] >= mb_area_start[a2+1]; a2++)
00628 b->prev[a2] = prev;
00629 assert(a2 < 4);
00630 assert(b->mb[b->next[k]]);
00631 b->bit_size[a2] += dv_rl2vlc_size(b->next[k] - prev - 1, b->mb[b->next[k]])
00632 -dv_rl2vlc_size(b->next[k] - k - 1, b->mb[b->next[k]]);
00633 assert(b->prev[a2] == k && (a2 + 1 >= 4 || b->prev[a2+1] != k));
00634 b->prev[a2] = prev;
00635 }
00636 b->next[prev] = b->next[k];
00637 }
00638 }
00639 b->prev[a+1]= prev;
00640 }
00641 size[i] += b->bit_size[a];
00642 }
00643 }
00644 if (vs_total_ac_bits >= size[0] + size[1] + size[2] + size[3] + size[4])
00645 return;
00646 }
00647 } while (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4]);
00648
00649
00650 for (a = 2; a == 2 || vs_total_ac_bits < size[0]; a += a){
00651 b = blks;
00652 size[0] = 5 * 6 * 4;
00653 for (j = 0; j < 6 *5; j++, b++) {
00654 prev = b->prev[0];
00655 for (k = b->next[prev]; k < 64; k = b->next[k]) {
00656 if (b->mb[k] < a && b->mb[k] > -a){
00657 b->next[prev] = b->next[k];
00658 }else{
00659 size[0] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
00660 prev = k;
00661 }
00662 }
00663 }
00664 }
00665 }
00666
00667 static int dv_encode_video_segment(AVCodecContext *avctx, void *arg)
00668 {
00669 DVVideoContext *s = avctx->priv_data;
00670 DVwork_chunk *work_chunk = arg;
00671 int mb_index, i, j;
00672 int mb_x, mb_y, c_offset, linesize, y_stride;
00673 uint8_t* y_ptr;
00674 uint8_t* dif;
00675 LOCAL_ALIGNED_8(uint8_t, scratch, [128]);
00676 EncBlockInfo enc_blks[5*DV_MAX_BPM];
00677 PutBitContext pbs[5*DV_MAX_BPM];
00678 PutBitContext* pb;
00679 EncBlockInfo* enc_blk;
00680 int vs_bit_size = 0;
00681 int qnos[5] = {15, 15, 15, 15, 15};
00682 int* qnosp = &qnos[0];
00683
00684 dif = &s->buf[work_chunk->buf_offset*80];
00685 enc_blk = &enc_blks[0];
00686 for (mb_index = 0; mb_index < 5; mb_index++) {
00687 dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);
00688
00689
00690 if ((s->sys->pix_fmt == PIX_FMT_YUV420P) ||
00691 (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
00692 (s->sys->height >= 720 && mb_y != 134)) {
00693 y_stride = s->picture.linesize[0] << 3;
00694 } else {
00695 y_stride = 16;
00696 }
00697 y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << 3);
00698 linesize = s->picture.linesize[0];
00699
00700 if (s->sys->video_stype == 4) {
00701 vs_bit_size +=
00702 dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) +
00703 dv_init_enc_block(enc_blk+1, NULL , linesize, s, 0) +
00704 dv_init_enc_block(enc_blk+2, y_ptr + 8 , linesize, s, 0) +
00705 dv_init_enc_block(enc_blk+3, NULL , linesize, s, 0);
00706 } else {
00707 vs_bit_size +=
00708 dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) +
00709 dv_init_enc_block(enc_blk+1, y_ptr + 8 , linesize, s, 0) +
00710 dv_init_enc_block(enc_blk+2, y_ptr + y_stride, linesize, s, 0) +
00711 dv_init_enc_block(enc_blk+3, y_ptr + 8 + y_stride, linesize, s, 0);
00712 }
00713 enc_blk += 4;
00714
00715
00716 c_offset = (((mb_y >> (s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] +
00717 (mb_x >> ((s->sys->pix_fmt == PIX_FMT_YUV411P) ? 2 : 1))) << 3);
00718 for (j = 2; j; j--) {
00719 uint8_t *c_ptr = s->picture.data[j] + c_offset;
00720 linesize = s->picture.linesize[j];
00721 y_stride = (mb_y == 134) ? 8 : (s->picture.linesize[j] << 3);
00722 if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
00723 uint8_t* d;
00724 uint8_t* b = scratch;
00725 for (i = 0; i < 8; i++) {
00726 d = c_ptr + (linesize << 3);
00727 b[0] = c_ptr[0]; b[1] = c_ptr[1]; b[2] = c_ptr[2]; b[3] = c_ptr[3];
00728 b[4] = d[0]; b[5] = d[1]; b[6] = d[2]; b[7] = d[3];
00729 c_ptr += linesize;
00730 b += 16;
00731 }
00732 c_ptr = scratch;
00733 linesize = 16;
00734 }
00735
00736 vs_bit_size += dv_init_enc_block( enc_blk++, c_ptr , linesize, s, 1);
00737 if (s->sys->bpm == 8) {
00738 vs_bit_size += dv_init_enc_block(enc_blk++, c_ptr + y_stride, linesize, s, 1);
00739 }
00740 }
00741 }
00742
00743 if (vs_total_ac_bits < vs_bit_size)
00744 dv_guess_qnos(&enc_blks[0], qnosp);
00745
00746
00747 for (j=0; j<5*s->sys->bpm;) {
00748 int start_mb = j;
00749
00750 dif[3] = *qnosp++;
00751 dif += 4;
00752
00753
00754 for (i=0; i<s->sys->bpm; i++, j++) {
00755 int sz = s->sys->block_sizes[i]>>3;
00756
00757 init_put_bits(&pbs[j], dif, sz);
00758 put_sbits(&pbs[j], 9, ((enc_blks[j].mb[0] >> 3) - 1024 + 2) >> 2);
00759 put_bits(&pbs[j], 1, enc_blks[j].dct_mode);
00760 put_bits(&pbs[j], 2, enc_blks[j].cno);
00761
00762 dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]);
00763 dif += sz;
00764 }
00765
00766
00767 pb = &pbs[start_mb];
00768 for (i=0; i<s->sys->bpm; i++) {
00769 if (enc_blks[start_mb+i].partial_bit_count)
00770 pb = dv_encode_ac(&enc_blks[start_mb+i], pb, &pbs[start_mb+s->sys->bpm]);
00771 }
00772 }
00773
00774
00775 pb = &pbs[0];
00776 for (j=0; j<5*s->sys->bpm; j++) {
00777 if (enc_blks[j].partial_bit_count)
00778 pb = dv_encode_ac(&enc_blks[j], pb, &pbs[s->sys->bpm*5]);
00779 if (enc_blks[j].partial_bit_count)
00780 av_log(avctx, AV_LOG_ERROR, "ac bitstream overflow\n");
00781 }
00782
00783 for (j=0; j<5*s->sys->bpm; j++) {
00784 int pos;
00785 int size = pbs[j].size_in_bits >> 3;
00786 flush_put_bits(&pbs[j]);
00787 pos = put_bits_count(&pbs[j]) >> 3;
00788 if (pos > size) {
00789 av_log(avctx, AV_LOG_ERROR, "bitstream written beyond buffer size\n");
00790 return -1;
00791 }
00792 memset(pbs[j].buf + pos, 0xff, size - pos);
00793 }
00794
00795 return 0;
00796 }
00797
00798 static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c,
00799 uint8_t* buf)
00800 {
00801
00802
00803
00804
00805
00806
00807
00808
00809
00810
00811
00812
00813
00814
00815
00816
00817
00818
00819 int apt = (c->sys->pix_fmt == PIX_FMT_YUV420P ? 0 : 1);
00820
00821 uint8_t aspect = 0;
00822 if ((int)(av_q2d(c->avctx->sample_aspect_ratio) * c->avctx->width / c->avctx->height * 10) >= 17)
00823 aspect = 0x02;
00824
00825 buf[0] = (uint8_t)pack_id;
00826 switch (pack_id) {
00827 case dv_header525:
00828 case dv_header625:
00829 buf[1] = 0xf8 |
00830 (apt & 0x07);
00831 buf[2] = (0 << 7) |
00832 (0x0f << 3) |
00833 (apt & 0x07);
00834 buf[3] = (0 << 7) |
00835 (0x0f << 3) |
00836 (apt & 0x07);
00837 buf[4] = (0 << 7) |
00838 (0x0f << 3) |
00839 (apt & 0x07);
00840 break;
00841 case dv_video_source:
00842 buf[1] = 0xff;
00843 buf[2] = (1 << 7) |
00844 (1 << 6) |
00845 (3 << 4) |
00846 0xf;
00847 buf[3] = (3 << 6) |
00848 (c->sys->dsf << 5) |
00849 c->sys->video_stype;
00850 buf[4] = 0xff;
00851 break;
00852 case dv_video_control:
00853 buf[1] = (0 << 6) |
00854 0x3f;
00855 buf[2] = 0xc8 |
00856 aspect;
00857 buf[3] = (1 << 7) |
00858 (1 << 6) |
00859 (1 << 5) |
00860 (1 << 4) |
00861 0xc;
00862 buf[4] = 0xff;
00863 break;
00864 default:
00865 buf[1] = buf[2] = buf[3] = buf[4] = 0xff;
00866 }
00867 return 5;
00868 }
00869
00870 #if CONFIG_DVVIDEO_ENCODER
00871 static inline int dv_write_dif_id(enum dv_section_type t, uint8_t chan_num,
00872 uint8_t seq_num, uint8_t dif_num,
00873 uint8_t* buf)
00874 {
00875 buf[0] = (uint8_t)t;
00876 buf[1] = (seq_num << 4) |
00877 (chan_num << 3) |
00878 7;
00879 buf[2] = dif_num;
00880 return 3;
00881 }
00882
00883
00884 static inline int dv_write_ssyb_id(uint8_t syb_num, uint8_t fr, uint8_t* buf)
00885 {
00886 if (syb_num == 0 || syb_num == 6) {
00887 buf[0] = (fr << 7) |
00888 (0 << 4) |
00889 0x0f;
00890 }
00891 else if (syb_num == 11) {
00892 buf[0] = (fr << 7) |
00893 0x7f;
00894 }
00895 else {
00896 buf[0] = (fr << 7) |
00897 (0 << 4) |
00898 0x0f;
00899 }
00900 buf[1] = 0xf0 |
00901 (syb_num & 0x0f);
00902 buf[2] = 0xff;
00903 return 3;
00904 }
00905
00906 static void dv_format_frame(DVVideoContext* c, uint8_t* buf)
00907 {
00908 int chan, i, j, k;
00909
00910 for (chan = 0; chan < c->sys->n_difchan; chan++) {
00911 for (i = 0; i < c->sys->difseg_size; i++) {
00912 memset(buf, 0xff, 80 * 6);
00913
00914
00915 buf += dv_write_dif_id(dv_sect_header, chan, i, 0, buf);
00916 buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525), c, buf);
00917 buf += 72;
00918
00919
00920 for (j = 0; j < 2; j++) {
00921 buf += dv_write_dif_id(dv_sect_subcode, chan, i, j, buf);
00922 for (k = 0; k < 6; k++)
00923 buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size/2), buf) + 5;
00924 buf += 29;
00925 }
00926
00927
00928 for (j = 0; j < 3; j++) {
00929 buf += dv_write_dif_id(dv_sect_vaux, chan, i, j, buf);
00930 buf += dv_write_pack(dv_video_source, c, buf);
00931 buf += dv_write_pack(dv_video_control, c, buf);
00932 buf += 7*5;
00933 buf += dv_write_pack(dv_video_source, c, buf);
00934 buf += dv_write_pack(dv_video_control, c, buf);
00935 buf += 4*5 + 2;
00936 }
00937
00938
00939 for (j = 0; j < 135; j++) {
00940 if (j%15 == 0) {
00941 memset(buf, 0xff, 80);
00942 buf += dv_write_dif_id(dv_sect_audio, chan, i, j/15, buf);
00943 buf += 77;
00944 }
00945 buf += dv_write_dif_id(dv_sect_video, chan, i, j, buf);
00946 buf += 77;
00947
00948
00949
00950 }
00951 }
00952 }
00953 }
00954
00955
00956 static int dvvideo_encode_frame(AVCodecContext *c, AVPacket *pkt,
00957 const AVFrame *frame, int *got_packet)
00958 {
00959 DVVideoContext *s = c->priv_data;
00960 int ret;
00961
00962 s->sys = avpriv_dv_codec_profile(c);
00963 if (!s->sys || ff_dv_init_dynamic_tables(s->sys))
00964 return -1;
00965 if ((ret = ff_alloc_packet2(c, pkt, s->sys->frame_size)) < 0)
00966 return ret;
00967
00968 c->pix_fmt = s->sys->pix_fmt;
00969 s->picture = *frame;
00970 s->picture.key_frame = 1;
00971 s->picture.pict_type = AV_PICTURE_TYPE_I;
00972
00973 s->buf = pkt->data;
00974 c->execute(c, dv_encode_video_segment, s->sys->work_chunks, NULL,
00975 dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
00976
00977 emms_c();
00978
00979 dv_format_frame(s, pkt->data);
00980
00981 pkt->flags |= AV_PKT_FLAG_KEY;
00982 *got_packet = 1;
00983
00984 return 0;
00985 }
00986
00987 AVCodec ff_dvvideo_encoder = {
00988 .name = "dvvideo",
00989 .type = AVMEDIA_TYPE_VIDEO,
00990 .id = AV_CODEC_ID_DVVIDEO,
00991 .priv_data_size = sizeof(DVVideoContext),
00992 .init = dvvideo_init_encoder,
00993 .encode2 = dvvideo_encode_frame,
00994 .capabilities = CODEC_CAP_SLICE_THREADS,
00995 .pix_fmts = (const enum PixelFormat[]) {
00996 PIX_FMT_YUV411P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, PIX_FMT_NONE
00997 },
00998 .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
00999 };
01000 #endif // CONFIG_DVVIDEO_ENCODER