Home | History | Annotate | Download | only in parser
      1 #include "viddec_mp4_videoobjectplane.h"
      2 
      3 mp4_Status_t mp4_Parse_GroupOfVideoObjectPlane(void *parent, viddec_mp4_parser_t *parser)
      4 {
      5     mp4_Info_t* pInfo = &(parser->info);
      6     uint32_t  code;
      7     int32_t getbits=0;
      8     mp4_Status_t ret = MP4_STATUS_REQD_DATA_ERROR;
      9     mp4_GroupOfVideoObjectPlane_t *data;
     10     uint32_t time_code = 0;
     11 
     12     data = &(pInfo->VisualObject.VideoObject.GroupOfVideoObjectPlane);
     13 
     14     do
     15     {
     16         getbits = viddec_pm_get_bits(parent, &code, 20);
     17         BREAK_GETBITS_FAIL(getbits, ret);
     18         ret = MP4_STATUS_OK;
     19 
     20         data->broken_link = ((code & 0x1) > 0);
     21         data->closed_gov = ((code & 0x2) > 0);
     22         time_code = code = code >> 2;
     23         data->time_code_seconds = code & 0x3F;
     24         code = code >> 6;
     25         if((code & 1) == 0)
     26         {/* SGA:Should we ignore marker bit? */
     27             DEB("Error:mp4_Parse_GroupOfVideoObjectPlane: Invalid marker\n");
     28         }
     29         code = code >>1;
     30         data->time_code_minutes = code & 0x3F;
     31         code = code >> 6;
     32         data->time_code_hours = code & 0x1F;
     33 
     34         // This is the timebase in full second units
     35         data->time_base = data->time_code_seconds + (60*data->time_code_minutes) + (3600*data->time_code_hours);
     36         // Need to convert this into no. of ticks
     37         data->time_base *= pInfo->VisualObject.VideoObject.vop_time_increment_resolution;
     38 
     39     } while(0);
     40 
     41     mp4_set_hdr_bitstream_error(parser, true, ret);
     42 
     43     // POPULATE WORKLOAD ITEM
     44     {
     45         viddec_workload_item_t wi;
     46 
     47         wi.vwi_type = VIDDEC_WORKLOAD_MPEG4_GRP_VIDEO_OBJ;
     48 
     49         wi.mp4_gvop.gvop_info = 0;
     50         wi.mp4_gvop.pad1 = 0;
     51         wi.mp4_gvop.pad2 = 0;
     52 
     53         viddec_fw_mp4_gvop_set_broken_link(&wi.mp4_gvop, data->broken_link);
     54         viddec_fw_mp4_gvop_set_closed_gov(&wi.mp4_gvop, data->closed_gov);
     55         viddec_fw_mp4_gvop_set_time_code(&wi.mp4_gvop, time_code);
     56 
     57         ret = viddec_pm_append_workitem(parent, &wi);
     58         if(ret == 1)
     59             ret = MP4_STATUS_OK;
     60     }
     61 
     62     return ret;
     63 }
     64 
     65 static inline mp4_Status_t mp4_brightness_change(void *parent, int32_t *b_change)
     66 {
     67     uint32_t code;
     68     int32_t getbits=0;
     69 
     70     *b_change = 0;
     71     getbits = viddec_pm_peek_bits(parent, &code, 4);
     72     if (code == 15)
     73     {
     74         getbits = viddec_pm_skip_bits(parent, 4);
     75         getbits = viddec_pm_get_bits(parent, &code, 10);
     76         *b_change = 625 + code;
     77     }
     78     else if (code == 14)
     79     {
     80         getbits = viddec_pm_skip_bits(parent, 4);
     81         getbits = viddec_pm_get_bits(parent, &code, 9);
     82         *b_change = 113 + code;
     83     }
     84     else if (code >= 12)
     85     {
     86         getbits = viddec_pm_skip_bits(parent, 3);
     87         getbits = viddec_pm_get_bits(parent, &code, 7);
     88         *b_change = (code < 64) ? ((int32_t)code - 112) : ((int32_t)code - 15);
     89     }
     90     else if (code >= 8)
     91     {
     92         getbits = viddec_pm_skip_bits(parent, 2);
     93         getbits = viddec_pm_get_bits(parent, &code, 6);
     94         *b_change = (code < 32) ? ((int32_t)code - 48) : ((int32_t)code - 15);
     95     }
     96     else
     97     {
     98         getbits = viddec_pm_skip_bits(parent, 1);
     99         getbits = viddec_pm_get_bits(parent, &code, 5);
    100         *b_change = (code < 16) ? ((int32_t)code - 16) : ((int32_t)code - 15);
    101     }
    102 
    103     return ( (getbits == -1) ? MP4_STATUS_PARSE_ERROR: MP4_STATUS_OK);
    104 }
    105 static inline int32_t mp4_Sprite_dmv_length(void * parent, int32_t *dmv_length)
    106 {
    107     uint32_t code, skip;
    108     int32_t getbits=0;
    109     mp4_Status_t ret= MP4_STATUS_PARSE_ERROR;
    110     *dmv_length=0;
    111     skip=3;
    112     do{
    113         getbits = viddec_pm_peek_bits(parent, &code, skip);
    114         BREAK_GETBITS_REQD_MISSING(getbits, ret);
    115 
    116         if(code == 7)
    117         {
    118             viddec_pm_skip_bits(parent, skip);
    119             getbits = viddec_pm_peek_bits(parent, &code, 9);
    120             BREAK_GETBITS_REQD_MISSING(getbits, ret);
    121 
    122             skip=1;
    123             while((code & 256) != 0)
    124             {/* count number of 1 bits */
    125                 code <<=1;
    126                 skip++;
    127             }
    128             *dmv_length = 5 + skip;
    129         }
    130         else
    131         {
    132             skip=(code <= 1) ? 2 : 3;
    133             *dmv_length = code - 1;
    134         }
    135         viddec_pm_skip_bits(parent, skip);
    136         ret= MP4_STATUS_OK;
    137 
    138     }while(0);
    139     return ret;
    140 }
    141 
    142 static inline mp4_Status_t
    143 mp4_Sprite_Trajectory(void *parent, mp4_VideoObjectLayer_t *vidObjLay, mp4_VideoObjectPlane_t *vidObjPlane)
    144 {
    145     uint32_t code, i;
    146     int32_t dmv_length=0, dmv_code=0, getbits=0;
    147     mp4_Status_t ret = MP4_STATUS_OK;
    148     for(i=0; i < (uint32_t)vidObjLay->sprite_info.no_of_sprite_warping_points; i++ )
    149     {
    150         ret = mp4_Sprite_dmv_length(parent, &dmv_length);
    151         if(ret != MP4_STATUS_OK)
    152         {
    153             break;
    154         }
    155         if(dmv_length <= 0)
    156         {
    157             dmv_code = 0;
    158         }
    159         else
    160         {
    161             getbits = viddec_pm_get_bits(parent, &code, (uint32_t)dmv_length);
    162             BREAK_GETBITS_REQD_MISSING(getbits, ret);
    163             dmv_code = (int32_t)code;
    164             if ((dmv_code & (1 << (dmv_length - 1))) == 0)
    165             {
    166                 dmv_code -= (1 << dmv_length) - 1;
    167             }
    168         }
    169         getbits = viddec_pm_get_bits(parent, &code, 1);
    170         BREAK_GETBITS_REQD_MISSING(getbits, ret);
    171         if(code != 1)
    172         {
    173             ret = MP4_STATUS_NOTSUPPORT;
    174             break;
    175         }
    176         vidObjPlane->warping_mv_code_du[i] = dmv_code;
    177         /* TODO: create another inline function to avoid code duplication */
    178         ret = mp4_Sprite_dmv_length(parent, &dmv_length);
    179         if(ret != MP4_STATUS_OK)
    180         {
    181             break;
    182         }
    183         if(dmv_length <= 0)
    184         {
    185             dmv_code = 0;
    186         }
    187         else
    188         {
    189             getbits = viddec_pm_get_bits(parent, &code, (uint32_t)dmv_length);
    190             BREAK_GETBITS_REQD_MISSING(getbits, ret);
    191             dmv_code = (int32_t)code;
    192             if ((dmv_code & (1 << (dmv_length - 1))) == 0)
    193             {
    194                 dmv_code -= (1 << dmv_length) - 1;
    195             }
    196         }
    197         getbits = viddec_pm_get_bits(parent, &code, 1);
    198         BREAK_GETBITS_REQD_MISSING(getbits, ret);
    199         if(code != 1)
    200         {
    201             ret = MP4_STATUS_NOTSUPPORT;
    202             break;
    203         }
    204         vidObjPlane->warping_mv_code_dv[i] = dmv_code;
    205 
    206     }
    207     return ret;
    208 }
    209 
    210 static inline mp4_Status_t mp4_pvt_extract_modulotimebase_from_VideoObjectPlane(void *parent, uint32_t *base)
    211 {
    212     mp4_Status_t ret= MP4_STATUS_OK;
    213     int32_t getbits=0;
    214     uint32_t  code = 0;
    215 
    216     *base = 0;
    217     do
    218     {
    219         getbits = viddec_pm_get_bits(parent, &code, 1);
    220         BREAK_GETBITS_REQD_MISSING(getbits, ret);
    221         *base += code;
    222     }while(code != 0);
    223     return ret;
    224 }
    225 
    226 mp4_Status_t mp4_Parse_VideoObjectPlane(void *parent, viddec_mp4_parser_t *parser)
    227 {
    228     uint32_t  code;
    229     mp4_Info_t               *pInfo = &(parser->info);
    230     mp4_VideoObjectLayer_t   *vidObjLay  = &(pInfo->VisualObject.VideoObject);
    231     mp4_VideoObjectPlane_t   *vidObjPlane = &(pInfo->VisualObject.VideoObject.VideoObjectPlane);
    232     int32_t getbits=0;
    233     mp4_Status_t ret= MP4_STATUS_PARSE_ERROR;
    234 
    235     do
    236     {
    237         getbits = viddec_pm_get_bits(parent, &code, 2);
    238         BREAK_GETBITS_REQD_MISSING(getbits, ret);
    239         vidObjPlane->vop_coding_type = code & 0x3;
    240         if( mp4_pvt_extract_modulotimebase_from_VideoObjectPlane(parent,
    241                                                                  &(vidObjPlane->modulo_time_base)) == MP4_STATUS_REQD_DATA_ERROR)
    242         {
    243             break;
    244         }
    245 
    246         getbits = viddec_pm_get_bits(parent, &code, 1);
    247         /* TODO: check for marker bit validity */
    248         {
    249             uint32_t numbits=0;
    250             numbits = vidObjLay->vop_time_increment_resolution_bits;
    251             if(numbits == 0) numbits=1; /*TODO:check if its greater than 16 bits ?? */
    252             getbits = viddec_pm_get_bits(parent, &code, numbits);
    253             BREAK_GETBITS_REQD_MISSING(getbits, ret);
    254             vidObjPlane->vop_time_increment = code;
    255         }
    256 
    257         getbits = viddec_pm_get_bits(parent, &code, 2);
    258         BREAK_GETBITS_REQD_MISSING(getbits, ret);
    259 
    260         vidObjPlane->vop_coded = code & 0x1;
    261         if(vidObjPlane->vop_coded == 0)
    262         {
    263             ret = MP4_STATUS_OK;/* Exit point 1 */
    264             break;
    265         }
    266 
    267         if(vidObjLay->newpred_enable)
    268         {
    269             /* New pred mode not supported in HW */
    270             DEB("Error: mp4_Parse_VideoObjectPlane: New pred in vidObjPlane is not supported\n");
    271             ret = MP4_STATUS_NOTSUPPORT;
    272             break;
    273         }
    274 
    275         if ((vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_BINARYONLY) &&
    276             ((vidObjPlane->vop_coding_type == MP4_VOP_TYPE_P) ||
    277              ((vidObjPlane->vop_coding_type == MP4_VOP_TYPE_S) &&
    278               (vidObjLay->sprite_enable == MP4_SPRITE_GMC))))
    279         {
    280             getbits = viddec_pm_get_bits(parent, &code, 1);
    281             BREAK_GETBITS_REQD_MISSING(getbits, ret);
    282             vidObjPlane->vop_rounding_type = code;
    283         }
    284 
    285         if (vidObjLay->reduced_resolution_vop_enable &&
    286             (vidObjLay->video_object_layer_shape == MP4_SHAPE_TYPE_RECTANGULAR) &&
    287             ((vidObjPlane->vop_coding_type == MP4_VOP_TYPE_I) ||
    288              (vidObjPlane->vop_coding_type == MP4_VOP_TYPE_P)))
    289         {
    290             getbits = viddec_pm_get_bits(parent, &code, 1);
    291             BREAK_GETBITS_REQD_MISSING(getbits, ret);
    292             vidObjPlane->vop_reduced_resolution = code;
    293             if (vidObjPlane->vop_reduced_resolution)
    294             {
    295                 DEB("Error: mp4_Parse_VideoObjectPlane: Reduced Resolution vidObjPlane is not supported\n");
    296                 ret = MP4_STATUS_NOTSUPPORT;
    297                 break;
    298             }
    299         }
    300 
    301         if (vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_RECTANGULAR)
    302         {
    303             /* we support only rectangular shapes so the following logic is not required */
    304             ret = MP4_STATUS_NOTSUPPORT;
    305             break;
    306         }
    307 
    308         if ((vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_BINARYONLY) &&
    309             (!vidObjLay->complexity_estimation_disable))
    310         {
    311             /* Not required according to DE team */
    312             //read_vop_complexity_estimation_header();
    313             ret = MP4_STATUS_NOTSUPPORT;
    314             break;
    315         }
    316 
    317         if (vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_BINARYONLY)
    318         {
    319             getbits = viddec_pm_get_bits(parent, &code, 3);
    320             BREAK_GETBITS_REQD_MISSING(getbits, ret);
    321             vidObjPlane->intra_dc_vlc_thr = code;
    322             if (vidObjLay->interlaced)
    323             {
    324                 getbits = viddec_pm_get_bits(parent, &code, 2);
    325                 BREAK_GETBITS_REQD_MISSING(getbits, ret);
    326                 vidObjPlane->top_field_first = ((code & 0x2) > 0);
    327                 vidObjPlane->alternate_vertical_scan_flag = code & 0x1;
    328             }
    329         }
    330 
    331         if (((vidObjLay->sprite_enable == MP4_SPRITE_STATIC) || (vidObjLay->sprite_enable == MP4_SPRITE_GMC)) &&
    332             (vidObjPlane->vop_coding_type == MP4_VOP_TYPE_S))
    333         {
    334             if (vidObjLay->sprite_info.no_of_sprite_warping_points > 0){
    335                 if (mp4_Sprite_Trajectory(parent, vidObjLay, vidObjPlane) != MP4_STATUS_OK){
    336                     break;
    337                 }
    338             }
    339             vidObjPlane->brightness_change_factor = 0;
    340             if (vidObjLay->sprite_info.sprite_brightness_change)
    341             {
    342                 int32_t change=0;
    343                 if(mp4_brightness_change(parent, &change) == MP4_STATUS_PARSE_ERROR)
    344                 {
    345                     break;
    346                 }
    347                 vidObjPlane->brightness_change_factor = change;
    348             }
    349 
    350             if (vidObjLay->sprite_enable == MP4_SPRITE_STATIC)
    351             {
    352                 /* SGA: IS decode sprite not required. Is static even supported */
    353                 ret = MP4_STATUS_OK;/* Exit point 2 */
    354                 break;
    355             }
    356         }
    357 
    358         if (vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_BINARYONLY)
    359         {
    360             // Length of vop_quant is specified by quant_precision
    361             getbits = viddec_pm_get_bits(parent, &code, vidObjLay->quant_precision);
    362             BREAK_GETBITS_REQD_MISSING(getbits, ret);
    363             vidObjPlane->vop_quant = code;
    364             if (vidObjLay->video_object_layer_shape == MP4_SHAPE_TYPE_GRAYSCALE)
    365             {
    366                 ret = MP4_STATUS_NOTSUPPORT;
    367                 break;
    368             }
    369             if (vidObjPlane->vop_coding_type != MP4_VOP_TYPE_I)
    370             {
    371                 vidObjPlane->vop_fcode_forward = 0;
    372                 getbits = viddec_pm_get_bits(parent, &code, 3);
    373                 BREAK_GETBITS_REQD_MISSING(getbits, ret);
    374                 vidObjPlane->vop_fcode_forward = code & 0x7;
    375                 if (vidObjPlane->vop_fcode_forward == 0)
    376                 {
    377                     DEB("Error: vop_fcode_forward == 0\n");
    378                     break;
    379                 }
    380             }
    381             if (vidObjPlane->vop_coding_type == MP4_VOP_TYPE_B)
    382             {
    383                 vidObjPlane->vop_fcode_backward = 0;
    384                 getbits = viddec_pm_get_bits(parent, &code, 3);
    385                 BREAK_GETBITS_REQD_MISSING(getbits, ret);
    386                 vidObjPlane->vop_fcode_backward = code &0x7;
    387                 if (vidObjPlane->vop_fcode_backward == 0)
    388                 {
    389                     DEB("Error: vop_fcode_backward == 0\n");
    390                     break;
    391                 }
    392             }
    393             if (!vidObjLay->scalability)
    394             {
    395                 if ((vidObjLay->video_object_layer_shape != MP4_SHAPE_TYPE_RECTANGULAR) &&
    396                     (vidObjPlane->vop_coding_type != MP4_VOP_TYPE_I))
    397                 {
    398                     ret = MP4_STATUS_NOTSUPPORT;
    399                     break;
    400                 }
    401                 // The remaining data contains the macroblock information that is handled by the BSP
    402                 // The offsets to be sent to the BSP are obtained in the workload population
    403             }
    404             else
    405             {
    406                 ret = MP4_STATUS_NOTSUPPORT;
    407                 break;
    408             }
    409         }
    410         else
    411         {/* Binary Not supported */
    412             ret = MP4_STATUS_NOTSUPPORT;
    413             break;
    414         }
    415         /* Since we made it all the way here it a success condition */
    416         ret = MP4_STATUS_OK;  /* Exit point 3 */
    417     }while(0);
    418 
    419     mp4_set_hdr_bitstream_error(parser, false, ret);
    420 
    421     return ret;
    422 } // mp4_Parse_VideoObjectPlane
    423