~ubuntu-dev/mplayer/ubuntu-feisty

« back to all changes in this revision

Viewing changes to libavcodec/dv.c

  • Committer: Reinhard Tartler
  • Date: 2006-07-08 08:47:54 UTC
  • Revision ID: siretart@tauware.de-20060708084754-c3ff228cc9c2d8de
upgrade to pre8

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
 * DV encoder
7
7
 * Copyright (c) 2003 Roman Shaposhnik.
8
8
 *
 
9
 * 50 Mbps (DVCPRO50) support
 
10
 * Copyright (c) 2006 Daniel Maas <dmaas@maasdigital.com>
 
11
 *
9
12
 * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth
10
13
 * of DV technical info.
11
14
 *
51
54
    void (*idct_put[2])(uint8_t *dest, int line_size, DCTELEM *block);
52
55
} DVVideoContext;
53
56
 
54
 
/* MultiThreading - applies to entire DV codec, not just the avcontext */
55
 
uint8_t** dv_anchor;
 
57
/* MultiThreading - dv_anchor applies to entire DV codec, not just the avcontext */
 
58
/* one element is needed for each video segment in a DV frame */
 
59
/* at most there are 2 DIF channels * 12 DIF sequences * 27 video segments (PAL 50Mbps) */
 
60
#define DV_ANCHOR_SIZE (2*12*27)
 
61
 
 
62
static void* dv_anchor[DV_ANCHOR_SIZE];
56
63
 
57
64
#define TEX_VLC_BITS 9
58
65
 
118
125
            return -ENOMEM;
119
126
 
120
127
        /* dv_anchor lets each thread know its Id */
121
 
        dv_anchor = av_malloc(12*27*sizeof(void*));
122
 
        if (!dv_anchor) {
123
 
            return -ENOMEM;
124
 
        }
125
 
        for (i=0; i<12*27; i++)
 
128
        for (i=0; i<DV_ANCHOR_SIZE; i++)
126
129
            dv_anchor[i] = (void*)(size_t)i;
127
130
 
128
131
        /* it's faster to include sign bit in a generic VLC parsing scheme */
238
241
    /* XXX: do it only for constant case */
239
242
    dv_build_unquantize_tables(s, dsp.idct_permutation);
240
243
 
241
 
    /* FIXME: I really don't think this should be here */
242
 
    if (dv_codec_profile(avctx))
243
 
        avctx->pix_fmt = dv_codec_profile(avctx)->pix_fmt;
244
244
    avctx->coded_frame = &s->picture;
245
245
    s->avctx= avctx;
246
246
 
253
253
typedef struct BlockInfo {
254
254
    const uint8_t *shift_table;
255
255
    const uint8_t *scan_table;
 
256
    const int *iweight_table;
256
257
    uint8_t pos; /* position in block */
257
258
    uint8_t dct_mode;
258
259
    uint8_t partial_bit_count;
295
296
    int last_index = get_bits_size(gb);
296
297
    const uint8_t *scan_table = mb->scan_table;
297
298
    const uint8_t *shift_table = mb->shift_table;
 
299
    const int *iweight_table = mb->iweight_table;
298
300
    int pos = mb->pos;
299
301
    int partial_bit_count = mb->partial_bit_count;
300
302
    int level, pos1, run, vlc_len, index;
342
344
        if (pos >= 64)
343
345
            break;
344
346
 
345
 
        assert(level);
346
347
        pos1 = scan_table[pos];
347
 
        block[pos1] = level << shift_table[pos1];
 
348
        level <<= shift_table[pos1];
 
349
 
 
350
        /* unweigh, round, and shift down */
 
351
        level = (level*iweight_table[pos] + (1 << (dv_iweight_bits-1))) >> dv_iweight_bits;
 
352
 
 
353
        block[pos1] = level;
348
354
 
349
355
        UPDATE_CACHE(re, gb);
350
356
    }
379
385
    PutBitContext pb, vs_pb;
380
386
    GetBitContext gb;
381
387
    BlockInfo mb_data[5 * 6], *mb, *mb1;
382
 
    DCTELEM sblock[5*6][64] __align8;
383
 
    uint8_t mb_bit_buffer[80 + 4] __align8; /* allow some slack */
384
 
    uint8_t vs_bit_buffer[5 * 80 + 4] __align8; /* allow some slack */
 
388
    DECLARE_ALIGNED_8(DCTELEM, sblock[5*6][64]);
 
389
    DECLARE_ALIGNED_8(uint8_t, mb_bit_buffer[80 + 4]); /* allow some slack */
 
390
    DECLARE_ALIGNED_8(uint8_t, vs_bit_buffer[5 * 80 + 4]); /* allow some slack */
385
391
    const int log2_blocksize= 3-s->avctx->lowres;
386
392
 
387
393
    assert((((int)mb_bit_buffer)&7)==0);
410
416
            dct_mode = get_bits1(&gb);
411
417
            mb->dct_mode = dct_mode;
412
418
            mb->scan_table = s->dv_zigzag[dct_mode];
 
419
            mb->iweight_table = dct_mode ? dv_iweight_248 : dv_iweight_88;
413
420
            class1 = get_bits(&gb, 2);
414
421
            mb->shift_table = s->dv_idct_shift[class1 == 3][dct_mode]
415
422
                [quant + dv_quant_offset[class1]];
488
495
        v = *mb_pos_ptr++;
489
496
        mb_x = v & 0xff;
490
497
        mb_y = v >> 8;
491
 
        y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x)<<log2_blocksize);
492
 
        if (s->sys->pix_fmt == PIX_FMT_YUV411P)
 
498
        if (s->sys->pix_fmt == PIX_FMT_YUV422P) {
 
499
            y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + (mb_x>>1))<<log2_blocksize);
493
500
            c_offset = ((mb_y * s->picture.linesize[1] + (mb_x >> 2))<<log2_blocksize);
494
 
        else
495
 
            c_offset = (((mb_y >> 1) * s->picture.linesize[1] + (mb_x >> 1))<<log2_blocksize);
 
501
        } else { /* 4:1:1 or 4:2:0 */
 
502
            y_ptr = s->picture.data[0] + ((mb_y * s->picture.linesize[0] + mb_x)<<log2_blocksize);
 
503
            if (s->sys->pix_fmt == PIX_FMT_YUV411P)
 
504
                c_offset = ((mb_y * s->picture.linesize[1] + (mb_x >> 2))<<log2_blocksize);
 
505
            else /* 4:2:0 */
 
506
                c_offset = (((mb_y >> 1) * s->picture.linesize[1] + (mb_x >> 1))<<log2_blocksize);
 
507
        }
496
508
        for(j = 0;j < 6; j++) {
497
509
            idct_put = s->idct_put[mb->dct_mode && log2_blocksize==3];
498
 
            if (j < 4) {
499
 
                if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) {
500
 
                    /* NOTE: at end of line, the macroblock is handled as 420 */
501
 
                    idct_put(y_ptr + (j<<log2_blocksize), s->picture.linesize[0], block);
502
 
                } else {
503
 
                    idct_put(y_ptr + (((j & 1) + (j >> 1) * s->picture.linesize[0])<<log2_blocksize),
 
510
            if (s->sys->pix_fmt == PIX_FMT_YUV422P) { /* 4:2:2 */
 
511
                if (j == 0 || j == 2) {
 
512
                    /* Y0 Y1 */
 
513
                    idct_put(y_ptr + ((j >> 1)<<log2_blocksize),
504
514
                             s->picture.linesize[0], block);
505
 
                }
506
 
            } else {
507
 
                if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
508
 
                    uint64_t aligned_pixels[64/8];
509
 
                    uint8_t *pixels= (uint8_t*)aligned_pixels;
510
 
                    uint8_t *c_ptr, *c_ptr1, *ptr, *ptr1;
511
 
                    int x, y, linesize;
512
 
                    /* NOTE: at end of line, the macroblock is handled as 420 */
513
 
                    idct_put(pixels, 8, block);
514
 
                    linesize = s->picture.linesize[6 - j];
515
 
                    c_ptr = s->picture.data[6 - j] + c_offset;
516
 
                    ptr = pixels;
517
 
                    for(y = 0;y < (1<<log2_blocksize); y++) {
518
 
                        ptr1= ptr + (1<<(log2_blocksize-1));
519
 
                        c_ptr1 = c_ptr + (linesize<<log2_blocksize);
520
 
                        for(x=0; x < (1<<(log2_blocksize-1)); x++){
521
 
                            c_ptr[x]= ptr[x]; c_ptr1[x]= ptr1[x];
522
 
                        }
523
 
                        c_ptr += linesize;
524
 
                        ptr += 8;
525
 
                    }
526
 
                } else {
527
 
                    /* don't ask me why they inverted Cb and Cr ! */
 
515
                } else if(j > 3) {
 
516
                    /* Cr Cb */
528
517
                    idct_put(s->picture.data[6 - j] + c_offset,
529
518
                             s->picture.linesize[6 - j], block);
530
519
                }
 
520
                /* note: j=1 and j=3 are "dummy" blocks in 4:2:2 */
 
521
            } else { /* 4:1:1 or 4:2:0 */
 
522
                if (j < 4) {
 
523
                    if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) {
 
524
                        /* NOTE: at end of line, the macroblock is handled as 420 */
 
525
                        idct_put(y_ptr + (j<<log2_blocksize), s->picture.linesize[0], block);
 
526
                    } else {
 
527
                        idct_put(y_ptr + (((j & 1) + (j >> 1) * s->picture.linesize[0])<<log2_blocksize),
 
528
                                 s->picture.linesize[0], block);
 
529
                    }
 
530
                } else {
 
531
                    if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8)) {
 
532
                        uint64_t aligned_pixels[64/8];
 
533
                        uint8_t *pixels= (uint8_t*)aligned_pixels;
 
534
                        uint8_t *c_ptr, *c_ptr1, *ptr, *ptr1;
 
535
                        int x, y, linesize;
 
536
                        /* NOTE: at end of line, the macroblock is handled as 420 */
 
537
                        idct_put(pixels, 8, block);
 
538
                        linesize = s->picture.linesize[6 - j];
 
539
                        c_ptr = s->picture.data[6 - j] + c_offset;
 
540
                        ptr = pixels;
 
541
                        for(y = 0;y < (1<<log2_blocksize); y++) {
 
542
                            ptr1= ptr + (1<<(log2_blocksize-1));
 
543
                            c_ptr1 = c_ptr + (linesize<<log2_blocksize);
 
544
                            for(x=0; x < (1<<(log2_blocksize-1)); x++){
 
545
                                c_ptr[x]= ptr[x]; c_ptr1[x]= ptr1[x];
 
546
                            }
 
547
                            c_ptr += linesize;
 
548
                            ptr += 8;
 
549
                        }
 
550
                    } else {
 
551
                        /* don't ask me why they inverted Cb and Cr ! */
 
552
                        idct_put(s->picture.data[6 - j] + c_offset,
 
553
                                 s->picture.linesize[6 - j], block);
 
554
                    }
 
555
                }
531
556
            }
532
557
            block += 64;
533
558
            mb++;
648
673
}
649
674
 
650
675
static always_inline void dv_set_class_number(DCTELEM* blk, EncBlockInfo* bi,
651
 
                                              const uint8_t* zigzag_scan, int bias)
 
676
                                              const uint8_t* zigzag_scan, const int *weight, int bias)
652
677
{
653
678
    int i, area;
 
679
    /* We offer two different methods for class number assignment: the
 
680
       method suggested in SMPTE 314M Table 22, and an improved
 
681
       method. The SMPTE method is very conservative; it assigns class
 
682
       3 (i.e. severe quantization) to any block where the largest AC
 
683
       component is greater than 36. ffmpeg's DV encoder tracks AC bit
 
684
       consumption precisely, so there is no need to bias most blocks
 
685
       towards strongly lossy compression. Instead, we assign class 2
 
686
       to most blocks, and use class 3 only when strictly necessary
 
687
       (for blocks whose largest AC component exceeds 255). */
 
688
 
 
689
#if 0 /* SMPTE spec method */
654
690
    static const int classes[] = {12, 24, 36, 0xffff};
655
 
    int max=12;
 
691
#else /* improved ffmpeg method */
 
692
    static const int classes[] = {-1, -1, 255, 0xffff};
 
693
#endif
 
694
    int max=classes[0];
656
695
    int prev=0;
657
696
 
658
697
    bi->mb[0] = blk[0];
665
704
 
666
705
          if (level+15 > 30U) {
667
706
              bi->sign[i] = (level>>31)&1;
668
 
              bi->mb[i] = level= ABS(level)>>4;
 
707
              /* weigh it and and shift down into range, adding for rounding */
 
708
              /* the extra division by a factor of 2^4 reverses the 8x expansion of the DCT
 
709
                 AND the 2x doubling of the weights */
 
710
              level = (ABS(level) * weight[i] + (1<<(dv_weight_bits+3))) >> (dv_weight_bits+4);
 
711
              bi->mb[i] = level;
669
712
              if(level>max) max= level;
670
713
              bi->bit_size[area] += dv_rl2vlc_size(i - prev  - 1, level);
671
714
              bi->next[prev]= i;
728
771
static inline void dv_guess_qnos(EncBlockInfo* blks, int* qnos)
729
772
{
730
773
    int size[5];
731
 
    int i, j, k, a, prev;
 
774
    int i, j, k, a, prev, a2;
732
775
    EncBlockInfo* b;
733
776
 
 
777
    size[0] = size[1] = size[2] = size[3] = size[4] = 1<<24;
734
778
    do {
735
779
       b = blks;
736
780
       for (i=0; i<5; i++) {
745
789
                    b->bit_size[a] = 1; // 4 areas 4 bits for EOB :)
746
790
                    b->area_q[a]++;
747
791
                    prev= b->prev[a];
 
792
                    assert(b->next[prev] >= mb_area_start[a+1] || b->mb[prev]);
748
793
                    for (k= b->next[prev] ; k<mb_area_start[a+1]; k= b->next[k]) {
749
794
                       b->mb[k] >>= 1;
750
795
                       if (b->mb[k]) {
751
796
                           b->bit_size[a] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
752
797
                           prev= k;
753
798
                       } else {
 
799
                           if(b->next[k] >= mb_area_start[a+1] && b->next[k]<64){
 
800
                                for(a2=a+1; b->next[k] >= mb_area_start[a2+1]; a2++)
 
801
                                    b->prev[a2] = prev;
 
802
                                assert(a2<4);
 
803
                                assert(b->mb[b->next[k]]);
 
804
                                b->bit_size[a2] += dv_rl2vlc_size(b->next[k] - prev - 1, b->mb[b->next[k]])
 
805
                                                  -dv_rl2vlc_size(b->next[k] -    k - 1, b->mb[b->next[k]]);
 
806
                                assert(b->prev[a2]==k && (a2+1 >= 4 || b->prev[a2+1]!=k));
 
807
                                b->prev[a2] = prev;
 
808
                           }
754
809
                           b->next[prev] = b->next[k];
755
810
                       }
756
811
                    }
759
814
                size[i] += b->bit_size[a];
760
815
             }
761
816
          }
 
817
          if(vs_total_ac_bits >= size[0] + size[1] + size[2] + size[3] + size[4])
 
818
                return;
762
819
       }
763
 
    } while ((vs_total_ac_bits < size[0] + size[1] + size[2] + size[3] + size[4]) &&
764
 
             (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4]));
 
820
    } while (qnos[0]|qnos[1]|qnos[2]|qnos[3]|qnos[4]);
 
821
 
 
822
 
 
823
    for(a=2; a==2 || vs_total_ac_bits < size[0]; a+=a){
 
824
        b = blks;
 
825
        size[0] = 5*6*4; //EOB
 
826
        for (j=0; j<6*5; j++, b++) {
 
827
            prev= b->prev[0];
 
828
            for (k= b->next[prev]; k<64; k= b->next[k]) {
 
829
                if(b->mb[k] < a && b->mb[k] > -a){
 
830
                    b->next[prev] = b->next[k];
 
831
                }else{
 
832
                    size[0] += dv_rl2vlc_size(k - prev - 1, b->mb[k]);
 
833
                    prev= k;
 
834
                }
 
835
            }
 
836
        }
 
837
    }
765
838
}
766
839
 
767
 
/*
768
 
 * This is a very rough initial implementaion. The performance is
769
 
 * horrible and the weighting is missing. But it's missing from the
770
 
 * decoding step also -- so at least we're on the same page with decoder ;-)
771
 
 */
772
840
static inline void dv_encode_video_segment(DVVideoContext *s,
773
841
                                           uint8_t *dif,
774
842
                                           const uint16_t *mb_pos_ptr)
779
847
    uint8_t*  data;
780
848
    uint8_t*  ptr;
781
849
    int       do_edge_wrap;
782
 
    DCTELEM   block[64] __align8;
 
850
    DECLARE_ALIGNED_8(DCTELEM, block[64]);
783
851
    EncBlockInfo  enc_blks[5*6];
784
852
    PutBitContext pbs[5*6];
785
853
    PutBitContext* pb;
795
863
        v = *mb_pos_ptr++;
796
864
        mb_x = v & 0xff;
797
865
        mb_y = v >> 8;
798
 
        y_ptr = s->picture.data[0] + (mb_y * s->picture.linesize[0] * 8) + (mb_x * 8);
799
 
        c_offset = (s->sys->pix_fmt == PIX_FMT_YUV411P) ?
800
 
                   ((mb_y * s->picture.linesize[1] * 8) + ((mb_x >> 2) * 8)) :
801
 
                   (((mb_y >> 1) * s->picture.linesize[1] * 8) + ((mb_x >> 1) * 8));
 
866
        if (s->sys->pix_fmt == PIX_FMT_YUV422P) {
 
867
            y_ptr = s->picture.data[0] + (mb_y * s->picture.linesize[0] * 8) + (mb_x * 4);
 
868
        } else { /* 4:1:1 */
 
869
            y_ptr = s->picture.data[0] + (mb_y * s->picture.linesize[0] * 8) + (mb_x * 8);
 
870
        }
 
871
        if (s->sys->pix_fmt == PIX_FMT_YUV420P) {
 
872
            c_offset = (((mb_y >> 1) * s->picture.linesize[1] * 8) + ((mb_x >> 1) * 8));
 
873
        } else { /* 4:2:2 or 4:1:1 */
 
874
            c_offset = ((mb_y * s->picture.linesize[1] * 8) + ((mb_x >> 2) * 8));
 
875
        }
802
876
        do_edge_wrap = 0;
803
877
        qnos[mb_index] = 15; /* No quantization */
804
878
        ptr = dif + mb_index*80 + 4;
805
879
        for(j = 0;j < 6; j++) {
806
 
            if (j < 4) {  /* Four Y blocks */
807
 
                /* NOTE: at end of line, the macroblock is handled as 420 */
808
 
                if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) {
809
 
                    data = y_ptr + (j * 8);
 
880
            int dummy = 0;
 
881
            if (s->sys->pix_fmt == PIX_FMT_YUV422P) { /* 4:2:2 */
 
882
                if (j == 0 || j == 2) {
 
883
                    /* Y0 Y1 */
 
884
                    data = y_ptr + ((j>>1) * 8);
 
885
                    linesize = s->picture.linesize[0];
 
886
                } else if (j > 3) {
 
887
                    /* Cr Cb */
 
888
                    data = s->picture.data[6 - j] + c_offset;
 
889
                    linesize = s->picture.linesize[6 - j];
810
890
                } else {
811
 
                    data = y_ptr + ((j & 1) * 8) + ((j >> 1) * 8 * s->picture.linesize[0]);
812
 
                }
813
 
                linesize = s->picture.linesize[0];
814
 
            } else {      /* Cr and Cb blocks */
815
 
                /* don't ask Fabrice why they inverted Cb and Cr ! */
816
 
                data = s->picture.data[6 - j] + c_offset;
817
 
                linesize = s->picture.linesize[6 - j];
818
 
                if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8))
819
 
                    do_edge_wrap = 1;
 
891
                    /* j=1 and j=3 are "dummy" blocks, used for AC data only */
 
892
                    data = 0;
 
893
                    linesize = 0;
 
894
                    dummy = 1;
 
895
                }
 
896
            } else { /* 4:1:1 or 4:2:0 */
 
897
                if (j < 4) {  /* Four Y blocks */
 
898
                    /* NOTE: at end of line, the macroblock is handled as 420 */
 
899
                    if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x < (704 / 8)) {
 
900
                        data = y_ptr + (j * 8);
 
901
                    } else {
 
902
                        data = y_ptr + ((j & 1) * 8) + ((j >> 1) * 8 * s->picture.linesize[0]);
 
903
                    }
 
904
                    linesize = s->picture.linesize[0];
 
905
                } else {      /* Cr and Cb blocks */
 
906
                    /* don't ask Fabrice why they inverted Cb and Cr ! */
 
907
                    data = s->picture.data[6 - j] + c_offset;
 
908
                    linesize = s->picture.linesize[6 - j];
 
909
                    if (s->sys->pix_fmt == PIX_FMT_YUV411P && mb_x >= (704 / 8))
 
910
                        do_edge_wrap = 1;
 
911
                }
820
912
            }
821
913
 
822
914
            /* Everything is set up -- now just copy data -> DCT block */
831
923
                   b += 8;
832
924
                }
833
925
            } else {             /* Simple copy: 8x8 -> 8x8 */
834
 
                s->get_pixels(block, data, linesize);
 
926
                if (!dummy)
 
927
                    s->get_pixels(block, data, linesize);
835
928
            }
836
929
 
837
930
            if(s->avctx->flags & CODEC_FLAG_INTERLACED_DCT)
843
936
            enc_blk->partial_bit_buffer = 0;
844
937
            enc_blk->cur_ac = 0;
845
938
 
846
 
            s->fdct[enc_blk->dct_mode](block);
 
939
            if (dummy) {
 
940
                /* We rely on the fact that encoding all zeros leads to an immediate EOB,
 
941
                   which is precisely what the spec calls for in the "dummy" blocks. */
 
942
                memset(block, 0, sizeof(block));
 
943
            } else {
 
944
                s->fdct[enc_blk->dct_mode](block);
 
945
            }
847
946
 
848
947
            dv_set_class_number(block, enc_blk,
849
 
                                enc_blk->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct, j/4);
 
948
                                enc_blk->dct_mode ? ff_zigzag248_direct : ff_zigzag_direct,
 
949
                                enc_blk->dct_mode ? dv_weight_248 : dv_weight_88,
 
950
                                j/4);
850
951
 
851
952
            init_put_bits(pb, ptr, block_sizes[j]/8);
852
953
            put_bits(pb, 9, (uint16_t)(((enc_blk->mb[0] >> 3) - 1024 + 2) >> 2));
886
987
    for (j=0; j<5*6; j++) {
887
988
       if (enc_blks[j].partial_bit_count)
888
989
           pb=dv_encode_ac(&enc_blks[j], pb, &pbs[6*5]);
 
990
       if (enc_blks[j].partial_bit_count)
 
991
            av_log(NULL, AV_LOG_ERROR, "ac bitstream overflow\n");
889
992
    }
890
993
 
891
994
    for (j=0; j<5*6; j++)
896
999
{
897
1000
    DVVideoContext *s = avctx->priv_data;
898
1001
    int slice = (size_t)sl;
899
 
    dv_decode_video_segment(s, &s->buf[((slice/27)*6+(slice/3)+slice*5+7)*80],
 
1002
 
 
1003
    /* which DIF channel is this? */
 
1004
    int chan = slice / (s->sys->difseg_size * 27);
 
1005
 
 
1006
    /* slice within the DIF channel */
 
1007
    int chan_slice = slice % (s->sys->difseg_size * 27);
 
1008
 
 
1009
    /* byte offset of this channel's data */
 
1010
    int chan_offset = chan * s->sys->difseg_size * 150 * 80;
 
1011
 
 
1012
    dv_decode_video_segment(s, &s->buf[((chan_slice/27)*6+(chan_slice/3)+chan_slice*5+7)*80 + chan_offset],
900
1013
                            &s->sys->video_place[slice*5]);
901
1014
    return 0;
902
1015
}
905
1018
{
906
1019
    DVVideoContext *s = avctx->priv_data;
907
1020
    int slice = (size_t)sl;
908
 
    dv_encode_video_segment(s, &s->buf[((slice/27)*6+(slice/3)+slice*5+7)*80],
 
1021
 
 
1022
    /* which DIF channel is this? */
 
1023
    int chan = slice / (s->sys->difseg_size * 27);
 
1024
 
 
1025
    /* slice within the DIF channel */
 
1026
    int chan_slice = slice % (s->sys->difseg_size * 27);
 
1027
 
 
1028
    /* byte offset of this channel's data */
 
1029
    int chan_offset = chan * s->sys->difseg_size * 150 * 80;
 
1030
 
 
1031
    dv_encode_video_segment(s, &s->buf[((chan_slice/27)*6+(chan_slice/3)+chan_slice*5+7)*80 + chan_offset],
909
1032
                            &s->sys->video_place[slice*5]);
910
1033
    return 0;
911
1034
}
912
1035
 
913
1036
/* NOTE: exactly one frame must be given (120000 bytes for NTSC,
914
 
   144000 bytes for PAL) */
 
1037
   144000 bytes for PAL - or twice those for 50Mbps) */
915
1038
static int dvvideo_decode_frame(AVCodecContext *avctx,
916
1039
                                 void *data, int *data_size,
917
1040
                                 uint8_t *buf, int buf_size)
939
1062
 
940
1063
    s->buf = buf;
941
1064
    avctx->execute(avctx, dv_decode_mt, (void**)&dv_anchor[0], NULL,
942
 
                   s->sys->difseg_size * 27);
 
1065
                   s->sys->n_difchan * s->sys->difseg_size * 27);
943
1066
 
944
1067
    emms_c();
945
1068
 
968
1091
 
969
1092
    s->buf = buf;
970
1093
    c->execute(c, dv_encode_mt, (void**)&dv_anchor[0], NULL,
971
 
               s->sys->difseg_size * 27);
 
1094
               s->sys->n_difchan * s->sys->difseg_size * 27);
972
1095
 
973
1096
    emms_c();
 
1097
 
 
1098
    /* Fill in just enough of the header for dv_frame_profile() to
 
1099
       return the correct result, so that the frame can be decoded
 
1100
       correctly. The rest of the metadata is filled in by the dvvideo
 
1101
       avformat. (this should probably change so that encode_frame()
 
1102
       fills in ALL of the metadata - e.g. for Quicktime-wrapped DV
 
1103
       streams) */
 
1104
 
 
1105
    /* NTSC/PAL format */
 
1106
    buf[3] = s->sys->dsf ? 0x80 : 0x00;
 
1107
 
 
1108
    /* 25Mbps or 50Mbps */
 
1109
    buf[80*5 + 48 + 3] = (s->sys->pix_fmt == PIX_FMT_YUV422P) ? 0x4 : 0x0;
 
1110
 
974
1111
    return s->sys->frame_size;
975
1112
}
976
1113