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