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         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