Home | History | Annotate | Download | only in parser
      1 #include "viddec_fw_workload.h"
      2 #include "viddec_parser_ops.h"
      3 #include "viddec_fw_mp4.h"
      4 #include "viddec_mp4_parse.h"
      5 
      6 uint32_t viddec_fw_mp4_populate_attr(viddec_workload_t *wl, viddec_mp4_parser_t *parser)
      7 {
      8     uint32_t result = MP4_STATUS_OK;
      9     viddec_frame_attributes_t *attr = &(wl->attrs);
     10     mp4_VideoObjectLayer_t *vol = &(parser->info.VisualObject.VideoObject);
     11 
     12     memset(attr, 0, sizeof(viddec_frame_attributes_t));
     13 
     14     attr->cont_size.width = vol->video_object_layer_width;
     15     attr->cont_size.height = vol->video_object_layer_height;
     16 
     17     // Translate vop_coding_type
     18     switch(vol->VideoObjectPlane.vop_coding_type)
     19     {
     20         case MP4_VOP_TYPE_B:
     21             attr->frame_type = VIDDEC_FRAME_TYPE_B;
     22             break;
     23         case MP4_VOP_TYPE_P:
     24             attr->frame_type = VIDDEC_FRAME_TYPE_P;
     25             break;
     26         case MP4_VOP_TYPE_S:
     27             attr->frame_type = VIDDEC_FRAME_TYPE_S;
     28             break;
     29         case MP4_VOP_TYPE_I:
     30             attr->frame_type = VIDDEC_FRAME_TYPE_I;
     31             break;
     32         default:
     33             break;
     34     } // switch on vop_coding_type
     35 
     36     attr->mpeg4.top_field_first = vol->VideoObjectPlane.top_field_first;
     37 
     38     return result;
     39 } // viddec_fw_mp4_populate_attr
     40 
     41 uint32_t viddec_fw_mp4_insert_vol_workitem(void *parent, viddec_mp4_parser_t *parser)
     42 {
     43     uint32_t result = MP4_STATUS_OK;
     44     viddec_workload_item_t wi;
     45     viddec_fw_mp4_vol_info_t vol_info;
     46     mp4_VideoObjectLayer_t *vol = &(parser->info.VisualObject.VideoObject);
     47 
     48     memset(&vol_info, 0, sizeof(viddec_fw_mp4_vol_info_t));
     49 
     50     // Get vol_flags
     51     viddec_fw_mp4_set_reversible_vlc(&vol_info, vol->reversible_vlc);
     52     viddec_fw_mp4_set_data_partitioned(&vol_info, vol->data_partitioned);
     53     viddec_fw_mp4_set_resync_marker_disable(&vol_info, vol->resync_marker_disable);
     54     viddec_fw_mp4_set_quarter_sample(&vol_info, vol->quarter_sample);
     55     viddec_fw_mp4_set_obmc_disable(&vol_info, vol->obmc_disable);
     56     viddec_fw_mp4_set_interlaced(&vol_info, vol->interlaced);
     57     viddec_fw_mp4_set_vol_shape(&vol_info, vol->video_object_layer_shape);
     58     viddec_fw_mp4_set_short_video_header_flag(&vol_info, vol->short_video_header);
     59 
     60     // Get vol_size
     61     viddec_fw_mp4_set_vol_width(&vol_info, vol->video_object_layer_width);
     62     viddec_fw_mp4_set_vol_height(&vol_info, vol->video_object_layer_height);
     63 
     64     // Get vol_item
     65     viddec_fw_mp4_set_quant_type(&vol_info, vol->quant_type);
     66     viddec_fw_mp4_set_quant_precision(&vol_info, vol->quant_precision);
     67     viddec_fw_mp4_set_sprite_warping_accuracy(&vol_info, vol->sprite_info.sprite_warping_accuracy);
     68     viddec_fw_mp4_set_sprite_warping_points(&vol_info, vol->sprite_info.no_of_sprite_warping_points);
     69     viddec_fw_mp4_set_sprite_enable(&vol_info, vol->sprite_enable);
     70     viddec_fw_mp4_set_vop_time_increment_resolution(&vol_info, vol->vop_time_increment_resolution);
     71 
     72 
     73     wi.vwi_type = VIDDEC_WORKLOAD_MP4_VOL_INFO;
     74     wi.vwi_payload[0] = vol_info.vol_flags;
     75     wi.vwi_payload[1] = vol_info.vol_size;
     76     wi.vwi_payload[2] = vol_info.vol_item;
     77 
     78     result = viddec_pm_append_workitem(parent, &wi);
     79 
     80     return result;
     81 } // viddec_fw_mp4_insert_vol_workitem
     82 
     83 uint32_t viddec_fw_mp4_insert_vop_workitem(void *parent, viddec_mp4_parser_t *parser)
     84 {
     85     uint32_t result = MP4_STATUS_OK;
     86     viddec_workload_item_t wi;
     87     viddec_fw_mp4_vop_info_t vop_info;
     88     mp4_VideoObjectPlane_t *vop = &(parser->info.VisualObject.VideoObject.VideoObjectPlane);
     89     uint32_t byte = 0;
     90     unsigned char is_emul;
     91 
     92     memset(&vop_info, 0, sizeof(viddec_fw_mp4_vop_info_t));
     93 
     94     // Get frame_info
     95     viddec_fw_mp4_set_past_field_frame(&vop_info, parser->ref_frame[VIDDEC_MP4_INDX_2].is_field);
     96     viddec_fw_mp4_set_past_frame_id(&vop_info, VIDDEC_MP4_FRAME_PAST);
     97     viddec_fw_mp4_set_future_field_frame(&vop_info, parser->ref_frame[VIDDEC_MP4_INDX_1].is_field);
     98     viddec_fw_mp4_set_future_frame_id(&vop_info, VIDDEC_MP4_FRAME_FUTURE);
     99     viddec_fw_mp4_set_current_field_frame(&vop_info, parser->ref_frame[VIDDEC_MP4_INDX_0].is_field);
    100     viddec_fw_mp4_set_current_frame_id(&vop_info, VIDDEC_MP4_FRAME_CURRENT);
    101 
    102     // HW has a limitation that the enums for PAST(1), FUTURE(2) and CURRENT(0) cannot be changed and
    103     // the spec does not support field pictures. Hence the field_frame bits are always zero.
    104     // This gives us the constant 0x10200.
    105     vop_info.frame_info = 0x10200;
    106 
    107     // Get vop_data
    108     // Quant scale is in the video_packet_header or the gob_layer - both of which are parsed by the BSP
    109     viddec_fw_mp4_set_vop_quant_scale(&vop_info, 0);
    110     viddec_fw_mp4_set_vop_fcode_backward(&vop_info, vop->vop_fcode_backward);
    111     viddec_fw_mp4_set_vop_fcode_forward(&vop_info, vop->vop_fcode_forward);
    112     viddec_fw_mp4_set_vop_quant(&vop_info, vop->vop_quant);
    113     viddec_fw_mp4_set_alternate_vertical_scan_flag(&vop_info, vop->alternate_vertical_scan_flag);
    114     viddec_fw_mp4_set_top_field_first(&vop_info, vop->top_field_first);
    115     viddec_fw_mp4_set_intra_dc_vlc_thr(&vop_info, vop->intra_dc_vlc_thr);
    116     viddec_fw_mp4_set_vop_rounding_type(&vop_info, vop->vop_rounding_type);
    117     viddec_fw_mp4_set_vop_coding_type(&vop_info, vop->vop_coding_type);
    118 
    119     // Get vol_item
    120     result = viddec_pm_get_au_pos(parent, &vop_info.bit_offset, &byte, &is_emul);
    121 
    122     wi.vwi_type = VIDDEC_WORKLOAD_MP4_VOP_INFO;
    123     wi.vwi_payload[0] = vop_info.frame_info;
    124     wi.vwi_payload[1] = vop_info.vop_data;
    125     wi.vwi_payload[2] = vop_info.bit_offset;
    126 
    127     result = viddec_pm_append_workitem(parent, &wi);
    128 
    129     return result;
    130 } // viddec_fw_mp4_insert_vop_workitem
    131 
    132 uint32_t viddec_fw_mp4_insert_vpsh_workitem(void *parent, viddec_mp4_parser_t *parser)
    133 {
    134     uint32_t result = MP4_STATUS_OK;
    135     viddec_workload_item_t wi;
    136     viddec_fw_mp4_svh_t svh_info;
    137     mp4_VideoObjectPlaneH263 *svh = &(parser->info.VisualObject.VideoObject.VideoObjectPlaneH263);
    138 
    139     memset(&svh_info, 0, sizeof(viddec_fw_mp4_svh_t));
    140 
    141     // Get svh_data
    142     viddec_fw_mp4_set_temporal_reference(&svh_info, svh->temporal_reference);
    143     viddec_fw_mp4_set_num_macroblocks_in_gob(&svh_info, svh->num_macroblocks_in_gob);
    144     viddec_fw_mp4_set_num_gobs_in_vop(&svh_info, svh->num_gobs_in_vop);
    145     viddec_fw_mp4_set_num_rows_in_gob(&svh_info, svh->num_rows_in_gob);
    146 
    147     wi.vwi_type = VIDDEC_WORKLOAD_MP4_SVH;
    148     wi.vwi_payload[0] = svh_info.svh_data;
    149     wi.vwi_payload[1] = svh_info.pad1;
    150     wi.vwi_payload[2] = svh_info.pad2;
    151 
    152     result = viddec_pm_append_workitem(parent, &wi);
    153 
    154     return result;
    155 } // viddec_fw_mp4_insert_vpsh_workitem
    156 
    157 uint32_t viddec_fw_mp4_insert_sprite_workitem(void *parent, viddec_mp4_parser_t *parser)
    158 {
    159     uint32_t result = MP4_STATUS_OK;
    160     viddec_workload_item_t wi;
    161     viddec_fw_mp4_sprite_trajectory_t sprite_info;
    162     mp4_VideoObjectLayer_t *vol = &(parser->info.VisualObject.VideoObject);
    163     mp4_VideoObjectPlane_t *vop = &(parser->info.VisualObject.VideoObject.VideoObjectPlane);
    164     uint8_t no_of_entries_per_item = 3;
    165     uint8_t no_of_sprite_workitems = 0;
    166     uint8_t warp_index = 0;
    167     int i, j;
    168 
    169     if(!vol->sprite_info.no_of_sprite_warping_points)
    170         return result;
    171 
    172     no_of_sprite_workitems = (vol->sprite_info.no_of_sprite_warping_points > 3) ? 2 : 1;
    173 
    174     for(i=0; i<no_of_sprite_workitems; i++)
    175     {
    176         memset(&sprite_info, 0, sizeof(viddec_fw_mp4_sprite_trajectory_t));
    177 
    178         for(j=0; j<no_of_entries_per_item; j++)
    179         {
    180             if(warp_index < vol->sprite_info.no_of_sprite_warping_points)
    181             {
    182                 viddec_fw_mp4_set_warping_point_index(sprite_info.warping_mv_code[j], warp_index);
    183                 viddec_fw_mp4_set_warping_mv_code_du(sprite_info.warping_mv_code[j], vop->warping_mv_code_du[warp_index]);
    184                 viddec_fw_mp4_set_warping_mv_code_dv(sprite_info.warping_mv_code[j], vop->warping_mv_code_dv[warp_index]);
    185             }
    186             else
    187             {
    188                sprite_info.warping_mv_code[j] = 0xF << 28;
    189             }
    190             warp_index++;
    191         }
    192 
    193         wi.vwi_type = VIDDEC_WORKLOAD_MP4_SPRT_TRAJ;
    194         wi.vwi_payload[0] = sprite_info.warping_mv_code[0];
    195         wi.vwi_payload[1] = sprite_info.warping_mv_code[1];
    196         wi.vwi_payload[2] = sprite_info.warping_mv_code[2];
    197 
    198         result = viddec_pm_append_workitem(parent, &wi);
    199     }
    200 
    201     return result;
    202 } // viddec_fw_mp4_insert_sprite_workitem
    203 
    204 uint32_t viddec_fw_mp4_insert_bvop_workitem(void *parent, viddec_mp4_parser_t *parser)
    205 {
    206     uint32_t result = MP4_STATUS_OK;
    207     viddec_workload_item_t wi;
    208     mp4_VideoObjectLayer_t *vol = &(parser->info.VisualObject.VideoObject);
    209 
    210     wi.vwi_type = VIDDEC_WORKLOAD_MP4_BVOP_INFO;
    211     wi.vwi_payload[0] = vol->Tframe;
    212     wi.vwi_payload[1] = vol->TRD;
    213     wi.vwi_payload[2] = vol->TRB;
    214 
    215     result = viddec_pm_append_workitem(parent, &wi);
    216 
    217     return result;
    218 } // viddec_fw_mp4_insert_bvop_workitem
    219 
    220 uint32_t viddec_fw_mp4_insert_qmat(void *parent, uint8_t intra_quant_flag, uint32_t *qmat)
    221 {
    222     uint32_t result = MP4_STATUS_OK;
    223     viddec_workload_item_t wi;
    224     uint8_t i;
    225 
    226     // No of items = (64/4 Dwords / 3 entries per workload item)
    227     // 64 8b entries => 64 * 8 / 32 DWORDS => 64/4 DWORDS => 16 DWORDS
    228     // Each item can store 3 DWORDS, 16 DWORDS => 16/3 items => 6 items
    229     for(i=0; i<6; i++)
    230     {
    231         memset(&wi, 0, sizeof(viddec_workload_item_t));
    232 
    233         if(intra_quant_flag)
    234             wi.vwi_type = VIDDEC_WORKLOAD_MP4_IQUANT;
    235         else
    236             wi.vwi_type = VIDDEC_WORKLOAD_MP4_NIQUANT;
    237 
    238         if(i == 6)
    239         {
    240             wi.vwi_payload[0] = qmat[0];
    241             wi.vwi_payload[1] = 0;
    242             wi.vwi_payload[2] = 0;
    243         }
    244         else
    245         {
    246             wi.vwi_payload[0] = qmat[0];
    247             wi.vwi_payload[1] = qmat[1];
    248             wi.vwi_payload[2] = qmat[2];
    249         }
    250 
    251         qmat += 3;
    252 
    253         result = viddec_pm_append_workitem(parent, &wi);
    254     }
    255 
    256     return result;
    257 } // viddec_fw_mp4_insert_qmat
    258 
    259 uint32_t viddec_fw_mp4_insert_inversequant_workitem(void *parent, mp4_VOLQuant_mat_t *qmat)
    260 {
    261     uint32_t result = MP4_STATUS_OK;
    262 
    263     if(qmat->load_intra_quant_mat)
    264     {
    265         result = viddec_fw_mp4_insert_qmat(parent, true, (uint32_t *) &(qmat->intra_quant_mat));
    266     }
    267 
    268     if(qmat->load_nonintra_quant_mat)
    269     {
    270         result = viddec_fw_mp4_insert_qmat(parent, false, (uint32_t *) &(qmat->nonintra_quant_mat));
    271     }
    272 
    273     return result;
    274 } // viddec_fw_mp4_insert_inversequant_workitem
    275 
    276 uint32_t viddec_fw_mp4_insert_past_frame_workitem(void *parent)
    277 {
    278     uint32_t result = MP4_STATUS_OK;
    279     viddec_workload_item_t wi;
    280 
    281     wi.vwi_type = VIDDEC_WORKLOAD_MP4_PAST_FRAME;
    282     wi.ref_frame.reference_id = 0;
    283     wi.ref_frame.luma_phys_addr = 0;
    284     wi.ref_frame.chroma_phys_addr = 0;
    285     result = viddec_pm_append_workitem(parent, &wi);
    286 
    287     return result;
    288 } // viddec_fw_mp4_insert_past_frame_workitem
    289 
    290 uint32_t viddec_fw_mp4_insert_future_frame_workitem(void *parent)
    291 {
    292     uint32_t result = MP4_STATUS_OK;
    293     viddec_workload_item_t wi;
    294 
    295     wi.vwi_type = VIDDEC_WORKLOAD_MP4_FUTURE_FRAME;
    296     wi.ref_frame.reference_id = 0;
    297     wi.ref_frame.luma_phys_addr = 0;
    298     wi.ref_frame.chroma_phys_addr = 0;
    299     result = viddec_pm_append_workitem(parent, &wi);
    300 
    301     return result;
    302 } // viddec_fw_mp4_insert_future_frame_workitem
    303 
    304 uint32_t viddec_fw_mp4_insert_reorder_workitem(void *parent)
    305 {
    306     uint32_t result = MP4_STATUS_OK;
    307     viddec_workload_item_t wi;
    308 
    309     // Move frame at location 1 of the reference table to location 0
    310     wi.vwi_type = VIDDEC_WORKLOAD_REFERENCE_FRAME_REORDER;
    311     wi.ref_reorder.ref_table_offset = 0;
    312     wi.ref_reorder.ref_reorder_00010203 = 0x01010203;
    313     wi.ref_reorder.ref_reorder_04050607 = 0x04050607;
    314 
    315     result = viddec_pm_append_workitem(parent, &wi);
    316 
    317     return result;
    318 } // viddec_fw_mp4_insert_reorder_workitem
    319 
    320 uint32_t viddec_fw_mp4_emit_workload(void *parent, void *ctxt)
    321 {
    322     uint32_t result = 0;
    323     viddec_mp4_parser_t *parser = (viddec_mp4_parser_t *) ctxt;
    324     viddec_workload_t *wl = viddec_pm_get_header(parent);
    325 
    326     result = viddec_fw_mp4_populate_attr(wl, parser);
    327     result = viddec_fw_mp4_insert_vol_workitem(parent, parser);
    328     result = viddec_fw_mp4_insert_vop_workitem(parent, parser);
    329     result = viddec_fw_mp4_insert_sprite_workitem(parent, parser);
    330     result = viddec_fw_mp4_insert_inversequant_workitem(parent, &(parser->info.VisualObject.VideoObject.quant_mat_info));
    331 
    332     if(parser->info.VisualObject.VideoObject.short_video_header)
    333       result = viddec_fw_mp4_insert_vpsh_workitem(parent, parser);
    334 
    335     if(!parser->info.VisualObject.VideoObject.VideoObjectPlane.vop_coded)
    336         wl->is_reference_frame |= WORKLOAD_SKIPPED_FRAME;
    337 
    338     // Send reference re-order tag for all reference frame types
    339     if (parser->info.VisualObject.VideoObject.VideoObjectPlane.vop_coding_type != MP4_VOP_TYPE_B)
    340     {
    341         result = viddec_fw_mp4_insert_reorder_workitem(parent);
    342     }
    343 
    344     // Handle vop_coding_type based information
    345     switch(parser->info.VisualObject.VideoObject.VideoObjectPlane.vop_coding_type)
    346     {
    347         case MP4_VOP_TYPE_B:
    348             result = viddec_fw_mp4_insert_bvop_workitem(parent, parser);
    349             result = viddec_fw_mp4_insert_past_frame_workitem(parent);
    350             result = viddec_fw_mp4_insert_future_frame_workitem(parent);
    351             break;
    352         case MP4_VOP_TYPE_P:
    353         case MP4_VOP_TYPE_S:
    354             result = viddec_fw_mp4_insert_past_frame_workitem(parent);
    355             // Deliberate fall-thru to type I
    356         case MP4_VOP_TYPE_I:
    357             wl->is_reference_frame |= WORKLOAD_REFERENCE_FRAME | (1 & WORKLOAD_REFERENCE_FRAME_BMASK);
    358             // Swap reference information
    359             parser->ref_frame[VIDDEC_MP4_INDX_2] = parser->ref_frame[VIDDEC_MP4_INDX_1];
    360             parser->ref_frame[VIDDEC_MP4_INDX_1] = parser->ref_frame[VIDDEC_MP4_INDX_0];
    361             break;
    362             break;
    363         default:
    364             break;
    365     } // switch on vop_coding_type
    366 
    367     result = viddec_pm_append_pixeldata(parent);
    368 
    369     return result;
    370 } // viddec_fw_mp4_emit_workload
    371 
    372