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 "put_bits.h"
00046 #include "simple_idct.h"
00047 #include "dvdata.h"
00048 #include "dv_tablegen.h"
00049
00050
00051
00052
00053 typedef struct DVVideoContext {
00054 const DVprofile *sys;
00055 AVFrame picture;
00056 AVCodecContext *avctx;
00057 uint8_t *buf;
00058
00059 uint8_t dv_zigzag[2][64];
00060
00061 void (*get_pixels)(DCTELEM *block, const uint8_t *pixels, int line_size);
00062 void (*fdct[2])(DCTELEM *block);
00063 void (*idct_put[2])(uint8_t *dest, int line_size, DCTELEM *block);
00064 me_cmp_func ildct_cmp;
00065 } DVVideoContext;
00066
00067 #define TEX_VLC_BITS 9
00068
00069
00070 static RL_VLC_ELEM dv_rl_vlc[1184];
00071
00072 static inline int dv_work_pool_size(const DVprofile *d)
00073 {
00074 int size = d->n_difchan*d->difseg_size*27;
00075 if (DV_PROFILE_IS_1080i50(d))
00076 size -= 3*27;
00077 if (DV_PROFILE_IS_720p50(d))
00078 size -= 4*27;
00079 return size;
00080 }
00081
00082 static inline void dv_calc_mb_coordinates(const DVprofile *d, int chan, int seq, int slot,
00083 uint16_t *tbl)
00084 {
00085 static const uint8_t off[] = { 2, 6, 8, 0, 4 };
00086 static const uint8_t shuf1[] = { 36, 18, 54, 0, 72 };
00087 static const uint8_t shuf2[] = { 24, 12, 36, 0, 48 };
00088 static const uint8_t shuf3[] = { 18, 9, 27, 0, 36 };
00089
00090 static const uint8_t l_start[] = {0, 4, 9, 13, 18, 22, 27, 31, 36, 40};
00091 static const uint8_t l_start_shuffled[] = { 9, 4, 13, 0, 18 };
00092
00093 static const uint8_t serpent1[] = {0, 1, 2, 2, 1, 0,
00094 0, 1, 2, 2, 1, 0,
00095 0, 1, 2, 2, 1, 0,
00096 0, 1, 2, 2, 1, 0,
00097 0, 1, 2};
00098 static const uint8_t serpent2[] = {0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
00099 0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
00100 0, 1, 2, 3, 4, 5};
00101
00102 static const uint8_t remap[][2] = {{ 0, 0}, { 0, 0}, { 0, 0}, { 0, 0},
00103 { 0, 0}, { 0, 1}, { 0, 2}, { 0, 3}, {10, 0},
00104 {10, 1}, {10, 2}, {10, 3}, {20, 0}, {20, 1},
00105 {20, 2}, {20, 3}, {30, 0}, {30, 1}, {30, 2},
00106 {30, 3}, {40, 0}, {40, 1}, {40, 2}, {40, 3},
00107 {50, 0}, {50, 1}, {50, 2}, {50, 3}, {60, 0},
00108 {60, 1}, {60, 2}, {60, 3}, {70, 0}, {70, 1},
00109 {70, 2}, {70, 3}, { 0,64}, { 0,65}, { 0,66},
00110 {10,64}, {10,65}, {10,66}, {20,64}, {20,65},
00111 {20,66}, {30,64}, {30,65}, {30,66}, {40,64},
00112 {40,65}, {40,66}, {50,64}, {50,65}, {50,66},
00113 {60,64}, {60,65}, {60,66}, {70,64}, {70,65},
00114 {70,66}, { 0,67}, {20,67}, {40,67}, {60,67}};
00115
00116 int i, k, m;
00117 int x, y, blk;
00118
00119 for (m=0; m<5; m++) {
00120 switch (d->width) {
00121 case 1440:
00122 blk = (chan*11+seq)*27+slot;
00123
00124 if (chan == 0 && seq == 11) {
00125 x = m*27+slot;
00126 if (x<90) {
00127 y = 0;
00128 } else {
00129 x = (x - 90)*2;
00130 y = 67;
00131 }
00132 } else {
00133 i = (4*chan + blk + off[m])%11;
00134 k = (blk/11)%27;
00135
00136 x = shuf1[m] + (chan&1)*9 + k%9;
00137 y = (i*3+k/9)*2 + (chan>>1) + 1;
00138 }
00139 tbl[m] = (x<<1)|(y<<9);
00140 break;
00141 case 1280:
00142 blk = (chan*10+seq)*27+slot;
00143
00144 i = (4*chan + (seq/5) + 2*blk + off[m])%10;
00145 k = (blk/5)%27;
00146
00147 x = shuf1[m]+(chan&1)*9 + k%9;
00148 y = (i*3+k/9)*2 + (chan>>1) + 4;
00149
00150 if (x >= 80) {
00151 x = remap[y][0]+((x-80)<<(y>59));
00152 y = remap[y][1];
00153 }
00154 tbl[m] = (x<<1)|(y<<9);
00155 break;
00156 case 960:
00157 blk = (chan*10+seq)*27+slot;
00158
00159 i = (4*chan + (seq/5) + 2*blk + off[m])%10;
00160 k = (blk/5)%27 + (i&1)*3;
00161
00162 x = shuf2[m] + k%6 + 6*(chan&1);
00163 y = l_start[i] + k/6 + 45*(chan>>1);
00164 tbl[m] = (x<<1)|(y<<9);
00165 break;
00166 case 720:
00167 switch (d->pix_fmt) {
00168 case PIX_FMT_YUV422P:
00169 x = shuf3[m] + slot/3;
00170 y = serpent1[slot] +
00171 ((((seq + off[m]) % d->difseg_size)<<1) + chan)*3;
00172 tbl[m] = (x<<1)|(y<<8);
00173 break;
00174 case PIX_FMT_YUV420P:
00175 x = shuf3[m] + slot/3;
00176 y = serpent1[slot] +
00177 ((seq + off[m]) % d->difseg_size)*3;
00178 tbl[m] = (x<<1)|(y<<9);
00179 break;
00180 case PIX_FMT_YUV411P:
00181 i = (seq + off[m]) % d->difseg_size;
00182 k = slot + ((m==1||m==2)?3:0);
00183
00184 x = l_start_shuffled[m] + k/6;
00185 y = serpent2[k] + i*6;
00186 if (x>21)
00187 y = y*2 - i*6;
00188 tbl[m] = (x<<2)|(y<<8);
00189 break;
00190 }
00191 default:
00192 break;
00193 }
00194 }
00195 }
00196
00197 static int dv_init_dynamic_tables(const DVprofile *d)
00198 {
00199 int j,i,c,s,p;
00200 uint32_t *factor1, *factor2;
00201 const int *iweight1, *iweight2;
00202
00203 if (!d->work_chunks[dv_work_pool_size(d)-1].buf_offset) {
00204 p = i = 0;
00205 for (c=0; c<d->n_difchan; c++) {
00206 for (s=0; s<d->difseg_size; s++) {
00207 p += 6;
00208 for (j=0; j<27; j++) {
00209 p += !(j%3);
00210 if (!(DV_PROFILE_IS_1080i50(d) && c != 0 && s == 11) &&
00211 !(DV_PROFILE_IS_720p50(d) && s > 9)) {
00212 dv_calc_mb_coordinates(d, c, s, j, &d->work_chunks[i].mb_coordinates[0]);
00213 d->work_chunks[i++].buf_offset = p;
00214 }
00215 p += 5;
00216 }
00217 }
00218 }
00219 }
00220
00221 if (!d->idct_factor[DV_PROFILE_IS_HD(d)?8191:5631]) {
00222 factor1 = &d->idct_factor[0];
00223 factor2 = &d->idct_factor[DV_PROFILE_IS_HD(d)?4096:2816];
00224 if (d->height == 720) {
00225 iweight1 = &dv_iweight_720_y[0];
00226 iweight2 = &dv_iweight_720_c[0];
00227 } else {
00228 iweight1 = &dv_iweight_1080_y[0];
00229 iweight2 = &dv_iweight_1080_c[0];
00230 }
00231 if (DV_PROFILE_IS_HD(d)) {
00232 for (c = 0; c < 4; c++) {
00233 for (s = 0; s < 16; s++) {
00234 for (i = 0; i < 64; i++) {
00235 *factor1++ = (dv100_qstep[s] << (c + 9)) * iweight1[i];
00236 *factor2++ = (dv100_qstep[s] << (c + 9)) * iweight2[i];
00237 }
00238 }
00239 }
00240 } else {
00241 iweight1 = &dv_iweight_88[0];
00242 for (j = 0; j < 2; j++, iweight1 = &dv_iweight_248[0]) {
00243 for (s = 0; s < 22; s++) {
00244 for (i = c = 0; c < 4; c++) {
00245 for (; i < dv_quant_areas[c]; i++) {
00246 *factor1 = iweight1[i] << (dv_quant_shifts[s][c] + 1);
00247 *factor2++ = (*factor1++) << 1;
00248 }
00249 }
00250 }
00251 }
00252 }
00253 }
00254
00255 return 0;
00256 }
00257
00258 static av_cold int dvvideo_init(AVCodecContext *avctx)
00259 {
00260 DVVideoContext *s = avctx->priv_data;
00261 DSPContext dsp;
00262 static int done = 0;
00263 int i, j;
00264
00265 if (!done) {
00266 VLC dv_vlc;
00267 uint16_t new_dv_vlc_bits[NB_DV_VLC*2];
00268 uint8_t new_dv_vlc_len[NB_DV_VLC*2];
00269 uint8_t new_dv_vlc_run[NB_DV_VLC*2];
00270 int16_t new_dv_vlc_level[NB_DV_VLC*2];
00271
00272 done = 1;
00273
00274
00275 for (i = 0, j = 0; i < NB_DV_VLC; i++, j++) {
00276 new_dv_vlc_bits[j] = dv_vlc_bits[i];
00277 new_dv_vlc_len[j] = dv_vlc_len[i];
00278 new_dv_vlc_run[j] = dv_vlc_run[i];
00279 new_dv_vlc_level[j] = dv_vlc_level[i];
00280
00281 if (dv_vlc_level[i]) {
00282 new_dv_vlc_bits[j] <<= 1;
00283 new_dv_vlc_len[j]++;
00284
00285 j++;
00286 new_dv_vlc_bits[j] = (dv_vlc_bits[i] << 1) | 1;
00287 new_dv_vlc_len[j] = dv_vlc_len[i] + 1;
00288 new_dv_vlc_run[j] = dv_vlc_run[i];
00289 new_dv_vlc_level[j] = -dv_vlc_level[i];
00290 }
00291 }
00292
00293
00294
00295 init_vlc(&dv_vlc, TEX_VLC_BITS, j,
00296 new_dv_vlc_len, 1, 1, new_dv_vlc_bits, 2, 2, 0);
00297 assert(dv_vlc.table_size == 1184);
00298
00299 for (i = 0; i < dv_vlc.table_size; i++){
00300 int code = dv_vlc.table[i][0];
00301 int len = dv_vlc.table[i][1];
00302 int level, run;
00303
00304 if (len < 0){
00305 run = 0;
00306 level = code;
00307 } else {
00308 run = new_dv_vlc_run [code] + 1;
00309 level = new_dv_vlc_level[code];
00310 }
00311 dv_rl_vlc[i].len = len;
00312 dv_rl_vlc[i].level = level;
00313 dv_rl_vlc[i].run = run;
00314 }
00315 ff_free_vlc(&dv_vlc);
00316
00317 dv_vlc_map_tableinit();
00318 }
00319
00320
00321 dsputil_init(&dsp, avctx);
00322 ff_set_cmp(&dsp, dsp.ildct_cmp, avctx->ildct_cmp);
00323 s->get_pixels = dsp.get_pixels;
00324 s->ildct_cmp = dsp.ildct_cmp[5];
00325
00326
00327 s->fdct[0] = dsp.fdct;
00328 s->idct_put[0] = dsp.idct_put;
00329 for (i = 0; i < 64; i++)
00330 s->dv_zigzag[0][i] = dsp.idct_permutation[ff_zigzag_direct[i]];
00331
00332
00333 s->fdct[1] = dsp.fdct248;
00334 s->idct_put[1] = ff_simple_idct248_put;
00335 if (avctx->lowres){
00336 for (i = 0; i < 64; i++){
00337 int j = ff_zigzag248_direct[i];
00338 s->dv_zigzag[1][i] = dsp.idct_permutation[(j & 7) + (j & 8) * 4 + (j & 48) / 2];
00339 }
00340 }else
00341 memcpy(s->dv_zigzag[1], ff_zigzag248_direct, 64);
00342
00343 avctx->coded_frame = &s->picture;
00344 s->avctx = avctx;
00345 avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT;
00346
00347 return 0;
00348 }
00349
00350 static av_cold int dvvideo_init_encoder(AVCodecContext *avctx)
00351 {
00352 if (!avpriv_dv_codec_profile(avctx)) {
00353 av_log(avctx, AV_LOG_ERROR, "Found no DV profile for %ix%i %s video\n",
00354 avctx->width, avctx->height, av_get_pix_fmt_name(avctx->pix_fmt));
00355 return -1;
00356 }
00357
00358 return dvvideo_init(avctx);
00359 }
00360
00361 typedef struct BlockInfo {
00362 const uint32_t *factor_table;
00363 const uint8_t *scan_table;
00364 uint8_t pos;
00365 void (*idct_put)(uint8_t *dest, int line_size, DCTELEM *block);
00366 uint8_t partial_bit_count;
00367 uint32_t partial_bit_buffer;
00368 int shift_offset;
00369 } BlockInfo;
00370
00371
00372 static const int vs_total_ac_bits = (100 * 4 + 68*2) * 5;
00373 static const int mb_area_start[5] = { 1, 6, 21, 43, 64 };
00374
00375
00376 static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block)
00377 {
00378 int last_index = gb->size_in_bits;
00379 const uint8_t *scan_table = mb->scan_table;
00380 const uint32_t *factor_table = mb->factor_table;
00381 int pos = mb->pos;
00382 int partial_bit_count = mb->partial_bit_count;
00383 int level, run, vlc_len, index;
00384
00385 OPEN_READER(re, gb);
00386 UPDATE_CACHE(re, gb);
00387
00388
00389 if (partial_bit_count > 0) {
00390 re_cache = re_cache >> partial_bit_count | mb->partial_bit_buffer;
00391 re_index -= partial_bit_count;
00392 mb->partial_bit_count = 0;
00393 }
00394
00395
00396 for (;;) {
00397 av_dlog(NULL, "%2d: bits=%04x index=%d\n", pos, SHOW_UBITS(re, gb, 16),
00398 re_index);
00399
00400 index = NEG_USR32(re_cache, TEX_VLC_BITS);
00401 vlc_len = dv_rl_vlc[index].len;
00402 if (vlc_len < 0) {
00403 index = NEG_USR32((unsigned)re_cache << TEX_VLC_BITS, -vlc_len) + dv_rl_vlc[index].level;
00404 vlc_len = TEX_VLC_BITS - vlc_len;
00405 }
00406 level = dv_rl_vlc[index].level;
00407 run = dv_rl_vlc[index].run;
00408
00409
00410 if (re_index + vlc_len > last_index) {
00411
00412 mb->partial_bit_count = last_index - re_index;
00413 mb->partial_bit_buffer = re_cache & ~(-1u >> mb->partial_bit_count);
00414 re_index = last_index;
00415 break;
00416 }
00417 re_index += vlc_len;
00418
00419 av_dlog(NULL, "run=%d level=%d\n", run, level);
00420 pos += run;
00421 if (pos >= 64)
00422 break;
00423
00424 level = (level * factor_table[pos] + (1 << (dv_iweight_bits - 1))) >> dv_iweight_bits;
00425 block[scan_table[pos]] = level;
00426
00427 UPDATE_CACHE(re, gb);
00428 }
00429 CLOSE_READER(re, gb);
00430 mb->pos = pos;
00431 }
00432
00433 static inline void bit_copy(PutBitContext *pb, GetBitContext *gb)
00434 {
00435 int bits_left = get_bits_left(gb);
00436 while (bits_left >= MIN_CACHE_BITS) {
00437 put_bits(pb, MIN_CACHE_BITS, get_bits(gb, MIN_CACHE_BITS));
00438 bits_left -= MIN_CACHE_BITS;
00439 }
00440 if (bits_left > 0) {
00441 put_bits(pb, bits_left, get_bits(gb, bits_left));
00442 }
00443 }
00444
00445 static inline void dv_calculate_mb_xy(DVVideoContext *s, DVwork_chunk *work_chunk, int m, int *mb_x, int *mb_y)
00446 {
00447 *mb_x = work_chunk->mb_coordinates[m] & 0xff;
00448 *mb_y = work_chunk->mb_coordinates[m] >> 8;
00449
00450
00451 if (s->sys->height == 720 && !(s->buf[1]&0x0C)) {
00452 *mb_y -= (*mb_y>17)?18:-72;
00453 }
00454 }
00455
00456
00457 static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
00458 {
00459 DVVideoContext *s = avctx->priv_data;
00460 DVwork_chunk *work_chunk = arg;
00461 int quant, dc, dct_mode, class1, j;
00462 int mb_index, mb_x, mb_y, last_index;
00463 int y_stride, linesize;
00464 DCTELEM *block, *block1;
00465 int c_offset;
00466 uint8_t *y_ptr;
00467 const uint8_t *buf_ptr;
00468 PutBitContext pb, vs_pb;
00469 GetBitContext gb;
00470 BlockInfo mb_data[5 * DV_MAX_BPM], *mb, *mb1;
00471 LOCAL_ALIGNED_16(DCTELEM, sblock, [5*DV_MAX_BPM], [64]);
00472 LOCAL_ALIGNED_16(uint8_t, mb_bit_buffer, [ 80 + FF_INPUT_BUFFER_PADDING_SIZE]);
00473 LOCAL_ALIGNED_16(uint8_t, vs_bit_buffer, [5*80 + FF_INPUT_BUFFER_PADDING_SIZE]);
00474 const int log2_blocksize = 3-s->avctx->lowres;
00475 int is_field_mode[5];
00476
00477 assert((((int)mb_bit_buffer) & 7) == 0);
00478 assert((((int)vs_bit_buffer) & 7) == 0);
00479
00480 memset(sblock, 0, 5*DV_MAX_BPM*sizeof(*sblock));
00481
00482
00483 buf_ptr = &s->buf[work_chunk->buf_offset*80];
00484 block1 = &sblock[0][0];
00485 mb1 = mb_data;
00486 init_put_bits(&vs_pb, vs_bit_buffer, 5 * 80);
00487 for (mb_index = 0; mb_index < 5; mb_index++, mb1 += s->sys->bpm, block1 += s->sys->bpm * 64) {
00488
00489 quant = buf_ptr[3] & 0x0f;
00490 buf_ptr += 4;
00491 init_put_bits(&pb, mb_bit_buffer, 80);
00492 mb = mb1;
00493 block = block1;
00494 is_field_mode[mb_index] = 0;
00495 for (j = 0; j < s->sys->bpm; j++) {
00496 last_index = s->sys->block_sizes[j];
00497 init_get_bits(&gb, buf_ptr, last_index);
00498
00499
00500 dc = get_sbits(&gb, 9);
00501 dct_mode = get_bits1(&gb);
00502 class1 = get_bits(&gb, 2);
00503 if (DV_PROFILE_IS_HD(s->sys)) {
00504 mb->idct_put = s->idct_put[0];
00505 mb->scan_table = s->dv_zigzag[0];
00506 mb->factor_table = &s->sys->idct_factor[(j >= 4)*4*16*64 + class1*16*64 + quant*64];
00507 is_field_mode[mb_index] |= !j && dct_mode;
00508 } else {
00509 mb->idct_put = s->idct_put[dct_mode && log2_blocksize == 3];
00510 mb->scan_table = s->dv_zigzag[dct_mode];
00511 mb->factor_table = &s->sys->idct_factor[(class1 == 3)*2*22*64 + dct_mode*22*64 +
00512 (quant + dv_quant_offset[class1])*64];
00513 }
00514 dc = dc << 2;
00515
00516
00517 dc += 1024;
00518 block[0] = dc;
00519 buf_ptr += last_index >> 3;
00520 mb->pos = 0;
00521 mb->partial_bit_count = 0;
00522
00523 av_dlog(avctx, "MB block: %d, %d ", mb_index, j);
00524 dv_decode_ac(&gb, mb, block);
00525
00526
00527
00528 if (mb->pos >= 64)
00529 bit_copy(&pb, &gb);
00530
00531 block += 64;
00532 mb++;
00533 }
00534
00535
00536 av_dlog(avctx, "***pass 2 size=%d MB#=%d\n", put_bits_count(&pb), mb_index);
00537 block = block1;
00538 mb = mb1;
00539 init_get_bits(&gb, mb_bit_buffer, put_bits_count(&pb));
00540 put_bits32(&pb, 0);
00541 flush_put_bits(&pb);
00542 for (j = 0; j < s->sys->bpm; j++, block += 64, mb++) {
00543 if (mb->pos < 64 && get_bits_left(&gb) > 0) {
00544 dv_decode_ac(&gb, mb, block);
00545
00546 if (mb->pos < 64)
00547 break;
00548 }
00549 }
00550
00551
00552 if (j >= s->sys->bpm)
00553 bit_copy(&vs_pb, &gb);
00554 }
00555
00556
00557 av_dlog(avctx, "***pass 3 size=%d\n", put_bits_count(&vs_pb));
00558 block = &sblock[0][0];
00559 mb = mb_data;
00560 init_get_bits(&gb, vs_bit_buffer, put_bits_count(&vs_pb));
00561 put_bits32(&vs_pb, 0);
00562 flush_put_bits(&vs_pb);
00563 for (mb_index = 0; mb_index < 5; mb_index++) {
00564 for (j = 0; j < s->sys->bpm; j++) {
00565 if (mb->pos < 64) {
00566 av_dlog(avctx, "start %d:%d\n", mb_index, j);
00567 dv_decode_ac(&gb, mb, block);
00568 }
00569 if (mb->pos >= 64 && mb->pos < 127)
00570 av_log(avctx, AV_LOG_ERROR, "AC EOB marker is absent pos=%d\n", mb->pos);
00571 block += 64;
00572 mb++;
00573 }
00574 }
00575
00576
00577 block = &sblock[0][0];
00578 mb = mb_data;
00579 for (mb_index = 0; mb_index < 5; mb_index++) {
00580 dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);
00581
00582
00583 if ((s->sys->pix_fmt == PIX_FMT_YUV420P) ||
00584 (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
00585 (s->sys->height >= 720 && mb_y != 134)) {
00586 y_stride = (s->picture.linesize[0] << ((!is_field_mode[mb_index]) * log2_blocksize));
00587 } else {
00588 y_stride = (2 << log2_blocksize);
00589 }
00590 y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << log2_blocksize);
00591 linesize = s->picture.linesize[0] << is_field_mode[mb_index];
00592 mb[0] .idct_put(y_ptr , linesize, block + 0*64);
00593 if (s->sys->video_stype == 4) {
00594 mb[2].idct_put(y_ptr + (1 << log2_blocksize) , linesize, block + 2*64);
00595 } else {
00596 mb[1].idct_put(y_ptr + (1 << log2_blocksize) , linesize, block + 1*64);
00597 mb[2].idct_put(y_ptr + y_stride, linesize, block + 2*64);
00598 mb[3].idct_put(y_ptr + (1 << log2_blocksize) + y_stride, linesize, block + 3*64);
00599 }
00600 mb += 4;
00601 block += 4*64;
00602
00603
00604 c_offset = (((mb_y >> (s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] +
00605 (mb_x >> ((s->sys->pix_fmt == PIX_FMT_YUV411P) ? 2 : 1))) << log2_blocksize);
00606 for (j = 2; j; j--) {
00607 uint8_t *c_ptr = s->picture.data[j] + c_offset;
00608 if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
00609 uint64_t aligned_pixels[64/8];
00610 uint8_t *pixels = (uint8_t*)aligned_pixels;
00611 uint8_t *c_ptr1, *ptr1;
00612 int x, y;
00613 mb->idct_put(pixels, 8, block);
00614 for (y = 0; y < (1 << log2_blocksize); y++, c_ptr += s->picture.linesize[j], pixels += 8) {
00615 ptr1 = pixels + (1 << (log2_blocksize - 1));
00616 c_ptr1 = c_ptr + (s->picture.linesize[j] << log2_blocksize);
00617 for (x = 0; x < (1 << (log2_blocksize - 1)); x++) {
00618 c_ptr[x] = pixels[x];
00619 c_ptr1[x] = ptr1[x];
00620 }
00621 }
00622 block += 64; mb++;
00623 } else {
00624 y_stride = (mb_y == 134) ? (1 << log2_blocksize) :
00625 s->picture.linesize[j] << ((!is_field_mode[mb_index]) * log2_blocksize);
00626 linesize = s->picture.linesize[j] << is_field_mode[mb_index];
00627 (mb++)-> idct_put(c_ptr , linesize, block); block += 64;
00628 if (s->sys->bpm == 8) {
00629 (mb++)->idct_put(c_ptr + y_stride, linesize, block); block += 64;
00630 }
00631 }
00632 }
00633 }
00634 return 0;
00635 }
00636
00637 #if CONFIG_SMALL
00638
00639 static av_always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc)
00640 {
00641 int size;
00642 if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
00643 *vlc = dv_vlc_map[run][level].vlc | sign;
00644 size = dv_vlc_map[run][level].size;
00645 }
00646 else {
00647 if (level < DV_VLC_MAP_LEV_SIZE) {
00648 *vlc = dv_vlc_map[0][level].vlc | sign;
00649 size = dv_vlc_map[0][level].size;
00650 } else {
00651 *vlc = 0xfe00 | (level << 1) | sign;
00652 size = 16;
00653 }
00654 if (run) {
00655 *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc :
00656 (0x1f80 | (run - 1))) << size;
00657 size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
00658 }
00659 }
00660
00661 return size;
00662 }
00663
00664 static av_always_inline int dv_rl2vlc_size(int run, int level)
00665 {
00666 int size;
00667
00668 if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
00669 size = dv_vlc_map[run][level].size;
00670 }
00671 else {
00672 size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16;
00673 if (run) {
00674 size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
00675 }
00676 }
00677 return size;
00678 }
00679 #else
00680 static av_always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc)
00681 {
00682 *vlc = dv_vlc_map[run][l].vlc | sign;
00683 return dv_vlc_map[run][l].size;
00684 }
00685
00686 static av_always_inline int dv_rl2vlc_size(int run, int l)
00687 {
00688 return dv_vlc_map[run][l].size;
00689 }
00690 #endif
00691
00692 typedef struct EncBlockInfo {
00693 int area_q[4];
00694 int bit_size[4];
00695 int prev[5];
00696 int cur_ac;
00697 int cno;
00698 int dct_mode;
00699 DCTELEM mb[64];
00700 uint8_t next[64];
00701 uint8_t sign[64];
00702 uint8_t partial_bit_count;
00703 uint32_t partial_bit_buffer;
00704 } EncBlockInfo;
00705
00706 static av_always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi,
00707 PutBitContext* pb_pool,
00708 PutBitContext* pb_end)
00709 {
00710 int prev, bits_left;
00711 PutBitContext* pb = pb_pool;
00712 int size = bi->partial_bit_count;
00713 uint32_t vlc = bi->partial_bit_buffer;
00714
00715 bi->partial_bit_count = bi->partial_bit_buffer = 0;
00716 for (;;){
00717
00718 for (; size > (bits_left = put_bits_left(pb)); pb++) {
00719 if (bits_left) {
00720 size -= bits_left;
00721 put_bits(pb, bits_left, vlc >> size);
00722 vlc = vlc & ((1 << size) - 1);
00723 }
00724 if (pb + 1 >= pb_end) {
00725 bi->partial_bit_count = size;
00726 bi->partial_bit_buffer = vlc;
00727 return pb;
00728 }
00729 }
00730
00731
00732 put_bits(pb, size, vlc);
00733
00734 if (bi->cur_ac >= 64)
00735 break;
00736
00737
00738 prev = bi->cur_ac;
00739 bi->cur_ac = bi->next[prev];
00740 if (bi->cur_ac < 64){
00741 size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc);
00742 } else {
00743 size = 4; vlc = 6;
00744 }
00745 }
00746 return pb;
00747 }
00748
00749 static av_always_inline int dv_guess_dct_mode(DVVideoContext *s, uint8_t *data, int linesize) {
00750 if (s->avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
00751 int ps = s->ildct_cmp(NULL, data, NULL, linesize, 8) - 400;
00752 if (ps > 0) {
00753 int is = s->ildct_cmp(NULL, data , NULL, linesize<<1, 4) +
00754 s->ildct_cmp(NULL, data + linesize, NULL, linesize<<1, 4);
00755 return ps > is;
00756 }
00757 }
00758
00759 return 0;
00760 }
00761
00762 static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, int linesize, DVVideoContext *s, int bias)
00763 {
00764 const int *weight;
00765 const uint8_t* zigzag_scan;
00766 LOCAL_ALIGNED_16(DCTELEM, blk, [64]);
00767 int i, area;
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778 #if 0
00779 static const int classes[] = {12, 24, 36, 0xffff};
00780 #else
00781 static const int classes[] = {-1, -1, 255, 0xffff};
00782 #endif
00783 int max = classes[0];
00784 int prev = 0;
00785
00786 assert((((int)blk) & 15) == 0);
00787
00788 bi->area_q[0] = bi->area_q[1] = bi->area_q[2] = bi->area_q[3] = 0;
00789 bi->partial_bit_count = 0;
00790 bi->partial_bit_buffer = 0;
00791 bi->cur_ac = 0;
00792 if (data) {
00793 bi->dct_mode = dv_guess_dct_mode(s, data, linesize);
00794 s->get_pixels(blk, data, linesize);
00795 s->fdct[bi->dct_mode](blk);
00796 } else {
00797
00798
00799 memset(blk, 0, 64*sizeof(*blk));
00800 bi->dct_mode = 0;
00801 }
00802 bi->mb[0] = blk[0];
00803
00804 zigzag_scan = bi->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct;
00805 weight = bi->dct_mode ? dv_weight_248 : dv_weight_88;
00806
00807 for (area = 0; area < 4; area++) {
00808 bi->prev[area] = prev;
00809 bi->bit_size[area] = 1;
00810 for (i = mb_area_start[area]; i < mb_area_start[area+1]; i++) {
00811 int level = blk[zigzag_scan[i]];
00812
00813 if (level + 15 > 30U) {
00814 bi->sign[i] = (level >> 31) & 1;
00815
00816
00817
00818 level = (FFABS(level) * weight[i] + (1 << (dv_weight_bits+3))) >> (dv_weight_bits+4);
00819 bi->mb[i] = level;
00820 if (level > max)
00821 max = level;
00822 bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, level);
00823 bi->next[prev]= i;
00824 prev = i;
00825 }
00826 }
00827 }
00828 bi->next[prev]= i;
00829 for (bi->cno = 0; max > classes[bi->cno]; bi->cno++);
00830
00831 bi->cno += bias;
00832
00833 if (bi->cno >= 3) {
00834 bi->cno = 3;
00835 prev = 0;
00836 i = bi->next[prev];
00837 for (area = 0; area < 4; area++) {
00838 bi->prev[area] = prev;
00839 bi->bit_size[area] = 1;
00840 for (; i < mb_area_start[area+1]; i = bi->next[i]) {
00841 bi->mb[i] >>= 1;
00842
00843 if (bi->mb[i]) {
00844 bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, bi->mb[i]);
00845 bi->next[prev]= i;
00846 prev = i;
00847 }
00848 }
00849 }
00850 bi->next[prev]= i;
00851 }
00852
00853 return bi->bit_size[0] + bi->bit_size[1] + bi->bit_size[2] + bi->bit_size[3];
00854 }
00855
00856 static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos)
00857 {
00858 int size[5];
00859 int i, j, k, a, prev, a2;
00860 EncBlockInfo* b;
00861
00862 size[0] = size[1] = size[2] = size[3] = size[4] = 1 << 24;
00863 do {
00864 b = blks;
00865 for (i = 0; i < 5; i++) {
00866 if (!qnos[i])
00867 continue;
00868
00869 qnos[i]--;
00870 size[i] = 0;
00871 for (j = 0; j < 6; j++, b++) {
00872 for (a = 0; a < 4; a++) {
00873 if (b->area_q[a] != dv_quant_shifts[qnos[i] + dv_quant_offset[b->cno]][a]) {
00874 b->bit_size[a] = 1;
00875 b->area_q[a]++;
00876 prev = b->prev[a];
00877 assert(b->next[prev] >= mb_area_start[a+1] || b->mb[prev]);
00878 for (k = b->next[prev] ; k < mb_area_start[a+1]; k = b->next[k]) {
00879 b->mb[k] >>= 1;
00880 if (b->mb[k]) {
00881 b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
00882 prev = k;
00883 } else {
00884 if (b->next[k] >= mb_area_start[a+1] && b->next[k]<64){
00885 for (a2 = a + 1; b->next[k] >= mb_area_start[a2+1]; a2++)
00886 b->prev[a2] = prev;
00887 assert(a2 < 4);
00888 assert(b->mb[b->next[k]]);
00889 b->bit_size[a2] += dv_rl2vlc_size(b->next[k] - prev - 1, b->mb[b->next[k]])
00890 -dv_rl2vlc_size(b->next[k] - k - 1, b->mb[b->next[k]]);
00891 assert(b->prev[a2] == k && (a2 + 1 >= 4 || b->prev[a2+1] != k));
00892 b->prev[a2] = prev;
00893 }
00894 b->next[prev] = b->next[k];
00895 }
00896 }
00897 b->prev[a+1]= prev;
00898 }
00899 size[i] += b->bit_size[a];
00900 }
00901 }
00902 if (vs_total_ac_bits >= size[0] + size[1] + size[2] + size[3] + size[4])
00903 return;
00904 }
00905 } while (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4]);
00906
00907
00908 for (a = 2; a == 2 || vs_total_ac_bits < size[0]; a += a){
00909 b = blks;
00910 size[0] = 5 * 6 * 4;
00911 for (j = 0; j < 6 *5; j++, b++) {
00912 prev = b->prev[0];
00913 for (k = b->next[prev]; k < 64; k = b->next[k]) {
00914 if (b->mb[k] < a && b->mb[k] > -a){
00915 b->next[prev] = b->next[k];
00916 }else{
00917 size[0] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
00918 prev = k;
00919 }
00920 }
00921 }
00922 }
00923 }
00924
00925 static int dv_encode_video_segment(AVCodecContext *avctx, void *arg)
00926 {
00927 DVVideoContext *s = avctx->priv_data;
00928 DVwork_chunk *work_chunk = arg;
00929 int mb_index, i, j;
00930 int mb_x, mb_y, c_offset, linesize, y_stride;
00931 uint8_t* y_ptr;
00932 uint8_t* dif;
00933 LOCAL_ALIGNED_8(uint8_t, scratch, [64]);
00934 EncBlockInfo enc_blks[5*DV_MAX_BPM];
00935 PutBitContext pbs[5*DV_MAX_BPM];
00936 PutBitContext* pb;
00937 EncBlockInfo* enc_blk;
00938 int vs_bit_size = 0;
00939 int qnos[5] = {15, 15, 15, 15, 15};
00940 int* qnosp = &qnos[0];
00941
00942 dif = &s->buf[work_chunk->buf_offset*80];
00943 enc_blk = &enc_blks[0];
00944 for (mb_index = 0; mb_index < 5; mb_index++) {
00945 dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);
00946
00947
00948 if ((s->sys->pix_fmt == PIX_FMT_YUV420P) ||
00949 (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
00950 (s->sys->height >= 720 && mb_y != 134)) {
00951 y_stride = s->picture.linesize[0] << 3;
00952 } else {
00953 y_stride = 16;
00954 }
00955 y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << 3);
00956 linesize = s->picture.linesize[0];
00957
00958 if (s->sys->video_stype == 4) {
00959 vs_bit_size +=
00960 dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) +
00961 dv_init_enc_block(enc_blk+1, NULL , linesize, s, 0) +
00962 dv_init_enc_block(enc_blk+2, y_ptr + 8 , linesize, s, 0) +
00963 dv_init_enc_block(enc_blk+3, NULL , linesize, s, 0);
00964 } else {
00965 vs_bit_size +=
00966 dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) +
00967 dv_init_enc_block(enc_blk+1, y_ptr + 8 , linesize, s, 0) +
00968 dv_init_enc_block(enc_blk+2, y_ptr + y_stride, linesize, s, 0) +
00969 dv_init_enc_block(enc_blk+3, y_ptr + 8 + y_stride, linesize, s, 0);
00970 }
00971 enc_blk += 4;
00972
00973
00974 c_offset = (((mb_y >> (s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] +
00975 (mb_x >> ((s->sys->pix_fmt == PIX_FMT_YUV411P) ? 2 : 1))) << 3);
00976 for (j = 2; j; j--) {
00977 uint8_t *c_ptr = s->picture.data[j] + c_offset;
00978 linesize = s->picture.linesize[j];
00979 y_stride = (mb_y == 134) ? 8 : (s->picture.linesize[j] << 3);
00980 if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
00981 uint8_t* d;
00982 uint8_t* b = scratch;
00983 for (i = 0; i < 8; i++) {
00984 d = c_ptr + (linesize << 3);
00985 b[0] = c_ptr[0]; b[1] = c_ptr[1]; b[2] = c_ptr[2]; b[3] = c_ptr[3];
00986 b[4] = d[0]; b[5] = d[1]; b[6] = d[2]; b[7] = d[3];
00987 c_ptr += linesize;
00988 b += 8;
00989 }
00990 c_ptr = scratch;
00991 linesize = 8;
00992 }
00993
00994 vs_bit_size += dv_init_enc_block( enc_blk++, c_ptr , linesize, s, 1);
00995 if (s->sys->bpm == 8) {
00996 vs_bit_size += dv_init_enc_block(enc_blk++, c_ptr + y_stride, linesize, s, 1);
00997 }
00998 }
00999 }
01000
01001 if (vs_total_ac_bits < vs_bit_size)
01002 dv_guess_qnos(&enc_blks[0], qnosp);
01003
01004
01005 for (j=0; j<5*s->sys->bpm;) {
01006 int start_mb = j;
01007
01008 dif[3] = *qnosp++;
01009 dif += 4;
01010
01011
01012 for (i=0; i<s->sys->bpm; i++, j++) {
01013 int sz = s->sys->block_sizes[i]>>3;
01014
01015 init_put_bits(&pbs[j], dif, sz);
01016 put_sbits(&pbs[j], 9, ((enc_blks[j].mb[0] >> 3) - 1024 + 2) >> 2);
01017 put_bits(&pbs[j], 1, enc_blks[j].dct_mode);
01018 put_bits(&pbs[j], 2, enc_blks[j].cno);
01019
01020 dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]);
01021 dif += sz;
01022 }
01023
01024
01025 pb = &pbs[start_mb];
01026 for (i=0; i<s->sys->bpm; i++) {
01027 if (enc_blks[start_mb+i].partial_bit_count)
01028 pb = dv_encode_ac(&enc_blks[start_mb+i], pb, &pbs[start_mb+s->sys->bpm]);
01029 }
01030 }
01031
01032
01033 pb = &pbs[0];
01034 for (j=0; j<5*s->sys->bpm; j++) {
01035 if (enc_blks[j].partial_bit_count)
01036 pb = dv_encode_ac(&enc_blks[j], pb, &pbs[s->sys->bpm*5]);
01037 if (enc_blks[j].partial_bit_count)
01038 av_log(avctx, AV_LOG_ERROR, "ac bitstream overflow\n");
01039 }
01040
01041 for (j=0; j<5*s->sys->bpm; j++) {
01042 int pos;
01043 int size = pbs[j].size_in_bits >> 3;
01044 flush_put_bits(&pbs[j]);
01045 pos = put_bits_count(&pbs[j]) >> 3;
01046 if (pos > size) {
01047 av_log(avctx, AV_LOG_ERROR, "bitstream written beyond buffer size\n");
01048 return -1;
01049 }
01050 memset(pbs[j].buf + pos, 0xff, size - pos);
01051 }
01052
01053 return 0;
01054 }
01055
01056 #if CONFIG_DVVIDEO_DECODER
01057
01058
01059 static int dvvideo_decode_frame(AVCodecContext *avctx,
01060 void *data, int *data_size,
01061 AVPacket *avpkt)
01062 {
01063 const uint8_t *buf = avpkt->data;
01064 int buf_size = avpkt->size;
01065 DVVideoContext *s = avctx->priv_data;
01066 const uint8_t* vsc_pack;
01067 int apt, is16_9;
01068
01069 s->sys = avpriv_dv_frame_profile(s->sys, buf, buf_size);
01070 if (!s->sys || buf_size < s->sys->frame_size || dv_init_dynamic_tables(s->sys)) {
01071 av_log(avctx, AV_LOG_ERROR, "could not find dv frame profile\n");
01072 return -1;
01073 }
01074
01075 if (s->picture.data[0])
01076 avctx->release_buffer(avctx, &s->picture);
01077
01078 s->picture.reference = 0;
01079 s->picture.key_frame = 1;
01080 s->picture.pict_type = AV_PICTURE_TYPE_I;
01081 avctx->pix_fmt = s->sys->pix_fmt;
01082 avctx->time_base = s->sys->time_base;
01083 avcodec_set_dimensions(avctx, s->sys->width, s->sys->height);
01084 if (avctx->get_buffer(avctx, &s->picture) < 0) {
01085 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
01086 return -1;
01087 }
01088 s->picture.interlaced_frame = 1;
01089 s->picture.top_field_first = 0;
01090
01091 s->buf = buf;
01092 avctx->execute(avctx, dv_decode_video_segment, s->sys->work_chunks, NULL,
01093 dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
01094
01095 emms_c();
01096
01097
01098 *data_size = sizeof(AVFrame);
01099 *(AVFrame*)data = s->picture;
01100
01101
01102 vsc_pack = buf + 80*5 + 48 + 5;
01103 if ( *vsc_pack == dv_video_control ) {
01104 apt = buf[4] & 0x07;
01105 is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07)));
01106 avctx->sample_aspect_ratio = s->sys->sar[is16_9];
01107 }
01108
01109 return s->sys->frame_size;
01110 }
01111 #endif
01112
01113
01114 static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c,
01115 uint8_t* buf)
01116 {
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135 int apt = (c->sys->pix_fmt == PIX_FMT_YUV420P ? 0 : 1);
01136
01137 uint8_t aspect = 0;
01138 if ((int)(av_q2d(c->avctx->sample_aspect_ratio) * c->avctx->width / c->avctx->height * 10) >= 17)
01139 aspect = 0x02;
01140
01141 buf[0] = (uint8_t)pack_id;
01142 switch (pack_id) {
01143 case dv_header525:
01144 case dv_header625:
01145 buf[1] = 0xf8 |
01146 (apt & 0x07);
01147 buf[2] = (0 << 7) |
01148 (0x0f << 3) |
01149 (apt & 0x07);
01150 buf[3] = (0 << 7) |
01151 (0x0f << 3) |
01152 (apt & 0x07);
01153 buf[4] = (0 << 7) |
01154 (0x0f << 3) |
01155 (apt & 0x07);
01156 break;
01157 case dv_video_source:
01158 buf[1] = 0xff;
01159 buf[2] = (1 << 7) |
01160 (1 << 6) |
01161 (3 << 4) |
01162 0xf;
01163 buf[3] = (3 << 6) |
01164 (c->sys->dsf << 5) |
01165 c->sys->video_stype;
01166 buf[4] = 0xff;
01167 break;
01168 case dv_video_control:
01169 buf[1] = (0 << 6) |
01170 0x3f;
01171 buf[2] = 0xc8 |
01172 aspect;
01173 buf[3] = (1 << 7) |
01174 (1 << 6) |
01175 (1 << 5) |
01176 (1 << 4) |
01177 0xc;
01178 buf[4] = 0xff;
01179 break;
01180 default:
01181 buf[1] = buf[2] = buf[3] = buf[4] = 0xff;
01182 }
01183 return 5;
01184 }
01185
01186 #if CONFIG_DVVIDEO_ENCODER
01187 static void dv_format_frame(DVVideoContext* c, uint8_t* buf)
01188 {
01189 int chan, i, j, k;
01190
01191 for (chan = 0; chan < c->sys->n_difchan; chan++) {
01192 for (i = 0; i < c->sys->difseg_size; i++) {
01193 memset(buf, 0xff, 80 * 6);
01194
01195
01196 buf += dv_write_dif_id(dv_sect_header, chan, i, 0, buf);
01197 buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525), c, buf);
01198 buf += 72;
01199
01200
01201 for (j = 0; j < 2; j++) {
01202 buf += dv_write_dif_id(dv_sect_subcode, chan, i, j, buf);
01203 for (k = 0; k < 6; k++)
01204 buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size/2), buf) + 5;
01205 buf += 29;
01206 }
01207
01208
01209 for (j = 0; j < 3; j++) {
01210 buf += dv_write_dif_id(dv_sect_vaux, chan, i, j, buf);
01211 buf += dv_write_pack(dv_video_source, c, buf);
01212 buf += dv_write_pack(dv_video_control, c, buf);
01213 buf += 7*5;
01214 buf += dv_write_pack(dv_video_source, c, buf);
01215 buf += dv_write_pack(dv_video_control, c, buf);
01216 buf += 4*5 + 2;
01217 }
01218
01219
01220 for (j = 0; j < 135; j++) {
01221 if (j%15 == 0) {
01222 memset(buf, 0xff, 80);
01223 buf += dv_write_dif_id(dv_sect_audio, chan, i, j/15, buf);
01224 buf += 77;
01225 }
01226 buf += dv_write_dif_id(dv_sect_video, chan, i, j, buf);
01227 buf += 77;
01228
01229
01230
01231 }
01232 }
01233 }
01234 }
01235
01236
01237 static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size,
01238 void *data)
01239 {
01240 DVVideoContext *s = c->priv_data;
01241
01242 s->sys = avpriv_dv_codec_profile(c);
01243 if (!s->sys || buf_size < s->sys->frame_size || dv_init_dynamic_tables(s->sys))
01244 return -1;
01245
01246 c->pix_fmt = s->sys->pix_fmt;
01247 s->picture = *((AVFrame *)data);
01248 s->picture.key_frame = 1;
01249 s->picture.pict_type = AV_PICTURE_TYPE_I;
01250
01251 s->buf = buf;
01252 c->execute(c, dv_encode_video_segment, s->sys->work_chunks, NULL,
01253 dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
01254
01255 emms_c();
01256
01257 dv_format_frame(s, buf);
01258
01259 return s->sys->frame_size;
01260 }
01261 #endif
01262
01263 static int dvvideo_close(AVCodecContext *c)
01264 {
01265 DVVideoContext *s = c->priv_data;
01266
01267 if (s->picture.data[0])
01268 c->release_buffer(c, &s->picture);
01269
01270 return 0;
01271 }
01272
01273
01274 #if CONFIG_DVVIDEO_ENCODER
01275 AVCodec ff_dvvideo_encoder = {
01276 .name = "dvvideo",
01277 .type = AVMEDIA_TYPE_VIDEO,
01278 .id = CODEC_ID_DVVIDEO,
01279 .priv_data_size = sizeof(DVVideoContext),
01280 .init = dvvideo_init_encoder,
01281 .encode = dvvideo_encode_frame,
01282 .capabilities = CODEC_CAP_SLICE_THREADS,
01283 .pix_fmts = (const enum PixelFormat[]) {PIX_FMT_YUV411P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, PIX_FMT_NONE},
01284 .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
01285 };
01286 #endif // CONFIG_DVVIDEO_ENCODER
01287
01288 #if CONFIG_DVVIDEO_DECODER
01289 AVCodec ff_dvvideo_decoder = {
01290 .name = "dvvideo",
01291 .type = AVMEDIA_TYPE_VIDEO,
01292 .id = CODEC_ID_DVVIDEO,
01293 .priv_data_size = sizeof(DVVideoContext),
01294 .init = dvvideo_init,
01295 .close = dvvideo_close,
01296 .decode = dvvideo_decode_frame,
01297 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
01298 .max_lowres = 3,
01299 .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
01300 };
01301 #endif