Home | History | Annotate | Download | only in parser
      1 #include "viddec_mp4_visualobject.h"
      2 
      3 static inline uint8_t mp4_pvt_isValid_verID(uint8_t id)
      4 {
      5     uint8_t ret=true;
      6     switch(id)
      7     {
      8         case 1:
      9         case 2:
     10         case 4:
     11         case 5:
     12         {
     13             break;
     14         }
     15         default:
     16         {
     17             ret = false;
     18             break;
     19         }
     20     }
     21     return ret;
     22 } // mp4_pvt_isValid_verID
     23 
     24 static mp4_Status_t mp4_Parse_video_signal_type(void *parent, mp4_VideoSignalType_t *vidSignal)
     25 {
     26     uint32_t data=0;
     27     int32_t getbits=0;
     28     mp4_Status_t ret = MP4_STATUS_PARSE_ERROR;
     29 
     30     /* Set default values defined in spec first */
     31     vidSignal->video_format = 5;
     32     vidSignal->video_range = 0;
     33     vidSignal->colour_primaries = 1;
     34     vidSignal->transfer_characteristics = 1;
     35     vidSignal->matrix_coefficients = 1;
     36     do
     37     {
     38         getbits = viddec_pm_get_bits(parent, &data, 1);
     39         BREAK_GETBITS_FAIL(getbits, ret);
     40         vidSignal->is_video_signal_type = (data > 0);
     41         if(vidSignal->is_video_signal_type)
     42         {
     43             getbits = viddec_pm_get_bits(parent, &data, 5);
     44             BREAK_GETBITS_FAIL(getbits, ret);
     45             vidSignal->is_colour_description = data & 0x1;
     46             vidSignal->video_range = ((data & 0x2) > 0);
     47             data =  data >> 2;
     48             vidSignal->video_format = data & 0x7;
     49             if(vidSignal->is_colour_description)
     50             {
     51                 getbits = viddec_pm_get_bits(parent, &data, 24);
     52                 BREAK_GETBITS_FAIL(getbits, ret);
     53                 vidSignal->colour_primaries = (data >> 16) & 0xFF;
     54                 vidSignal->transfer_characteristics = (data >> 8) & 0xFF;
     55                 vidSignal->matrix_coefficients = data & 0xFF;
     56             }
     57         }
     58         ret = MP4_STATUS_OK;
     59     }while(0);
     60 
     61     return ret;
     62 } // mp4_Parse_video_signal_type
     63 
     64 void mp4_set_hdr_bitstream_error(viddec_mp4_parser_t *parser, uint8_t hdr_flag, mp4_Status_t parse_status)
     65 {
     66     //DEB("Entering mp4_set_hdr_bitstream_error: bs_err: 0x%x, hdr: %d, parse_status: %d\n",
     67     //  parser->bitstream_error, hdr_flag, parse_status);
     68 
     69     if(hdr_flag)
     70     {
     71         if(parse_status & MP4_STATUS_NOTSUPPORT)
     72             parser->bitstream_error |= MP4_BS_ERROR_HDR_UNSUP;
     73         if(parse_status & MP4_STATUS_PARSE_ERROR)
     74             parser->bitstream_error |= MP4_BS_ERROR_HDR_PARSE;
     75         if(parse_status & MP4_STATUS_REQD_DATA_ERROR)
     76             parser->bitstream_error |= MP4_BS_ERROR_HDR_NONDEC;
     77         parser->bitstream_error &= MP4_HDR_ERROR_MASK;
     78     }
     79     else
     80     {
     81         if(parse_status & MP4_STATUS_NOTSUPPORT)
     82             parser->bitstream_error |= MP4_BS_ERROR_FRM_UNSUP;
     83         if(parse_status & MP4_STATUS_PARSE_ERROR)
     84             parser->bitstream_error |= MP4_BS_ERROR_FRM_PARSE;
     85         if(parse_status & MP4_STATUS_REQD_DATA_ERROR)
     86             parser->bitstream_error |= MP4_BS_ERROR_FRM_NONDEC;
     87     }
     88 
     89     //DEB("Exiting mp4_set_hdr_bitstream_error: bs_err: 0x%x\n", parser->bitstream_error);
     90 
     91     return;
     92 } // mp4_set_hdr_bitstream_error
     93 
     94 mp4_Status_t mp4_Parse_VisualSequence(void *parent, viddec_mp4_parser_t *parser)
     95 {
     96     uint32_t data=0;
     97     int32_t getbits=0;
     98     mp4_Status_t ret = MP4_STATUS_PARSE_ERROR;
     99 
    100     getbits = viddec_pm_get_bits(parent, &data, 8);
    101     if(getbits != -1)
    102     {
    103         parser->info.profile_and_level_indication = data & 0xFF;
    104         // If present, check for validity
    105         switch(parser->info.profile_and_level_indication)
    106         {
    107             case MP4_SIMPLE_PROFILE_LEVEL_0:
    108             case MP4_SIMPLE_PROFILE_LEVEL_1:
    109             case MP4_SIMPLE_PROFILE_LEVEL_2:
    110             case MP4_SIMPLE_PROFILE_LEVEL_3:
    111             case MP4_SIMPLE_PROFILE_LEVEL_4a:
    112             case MP4_SIMPLE_PROFILE_LEVEL_5:
    113             case MP4_SIMPLE_PROFILE_LEVEL_6:
    114             case MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_0:
    115             case MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_1:
    116             case MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_2:
    117             case MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_3:
    118             case MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_4:
    119             case MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_5:
    120             case MP4_ADVANCED_SIMPLE_PROFILE_LEVEL_3B:
    121                 parser->bitstream_error = MP4_BS_ERROR_NONE;
    122                 ret = MP4_STATUS_OK;
    123                 break;
    124             default:
    125                 parser->bitstream_error = MP4_BS_ERROR_HDR_UNSUP | MP4_BS_ERROR_HDR_NONDEC;
    126                 break;
    127         }
    128     }
    129     else
    130     {
    131         parser->bitstream_error = MP4_BS_ERROR_HDR_PARSE | MP4_BS_ERROR_HDR_NONDEC;
    132     }
    133 
    134     return ret;
    135 } // mp4_Parse_VisualSequence
    136 
    137 mp4_Status_t mp4_Parse_VisualObject(void *parent, viddec_mp4_parser_t *parser)
    138 {
    139     mp4_Info_t *pInfo = &(parser->info);
    140     mp4_VisualObject_t *visObj = &(pInfo->VisualObject);
    141     uint32_t data=0;
    142     int32_t getbits=0;
    143     mp4_Status_t ret = MP4_STATUS_PARSE_ERROR;
    144 
    145     do
    146     {
    147         getbits = viddec_pm_get_bits(parent, &data, 1);
    148         BREAK_GETBITS_FAIL(getbits, ret);
    149         visObj->is_visual_object_identifier = (data > 0);
    150 
    151         visObj->visual_object_verid = 1; /* Default value as per spec */
    152         if (visObj->is_visual_object_identifier)
    153         {
    154             viddec_pm_get_bits(parent, &data, 7);
    155             visObj->visual_object_priority = data & 0x7;
    156             data = data >> 3;
    157             if(mp4_pvt_isValid_verID(data & 0xF))
    158             {
    159                 visObj->visual_object_verid = data & 0xF;
    160             }
    161             else
    162             {
    163                 DEB("Warning: Unsupported visual_object_verid\n");
    164                 parser->bitstream_error |= MP4_BS_ERROR_HDR_UNSUP;
    165                 // Continue parsing as it is not a required field for decoder
    166             }
    167         }
    168 
    169         getbits = viddec_pm_get_bits(parent, &data, 4);
    170         BREAK_GETBITS_FAIL(getbits, ret);
    171         visObj->visual_object_type = data;
    172         if (visObj->visual_object_type != MP4_VISUAL_OBJECT_TYPE_VIDEO)
    173         {
    174             /* VIDEO is the only supported type */
    175             DEB("Error: Unsupported object: visual_object_type != video ID\n");
    176             parser->bitstream_error |= MP4_BS_ERROR_HDR_UNSUP;
    177             break;
    178         }
    179 
    180         /* Not required to check for visual_object_type as we already handle it above */
    181         ret = mp4_Parse_video_signal_type(parent, &(visObj->VideoSignalType));
    182 
    183         // No need to check for user data or visual object layer because they have a different start code
    184         // and will not be part of this header
    185 
    186     } while(0);
    187 
    188     mp4_set_hdr_bitstream_error(parser, true, ret);
    189 
    190     // POPULATE WORKLOAD ITEM
    191     {
    192         viddec_workload_item_t wi;
    193         mp4_VideoSignalType_t *vst = &(visObj->VideoSignalType);
    194 
    195         wi.vwi_type = VIDDEC_WORKLOAD_MPEG4_VISUAL_SEQ_OBJ;
    196 
    197         wi.mp4_vs_vo.vs_item = 0;
    198         wi.mp4_vs_vo.video_signal_type = 0;
    199         wi.mp4_vs_vo.color_desc = 0;
    200 
    201         viddec_fw_mp4_vs_set_profile_and_level_indication(&wi.mp4_vs_vo, pInfo->profile_and_level_indication);
    202 
    203         viddec_fw_mp4_vo_set_video_signal_type(&wi.mp4_vs_vo, vst->is_video_signal_type);
    204         if(vst->is_video_signal_type)
    205         {
    206             viddec_fw_mp4_vo_set_video_range(&wi.mp4_vs_vo, vst->video_range);
    207             viddec_fw_mp4_vo_set_video_format(&wi.mp4_vs_vo, vst->video_format);
    208             viddec_fw_mp4_vo_set_colour_description(&wi.mp4_vs_vo, vst->is_colour_description);
    209             if(vst->is_colour_description)
    210             {
    211                 viddec_fw_mp4_vo_set_transfer_char(&wi.mp4_vs_vo, vst->transfer_characteristics);
    212                 viddec_fw_mp4_vo_set_color_primaries(&wi.mp4_vs_vo, vst->colour_primaries);
    213             }
    214         }
    215 
    216         ret = viddec_pm_append_workitem(parent, &wi);
    217         if(ret == 1)
    218             ret = MP4_STATUS_OK;
    219     }
    220 
    221     return ret;
    222 } // mp4_Parse_VisualObject
    223 
    224 mp4_Status_t mp4_Parse_UserData(void *parent, viddec_mp4_parser_t *parser)
    225 {
    226     mp4_Status_t ret = MP4_STATUS_PARSE_ERROR;
    227     uint32_t user_data;
    228     viddec_workload_item_t wi;
    229 
    230     DEB("ParseUser-prev_sc: 0x%x\n", parser->prev_sc);
    231 
    232     /* find the scope based on start code sc */
    233     switch(parser->prev_sc) {
    234         case MP4_SC_VISUAL_OBJECT_SEQUENCE:
    235             wi.vwi_type = VIDDEC_WORKLOAD_SEQ_USER_DATA;
    236             break;
    237         case MP4_SC_VISUAL_OBJECT:
    238             wi.vwi_type = VIDDEC_WORKLOAD_VISUAL_OBJ_USER_DATA;
    239             break;
    240         case MP4_SC_GROUP_OF_VOP:
    241             wi.vwi_type = VIDDEC_WORKLOAD_GOP_USER_DATA;
    242             break;
    243         case MP4_SC_VIDEO_OBJECT_LAYER_MIN:
    244             wi.vwi_type = VIDDEC_WORKLOAD_VIDEO_OBJ_USER_DATA;
    245             break;
    246         default:
    247             wi.vwi_type = VIDDEC_WORKLOAD_INVALID; //ERROR - should not happen
    248             break;
    249     }
    250 
    251     /* Read 1 byte of user data and store it in workitem for the current stream level (VS/VO/VOL/GVOP).
    252        Keep adding data payloads till it reaches size 11. When it is 11, the maximum user data payload size,
    253        append the workitem. This loop is repeated till all user data is extracted and appended. */
    254     wi.user_data.size = 0;
    255     while(viddec_pm_get_bits(parent, &user_data, 8) != -1)
    256     {
    257         /* Store the valid byte in data payload */
    258         wi.user_data.data_payload[wi.user_data.size] = user_data;
    259         wi.user_data.size++;
    260 
    261         /* When size exceeds payload size, append workitem and continue */
    262         if (wi.user_data.size >= 11)
    263         {
    264             viddec_pm_setup_userdata(&wi);
    265             ret = viddec_pm_append_workitem(parent, &wi);
    266             wi.user_data.size = 0;
    267         }
    268     }
    269     /* If size is not 0, append remaining user data. */
    270     if (wi.user_data.size > 0)
    271     {
    272         int i;
    273         for(i=wi.user_data.size;i<11;i++)
    274         {
    275             wi.user_data.data_payload[i] = 0;
    276         }
    277         viddec_pm_setup_userdata(&wi);
    278         ret = viddec_pm_append_workitem(parent, &wi);
    279         wi.user_data.size = 0;
    280     }
    281 
    282     if(ret == 1)
    283         ret = MP4_STATUS_OK;
    284 
    285     return ret;
    286 } // mp4_Parse_UserData
    287 
    288