Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  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.