Home | History | Annotate | Download | only in nouveau
      1 /*
      2  * Copyright 2011-2013 Maarten Lankhorst
      3  *
      4  * Permission is hereby granted, free of charge, to any person obtaining a
      5  * copy of this software and associated documentation files (the "Software"),
      6  * to deal in the Software without restriction, including without limitation
      7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
      8  * and/or sell copies of the Software, and to permit persons to whom the
      9  * Software is furnished to do so, subject to the following conditions:
     10  *
     11  * The above copyright notice and this permission notice shall be included in
     12  * all copies or substantial portions of the Software.
     13  *
     14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
     17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
     18  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
     19  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
     20  * OTHER DEALINGS IN THE SOFTWARE.
     21  */
     22 
     23 #include "nouveau_vp3_video.h"
     24 
     25 struct mpeg12_picparm_vp {
     26    uint16_t width; // 00 in mb units
     27    uint16_t height; // 02 in mb units
     28 
     29    uint32_t unk04; // 04 stride for Y?
     30    uint32_t unk08; // 08 stride for CbCr?
     31 
     32    uint32_t ofs[6]; // 1c..20 ofs
     33    uint32_t bucket_size; // 24
     34    uint32_t inter_ring_data_size; // 28
     35    uint16_t unk2c; // 2c
     36    uint16_t alternate_scan; // 2e
     37    uint16_t unk30; // 30 not seen set yet
     38    uint16_t picture_structure; // 32
     39    uint16_t pad2[3];
     40    uint16_t unk3a; // 3a set on I frame?
     41 
     42    uint32_t f_code[4]; // 3c
     43    uint32_t picture_coding_type; // 4c
     44    uint32_t intra_dc_precision; // 50
     45    uint32_t q_scale_type; // 54
     46    uint32_t top_field_first; // 58
     47    uint32_t full_pel_forward_vector; // 5c
     48    uint32_t full_pel_backward_vector; // 60
     49    uint8_t intra_quantizer_matrix[0x40]; // 64
     50    uint8_t non_intra_quantizer_matrix[0x40]; // a4
     51 };
     52 
     53 struct mpeg4_picparm_vp {
     54    uint32_t width; // 00 in normal units
     55    uint32_t height; // 04 in normal units
     56    uint32_t unk08; // stride 1
     57    uint32_t unk0c; // stride 2
     58    uint32_t ofs[6]; // 10..24 ofs
     59    uint32_t bucket_size; // 28
     60    uint32_t pad1; // 2c, pad
     61    uint32_t pad2; // 30
     62    uint32_t inter_ring_data_size; // 34
     63 
     64    uint32_t trd[2]; // 38, 3c
     65    uint32_t trb[2]; // 40, 44
     66    uint32_t u48; // XXX codec selection? Should test with different values of VdpDecoderProfile
     67    uint16_t f_code_fw; // 4c
     68    uint16_t f_code_bw; // 4e
     69    uint8_t interlaced; // 50
     70 
     71    uint8_t quant_type; // bool, written to 528
     72    uint8_t quarter_sample; // bool, written to 548
     73    uint8_t short_video_header; // bool, negated written to 528 shifted by 1
     74    uint8_t u54; // bool, written to 0x740
     75    uint8_t vop_coding_type; // 55
     76    uint8_t rounding_control; // 56
     77    uint8_t alternate_vertical_scan_flag; // 57 bool
     78    uint8_t top_field_first; // bool, written to vuc
     79 
     80    uint8_t pad4[3]; // 59, 5a, 5b, contains garbage on blob
     81 
     82    uint32_t intra[0x10]; // 5c
     83    uint32_t non_intra[0x10]; // 9c
     84    uint32_t pad5[0x10]; // bc what does this do?
     85    // udc..uff pad?
     86 };
     87 
     88 // Full version, with data pumped from BSP
     89 struct vc1_picparm_vp {
     90    uint32_t bucket_size; // 00
     91    uint32_t pad; // 04
     92 
     93    uint32_t inter_ring_data_size; // 08
     94    uint32_t unk0c; // stride 1
     95    uint32_t unk10; // stride 2
     96    uint32_t ofs[6]; // 14..28 ofs
     97 
     98    uint16_t width; // 2c
     99    uint16_t height; // 2e
    100 
    101    uint8_t profile; // 30 0 = simple, 1 = main, 2 = advanced
    102    uint8_t loopfilter; // 31 written into vuc
    103    uint8_t fastuvmc; // 32, written into vuc
    104    uint8_t dquant; // 33
    105 
    106    uint8_t overlap; // 34
    107    uint8_t quantizer; // 35
    108    uint8_t u36; // 36, bool
    109    uint8_t pad2; // 37, to align to 0x38
    110 };
    111 
    112 struct h264_picparm_vp { // 700..a00
    113    uint16_t width, height;
    114    uint32_t stride1, stride2; // 04 08
    115    uint32_t ofs[6]; // 0c..24 in-image offset
    116 
    117    uint32_t tmp_stride;
    118    uint32_t bucket_size; // 28 bucket size
    119    uint32_t inter_ring_data_size; // 2c
    120 
    121    unsigned mb_adaptive_frame_field_flag : 1; // 0
    122    unsigned direct_8x8_inference_flag : 1; // 1 0x02: into vuc ofs 56
    123    unsigned weighted_pred_flag : 1; // 2 0x04
    124    unsigned constrained_intra_pred_flag : 1; // 3 0x08: into vuc ofs 68
    125    unsigned is_reference : 1; // 4
    126    unsigned interlace : 1; // 5 field_pic_flag
    127    unsigned bottom_field_flag : 1; // 6
    128    unsigned second_field : 1; // 7 0x80: nfi yet
    129 
    130    signed log2_max_frame_num_minus4 : 4; // 31 0..3
    131    unsigned chroma_format_idc : 2; // 31 4..5
    132    unsigned pic_order_cnt_type : 2; // 31 6..7
    133    signed pic_init_qp_minus26 : 6; // 32 0..5
    134    signed chroma_qp_index_offset : 5; // 32 6..10
    135    signed second_chroma_qp_index_offset : 5; // 32 11..15
    136 
    137    unsigned weighted_bipred_idc : 2; // 34 0..1
    138    unsigned fifo_dec_index : 7; // 34 2..8
    139    unsigned tmp_idx : 5; // 34 9..13
    140    unsigned frame_number : 16; // 34 14..29
    141    unsigned u34_3030 : 1; // 34 30..30 pp.u34[30:30]
    142    unsigned u34_3131 : 1; // 34 31..31 pad?
    143 
    144    uint32_t field_order_cnt[2]; // 38, 3c
    145 
    146    struct { // 40
    147       unsigned fifo_idx : 7; // 00 0..6
    148       unsigned tmp_idx : 5; // 00 7..11
    149       unsigned top_is_reference : 1; // 00 12
    150       unsigned bottom_is_reference : 1; // 00 13
    151       unsigned is_long_term : 1; // 00 14
    152       unsigned notseenyet : 1; // 00 15 pad?
    153       unsigned field_pic_flag : 1; // 00 16
    154       unsigned top_field_marking : 4; // 00 17..20
    155       unsigned bottom_field_marking : 4; // 00 21..24
    156       unsigned pad : 7; // 00 d25..31
    157 
    158       uint32_t field_order_cnt[2]; // 04,08
    159       uint32_t frame_idx; // 0c
    160    } refs[0x10];
    161 
    162    uint8_t m4x4[6][16]; // 140
    163    uint8_t m8x8[2][64]; // 1a0
    164    uint32_t u220; // 220 number of extra reorder_list to append?
    165    uint8_t u224[0x20]; // 224..244 reorder_list append ?
    166    uint8_t nfi244[0xb0]; // add some pad to make sure nulls are read
    167 };
    168 
    169 static void
    170 nouveau_vp3_handle_references(struct nouveau_vp3_decoder *dec, struct nouveau_vp3_video_buffer *refs[16], unsigned seq, struct nouveau_vp3_video_buffer *target)
    171 {
    172    unsigned i, idx, empty_spot = ~0;
    173 
    174    for (i = 0; i < dec->base.max_references; ++i) {
    175       if (!refs[i])
    176          continue;
    177 
    178       idx = refs[i]->valid_ref;
    179       //debug_printf("ref[%i] %p in slot %i\n", i, refs[i], idx);
    180 
    181       if (dec->refs[idx].vidbuf != refs[i]) {
    182          debug_printf("%p is not a real ref\n", refs[i]);
    183          // FIXME: Maybe do m2mf copy here if a application really depends on it?
    184          continue;
    185       }
    186 
    187       assert(dec->refs[idx].vidbuf == refs[i]);
    188       dec->refs[idx].last_used = seq;
    189    }
    190 
    191    if (dec->refs[target->valid_ref].vidbuf == target) {
    192       dec->refs[target->valid_ref].last_used = seq;
    193       return;
    194    }
    195 
    196    /* Try to find a real empty spot first, there should be one..
    197     */
    198    for (i = 0; i < dec->base.max_references + 1; ++i) {
    199       if (dec->refs[i].vidbuf == target) {
    200          empty_spot = i;
    201          break;
    202       } else if (!dec->refs[i].last_used) {
    203          empty_spot = i;
    204       } else if (empty_spot == ~0U && dec->refs[i].last_used != seq)
    205          empty_spot = i;
    206    }
    207 
    208    assert(empty_spot < dec->base.max_references+1);
    209    dec->refs[empty_spot].last_used = seq;
    210 //   debug_printf("Kicked %p to add %p to slot %i\n", dec->refs[empty_spot].vidbuf, target, empty_spot);
    211    dec->refs[empty_spot].vidbuf = target;
    212    dec->refs[empty_spot].decoded_bottom = dec->refs[empty_spot].decoded_top = 0;
    213    target->valid_ref = empty_spot;
    214 }
    215 
    216 static uint32_t
    217 nouveau_vp3_fill_picparm_mpeg12_vp(struct nouveau_vp3_decoder *dec,
    218                                    struct pipe_mpeg12_picture_desc *desc,
    219                                    struct nouveau_vp3_video_buffer *refs[16],
    220                                    unsigned *is_ref,
    221                                    char *map)
    222 {
    223    struct mpeg12_picparm_vp pic_vp_stub = {}, *pic_vp = &pic_vp_stub;
    224    uint32_t i, ret = 0x01010, ring; // !async_shutdown << 16 | watchdog << 12 | irq_record << 4 | unk;
    225    assert(!(dec->base.width & 0xf));
    226    *is_ref = desc->picture_coding_type <= 2;
    227 
    228    if (dec->base.profile == PIPE_VIDEO_PROFILE_MPEG1)
    229       pic_vp->picture_structure = 3;
    230    else
    231       pic_vp->picture_structure = desc->picture_structure;
    232 
    233    assert(desc->picture_structure != 4);
    234    if (desc->picture_structure == 4) // Untested, but should work
    235       ret |= 0x100;
    236    pic_vp->width = mb(dec->base.width);
    237    pic_vp->height = mb(dec->base.height);
    238    pic_vp->unk08 = pic_vp->unk04 = (dec->base.width+0xf)&~0xf; // Stride
    239 
    240    nouveau_vp3_ycbcr_offsets(dec, &pic_vp->ofs[1], &pic_vp->ofs[3], &pic_vp->ofs[4]);
    241    pic_vp->ofs[5] = pic_vp->ofs[3];
    242    pic_vp->ofs[0] = pic_vp->ofs[2] = 0;
    243    nouveau_vp3_inter_sizes(dec, 1, &ring, &pic_vp->bucket_size, &pic_vp->inter_ring_data_size);
    244 
    245    pic_vp->alternate_scan = desc->alternate_scan;
    246    pic_vp->pad2[0] = pic_vp->pad2[1] = pic_vp->pad2[2] = 0;
    247    pic_vp->unk30 = desc->picture_structure < 3 && (desc->picture_structure == 2 - desc->top_field_first);
    248    pic_vp->unk3a = (desc->picture_coding_type == 1);
    249    for (i = 0; i < 4; ++i)
    250       pic_vp->f_code[i] = desc->f_code[i/2][i%2] + 1; // FU
    251    pic_vp->picture_coding_type = desc->picture_coding_type;
    252    pic_vp->intra_dc_precision = desc->intra_dc_precision;
    253    pic_vp->q_scale_type = desc->q_scale_type;
    254    pic_vp->top_field_first = desc->top_field_first;
    255    pic_vp->full_pel_forward_vector = desc->full_pel_forward_vector;
    256    pic_vp->full_pel_backward_vector = desc->full_pel_backward_vector;
    257    memcpy(pic_vp->intra_quantizer_matrix, desc->intra_matrix, 0x40);
    258    memcpy(pic_vp->non_intra_quantizer_matrix, desc->non_intra_matrix, 0x40);
    259    memcpy(map, pic_vp, sizeof(*pic_vp));
    260    refs[0] = (struct nouveau_vp3_video_buffer *)desc->ref[0];
    261    refs[!!refs[0]] = (struct nouveau_vp3_video_buffer *)desc->ref[1];
    262    return ret | (dec->base.profile != PIPE_VIDEO_PROFILE_MPEG1);
    263 }
    264 
    265 static uint32_t
    266 nouveau_vp3_fill_picparm_mpeg4_vp(struct nouveau_vp3_decoder *dec,
    267                                   struct pipe_mpeg4_picture_desc *desc,
    268                                   struct nouveau_vp3_video_buffer *refs[16],
    269                                   unsigned *is_ref,
    270                                   char *map)
    271 {
    272    struct mpeg4_picparm_vp pic_vp_stub = {}, *pic_vp = &pic_vp_stub;
    273    uint32_t ring, ret = 0x01014; // !async_shutdown << 16 | watchdog << 12 | irq_record << 4 | unk;
    274    *is_ref = desc->vop_coding_type <= 1;
    275 
    276    pic_vp->width = dec->base.width;
    277    pic_vp->height = mb(dec->base.height)<<4;
    278    pic_vp->unk0c = pic_vp->unk08 = mb(dec->base.width)<<4; // Stride
    279 
    280    nouveau_vp3_ycbcr_offsets(dec, &pic_vp->ofs[1], &pic_vp->ofs[3], &pic_vp->ofs[4]);
    281    pic_vp->ofs[5] = pic_vp->ofs[3];
    282    pic_vp->ofs[0] = pic_vp->ofs[2] = 0;
    283    pic_vp->pad1 = pic_vp->pad2 = 0;
    284    nouveau_vp3_inter_sizes(dec, 1, &ring, &pic_vp->bucket_size, &pic_vp->inter_ring_data_size);
    285 
    286    pic_vp->trd[0] = desc->trd[0];
    287    pic_vp->trd[1] = desc->trd[1];
    288    pic_vp->trb[0] = desc->trb[0];
    289    pic_vp->trb[1] = desc->trb[1];
    290    pic_vp->u48 = 0; // Codec?
    291    pic_vp->pad1 = pic_vp->pad2 = 0;
    292    pic_vp->f_code_fw = desc->vop_fcode_forward;
    293    pic_vp->f_code_bw = desc->vop_fcode_backward;
    294    pic_vp->interlaced = desc->interlaced;
    295    pic_vp->quant_type = desc->quant_type;
    296    pic_vp->quarter_sample = desc->quarter_sample;
    297    pic_vp->short_video_header = desc->short_video_header;
    298    pic_vp->u54 = 0;
    299    pic_vp->vop_coding_type = desc->vop_coding_type;
    300    pic_vp->rounding_control = desc->rounding_control;
    301    pic_vp->alternate_vertical_scan_flag = desc->alternate_vertical_scan_flag;
    302    pic_vp->top_field_first = desc->top_field_first;
    303 
    304    memcpy(pic_vp->intra, desc->intra_matrix, 0x40);
    305    memcpy(pic_vp->non_intra, desc->non_intra_matrix, 0x40);
    306    memcpy(map, pic_vp, sizeof(*pic_vp));
    307    refs[0] = (struct nouveau_vp3_video_buffer *)desc->ref[0];
    308    refs[!!refs[0]] = (struct nouveau_vp3_video_buffer *)desc->ref[1];
    309    return ret;
    310 }
    311 
    312 static uint32_t
    313 nouveau_vp3_fill_picparm_h264_vp(struct nouveau_vp3_decoder *dec,
    314                                  const struct pipe_h264_picture_desc *d,
    315                                  struct nouveau_vp3_video_buffer *refs[16],
    316                                  unsigned *is_ref,
    317                                  char *map)
    318 {
    319    struct h264_picparm_vp stub_h = {}, *h = &stub_h;
    320    unsigned ring, i, j = 0;
    321    assert(offsetof(struct h264_picparm_vp, u224) == 0x224);
    322    *is_ref = d->is_reference;
    323    dec->last_frame_num = d->frame_num;
    324 
    325    h->width = mb(dec->base.width);
    326    h->height = mb(dec->base.height);
    327    h->stride1 = h->stride2 = mb(dec->base.width)*16;
    328    nouveau_vp3_ycbcr_offsets(dec, &h->ofs[1], &h->ofs[3], &h->ofs[4]);
    329    h->ofs[5] = h->ofs[3];
    330    h->ofs[0] = h->ofs[2] = 0;
    331    h->tmp_stride = dec->tmp_stride >> 8;
    332    assert(h->tmp_stride);
    333    nouveau_vp3_inter_sizes(dec, d->slice_count, &ring, &h->bucket_size, &h->inter_ring_data_size);
    334 
    335    h->u220 = 0;
    336    h->mb_adaptive_frame_field_flag = d->pps->sps->mb_adaptive_frame_field_flag;
    337    h->direct_8x8_inference_flag = d->pps->sps->direct_8x8_inference_flag;
    338    h->weighted_pred_flag = d->pps->weighted_pred_flag;
    339    h->constrained_intra_pred_flag = d->pps->constrained_intra_pred_flag;
    340    h->is_reference = d->is_reference;
    341    h->interlace = d->field_pic_flag;
    342    h->bottom_field_flag = d->bottom_field_flag;
    343    h->second_field = 0; // set in nouveau_vp3_fill_picparm_h264_vp_refs
    344 
    345    h->log2_max_frame_num_minus4 = d->pps->sps->log2_max_frame_num_minus4;
    346    h->chroma_format_idc = 1;
    347 
    348    h->pic_order_cnt_type = d->pps->sps->pic_order_cnt_type;
    349    h->pic_init_qp_minus26 = d->pps->pic_init_qp_minus26;
    350    h->chroma_qp_index_offset = d->pps->chroma_qp_index_offset;
    351    h->second_chroma_qp_index_offset = d->pps->second_chroma_qp_index_offset;
    352    h->weighted_bipred_idc = d->pps->weighted_bipred_idc;
    353    h->tmp_idx = 0; // set in h264_vp_refs below
    354    h->fifo_dec_index = 0; // always set to 0 to be fifo compatible with other codecs
    355    h->frame_number = d->frame_num;
    356    h->u34_3030 = h->u34_3131 = 0;
    357    h->field_order_cnt[0] = d->field_order_cnt[0];
    358    h->field_order_cnt[1] = d->field_order_cnt[1];
    359    memcpy(h->m4x4, d->pps->ScalingList4x4, sizeof(h->m4x4));
    360    memcpy(h->m8x8, d->pps->ScalingList8x8, sizeof(h->m8x8));
    361    h->u220 = 0;
    362    for (i = 0; i < d->num_ref_frames; ++i) {
    363       if (!d->ref[i])
    364          break;
    365       refs[j] = (struct nouveau_vp3_video_buffer *)d->ref[i];
    366       h->refs[j].fifo_idx = j + 1;
    367       h->refs[j].tmp_idx = refs[j]->valid_ref;
    368       assert(dec->refs[refs[j]->valid_ref].vidbuf == refs[j]);
    369       h->refs[j].field_order_cnt[0] = d->field_order_cnt_list[i][0];
    370       h->refs[j].field_order_cnt[1] = d->field_order_cnt_list[i][1];
    371       h->refs[j].frame_idx = d->frame_num_list[i];
    372       if (!dec->refs[refs[j]->valid_ref].field_pic_flag) {
    373          h->refs[j].top_is_reference = d->top_is_reference[i];
    374          h->refs[j].bottom_is_reference = d->bottom_is_reference[i];
    375       }
    376       h->refs[j].is_long_term = d->is_long_term[i];
    377       h->refs[j].notseenyet = 0;
    378       h->refs[j].field_pic_flag = dec->refs[refs[j]->valid_ref].field_pic_flag;
    379       h->refs[j].top_field_marking =
    380          dec->refs[refs[j]->valid_ref].decoded_top && d->top_is_reference[i] ?
    381          1 + d->is_long_term[i] : 0;
    382       h->refs[j].bottom_field_marking =
    383          dec->refs[refs[j]->valid_ref].decoded_bottom && d->bottom_is_reference[i] ?
    384          1 + d->is_long_term[i] : 0;
    385       h->refs[j].pad = 0;
    386       j++;
    387    }
    388    for (; i < 16; ++i)
    389       assert(!d->ref[i]);
    390    assert(d->num_ref_frames <= dec->base.max_references);
    391 
    392    for (; i < d->num_ref_frames; ++i)
    393       h->refs[j].field_pic_flag = d->field_pic_flag;
    394    *(struct h264_picparm_vp *)map = *h;
    395 
    396    return 0x1113;
    397 }
    398 
    399 static void
    400 nouveau_vp3_fill_picparm_h264_vp_refs(struct nouveau_vp3_decoder *dec,
    401                                       struct pipe_h264_picture_desc *d,
    402                                       struct nouveau_vp3_video_buffer *refs[16],
    403                                       struct nouveau_vp3_video_buffer *target,
    404                                       char *map)
    405 {
    406    struct h264_picparm_vp *h = (struct h264_picparm_vp *)map;
    407    assert(dec->refs[target->valid_ref].vidbuf == target);
    408 //    debug_printf("Target: %p\n", target);
    409 
    410    if (!dec->refs[target->valid_ref].decoded_top &&
    411        !dec->refs[target->valid_ref].decoded_bottom)
    412       dec->refs[target->valid_ref].decoded_first = d->bottom_field_flag;
    413    else if (dec->refs[target->valid_ref].decoded_first != d->bottom_field_flag)
    414       h->second_field = 1;
    415 
    416    h->tmp_idx = target->valid_ref;
    417    dec->refs[target->valid_ref].field_pic_flag = d->field_pic_flag;
    418    if (!d->field_pic_flag || d->bottom_field_flag)
    419       dec->refs[target->valid_ref].decoded_bottom = 1;
    420    if (!d->field_pic_flag || !d->bottom_field_flag)
    421       dec->refs[target->valid_ref].decoded_top = 1;
    422 }
    423 
    424 static uint32_t
    425 nouveau_vp3_fill_picparm_vc1_vp(struct nouveau_vp3_decoder *dec,
    426                                 struct pipe_vc1_picture_desc *d,
    427                                 struct nouveau_vp3_video_buffer *refs[16],
    428                                 unsigned *is_ref,
    429                                 char *map)
    430 {
    431    struct vc1_picparm_vp *vc = (struct vc1_picparm_vp *)map;
    432    unsigned ring;
    433    assert(dec->base.profile != PIPE_VIDEO_PROFILE_VC1_SIMPLE);
    434    *is_ref = d->picture_type <= 1;
    435 
    436    nouveau_vp3_ycbcr_offsets(dec, &vc->ofs[1], &vc->ofs[3], &vc->ofs[4]);
    437    vc->ofs[5] = vc->ofs[3];
    438    vc->ofs[0] = vc->ofs[2] = 0;
    439    vc->width = dec->base.width;
    440    vc->height = mb(dec->base.height)<<4;
    441    vc->unk0c = vc->unk10 = mb(dec->base.width)<<4; // Stride
    442    vc->pad = vc->pad2 = 0;
    443    nouveau_vp3_inter_sizes(dec, 1, &ring, &vc->bucket_size, &vc->inter_ring_data_size);
    444    vc->profile = dec->base.profile - PIPE_VIDEO_PROFILE_VC1_SIMPLE;
    445    vc->loopfilter = d->loopfilter;
    446    vc->fastuvmc = d->fastuvmc;
    447    vc->dquant = d->dquant;
    448    vc->overlap = d->overlap;
    449    vc->quantizer = d->quantizer;
    450    vc->u36 = 0; // ? No idea what this one is..
    451    refs[0] = (struct nouveau_vp3_video_buffer *)d->ref[0];
    452    refs[!!refs[0]] = (struct nouveau_vp3_video_buffer *)d->ref[1];
    453    return 0x12;
    454 }
    455 
    456 void nouveau_vp3_vp_caps(struct nouveau_vp3_decoder *dec, union pipe_desc desc,
    457                          struct nouveau_vp3_video_buffer *target, unsigned comm_seq,
    458                          unsigned *caps, unsigned *is_ref,
    459                          struct nouveau_vp3_video_buffer *refs[16])
    460 {
    461    struct nouveau_bo *bsp_bo = dec->bsp_bo[comm_seq % NOUVEAU_VP3_VIDEO_QDEPTH];
    462    enum pipe_video_format codec = u_reduce_video_profile(dec->base.profile);
    463    char *vp = bsp_bo->map + VP_OFFSET;
    464 
    465    switch (codec){
    466    case PIPE_VIDEO_FORMAT_MPEG12:
    467       *caps = nouveau_vp3_fill_picparm_mpeg12_vp(dec, desc.mpeg12, refs, is_ref, vp);
    468       nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target);
    469       switch (desc.mpeg12->picture_structure) {
    470       case PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_TOP:
    471          dec->refs[target->valid_ref].decoded_top = 1;
    472          break;
    473       case PIPE_MPEG12_PICTURE_STRUCTURE_FIELD_BOTTOM:
    474          dec->refs[target->valid_ref].decoded_bottom = 1;
    475          break;
    476       default:
    477          dec->refs[target->valid_ref].decoded_top = 1;
    478          dec->refs[target->valid_ref].decoded_bottom = 1;
    479          break;
    480       }
    481       return;
    482    case PIPE_VIDEO_FORMAT_MPEG4:
    483       *caps = nouveau_vp3_fill_picparm_mpeg4_vp(dec, desc.mpeg4, refs, is_ref, vp);
    484       nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target);
    485       // XXX: Correct?
    486       if (!desc.mpeg4->interlaced) {
    487          dec->refs[target->valid_ref].decoded_top = 1;
    488          dec->refs[target->valid_ref].decoded_bottom = 1;
    489       } else if (desc.mpeg4->top_field_first) {
    490          if (!dec->refs[target->valid_ref].decoded_top)
    491             dec->refs[target->valid_ref].decoded_top = 1;
    492          else
    493             dec->refs[target->valid_ref].decoded_bottom = 1;
    494       } else {
    495          if (!dec->refs[target->valid_ref].decoded_bottom)
    496             dec->refs[target->valid_ref].decoded_bottom = 1;
    497          else
    498             dec->refs[target->valid_ref].decoded_top = 1;
    499       }
    500       return;
    501    case PIPE_VIDEO_FORMAT_VC1: {
    502       *caps = nouveau_vp3_fill_picparm_vc1_vp(dec, desc.vc1, refs, is_ref, vp);
    503       nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target);
    504       if (desc.vc1->frame_coding_mode == 3)
    505          debug_printf("Field-Interlaced possibly incorrectly handled\n");
    506       dec->refs[target->valid_ref].decoded_top = 1;
    507       dec->refs[target->valid_ref].decoded_bottom = 1;
    508       return;
    509    }
    510    case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
    511       *caps = nouveau_vp3_fill_picparm_h264_vp(dec, desc.h264, refs, is_ref, vp);
    512       nouveau_vp3_handle_references(dec, refs, dec->fence_seq, target);
    513       nouveau_vp3_fill_picparm_h264_vp_refs(dec, desc.h264, refs, target, vp);
    514       return;
    515    }
    516    default: assert(0); return;
    517    }
    518 }
    519