• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "viddec_mp4_visualobject.h"
2 
mp4_pvt_isValid_verID(uint8_t id)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 
mp4_Parse_video_signal_type(void * parent,mp4_VideoSignalType_t * vidSignal)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 
mp4_set_hdr_bitstream_error(viddec_mp4_parser_t * parser,uint8_t hdr_flag,mp4_Status_t parse_status)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 
mp4_Parse_VisualSequence(void * parent,viddec_mp4_parser_t * parser)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 
mp4_Parse_VisualObject(void * parent,viddec_mp4_parser_t * parser)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 
mp4_Parse_UserData(void * parent,viddec_mp4_parser_t * parser)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