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