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