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 static inline int put_bits_left(PutBitContext* s)
00376 {
00377 return (s->buf_end - s->buf) * 8 - put_bits_count(s);
00378 }
00379
00380
00381 static void dv_decode_ac(GetBitContext *gb, BlockInfo *mb, DCTELEM *block)
00382 {
00383 int last_index = gb->size_in_bits;
00384 const uint8_t *scan_table = mb->scan_table;
00385 const uint32_t *factor_table = mb->factor_table;
00386 int pos = mb->pos;
00387 int partial_bit_count = mb->partial_bit_count;
00388 int level, run, vlc_len, index;
00389
00390 OPEN_READER(re, gb);
00391 UPDATE_CACHE(re, gb);
00392
00393
00394 if (partial_bit_count > 0) {
00395 re_cache = re_cache >> partial_bit_count | mb->partial_bit_buffer;
00396 re_index -= partial_bit_count;
00397 mb->partial_bit_count = 0;
00398 }
00399
00400
00401 for (;;) {
00402 av_dlog(NULL, "%2d: bits=%04x index=%d\n", pos, SHOW_UBITS(re, gb, 16),
00403 re_index);
00404
00405 index = NEG_USR32(re_cache, TEX_VLC_BITS);
00406 vlc_len = dv_rl_vlc[index].len;
00407 if (vlc_len < 0) {
00408 index = NEG_USR32((unsigned)re_cache << TEX_VLC_BITS, -vlc_len) + dv_rl_vlc[index].level;
00409 vlc_len = TEX_VLC_BITS - vlc_len;
00410 }
00411 level = dv_rl_vlc[index].level;
00412 run = dv_rl_vlc[index].run;
00413
00414
00415 if (re_index + vlc_len > last_index) {
00416
00417 mb->partial_bit_count = last_index - re_index;
00418 mb->partial_bit_buffer = re_cache & ~(-1u >> mb->partial_bit_count);
00419 re_index = last_index;
00420 break;
00421 }
00422 re_index += vlc_len;
00423
00424 av_dlog(NULL, "run=%d level=%d\n", run, level);
00425 pos += run;
00426 if (pos >= 64)
00427 break;
00428
00429 level = (level * factor_table[pos] + (1 << (dv_iweight_bits - 1))) >> dv_iweight_bits;
00430 block[scan_table[pos]] = level;
00431
00432 UPDATE_CACHE(re, gb);
00433 }
00434 CLOSE_READER(re, gb);
00435 mb->pos = pos;
00436 }
00437
00438 static inline void bit_copy(PutBitContext *pb, GetBitContext *gb)
00439 {
00440 int bits_left = get_bits_left(gb);
00441 while (bits_left >= MIN_CACHE_BITS) {
00442 put_bits(pb, MIN_CACHE_BITS, get_bits(gb, MIN_CACHE_BITS));
00443 bits_left -= MIN_CACHE_BITS;
00444 }
00445 if (bits_left > 0) {
00446 put_bits(pb, bits_left, get_bits(gb, bits_left));
00447 }
00448 }
00449
00450 static inline void dv_calculate_mb_xy(DVVideoContext *s, DVwork_chunk *work_chunk, int m, int *mb_x, int *mb_y)
00451 {
00452 *mb_x = work_chunk->mb_coordinates[m] & 0xff;
00453 *mb_y = work_chunk->mb_coordinates[m] >> 8;
00454
00455
00456 if (s->sys->height == 720 && !(s->buf[1]&0x0C)) {
00457 *mb_y -= (*mb_y>17)?18:-72;
00458 }
00459 }
00460
00461
00462 static int dv_decode_video_segment(AVCodecContext *avctx, void *arg)
00463 {
00464 DVVideoContext *s = avctx->priv_data;
00465 DVwork_chunk *work_chunk = arg;
00466 int quant, dc, dct_mode, class1, j;
00467 int mb_index, mb_x, mb_y, last_index;
00468 int y_stride, linesize;
00469 DCTELEM *block, *block1;
00470 int c_offset;
00471 uint8_t *y_ptr;
00472 const uint8_t *buf_ptr;
00473 PutBitContext pb, vs_pb;
00474 GetBitContext gb;
00475 BlockInfo mb_data[5 * DV_MAX_BPM], *mb, *mb1;
00476 LOCAL_ALIGNED_16(DCTELEM, sblock, [5*DV_MAX_BPM], [64]);
00477 LOCAL_ALIGNED_16(uint8_t, mb_bit_buffer, [ 80 + FF_INPUT_BUFFER_PADDING_SIZE]);
00478 LOCAL_ALIGNED_16(uint8_t, vs_bit_buffer, [5*80 + FF_INPUT_BUFFER_PADDING_SIZE]);
00479 const int log2_blocksize = 3-s->avctx->lowres;
00480 int is_field_mode[5];
00481
00482 assert((((int)mb_bit_buffer) & 7) == 0);
00483 assert((((int)vs_bit_buffer) & 7) == 0);
00484
00485 memset(sblock, 0, 5*DV_MAX_BPM*sizeof(*sblock));
00486
00487
00488 buf_ptr = &s->buf[work_chunk->buf_offset*80];
00489 block1 = &sblock[0][0];
00490 mb1 = mb_data;
00491 init_put_bits(&vs_pb, vs_bit_buffer, 5 * 80);
00492 for (mb_index = 0; mb_index < 5; mb_index++, mb1 += s->sys->bpm, block1 += s->sys->bpm * 64) {
00493
00494 quant = buf_ptr[3] & 0x0f;
00495 buf_ptr += 4;
00496 init_put_bits(&pb, mb_bit_buffer, 80);
00497 mb = mb1;
00498 block = block1;
00499 is_field_mode[mb_index] = 0;
00500 for (j = 0; j < s->sys->bpm; j++) {
00501 last_index = s->sys->block_sizes[j];
00502 init_get_bits(&gb, buf_ptr, last_index);
00503
00504
00505 dc = get_sbits(&gb, 9);
00506 dct_mode = get_bits1(&gb);
00507 class1 = get_bits(&gb, 2);
00508 if (DV_PROFILE_IS_HD(s->sys)) {
00509 mb->idct_put = s->idct_put[0];
00510 mb->scan_table = s->dv_zigzag[0];
00511 mb->factor_table = &s->sys->idct_factor[(j >= 4)*4*16*64 + class1*16*64 + quant*64];
00512 is_field_mode[mb_index] |= !j && dct_mode;
00513 } else {
00514 mb->idct_put = s->idct_put[dct_mode && log2_blocksize == 3];
00515 mb->scan_table = s->dv_zigzag[dct_mode];
00516 mb->factor_table = &s->sys->idct_factor[(class1 == 3)*2*22*64 + dct_mode*22*64 +
00517 (quant + dv_quant_offset[class1])*64];
00518 }
00519 dc = dc << 2;
00520
00521
00522 dc += 1024;
00523 block[0] = dc;
00524 buf_ptr += last_index >> 3;
00525 mb->pos = 0;
00526 mb->partial_bit_count = 0;
00527
00528 av_dlog(avctx, "MB block: %d, %d ", mb_index, j);
00529 dv_decode_ac(&gb, mb, block);
00530
00531
00532
00533 if (mb->pos >= 64)
00534 bit_copy(&pb, &gb);
00535
00536 block += 64;
00537 mb++;
00538 }
00539
00540
00541 av_dlog(avctx, "***pass 2 size=%d MB#=%d\n", put_bits_count(&pb), mb_index);
00542 block = block1;
00543 mb = mb1;
00544 init_get_bits(&gb, mb_bit_buffer, put_bits_count(&pb));
00545 put_bits32(&pb, 0);
00546 flush_put_bits(&pb);
00547 for (j = 0; j < s->sys->bpm; j++, block += 64, mb++) {
00548 if (mb->pos < 64 && get_bits_left(&gb) > 0) {
00549 dv_decode_ac(&gb, mb, block);
00550
00551 if (mb->pos < 64)
00552 break;
00553 }
00554 }
00555
00556
00557 if (j >= s->sys->bpm)
00558 bit_copy(&vs_pb, &gb);
00559 }
00560
00561
00562 av_dlog(avctx, "***pass 3 size=%d\n", put_bits_count(&vs_pb));
00563 block = &sblock[0][0];
00564 mb = mb_data;
00565 init_get_bits(&gb, vs_bit_buffer, put_bits_count(&vs_pb));
00566 put_bits32(&vs_pb, 0);
00567 flush_put_bits(&vs_pb);
00568 for (mb_index = 0; mb_index < 5; mb_index++) {
00569 for (j = 0; j < s->sys->bpm; j++) {
00570 if (mb->pos < 64) {
00571 av_dlog(avctx, "start %d:%d\n", mb_index, j);
00572 dv_decode_ac(&gb, mb, block);
00573 }
00574 if (mb->pos >= 64 && mb->pos < 127)
00575 av_log(avctx, AV_LOG_ERROR, "AC EOB marker is absent pos=%d\n", mb->pos);
00576 block += 64;
00577 mb++;
00578 }
00579 }
00580
00581
00582 block = &sblock[0][0];
00583 mb = mb_data;
00584 for (mb_index = 0; mb_index < 5; mb_index++) {
00585 dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);
00586
00587
00588 if ((s->sys->pix_fmt == PIX_FMT_YUV420P) ||
00589 (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
00590 (s->sys->height >= 720 && mb_y != 134)) {
00591 y_stride = (s->picture.linesize[0] << ((!is_field_mode[mb_index]) * log2_blocksize));
00592 } else {
00593 y_stride = (2 << log2_blocksize);
00594 }
00595 y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << log2_blocksize);
00596 linesize = s->picture.linesize[0] << is_field_mode[mb_index];
00597 mb[0] .idct_put(y_ptr , linesize, block + 0*64);
00598 if (s->sys->video_stype == 4) {
00599 mb[2].idct_put(y_ptr + (1 << log2_blocksize) , linesize, block + 2*64);
00600 } else {
00601 mb[1].idct_put(y_ptr + (1 << log2_blocksize) , linesize, block + 1*64);
00602 mb[2].idct_put(y_ptr + y_stride, linesize, block + 2*64);
00603 mb[3].idct_put(y_ptr + (1 << log2_blocksize) + y_stride, linesize, block + 3*64);
00604 }
00605 mb += 4;
00606 block += 4*64;
00607
00608
00609 c_offset = (((mb_y >> (s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] +
00610 (mb_x >> ((s->sys->pix_fmt == PIX_FMT_YUV411P) ? 2 : 1))) << log2_blocksize);
00611 for (j = 2; j; j--) {
00612 uint8_t *c_ptr = s->picture.data[j] + c_offset;
00613 if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
00614 uint64_t aligned_pixels[64/8];
00615 uint8_t *pixels = (uint8_t*)aligned_pixels;
00616 uint8_t *c_ptr1, *ptr1;
00617 int x, y;
00618 mb->idct_put(pixels, 8, block);
00619 for (y = 0; y < (1 << log2_blocksize); y++, c_ptr += s->picture.linesize[j], pixels += 8) {
00620 ptr1 = pixels + (1 << (log2_blocksize - 1));
00621 c_ptr1 = c_ptr + (s->picture.linesize[j] << log2_blocksize);
00622 for (x = 0; x < (1 << (log2_blocksize - 1)); x++) {
00623 c_ptr[x] = pixels[x];
00624 c_ptr1[x] = ptr1[x];
00625 }
00626 }
00627 block += 64; mb++;
00628 } else {
00629 y_stride = (mb_y == 134) ? (1 << log2_blocksize) :
00630 s->picture.linesize[j] << ((!is_field_mode[mb_index]) * log2_blocksize);
00631 linesize = s->picture.linesize[j] << is_field_mode[mb_index];
00632 (mb++)-> idct_put(c_ptr , linesize, block); block += 64;
00633 if (s->sys->bpm == 8) {
00634 (mb++)->idct_put(c_ptr + y_stride, linesize, block); block += 64;
00635 }
00636 }
00637 }
00638 }
00639 return 0;
00640 }
00641
00642 #if CONFIG_SMALL
00643
00644 static av_always_inline int dv_rl2vlc(int run, int level, int sign, uint32_t* vlc)
00645 {
00646 int size;
00647 if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
00648 *vlc = dv_vlc_map[run][level].vlc | sign;
00649 size = dv_vlc_map[run][level].size;
00650 }
00651 else {
00652 if (level < DV_VLC_MAP_LEV_SIZE) {
00653 *vlc = dv_vlc_map[0][level].vlc | sign;
00654 size = dv_vlc_map[0][level].size;
00655 } else {
00656 *vlc = 0xfe00 | (level << 1) | sign;
00657 size = 16;
00658 }
00659 if (run) {
00660 *vlc |= ((run < 16) ? dv_vlc_map[run-1][0].vlc :
00661 (0x1f80 | (run - 1))) << size;
00662 size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
00663 }
00664 }
00665
00666 return size;
00667 }
00668
00669 static av_always_inline int dv_rl2vlc_size(int run, int level)
00670 {
00671 int size;
00672
00673 if (run < DV_VLC_MAP_RUN_SIZE && level < DV_VLC_MAP_LEV_SIZE) {
00674 size = dv_vlc_map[run][level].size;
00675 }
00676 else {
00677 size = (level < DV_VLC_MAP_LEV_SIZE) ? dv_vlc_map[0][level].size : 16;
00678 if (run) {
00679 size += (run < 16) ? dv_vlc_map[run-1][0].size : 13;
00680 }
00681 }
00682 return size;
00683 }
00684 #else
00685 static av_always_inline int dv_rl2vlc(int run, int l, int sign, uint32_t* vlc)
00686 {
00687 *vlc = dv_vlc_map[run][l].vlc | sign;
00688 return dv_vlc_map[run][l].size;
00689 }
00690
00691 static av_always_inline int dv_rl2vlc_size(int run, int l)
00692 {
00693 return dv_vlc_map[run][l].size;
00694 }
00695 #endif
00696
00697 typedef struct EncBlockInfo {
00698 int area_q[4];
00699 int bit_size[4];
00700 int prev[5];
00701 int cur_ac;
00702 int cno;
00703 int dct_mode;
00704 DCTELEM mb[64];
00705 uint8_t next[64];
00706 uint8_t sign[64];
00707 uint8_t partial_bit_count;
00708 uint32_t partial_bit_buffer;
00709 } EncBlockInfo;
00710
00711 static av_always_inline PutBitContext* dv_encode_ac(EncBlockInfo* bi,
00712 PutBitContext* pb_pool,
00713 PutBitContext* pb_end)
00714 {
00715 int prev, bits_left;
00716 PutBitContext* pb = pb_pool;
00717 int size = bi->partial_bit_count;
00718 uint32_t vlc = bi->partial_bit_buffer;
00719
00720 bi->partial_bit_count = bi->partial_bit_buffer = 0;
00721 for (;;){
00722
00723 for (; size > (bits_left = put_bits_left(pb)); pb++) {
00724 if (bits_left) {
00725 size -= bits_left;
00726 put_bits(pb, bits_left, vlc >> size);
00727 vlc = vlc & ((1 << size) - 1);
00728 }
00729 if (pb + 1 >= pb_end) {
00730 bi->partial_bit_count = size;
00731 bi->partial_bit_buffer = vlc;
00732 return pb;
00733 }
00734 }
00735
00736
00737 put_bits(pb, size, vlc);
00738
00739 if (bi->cur_ac >= 64)
00740 break;
00741
00742
00743 prev = bi->cur_ac;
00744 bi->cur_ac = bi->next[prev];
00745 if (bi->cur_ac < 64){
00746 size = dv_rl2vlc(bi->cur_ac - prev - 1, bi->mb[bi->cur_ac], bi->sign[bi->cur_ac], &vlc);
00747 } else {
00748 size = 4; vlc = 6;
00749 }
00750 }
00751 return pb;
00752 }
00753
00754 static av_always_inline int dv_guess_dct_mode(DVVideoContext *s, uint8_t *data, int linesize) {
00755 if (s->avctx->flags & CODEC_FLAG_INTERLACED_DCT) {
00756 int ps = s->ildct_cmp(NULL, data, NULL, linesize, 8) - 400;
00757 if (ps > 0) {
00758 int is = s->ildct_cmp(NULL, data , NULL, linesize<<1, 4) +
00759 s->ildct_cmp(NULL, data + linesize, NULL, linesize<<1, 4);
00760 return ps > is;
00761 }
00762 }
00763
00764 return 0;
00765 }
00766
00767 static av_always_inline int dv_init_enc_block(EncBlockInfo* bi, uint8_t *data, int linesize, DVVideoContext *s, int bias)
00768 {
00769 const int *weight;
00770 const uint8_t* zigzag_scan;
00771 LOCAL_ALIGNED_16(DCTELEM, blk, [64]);
00772 int i, area;
00773
00774
00775
00776
00777
00778
00779
00780
00781
00782
00783 #if 0
00784 static const int classes[] = {12, 24, 36, 0xffff};
00785 #else
00786 static const int classes[] = {-1, -1, 255, 0xffff};
00787 #endif
00788 int max = classes[0];
00789 int prev = 0;
00790
00791 assert((((int)blk) & 15) == 0);
00792
00793 bi->area_q[0] = bi->area_q[1] = bi->area_q[2] = bi->area_q[3] = 0;
00794 bi->partial_bit_count = 0;
00795 bi->partial_bit_buffer = 0;
00796 bi->cur_ac = 0;
00797 if (data) {
00798 bi->dct_mode = dv_guess_dct_mode(s, data, linesize);
00799 s->get_pixels(blk, data, linesize);
00800 s->fdct[bi->dct_mode](blk);
00801 } else {
00802
00803
00804 memset(blk, 0, 64*sizeof(*blk));
00805 bi->dct_mode = 0;
00806 }
00807 bi->mb[0] = blk[0];
00808
00809 zigzag_scan = bi->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct;
00810 weight = bi->dct_mode ? dv_weight_248 : dv_weight_88;
00811
00812 for (area = 0; area < 4; area++) {
00813 bi->prev[area] = prev;
00814 bi->bit_size[area] = 1;
00815 for (i = mb_area_start[area]; i < mb_area_start[area+1]; i++) {
00816 int level = blk[zigzag_scan[i]];
00817
00818 if (level + 15 > 30U) {
00819 bi->sign[i] = (level >> 31) & 1;
00820
00821
00822
00823 level = (FFABS(level) * weight[i] + (1 << (dv_weight_bits+3))) >> (dv_weight_bits+4);
00824 bi->mb[i] = level;
00825 if (level > max)
00826 max = level;
00827 bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, level);
00828 bi->next[prev]= i;
00829 prev = i;
00830 }
00831 }
00832 }
00833 bi->next[prev]= i;
00834 for (bi->cno = 0; max > classes[bi->cno]; bi->cno++);
00835
00836 bi->cno += bias;
00837
00838 if (bi->cno >= 3) {
00839 bi->cno = 3;
00840 prev = 0;
00841 i = bi->next[prev];
00842 for (area = 0; area < 4; area++) {
00843 bi->prev[area] = prev;
00844 bi->bit_size[area] = 1;
00845 for (; i < mb_area_start[area+1]; i = bi->next[i]) {
00846 bi->mb[i] >>= 1;
00847
00848 if (bi->mb[i]) {
00849 bi->bit_size[area] += dv_rl2vlc_size(i - prev - 1, bi->mb[i]);
00850 bi->next[prev]= i;
00851 prev = i;
00852 }
00853 }
00854 }
00855 bi->next[prev]= i;
00856 }
00857
00858 return bi->bit_size[0] + bi->bit_size[1] + bi->bit_size[2] + bi->bit_size[3];
00859 }
00860
00861 static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos)
00862 {
00863 int size[5];
00864 int i, j, k, a, prev, a2;
00865 EncBlockInfo* b;
00866
00867 size[0] = size[1] = size[2] = size[3] = size[4] = 1 << 24;
00868 do {
00869 b = blks;
00870 for (i = 0; i < 5; i++) {
00871 if (!qnos[i])
00872 continue;
00873
00874 qnos[i]--;
00875 size[i] = 0;
00876 for (j = 0; j < 6; j++, b++) {
00877 for (a = 0; a < 4; a++) {
00878 if (b->area_q[a] != dv_quant_shifts[qnos[i] + dv_quant_offset[b->cno]][a]) {
00879 b->bit_size[a] = 1;
00880 b->area_q[a]++;
00881 prev = b->prev[a];
00882 assert(b->next[prev] >= mb_area_start[a+1] || b->mb[prev]);
00883 for (k = b->next[prev] ; k < mb_area_start[a+1]; k = b->next[k]) {
00884 b->mb[k] >>= 1;
00885 if (b->mb[k]) {
00886 b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
00887 prev = k;
00888 } else {
00889 if (b->next[k] >= mb_area_start[a+1] && b->next[k]<64){
00890 for (a2 = a + 1; b->next[k] >= mb_area_start[a2+1]; a2++)
00891 b->prev[a2] = prev;
00892 assert(a2 < 4);
00893 assert(b->mb[b->next[k]]);
00894 b->bit_size[a2] += dv_rl2vlc_size(b->next[k] - prev - 1, b->mb[b->next[k]])
00895 -dv_rl2vlc_size(b->next[k] - k - 1, b->mb[b->next[k]]);
00896 assert(b->prev[a2] == k && (a2 + 1 >= 4 || b->prev[a2+1] != k));
00897 b->prev[a2] = prev;
00898 }
00899 b->next[prev] = b->next[k];
00900 }
00901 }
00902 b->prev[a+1]= prev;
00903 }
00904 size[i] += b->bit_size[a];
00905 }
00906 }
00907 if (vs_total_ac_bits >= size[0] + size[1] + size[2] + size[3] + size[4])
00908 return;
00909 }
00910 } while (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4]);
00911
00912
00913 for (a = 2; a == 2 || vs_total_ac_bits < size[0]; a += a){
00914 b = blks;
00915 size[0] = 5 * 6 * 4;
00916 for (j = 0; j < 6 *5; j++, b++) {
00917 prev = b->prev[0];
00918 for (k = b->next[prev]; k < 64; k = b->next[k]) {
00919 if (b->mb[k] < a && b->mb[k] > -a){
00920 b->next[prev] = b->next[k];
00921 }else{
00922 size[0] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
00923 prev = k;
00924 }
00925 }
00926 }
00927 }
00928 }
00929
00930 static int dv_encode_video_segment(AVCodecContext *avctx, void *arg)
00931 {
00932 DVVideoContext *s = avctx->priv_data;
00933 DVwork_chunk *work_chunk = arg;
00934 int mb_index, i, j;
00935 int mb_x, mb_y, c_offset, linesize, y_stride;
00936 uint8_t* y_ptr;
00937 uint8_t* dif;
00938 LOCAL_ALIGNED_8(uint8_t, scratch, [64]);
00939 EncBlockInfo enc_blks[5*DV_MAX_BPM];
00940 PutBitContext pbs[5*DV_MAX_BPM];
00941 PutBitContext* pb;
00942 EncBlockInfo* enc_blk;
00943 int vs_bit_size = 0;
00944 int qnos[5] = {15, 15, 15, 15, 15};
00945 int* qnosp = &qnos[0];
00946
00947 dif = &s->buf[work_chunk->buf_offset*80];
00948 enc_blk = &enc_blks[0];
00949 for (mb_index = 0; mb_index < 5; mb_index++) {
00950 dv_calculate_mb_xy(s, work_chunk, mb_index, &mb_x, &mb_y);
00951
00952
00953 if ((s->sys->pix_fmt == PIX_FMT_YUV420P) ||
00954 (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) ||
00955 (s->sys->height >= 720 && mb_y != 134)) {
00956 y_stride = s->picture.linesize[0] << 3;
00957 } else {
00958 y_stride = 16;
00959 }
00960 y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x) << 3);
00961 linesize = s->picture.linesize[0];
00962
00963 if (s->sys->video_stype == 4) {
00964 vs_bit_size +=
00965 dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) +
00966 dv_init_enc_block(enc_blk+1, NULL , linesize, s, 0) +
00967 dv_init_enc_block(enc_blk+2, y_ptr + 8 , linesize, s, 0) +
00968 dv_init_enc_block(enc_blk+3, NULL , linesize, s, 0);
00969 } else {
00970 vs_bit_size +=
00971 dv_init_enc_block(enc_blk+0, y_ptr , linesize, s, 0) +
00972 dv_init_enc_block(enc_blk+1, y_ptr + 8 , linesize, s, 0) +
00973 dv_init_enc_block(enc_blk+2, y_ptr + y_stride, linesize, s, 0) +
00974 dv_init_enc_block(enc_blk+3, y_ptr + 8 + y_stride, linesize, s, 0);
00975 }
00976 enc_blk += 4;
00977
00978
00979 c_offset = (((mb_y >> (s->sys->pix_fmt == PIX_FMT_YUV420P)) * s->picture.linesize[1] +
00980 (mb_x >> ((s->sys->pix_fmt == PIX_FMT_YUV411P) ? 2 : 1))) << 3);
00981 for (j = 2; j; j--) {
00982 uint8_t *c_ptr = s->picture.data[j] + c_offset;
00983 linesize = s->picture.linesize[j];
00984 y_stride = (mb_y == 134) ? 8 : (s->picture.linesize[j] << 3);
00985 if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
00986 uint8_t* d;
00987 uint8_t* b = scratch;
00988 for (i = 0; i < 8; i++) {
00989 d = c_ptr + (linesize << 3);
00990 b[0] = c_ptr[0]; b[1] = c_ptr[1]; b[2] = c_ptr[2]; b[3] = c_ptr[3];
00991 b[4] = d[0]; b[5] = d[1]; b[6] = d[2]; b[7] = d[3];
00992 c_ptr += linesize;
00993 b += 8;
00994 }
00995 c_ptr = scratch;
00996 linesize = 8;
00997 }
00998
00999 vs_bit_size += dv_init_enc_block( enc_blk++, c_ptr , linesize, s, 1);
01000 if (s->sys->bpm == 8) {
01001 vs_bit_size += dv_init_enc_block(enc_blk++, c_ptr + y_stride, linesize, s, 1);
01002 }
01003 }
01004 }
01005
01006 if (vs_total_ac_bits < vs_bit_size)
01007 dv_guess_qnos(&enc_blks[0], qnosp);
01008
01009
01010 for (j=0; j<5*s->sys->bpm;) {
01011 int start_mb = j;
01012
01013 dif[3] = *qnosp++;
01014 dif += 4;
01015
01016
01017 for (i=0; i<s->sys->bpm; i++, j++) {
01018 int sz = s->sys->block_sizes[i]>>3;
01019
01020 init_put_bits(&pbs[j], dif, sz);
01021 put_sbits(&pbs[j], 9, ((enc_blks[j].mb[0] >> 3) - 1024 + 2) >> 2);
01022 put_bits(&pbs[j], 1, enc_blks[j].dct_mode);
01023 put_bits(&pbs[j], 2, enc_blks[j].cno);
01024
01025 dv_encode_ac(&enc_blks[j], &pbs[j], &pbs[j+1]);
01026 dif += sz;
01027 }
01028
01029
01030 pb = &pbs[start_mb];
01031 for (i=0; i<s->sys->bpm; i++) {
01032 if (enc_blks[start_mb+i].partial_bit_count)
01033 pb = dv_encode_ac(&enc_blks[start_mb+i], pb, &pbs[start_mb+s->sys->bpm]);
01034 }
01035 }
01036
01037
01038 pb = &pbs[0];
01039 for (j=0; j<5*s->sys->bpm; j++) {
01040 if (enc_blks[j].partial_bit_count)
01041 pb = dv_encode_ac(&enc_blks[j], pb, &pbs[s->sys->bpm*5]);
01042 if (enc_blks[j].partial_bit_count)
01043 av_log(avctx, AV_LOG_ERROR, "ac bitstream overflow\n");
01044 }
01045
01046 for (j=0; j<5*s->sys->bpm; j++) {
01047 int pos;
01048 int size = pbs[j].size_in_bits >> 3;
01049 flush_put_bits(&pbs[j]);
01050 pos = put_bits_count(&pbs[j]) >> 3;
01051 if (pos > size) {
01052 av_log(avctx, AV_LOG_ERROR, "bitstream written beyond buffer size\n");
01053 return -1;
01054 }
01055 memset(pbs[j].buf + pos, 0xff, size - pos);
01056 }
01057
01058 return 0;
01059 }
01060
01061 #if CONFIG_DVVIDEO_DECODER
01062
01063
01064 static int dvvideo_decode_frame(AVCodecContext *avctx,
01065 void *data, int *data_size,
01066 AVPacket *avpkt)
01067 {
01068 const uint8_t *buf = avpkt->data;
01069 int buf_size = avpkt->size;
01070 DVVideoContext *s = avctx->priv_data;
01071 const uint8_t* vsc_pack;
01072 int apt, is16_9;
01073
01074 s->sys = avpriv_dv_frame_profile2(avctx, s->sys, buf, buf_size);
01075 if (!s->sys || buf_size < s->sys->frame_size || dv_init_dynamic_tables(s->sys)) {
01076 av_log(avctx, AV_LOG_ERROR, "could not find dv frame profile\n");
01077 return -1;
01078 }
01079
01080 if (s->picture.data[0])
01081 avctx->release_buffer(avctx, &s->picture);
01082
01083 avcodec_get_frame_defaults(&s->picture);
01084 s->picture.reference = 0;
01085 s->picture.key_frame = 1;
01086 s->picture.pict_type = AV_PICTURE_TYPE_I;
01087 avctx->pix_fmt = s->sys->pix_fmt;
01088 avctx->time_base = s->sys->time_base;
01089 avcodec_set_dimensions(avctx, s->sys->width, s->sys->height);
01090 if (avctx->get_buffer(avctx, &s->picture) < 0) {
01091 av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
01092 return -1;
01093 }
01094 s->picture.interlaced_frame = 1;
01095 s->picture.top_field_first = 0;
01096
01097 s->buf = buf;
01098 avctx->execute(avctx, dv_decode_video_segment, s->sys->work_chunks, NULL,
01099 dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
01100
01101 emms_c();
01102
01103
01104 *data_size = sizeof(AVFrame);
01105 *(AVFrame*)data = s->picture;
01106
01107
01108 vsc_pack = buf + 80*5 + 48 + 5;
01109 if ( *vsc_pack == dv_video_control ) {
01110 apt = buf[4] & 0x07;
01111 is16_9 = (vsc_pack[2] & 0x07) == 0x02 || (!apt && (vsc_pack[2] & 0x07) == 0x07);
01112 avctx->sample_aspect_ratio = s->sys->sar[is16_9];
01113 }
01114
01115 return s->sys->frame_size;
01116 }
01117 #endif
01118
01119
01120 static inline int dv_write_pack(enum dv_pack_type pack_id, DVVideoContext *c,
01121 uint8_t* buf)
01122 {
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141 int apt = (c->sys->pix_fmt == PIX_FMT_YUV420P ? 0 : 1);
01142
01143 uint8_t aspect = 0;
01144 if ((int)(av_q2d(c->avctx->sample_aspect_ratio) * c->avctx->width / c->avctx->height * 10) >= 17)
01145 aspect = 0x02;
01146
01147 buf[0] = (uint8_t)pack_id;
01148 switch (pack_id) {
01149 case dv_header525:
01150 case dv_header625:
01151 buf[1] = 0xf8 |
01152 (apt & 0x07);
01153 buf[2] = (0 << 7) |
01154 (0x0f << 3) |
01155 (apt & 0x07);
01156 buf[3] = (0 << 7) |
01157 (0x0f << 3) |
01158 (apt & 0x07);
01159 buf[4] = (0 << 7) |
01160 (0x0f << 3) |
01161 (apt & 0x07);
01162 break;
01163 case dv_video_source:
01164 buf[1] = 0xff;
01165 buf[2] = (1 << 7) |
01166 (1 << 6) |
01167 (3 << 4) |
01168 0xf;
01169 buf[3] = (3 << 6) |
01170 (c->sys->dsf << 5) |
01171 c->sys->video_stype;
01172 buf[4] = 0xff;
01173 break;
01174 case dv_video_control:
01175 buf[1] = (0 << 6) |
01176 0x3f;
01177 buf[2] = 0xc8 |
01178 aspect;
01179 buf[3] = (1 << 7) |
01180 (1 << 6) |
01181 (1 << 5) |
01182 (1 << 4) |
01183 0xc;
01184 buf[4] = 0xff;
01185 break;
01186 default:
01187 buf[1] = buf[2] = buf[3] = buf[4] = 0xff;
01188 }
01189 return 5;
01190 }
01191
01192 #if CONFIG_DVVIDEO_ENCODER
01193 static void dv_format_frame(DVVideoContext* c, uint8_t* buf)
01194 {
01195 int chan, i, j, k;
01196
01197 for (chan = 0; chan < c->sys->n_difchan; chan++) {
01198 for (i = 0; i < c->sys->difseg_size; i++) {
01199 memset(buf, 0xff, 80 * 6);
01200
01201
01202 buf += dv_write_dif_id(dv_sect_header, chan, i, 0, buf);
01203 buf += dv_write_pack((c->sys->dsf ? dv_header625 : dv_header525), c, buf);
01204 buf += 72;
01205
01206
01207 for (j = 0; j < 2; j++) {
01208 buf += dv_write_dif_id(dv_sect_subcode, chan, i, j, buf);
01209 for (k = 0; k < 6; k++)
01210 buf += dv_write_ssyb_id(k, (i < c->sys->difseg_size/2), buf) + 5;
01211 buf += 29;
01212 }
01213
01214
01215 for (j = 0; j < 3; j++) {
01216 buf += dv_write_dif_id(dv_sect_vaux, chan, i, j, buf);
01217 buf += dv_write_pack(dv_video_source, c, buf);
01218 buf += dv_write_pack(dv_video_control, c, buf);
01219 buf += 7*5;
01220 buf += dv_write_pack(dv_video_source, c, buf);
01221 buf += dv_write_pack(dv_video_control, c, buf);
01222 buf += 4*5 + 2;
01223 }
01224
01225
01226 for (j = 0; j < 135; j++) {
01227 if (j%15 == 0) {
01228 memset(buf, 0xff, 80);
01229 buf += dv_write_dif_id(dv_sect_audio, chan, i, j/15, buf);
01230 buf += 77;
01231 }
01232 buf += dv_write_dif_id(dv_sect_video, chan, i, j, buf);
01233 buf += 77;
01234
01235
01236
01237 }
01238 }
01239 }
01240 }
01241
01242
01243 static int dvvideo_encode_frame(AVCodecContext *c, uint8_t *buf, int buf_size,
01244 void *data)
01245 {
01246 DVVideoContext *s = c->priv_data;
01247
01248 s->sys = avpriv_dv_codec_profile(c);
01249 if (!s->sys || buf_size < s->sys->frame_size || dv_init_dynamic_tables(s->sys))
01250 return -1;
01251
01252 c->pix_fmt = s->sys->pix_fmt;
01253 s->picture = *((AVFrame *)data);
01254 s->picture.key_frame = 1;
01255 s->picture.pict_type = AV_PICTURE_TYPE_I;
01256
01257 s->buf = buf;
01258 c->execute(c, dv_encode_video_segment, s->sys->work_chunks, NULL,
01259 dv_work_pool_size(s->sys), sizeof(DVwork_chunk));
01260
01261 emms_c();
01262
01263 dv_format_frame(s, buf);
01264
01265 return s->sys->frame_size;
01266 }
01267 #endif
01268
01269 static int dvvideo_close(AVCodecContext *c)
01270 {
01271 DVVideoContext *s = c->priv_data;
01272
01273 if (s->picture.data[0])
01274 c->release_buffer(c, &s->picture);
01275
01276 return 0;
01277 }
01278
01279
01280 #if CONFIG_DVVIDEO_ENCODER
01281 AVCodec ff_dvvideo_encoder = {
01282 .name = "dvvideo",
01283 .type = AVMEDIA_TYPE_VIDEO,
01284 .id = CODEC_ID_DVVIDEO,
01285 .priv_data_size = sizeof(DVVideoContext),
01286 .init = dvvideo_init_encoder,
01287 .encode = dvvideo_encode_frame,
01288 .capabilities = CODEC_CAP_SLICE_THREADS,
01289 .pix_fmts = (const enum PixelFormat[]) {PIX_FMT_YUV411P, PIX_FMT_YUV422P, PIX_FMT_YUV420P, PIX_FMT_NONE},
01290 .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
01291 };
01292 #endif // CONFIG_DVVIDEO_ENCODER
01293
01294 #if CONFIG_DVVIDEO_DECODER
01295 AVCodec ff_dvvideo_decoder = {
01296 .name = "dvvideo",
01297 .type = AVMEDIA_TYPE_VIDEO,
01298 .id = CODEC_ID_DVVIDEO,
01299 .priv_data_size = sizeof(DVVideoContext),
01300 .init = dvvideo_init,
01301 .close = dvvideo_close,
01302 .decode = dvvideo_decode_frame,
01303 .capabilities = CODEC_CAP_DR1 | CODEC_CAP_SLICE_THREADS,
01304 .max_lowres = 3,
01305 .long_name = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
01306 };
01307 #endif