1 /*
2  INTEL CONFIDENTIAL
3  Copyright 2009 Intel Corporation All Rights Reserved.
4  The source code contained or described herein and all documents related to the source code ("Material") are owned by Intel Corporation or its suppliers or licensors. Title to the Material remains with Intel Corporation or its suppliers and licensors. The Material contains trade secrets and proprietary and confidential information of Intel or its suppliers and licensors. The Material is protected by worldwide copyright and trade secret laws and treaty provisions. No part of the Material may be used, copied, reproduced, modified, published, uploaded, posted, transmitted, distributed, or disclosed in any way without Intel’s prior express written permission.
5 
6  No license under any patent, copyright, trade secret or other intellectual property right is granted to or conferred upon you by disclosure or delivery of the Materials, either expressly, by implication, inducement, estoppel or otherwise. Any license under such intellectual property rights must be express and approved by Intel in writing.
7  */
8 
9 
10 #include <glib.h>
11 #include <dlfcn.h>
12 
13 #include "h264.h"
14 #include "vbp_loader.h"
15 #include "vbp_utils.h"
16 #include "vbp_h264_parser.h"
17 
18 
19 /* number of bytes used to encode length of NAL payload. Default is 4 bytes. */
20 static int NAL_length_size = 4;
21 
22 /* default scaling list table */
23 unsigned char Default_4x4_Intra[16] =
24 {
25     6,13,20,28,
26     13,20,28,32,
27     20,28,32,37,
28     28,32,37,42
29 };
30 
31 unsigned char Default_4x4_Inter[16] =
32 {
33     10,14,20,24,
34     14,20,24,27,
35     20,24,27,30,
36     24,27,30,34
37 };
38 
39 unsigned char Default_8x8_Intra[64] =
40 {
41     6,10,13,16,18,23,25,27,
42     10,11,16,18,23,25,27,29,
43     13,16,18,23,25,27,29,31,
44     16,18,23,25,27,29,31,33,
45     18,23,25,27,29,31,33,36,
46     23,25,27,29,31,33,36,38,
47     25,27,29,31,33,36,38,40,
48     27,29,31,33,36,38,40,42
49 };
50 
51 unsigned char Default_8x8_Inter[64] =
52 {
53     9,13,15,17,19,21,22,24,
54     13,13,17,19,21,22,24,25,
55     15,17,19,21,22,24,25,27,
56     17,19,21,22,24,25,27,28,
57     19,21,22,24,25,27,28,30,
58     21,22,24,25,27,28,30,32,
59     22,24,25,27,28,30,32,33,
60     24,25,27,28,30,32,33,35
61 };
62 
63 unsigned char quant_flat[16] =
64 {
65     16,16,16,16,
66     16,16,16,16,
67     16,16,16,16,
68     16,16,16,16
69 };
70 
71 unsigned char quant8_flat[64] =
72 {
73     16,16,16,16,16,16,16,16,
74     16,16,16,16,16,16,16,16,
75     16,16,16,16,16,16,16,16,
76     16,16,16,16,16,16,16,16,
77     16,16,16,16,16,16,16,16,
78     16,16,16,16,16,16,16,16,
79     16,16,16,16,16,16,16,16,
80     16,16,16,16,16,16,16,16
81 };
82 
83 unsigned char* UseDefaultList[8] =
84 {
85     Default_4x4_Intra, Default_4x4_Intra, Default_4x4_Intra,
86     Default_4x4_Inter, Default_4x4_Inter, Default_4x4_Inter,
87     Default_8x8_Intra,
88     Default_8x8_Inter
89 };
90 
91 /**
92  *
93  */
vbp_init_parser_entries_h264(vbp_context * pcontext)94 uint32 vbp_init_parser_entries_h264(vbp_context *pcontext)
95 {
96  	if (NULL == pcontext->parser_ops)
97 	{
98 		return VBP_PARM;
99 	}
100 	pcontext->parser_ops->init = dlsym(pcontext->fd_parser, "viddec_h264_init");
101 	if (NULL == pcontext->parser_ops->init)
102 	{
103 		ETRACE ("Failed to set entry point." );
104 		return VBP_LOAD;
105 	}
106 
107 	pcontext->parser_ops->parse_sc = viddec_parse_sc;
108 
109 	pcontext->parser_ops->parse_syntax = dlsym(pcontext->fd_parser, "viddec_h264_parse");
110 	if (NULL == pcontext->parser_ops->parse_syntax)
111 	{
112 		ETRACE ("Failed to set entry point." );
113 		return VBP_LOAD;
114 	}
115 
116 	pcontext->parser_ops->get_cxt_size = dlsym(pcontext->fd_parser, "viddec_h264_get_context_size");
117 	if (NULL == pcontext->parser_ops->get_cxt_size)
118 	{
119 		ETRACE ("Failed to set entry point." );
120 		return VBP_LOAD;
121 	}
122 
123 	pcontext->parser_ops->is_wkld_done = dlsym(pcontext->fd_parser, "viddec_h264_wkld_done");
124 	if (NULL == pcontext->parser_ops->is_wkld_done)
125 	{
126 		ETRACE ("Failed to set entry point." );
127 		return VBP_LOAD;
128 	}
129 
130 	/* entry point not needed */
131 	pcontext->parser_ops->is_frame_start = NULL;
132 	return VBP_OK;
133 }
134 
135 
136 /**
137  *
138  */
vbp_allocate_query_data_h264(vbp_context * pcontext)139 uint32 vbp_allocate_query_data_h264(vbp_context *pcontext)
140 {
141 	if (NULL != pcontext->query_data)
142 	{
143 		return VBP_PARM;
144 	}
145 
146 	pcontext->query_data = NULL;
147 	vbp_data_h264 *query_data = NULL;
148 
149 	query_data = g_try_new0(vbp_data_h264, 1);
150 	if (NULL == query_data)
151 	{
152 		goto cleanup;
153 	}
154 
155 	/* assign the pointer */
156 	pcontext->query_data = (void *)query_data;
157 
158 	query_data->pic_data = g_try_new0(vbp_picture_data_h264, MAX_NUM_PICTURES);
159 	if (NULL == query_data->pic_data)
160 	{
161 		goto cleanup;
162 	}
163 
164 	int i;
165 	for (i = 0; i < MAX_NUM_PICTURES; i++)
166 	{
167 		query_data->pic_data[i].pic_parms = g_try_new0(VAPictureParameterBufferH264, 1);
168 		if (NULL == query_data->pic_data[i].pic_parms)
169 		{
170 			goto cleanup;
171 		}
172 		query_data->pic_data[i].num_slices = 0;
173 		query_data->pic_data[i].slc_data = g_try_new0(vbp_slice_data_h264, MAX_NUM_SLICES);
174 		if (NULL == query_data->pic_data[i].slc_data)
175 		{
176 			goto cleanup;
177 		}
178 	}
179 
180 
181 	query_data->IQ_matrix_buf = g_try_new0(VAIQMatrixBufferH264, 1);
182 	if (NULL == query_data->IQ_matrix_buf)
183 	{
184 		goto cleanup;
185 	}
186 
187 	query_data->codec_data = g_try_new0(vbp_codec_data_h264, 1);
188 	if (NULL == query_data->codec_data)
189 	{
190 		goto cleanup;
191 	}
192 
193 	return VBP_OK;
194 
195 cleanup:
196 	vbp_free_query_data_h264(pcontext);
197 
198 	return VBP_MEM;
199 }
200 
vbp_free_query_data_h264(vbp_context * pcontext)201 uint32 vbp_free_query_data_h264(vbp_context *pcontext)
202 {
203 	if (NULL == pcontext->query_data)
204 	{
205 		return VBP_OK;
206 	}
207 
208 	int i;
209 	vbp_data_h264 *query_data;
210 	query_data = (vbp_data_h264 *)pcontext->query_data;
211 
212 	if (query_data->pic_data)
213 	{
214 		for (i = 0; i < MAX_NUM_PICTURES; i++)
215 		{
216 			g_free(query_data->pic_data[i].slc_data);
217 			g_free(query_data->pic_data[i].pic_parms);
218 		}
219 		g_free(query_data->pic_data);
220 	}
221 
222 	g_free(query_data->IQ_matrix_buf);
223 	g_free(query_data->codec_data);
224 	g_free(query_data);
225 
226 	pcontext->query_data = NULL;
227 
228 	return VBP_OK;
229 }
230 
231 
vbp_utils_ntohs(uint8_t * p)232 static inline uint16_t vbp_utils_ntohs(uint8_t* p)
233 {
234 	uint16_t i = ((*p) << 8) + ((*(p+1)));
235 	return i;
236 }
237 
vbp_utils_ntohl(uint8_t * p)238 static inline uint32_t vbp_utils_ntohl(uint8_t* p)
239 {
240 	uint32_t i = ((*p) << 24) + ((*(p+1)) << 16) + ((*(p+2)) << 8) + ((*(p+3)));
241 	return i;
242 }
243 
244 
vbp_set_VAPicture_h264(int curr_picture_structure,int bottom_field,frame_store * store,VAPictureH264 * pic)245 static inline void vbp_set_VAPicture_h264(
246 	int curr_picture_structure,
247 	int bottom_field,
248 	frame_store* store,
249 	VAPictureH264* pic)
250 {
251 	if (FRAME == curr_picture_structure)
252 	{
253 		if (FRAME != viddec_h264_get_dec_structure(store))
254 		{
255 			WTRACE("Reference picture structure is not frame for current frame picture!");
256 		}
257 		pic->flags = 0;
258 		pic->TopFieldOrderCnt = store->frame.poc;
259 		pic->BottomFieldOrderCnt = store->frame.poc;
260 	}
261 	else
262 	{
263 		if (FRAME == viddec_h264_get_dec_structure(store))
264 		{
265 			WTRACE("reference picture structure is frame for current field picture!");
266 		}
267 		if (bottom_field)
268 		{
269 			pic->flags = VA_PICTURE_H264_BOTTOM_FIELD;
270 			pic->TopFieldOrderCnt = store->top_field.poc;
271 			pic->BottomFieldOrderCnt = store->bottom_field.poc;
272 		}
273 		else
274 		{
275 			pic->flags = VA_PICTURE_H264_TOP_FIELD;
276 			pic->TopFieldOrderCnt = store->top_field.poc;
277 			pic->BottomFieldOrderCnt = store->bottom_field.poc;
278 		}
279 	}
280 }
281 
vbp_set_slice_ref_list_h264(struct h264_viddec_parser * h264_parser,VASliceParameterBufferH264 * slc_parms)282 static inline void vbp_set_slice_ref_list_h264(
283 	struct h264_viddec_parser* h264_parser,
284 	VASliceParameterBufferH264 *slc_parms)
285 {
286 	int i, j;
287 	int num_ref_idx_active = 0;
288 	h264_Slice_Header_t* slice_header = &(h264_parser->info.SliceHeader);
289 	uint8_t* p_list = NULL;
290 	VAPictureH264* refPicListX = NULL;
291 	frame_store* fs = NULL;
292 
293 	/* initialize ref picutre list, set picture id and flags to invalid. */
294 
295 	for (i = 0; i < 2; i++)
296 	{
297 		refPicListX = (i == 0) ? &(slc_parms->RefPicList0[0]) : &(slc_parms->RefPicList1[0]);
298 		for (j = 0; j < 32; j++)
299     	{
300 	    	refPicListX->picture_id = VA_INVALID_SURFACE;
301 			refPicListX->frame_idx = 0;
302 	    	refPicListX->flags = VA_PICTURE_H264_INVALID;
303 			refPicListX->TopFieldOrderCnt = 0;
304 			refPicListX->BottomFieldOrderCnt = 0;
305 			refPicListX++;
306 		}
307     }
308 
309 	for (i = 0; i < 2; i++)
310 	{
311 		refPicListX = (i == 0) ? &(slc_parms->RefPicList0[0]) : &(slc_parms->RefPicList1[0]);
312 
313   		if ((i == 0) &&
314 			((h264_PtypeB == slice_header->slice_type) ||
315 			(h264_PtypeP == slice_header->slice_type)))
316    		{
317        		num_ref_idx_active = slice_header->num_ref_idx_l0_active;
318        		if (slice_header->sh_refpic_l0.ref_pic_list_reordering_flag)
319        		{
320        			p_list = h264_parser->info.slice_ref_list0;
321        		}
322        		else
323        		{
324        			p_list = h264_parser->info.dpb.listX_0;
325        		}
326    		}
327    		else if((i == 1) && (h264_PtypeB == slice_header->slice_type))
328    		{
329        		num_ref_idx_active = slice_header->num_ref_idx_l1_active;
330        		if (slice_header->sh_refpic_l1.ref_pic_list_reordering_flag)
331        		{
332        			p_list = h264_parser->info.slice_ref_list1;
333          	}
334          	else
335          	{
336             	p_list = h264_parser->info.dpb.listX_1;
337          	}
338    		}
339    		else
340    		{
341        	 	num_ref_idx_active = 0;
342        		p_list = NULL;
343       	}
344 
345 
346 		for (j = 0; j < num_ref_idx_active; j++)
347 		{
348 			fs = &(h264_parser->info.dpb.fs[(p_list[j] & 0x1f)]);
349 
350 			/* bit 5 indicates if reference picture is bottom field */
351 			vbp_set_VAPicture_h264(
352 				h264_parser->info.img.structure,
353 				(p_list[j] & 0x20) >> 5,
354 				fs,
355 				refPicListX);
356 
357 			refPicListX->frame_idx = fs->frame_num;
358 			refPicListX->flags |= viddec_h264_get_is_long_term(fs) ? VA_PICTURE_H264_LONG_TERM_REFERENCE : VA_PICTURE_H264_SHORT_TERM_REFERENCE;
359 			refPicListX++;
360 		}
361 	}
362 }
363 
vbp_set_pre_weight_table_h264(struct h264_viddec_parser * h264_parser,VASliceParameterBufferH264 * slc_parms)364 static inline void vbp_set_pre_weight_table_h264(
365 	struct h264_viddec_parser* h264_parser,
366 	VASliceParameterBufferH264 *slc_parms)
367 {
368 	h264_Slice_Header_t* slice_header = &(h264_parser->info.SliceHeader);
369 	int i, j;
370 
371 	if ((((h264_PtypeP == slice_header->slice_type) ||
372     	(h264_PtypeB == slice_header->slice_type)) &&
373     	h264_parser->info.active_PPS.weighted_pred_flag) ||
374     	((h264_PtypeB == slice_header->slice_type) &&
375     	(1 == h264_parser->info.active_PPS.weighted_bipred_idc)))
376     {
377      	slc_parms->luma_log2_weight_denom = slice_header->sh_predwttbl.luma_log2_weight_denom;
378     	slc_parms->chroma_log2_weight_denom = slice_header->sh_predwttbl.chroma_log2_weight_denom;
379    		slc_parms->luma_weight_l0_flag = slice_header->sh_predwttbl.luma_weight_l0_flag;
380    		slc_parms->chroma_weight_l0_flag = slice_header->sh_predwttbl.chroma_weight_l0_flag;
381 		slc_parms->luma_weight_l1_flag = slice_header->sh_predwttbl.luma_weight_l1_flag;
382    		slc_parms->chroma_weight_l1_flag = slice_header->sh_predwttbl.chroma_weight_l1_flag;
383 
384    		for (i = 0; i < 32; i++)
385    		{
386    			slc_parms->luma_weight_l0[i] = 	slice_header->sh_predwttbl.luma_weight_l0[i];
387    			slc_parms->luma_offset_l0[i] = 	slice_header->sh_predwttbl.luma_offset_l0[i];
388    			slc_parms->luma_weight_l1[i] = 	slice_header->sh_predwttbl.luma_weight_l1[i];
389    			slc_parms->luma_offset_l1[i] = 	slice_header->sh_predwttbl.luma_offset_l1[i];
390 
391    			for (j = 0; j < 2; j++)
392    			{
393 	   			slc_parms->chroma_weight_l0[i][j] = slice_header->sh_predwttbl.chroma_weight_l0[i][j];
394 	   			slc_parms->chroma_offset_l0[i][j] = slice_header->sh_predwttbl.chroma_offset_l0[i][j];
395 	   			slc_parms->chroma_weight_l1[i][j] = slice_header->sh_predwttbl.chroma_weight_l1[i][j];
396 	   			slc_parms->chroma_offset_l1[i][j] = slice_header->sh_predwttbl.chroma_offset_l1[i][j];
397    			}
398    		}
399    	}
400    	else
401    	{
402 	   	/* default weight table */
403     	slc_parms->luma_log2_weight_denom = 5;
404     	slc_parms->chroma_log2_weight_denom = 5;
405     	slc_parms->luma_weight_l0_flag = 0;
406     	slc_parms->luma_weight_l1_flag = 0;
407 		slc_parms->chroma_weight_l0_flag = 0;
408    		slc_parms->chroma_weight_l1_flag = 0;
409     	for (i = 0; i < 32; i++)
410     	{
411     		slc_parms->luma_weight_l0[i] = 0;
412     		slc_parms->luma_offset_l0[i] = 0;
413     		slc_parms->luma_weight_l1[i] = 0;
414     		slc_parms->luma_offset_l1[i] = 0;
415 
416 			for (j = 0; j < 2; j++)
417 			{
418    				slc_parms->chroma_weight_l0[i][j] = 0;
419     			slc_parms->chroma_offset_l0[i][j] = 0;
420     			slc_parms->chroma_weight_l1[i][j] = 0;
421 	 			slc_parms->chroma_offset_l1[i][j] = 0;
422 			}
423 		}
424     }
425 }
426 
427 
vbp_set_reference_frames_h264(struct h264_viddec_parser * parser,VAPictureParameterBufferH264 * pic_parms)428 static inline void vbp_set_reference_frames_h264(
429 	struct h264_viddec_parser *parser,
430 	VAPictureParameterBufferH264* pic_parms)
431 {
432 	int buffer_idx;
433 	int frame_idx;
434 	frame_store* store = NULL;
435 	h264_DecodedPictureBuffer* dpb = &(parser->info.dpb);
436 	/* initialize reference frames */
437 	for (frame_idx = 0; frame_idx < 16; frame_idx++)
438 	{
439 		pic_parms->ReferenceFrames[frame_idx].picture_id = VA_INVALID_SURFACE;
440 		pic_parms->ReferenceFrames[frame_idx].frame_idx = 0;
441 		pic_parms->ReferenceFrames[frame_idx].flags = VA_PICTURE_H264_INVALID;
442 		pic_parms->ReferenceFrames[frame_idx].TopFieldOrderCnt = 0;
443 		pic_parms->ReferenceFrames[frame_idx].BottomFieldOrderCnt = 0;
444 	}
445 	pic_parms->num_ref_frames = 0;
446 
447 	frame_idx = 0;
448 
449 	/* ITRACE("short term frame in dpb %d", dpb->ref_frames_in_buffer);  */
450 	/* set short term reference frames */
451 	for (buffer_idx = 0; buffer_idx < dpb->ref_frames_in_buffer; buffer_idx++)
452 	{
453 		if (frame_idx >= 16)
454 		{
455 			WTRACE("Frame index is out of bound.");
456 			break;
457 		}
458 
459 		store = &dpb->fs[dpb->fs_ref_idc[buffer_idx]];
460 		/* if (store->is_used == 3 && store->frame.used_for_reference == 3) */
461 		if (viddec_h264_get_is_used(store))
462 		{
463 			pic_parms->ReferenceFrames[frame_idx].frame_idx = store->frame_num;
464 			pic_parms->ReferenceFrames[frame_idx].flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE;
465 			if (FRAME == parser->info.img.structure)
466 			{
467 				pic_parms->ReferenceFrames[frame_idx].TopFieldOrderCnt = store->frame.poc;
468 				pic_parms->ReferenceFrames[frame_idx].BottomFieldOrderCnt = store->frame.poc;
469 			}
470 			else
471 			{
472 				pic_parms->ReferenceFrames[frame_idx].TopFieldOrderCnt = store->top_field.poc;
473 				pic_parms->ReferenceFrames[frame_idx].BottomFieldOrderCnt = store->bottom_field.poc;
474 				if (store->top_field.used_for_reference && store->bottom_field.used_for_reference)
475 				{
476 					/* if both fields are used for reference, just set flag to be frame (0) */
477 				}
478 				else
479 				{
480 					if (store->top_field.used_for_reference)
481 						pic_parms->ReferenceFrames[frame_idx].flags |= VA_PICTURE_H264_TOP_FIELD;
482 					if (store->bottom_field.used_for_reference)
483 						pic_parms->ReferenceFrames[frame_idx].flags |= VA_PICTURE_H264_BOTTOM_FIELD;
484 				}
485 			}
486 		}
487 		frame_idx++;
488 	}
489 
490 	/* set long term reference frames */
491 	for (buffer_idx = 0; buffer_idx < dpb->ltref_frames_in_buffer; buffer_idx++)
492 	{
493 		if (frame_idx >= 16)
494 		{
495 			WTRACE("Frame index is out of bound.");
496 			break;
497 		}
498 		store = &dpb->fs[dpb->fs_ltref_idc[buffer_idx]];
499 		if (!viddec_h264_get_is_long_term(store))
500 		{
501 			WTRACE("long term frame is not marked as long term.");
502 		}
503 		/*if (store->is_used == 3 && store->is_long_term && store->frame.used_for_reference == 3) */
504 		if (viddec_h264_get_is_used(store))
505 		{
506 			pic_parms->ReferenceFrames[frame_idx].flags = VA_PICTURE_H264_LONG_TERM_REFERENCE;
507 			if (FRAME == parser->info.img.structure)
508 			{
509 				pic_parms->ReferenceFrames[frame_idx].TopFieldOrderCnt = store->frame.poc;
510 				pic_parms->ReferenceFrames[frame_idx].BottomFieldOrderCnt = store->frame.poc;
511 			}
512 			else
513 			{
514 				pic_parms->ReferenceFrames[frame_idx].TopFieldOrderCnt = store->top_field.poc;
515 				pic_parms->ReferenceFrames[frame_idx].BottomFieldOrderCnt = store->bottom_field.poc;
516 				if (store->top_field.used_for_reference && store->bottom_field.used_for_reference)
517 				{
518 					/* if both fields are used for reference, just set flag to be frame (0)*/
519 				}
520 				else
521 				{
522 					if (store->top_field.used_for_reference)
523 						pic_parms->ReferenceFrames[frame_idx].flags |= VA_PICTURE_H264_TOP_FIELD;
524 					if (store->bottom_field.used_for_reference)
525 						pic_parms->ReferenceFrames[frame_idx].flags |= VA_PICTURE_H264_BOTTOM_FIELD;
526 				}
527 			}
528 		}
529 		frame_idx++;
530 	}
531 
532 	pic_parms->num_ref_frames = frame_idx;
533 
534 	if (frame_idx > parser->info.active_SPS.num_ref_frames)
535 	{
536 		WTRACE("actual num_ref_frames (%d) exceeds the value in the sequence header (%d).",
537 			frame_idx, parser->info.active_SPS.num_ref_frames);
538 	}
539 }
540 
541 
vbp_set_scaling_list_h264(struct h264_viddec_parser * parser,VAIQMatrixBufferH264 * IQ_matrix_buf)542 static inline void vbp_set_scaling_list_h264(
543 	struct h264_viddec_parser *parser,
544 	VAIQMatrixBufferH264* IQ_matrix_buf)
545 {
546   	int i;
547   	if (parser->info.active_PPS.pic_scaling_matrix_present_flag)
548   	{
549 		for (i = 0; i < 6 + 2 * parser->info.active_PPS.transform_8x8_mode_flag; i++)
550     	{
551       		if (parser->info.active_PPS.pic_scaling_list_present_flag[i])
552       		{
553         		if (((i < 6) && parser->info.active_PPS.UseDefaultScalingMatrix4x4Flag[i]) ||
554             		((i >= 6) && parser->info.active_PPS.UseDefaultScalingMatrix8x8Flag[i-6]))
555 				{
556   	  				/* use default scaling list */
557 	  				if (i < 6)
558           			{
559 	    				memcpy(IQ_matrix_buf->ScalingList4x4[i], UseDefaultList[i], 16);
560 	  				}
561 	  				else
562           			{
563 	    				memcpy(IQ_matrix_buf->ScalingList8x8[i - 6], UseDefaultList[i], 64);
564 	  				}
565 				}
566 				else
567 				{
568 	  				/* use PPS list */
569 	  				if (i < 6)
570 	  				{
571 	    				memcpy(IQ_matrix_buf->ScalingList4x4[i], parser->info.active_PPS.ScalingList4x4[i], 16);
572 	  				}
573 	  				else
574 	  				{
575 	    				memcpy(IQ_matrix_buf->ScalingList8x8[i - 6], parser->info.active_PPS.ScalingList8x8[i - 6], 64);
576 	  				}
577 				}
578       		}
579       		else /* pic_scaling_list not present */
580       		{
581 				if (parser->info.active_SPS.seq_scaling_matrix_present_flag)
582 				{
583   	  				/* SPS matrix present - use fallback rule B */
584 	  				switch (i)
585 	  				{
586 	    				case 0:
587 	    				case 3:
588 	      					memcpy(IQ_matrix_buf->ScalingList4x4[i],
589 								parser->info.active_SPS.seq_scaling_list_present_flag[i] ? parser->info.active_PPS.ScalingList4x4[i] : UseDefaultList[i],
590                 				16);
591 	      				break;
592 
593 					    case 6:
594 	    				case 7:
595 	      					memcpy(IQ_matrix_buf->ScalingList8x8[i - 6],
596 								parser->info.active_SPS.seq_scaling_list_present_flag[i] ? parser->info.active_PPS.ScalingList8x8[i - 6] : UseDefaultList[i],
597                 				64);
598 	      				break;
599 
600 	    				case 1:
601 	    				case 2:
602 	    				case 4:
603 	    				case 5:
604 	      					memcpy(IQ_matrix_buf->ScalingList4x4[i],
605 								IQ_matrix_buf->ScalingList4x4[i - 1],
606                 				16);
607 	      				break;
608 
609             			default:
610 	      					g_warning("invalid scaling list index.");
611               			break;
612 	  				}
613 				}
614 				else /* seq_scaling_matrix not present */
615 				{
616 	  				/* SPS matrix not present - use fallback rule A */
617 	  				switch (i)
618 	  				{
619 	    				case 0:
620 	    				case 3:
621 	      					memcpy(IQ_matrix_buf->ScalingList4x4[i], UseDefaultList[i], 16);
622 	      				break;
623 
624 	    				case 6:
625 	    				case 7:
626 	      					memcpy(IQ_matrix_buf->ScalingList8x8[i - 6], UseDefaultList[i], 64);
627               			break;
628 
629 				   	    case 1:
630 	    				case 2:
631 	    				case 4:
632 	    				case 5:
633 	      					memcpy(IQ_matrix_buf->ScalingList4x4[i],
634 								IQ_matrix_buf->ScalingList4x4[i - 1],
635                 				16);
636             			break;
637 
638 	    				default:
639 	      					WTRACE("invalid scaling list index.");
640               			break;
641 	  				}
642 				} /* end of seq_scaling_matrix not present */
643       		} /* end of  pic_scaling_list not present */
644     	} /* for loop for each index from 0 to 7 */
645   	} /* end of pic_scaling_matrix present */
646   	else
647   	{
648     	/* PPS matrix not present, use SPS information */
649     	if (parser->info.active_SPS.seq_scaling_matrix_present_flag)
650     	{
651       		for (i = 0; i < 6 + 2 * parser->info.active_PPS.transform_8x8_mode_flag; i++)
652       		{
653 				if (parser->info.active_SPS.seq_scaling_list_present_flag[i])
654 				{
655           			if (((i < 6) && parser->info.active_SPS.UseDefaultScalingMatrix4x4Flag[i]) ||
656             			((i >= 6) && parser->info.active_SPS.UseDefaultScalingMatrix8x8Flag[i - 6]))
657 	  				{
658  	    				/* use default scaling list */
659 	    				if (i < 6)
660             			{
661 	      					memcpy(IQ_matrix_buf->ScalingList4x4[i], UseDefaultList[i], 16);
662 	    				}
663 	    				else
664             			{
665 				      		memcpy(IQ_matrix_buf->ScalingList8x8[i - 6], UseDefaultList[i], 64);
666 					    }
667 					}
668 					else
669 					{
670   	    				/* use SPS list */
671 	    				if (i < 6)
672 	    				{
673 	      					memcpy(IQ_matrix_buf->ScalingList4x4[i], parser->info.active_SPS.ScalingList4x4[i], 16);
674 	    				}
675 	    				else
676 	    				{
677 	      					memcpy(IQ_matrix_buf->ScalingList8x8[i - 6], parser->info.active_SPS.ScalingList8x8[i - 6], 64);
678 	    				}
679 	  				}
680 				}
681 				else
682 				{
683 	  				/* SPS list not present - use fallback rule A */
684 	  				switch (i)
685 	  				{
686 	    				case 0:
687 	    				case 3:
688 	      					memcpy(IQ_matrix_buf->ScalingList4x4[i], UseDefaultList[i], 16);
689               			break;
690 
691 	    				case 6:
692 	    				case 7:
693 	      					memcpy(IQ_matrix_buf->ScalingList8x8[i - 6], UseDefaultList[i], 64);
694               			break;
695 
696 	    				case 1:
697 	    				case 2:
698 	    				case 4:
699 	    				case 5:
700 	      					memcpy(IQ_matrix_buf->ScalingList4x4[i],
701 								IQ_matrix_buf->ScalingList4x4[i - 1],
702                 				16);
703               			break;
704 
705   	    				default:
706 	      					WTRACE("invalid scaling list index.");
707               			break;
708 	  				}
709 				}
710       		}
711     	}
712     	else
713     	{
714       		/* SPS matrix not present - use flat lists */
715       		for (i = 0; i < 6; i++)
716       		{
717 				memcpy(IQ_matrix_buf->ScalingList4x4[i], quant_flat, 16);
718       		}
719       		for (i = 0; i < 2; i++)
720       		{
721  				memcpy(IQ_matrix_buf->ScalingList8x8[i], quant8_flat, 64);
722       		}
723     	}
724   	}
725 
726   	if ((0 == parser->info.active_PPS.transform_8x8_mode_flag) &&
727   		(parser->info.active_PPS.pic_scaling_matrix_present_flag ||
728   		parser->info.active_SPS.seq_scaling_matrix_present_flag))
729   	{
730      	for (i = 0; i < 2; i++)
731       	{
732  			memcpy(IQ_matrix_buf->ScalingList8x8[i], quant8_flat, 64);
733       	}
734   	}
735 }
736 
vbp_set_codec_data_h264(struct h264_viddec_parser * parser,vbp_codec_data_h264 * codec_data)737 static void vbp_set_codec_data_h264(
738 	struct h264_viddec_parser *parser,
739 	vbp_codec_data_h264* codec_data)
740 {
741 	/* parameter id */
742 	codec_data->seq_parameter_set_id = parser->info.active_SPS.seq_parameter_set_id;
743 	codec_data->pic_parameter_set_id = parser->info.active_PPS.pic_parameter_set_id;
744 
745 	/* profile and level */
746 	codec_data->profile_idc = parser->info.active_SPS.profile_idc;
747 	codec_data->level_idc = parser->info.active_SPS.level_idc;
748 
749 
750 	 codec_data->constraint_set1_flag = (parser->info.active_SPS.constraint_set_flags & 0x4) >> 2;
751 
752 
753 	/* reference frames */
754 	codec_data->num_ref_frames = parser->info.active_SPS.num_ref_frames;
755 
756 	if (!parser->info.active_SPS.sps_disp.frame_mbs_only_flag &&
757 		!parser->info.active_SPS.sps_disp.mb_adaptive_frame_field_flag)
758 	{
759 		/* no longer necessary: two fields share the same interlaced surface */
760 		/* codec_data->num_ref_frames *= 2; */
761 	}
762 
763 	codec_data->gaps_in_frame_num_value_allowed_flag = parser->info.active_SPS.gaps_in_frame_num_value_allowed_flag;
764 
765 	/* frame coding */
766 	codec_data->frame_mbs_only_flag = parser->info.active_SPS.sps_disp.frame_mbs_only_flag;
767 	codec_data->mb_adaptive_frame_field_flag = parser->info.active_SPS.sps_disp.mb_adaptive_frame_field_flag;
768 
769  	/* frame dimension */
770 	codec_data->frame_width = (parser->info.active_SPS.sps_disp.pic_width_in_mbs_minus1 + 1 ) * 16;
771 
772 	codec_data->frame_height = (2 - parser->info.active_SPS.sps_disp.frame_mbs_only_flag) *
773 			(parser->info.active_SPS.sps_disp.pic_height_in_map_units_minus1 + 1) * 16;
774 
775 	/* frame cropping */
776 	codec_data->frame_cropping_flag =
777 		parser->info.active_SPS.sps_disp.frame_cropping_flag;
778 
779 	codec_data->frame_crop_rect_left_offset =
780 		parser->info.active_SPS.sps_disp.frame_crop_rect_left_offset;
781 
782 	codec_data->frame_crop_rect_right_offset =
783 		parser->info.active_SPS.sps_disp.frame_crop_rect_right_offset;
784 
785 	codec_data->frame_crop_rect_top_offset =
786 		parser->info.active_SPS.sps_disp.frame_crop_rect_top_offset;
787 
788 	codec_data->frame_crop_rect_bottom_offset =
789 		parser->info.active_SPS.sps_disp.frame_crop_rect_bottom_offset;
790 
791 	/* aspect ratio	  */
792 	codec_data->aspect_ratio_info_present_flag =
793 		parser->info.active_SPS.sps_disp.vui_seq_parameters.aspect_ratio_info_present_flag;
794 
795 	codec_data->aspect_ratio_idc =
796 		parser->info.active_SPS.sps_disp.vui_seq_parameters.aspect_ratio_idc;
797 
798 	codec_data->sar_width =
799 		parser->info.active_SPS.sps_disp.vui_seq_parameters.sar_width;
800 
801 	codec_data->sar_height =
802 		parser->info.active_SPS.sps_disp.vui_seq_parameters.sar_height;
803 
804 	 /* video format */
805 	 codec_data->video_format =
806 		parser->info.active_SPS.sps_disp.vui_seq_parameters.video_format;
807 
808 	codec_data->video_format =
809 		parser->info.active_SPS.sps_disp.vui_seq_parameters.video_signal_type_present_flag;
810 }
811 
812 
vbp_add_pic_data_h264(vbp_context * pcontext,int list_index)813 static uint32_t vbp_add_pic_data_h264(vbp_context *pcontext, int list_index)
814 {
815 	viddec_pm_cxt_t *cxt = pcontext->parser_cxt;
816 
817 	vbp_data_h264 *query_data = (vbp_data_h264 *)pcontext->query_data;
818 	struct h264_viddec_parser* parser = NULL;
819 	vbp_picture_data_h264* pic_data = NULL;
820   	VAPictureParameterBufferH264* pic_parms = NULL;
821 
822 	parser = (struct h264_viddec_parser *)cxt->codec_data;
823 
824 	if (0 == parser->info.SliceHeader.first_mb_in_slice)
825 	{
826 		/* a new picture is parsed */
827 		query_data->num_pictures++;
828 	}
829 
830 	if (query_data->num_pictures > MAX_NUM_PICTURES)
831 	{
832 		ETRACE("num of pictures exceeds the limit (%d).", MAX_NUM_PICTURES);
833 		return VBP_DATA;
834 	}
835 
836 	int pic_data_index = query_data->num_pictures - 1;
837 	if (pic_data_index < 0)
838 	{
839 		WTRACE("MB address does not start from 0!");
840 		return VBP_DATA;
841 	}
842 
843 	pic_data = &(query_data->pic_data[pic_data_index]);
844 	pic_parms = pic_data->pic_parms;
845 
846 	if (parser->info.SliceHeader.first_mb_in_slice == 0)
847 	{
848 		/**
849 		* picture parameter only needs to be set once,
850 		* even multiple slices may be encoded
851 		*/
852 
853 	  	/* VAPictureParameterBufferH264 */
854 	  	pic_parms->CurrPic.picture_id = VA_INVALID_SURFACE;
855  		pic_parms->CurrPic.frame_idx = 0;
856 	  	if (parser->info.img.field_pic_flag == 1)
857 	  	{
858 	    	if (parser->info.img.bottom_field_flag)
859 			{
860 				pic_parms->CurrPic.flags = VA_PICTURE_H264_BOTTOM_FIELD;
861 			}
862 	    	else
863 			{
864 				/* also OK set to 0 (from test suite) */
865 				pic_parms->CurrPic.flags = VA_PICTURE_H264_TOP_FIELD;
866 			}
867 	  	}
868 		else
869 		{
870 			pic_parms->CurrPic.flags = 0; /* frame picture */
871 		}
872 	  	pic_parms->CurrPic.TopFieldOrderCnt = parser->info.img.toppoc;
873 	  	pic_parms->CurrPic.BottomFieldOrderCnt = parser->info.img.bottompoc;
874 	  	pic_parms->CurrPic.frame_idx = parser->info.SliceHeader.frame_num;
875 
876 	  	/* don't care if current frame is used as long term reference */
877 	  	if (parser->info.SliceHeader.nal_ref_idc != 0)
878 	  	{
879 	    	pic_parms->CurrPic.flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE;
880 	  	}
881 
882 	  	pic_parms->picture_width_in_mbs_minus1 = parser->info.active_SPS.sps_disp.pic_width_in_mbs_minus1;
883 
884 	  	/* frame height in MBS */
885 	  	pic_parms->picture_height_in_mbs_minus1 = (2 - parser->info.active_SPS.sps_disp.frame_mbs_only_flag) *
886 			(parser->info.active_SPS.sps_disp.pic_height_in_map_units_minus1 + 1) - 1;
887 
888 	  	pic_parms->bit_depth_luma_minus8 = parser->info.active_SPS.bit_depth_luma_minus8;
889 	  	pic_parms->bit_depth_chroma_minus8 = parser->info.active_SPS.bit_depth_chroma_minus8;
890 
891 
892 		pic_parms->seq_fields.value = 0;
893 	  	pic_parms->seq_fields.bits.chroma_format_idc = parser->info.active_SPS.sps_disp.chroma_format_idc;
894 	  	pic_parms->seq_fields.bits.residual_colour_transform_flag = parser->info.active_SPS.residual_colour_transform_flag;
895 	  	pic_parms->seq_fields.bits.frame_mbs_only_flag = parser->info.active_SPS.sps_disp.frame_mbs_only_flag;
896 	  	pic_parms->seq_fields.bits.mb_adaptive_frame_field_flag = parser->info.active_SPS.sps_disp.mb_adaptive_frame_field_flag;
897 	  	pic_parms->seq_fields.bits.direct_8x8_inference_flag = parser->info.active_SPS.sps_disp.direct_8x8_inference_flag;
898 
899 		/* new fields in libva 0.31 */
900 		pic_parms->seq_fields.bits.gaps_in_frame_num_value_allowed_flag = parser->info.active_SPS.gaps_in_frame_num_value_allowed_flag;
901         pic_parms->seq_fields.bits.log2_max_frame_num_minus4 = parser->info.active_SPS.log2_max_frame_num_minus4;
902         pic_parms->seq_fields.bits.pic_order_cnt_type = parser->info.active_SPS.pic_order_cnt_type;
903         pic_parms->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = parser->info.active_SPS.log2_max_pic_order_cnt_lsb_minus4;
904         pic_parms->seq_fields.bits.delta_pic_order_always_zero_flag =parser->info.active_SPS.delta_pic_order_always_zero_flag;
905 
906 
907 	  	/* referened from UMG_Moorstown_TestSuites */
908 	  	pic_parms->seq_fields.bits.MinLumaBiPredSize8x8 = (parser->info.active_SPS.level_idc > 30) ? 1 : 0;
909 
910 	  	pic_parms->num_slice_groups_minus1 = parser->info.active_PPS.num_slice_groups_minus1;
911 	  	pic_parms->slice_group_map_type = parser->info.active_PPS.slice_group_map_type;
912 		pic_parms->slice_group_change_rate_minus1 = 0;
913 	  	pic_parms->pic_init_qp_minus26 = parser->info.active_PPS.pic_init_qp_minus26;
914 		pic_parms->pic_init_qs_minus26 = 0;
915 	  	pic_parms->chroma_qp_index_offset = parser->info.active_PPS.chroma_qp_index_offset;
916 	  	pic_parms->second_chroma_qp_index_offset = parser->info.active_PPS.second_chroma_qp_index_offset;
917 
918 		pic_parms->pic_fields.value = 0;
919 	  	pic_parms->pic_fields.bits.entropy_coding_mode_flag = parser->info.active_PPS.entropy_coding_mode_flag;
920 	  	pic_parms->pic_fields.bits.weighted_pred_flag = parser->info.active_PPS.weighted_pred_flag;
921 	  	pic_parms->pic_fields.bits.weighted_bipred_idc = parser->info.active_PPS.weighted_bipred_idc;
922 	  	pic_parms->pic_fields.bits.transform_8x8_mode_flag = parser->info.active_PPS.transform_8x8_mode_flag;
923 
924 		/* new LibVA fields in v0.31*/
925 		pic_parms->pic_fields.bits.pic_order_present_flag = parser->info.active_PPS.pic_order_present_flag;
926 		pic_parms->pic_fields.bits.deblocking_filter_control_present_flag = parser->info.active_PPS.deblocking_filter_control_present_flag;
927         pic_parms->pic_fields.bits.redundant_pic_cnt_present_flag = parser->info.active_PPS.redundant_pic_cnt_present_flag;
928         pic_parms->pic_fields.bits.reference_pic_flag = parser->info.SliceHeader.nal_ref_idc != 0;
929 
930 	  	/* all slices in the pciture have the same field_pic_flag */
931 	  	pic_parms->pic_fields.bits.field_pic_flag = parser->info.SliceHeader.field_pic_flag;
932 	  	pic_parms->pic_fields.bits.constrained_intra_pred_flag = parser->info.active_PPS.constrained_intra_pred_flag;
933 
934 	  	pic_parms->frame_num = parser->info.SliceHeader.frame_num;
935 	}
936 
937 
938 	/* set reference frames, and num_ref_frames */
939   	vbp_set_reference_frames_h264(parser, pic_parms);
940 	if (parser->info.nal_unit_type == h264_NAL_UNIT_TYPE_IDR)
941 	{
942 		/* num of reference frame is 0 if current picture is IDR */
943 		pic_parms->num_ref_frames = 0;
944 	}
945 	else
946 	{
947 		/* actual num_ref_frames is set in vbp_set_reference_frames_h264 */
948 	}
949 
950 	return VBP_OK;
951 }
952 
953 #if 0
954 static inline void vbp_update_reference_frames_h264_methodA(vbp_picture_data_h264* pic_data)
955 {
956   	VAPictureParameterBufferH264* pic_parms = pic_data->pic_parms;
957 
958 	char is_used[16];
959 	memset(is_used, 0, sizeof(is_used));
960 
961 	int ref_list;
962 	int slice_index;
963 	int i, j;
964 	VAPictureH264* pRefList = NULL;
965 
966 	for (slice_index = 0; slice_index < pic_data->num_slices; slice_index++)
967 	{
968 		VASliceParameterBufferH264* slice_parms =
969 			 &(pic_data->slc_data[slice_index].slc_parms);
970 
971 		for (ref_list = 0; ref_list < 2; ref_list++)
972 		{
973 			if (0 == ref_list)
974 				pRefList = slice_parms->RefPicList0;
975 			else
976 				pRefList = slice_parms->RefPicList1;
977 
978 			for (i = 0; i < 32; i++, pRefList++)
979 			{
980 				if (VA_PICTURE_H264_INVALID == pRefList->flags)
981 					break;
982 
983 				for (j = 0; j < 16; j++)
984 				{
985 					if (pic_parms->ReferenceFrames[j].TopFieldOrderCnt ==
986 						pRefList->TopFieldOrderCnt)
987 					{
988 						is_used[j] = 1;
989 						break;
990 					}
991 				}
992 			}
993 		}
994 	}
995 
996 	int frame_idx = 0;
997   	VAPictureH264* pRefFrame = pic_parms->ReferenceFrames;
998   	for (i = 0; i < 16; i++)
999 	{
1000 		if (is_used[i])
1001 		{
1002 			memcpy(pRefFrame,
1003 				&(pic_parms->ReferenceFrames[i]),
1004 				sizeof(VAPictureH264));
1005 
1006 			pRefFrame++;
1007 			frame_idx++;
1008 		}
1009 	}
1010 	pic_parms->num_ref_frames = frame_idx;
1011 
1012 	for (; frame_idx < 16; frame_idx++)
1013 	{
1014 		pRefFrame->picture_id = VA_INVALID_SURFACE;
1015 		pRefFrame->frame_idx = -1;
1016 		pRefFrame->flags = VA_PICTURE_H264_INVALID;
1017 		pRefFrame->TopFieldOrderCnt = -1;
1018 		pRefFrame->BottomFieldOrderCnt = -1;
1019 		pRefFrame++;
1020 	}
1021 }
1022 #endif
1023 
1024 #if 0
1025 static inline void vbp_update_reference_frames_h264_methodB(vbp_picture_data_h264* pic_data)
1026 {
1027   	VAPictureParameterBufferH264* pic_parms = pic_data->pic_parms;
1028 	int i;
1029   	VAPictureH264* pRefFrame = pic_parms->ReferenceFrames;
1030   	for (i = 0; i < 16; i++)
1031 	{
1032 		pRefFrame->picture_id = VA_INVALID_SURFACE;
1033 		pRefFrame->frame_idx = -1;
1034 		pRefFrame->flags = VA_PICTURE_H264_INVALID;
1035 		pRefFrame->TopFieldOrderCnt = -1;
1036 		pRefFrame->BottomFieldOrderCnt = -1;
1037 		pRefFrame++;
1038 	}
1039 
1040 	pic_parms->num_ref_frames = 0;
1041 
1042 
1043 	int ref_list;
1044 	int slice_index;
1045 	int j;
1046 	VAPictureH264* pRefList = NULL;
1047 
1048 	for (slice_index = 0; slice_index < pic_data->num_slices; slice_index++)
1049 	{
1050 		VASliceParameterBufferH264* slice_parms =
1051 			 &(pic_data->slc_data[slice_index].slc_parms);
1052 
1053 		for (ref_list = 0; ref_list < 2; ref_list++)
1054 		{
1055 			if (0 == ref_list)
1056 				pRefList = slice_parms->RefPicList0;
1057 			else
1058 				pRefList = slice_parms->RefPicList1;
1059 
1060 			for (i = 0; i < 32; i++, pRefList++)
1061 			{
1062 				if (VA_PICTURE_H264_INVALID == pRefList->flags)
1063 					break;
1064 
1065 				for (j = 0; j < 16; j++)
1066 				{
1067 					if (pic_parms->ReferenceFrames[j].TopFieldOrderCnt ==
1068 						pRefList->TopFieldOrderCnt)
1069 					{
1070 						pic_parms->ReferenceFrames[j].flags |=
1071 							pRefList->flags;
1072 
1073 						if ((pic_parms->ReferenceFrames[j].flags & VA_PICTURE_H264_TOP_FIELD) &&
1074 							(pic_parms->ReferenceFrames[j].flags & VA_PICTURE_H264_BOTTOM_FIELD))
1075 						{
1076 							pic_parms->ReferenceFrames[j].flags = 0;
1077 						}
1078 						break;
1079 					}
1080 				}
1081 				if (j == 16)
1082 				{
1083 					memcpy(&(pic_parms->ReferenceFrames[pic_parms->num_ref_frames++]),
1084 						pRefList,
1085 						sizeof(VAPictureH264));
1086 				}
1087 
1088 			}
1089 		}
1090 	}
1091 }
1092 #endif
1093 
1094 
vbp_add_slice_data_h264(vbp_context * pcontext,int index)1095 static uint32_t vbp_add_slice_data_h264(vbp_context *pcontext, int index)
1096 {
1097   	viddec_pm_cxt_t *cxt = pcontext->parser_cxt;
1098   	uint32 bit, byte;
1099   	uint8 is_emul;
1100 
1101 	vbp_data_h264 *query_data = (vbp_data_h264 *)pcontext->query_data;
1102 	VASliceParameterBufferH264 *slc_parms = NULL;
1103 	vbp_slice_data_h264 *slc_data = NULL;
1104 	struct h264_viddec_parser* h264_parser = NULL;
1105 	h264_Slice_Header_t* slice_header = NULL;
1106 	vbp_picture_data_h264* pic_data = NULL;
1107 
1108 
1109 	h264_parser = (struct h264_viddec_parser *)cxt->codec_data;
1110 	int pic_data_index = query_data->num_pictures - 1;
1111 	if (pic_data_index < 0)
1112 	{
1113 		ETRACE("invalid picture data index.");
1114 		return VBP_DATA;
1115 	}
1116 
1117 	pic_data = &(query_data->pic_data[pic_data_index]);
1118 
1119 	slc_data = &(pic_data->slc_data[pic_data->num_slices]);
1120 	slc_data->buffer_addr = cxt->parse_cubby.buf;
1121 	slc_parms = &(slc_data->slc_parms);
1122 
1123 	/* byte: how many bytes have been parsed */
1124 	/* bit: bits parsed within the current parsing position */
1125 	viddec_pm_get_au_pos(cxt, &bit, &byte, &is_emul);
1126 
1127 
1128 #if 0
1129 	/* add 4 bytes of start code prefix */
1130 	slc_parms->slice_data_size = slc_data->slice_size =
1131           pcontext->parser_cxt->list.data[index].edpos -
1132           pcontext->parser_cxt->list.data[index].stpos + 4;
1133 
1134 	slc_data->slice_offset = pcontext->parser_cxt->list.data[index].stpos - 4;
1135 
1136 	/* overwrite the "length" bytes to start code (0x00000001) */
1137 	*(slc_data->buffer_addr + slc_data->slice_offset) = 0;
1138 	*(slc_data->buffer_addr + slc_data->slice_offset + 1) = 0;
1139 	*(slc_data->buffer_addr + slc_data->slice_offset + 2) = 0;
1140 	*(slc_data->buffer_addr + slc_data->slice_offset + 3) = 1;
1141 
1142 
1143 	/* the offset to the NAL start code for this slice */
1144 	slc_parms->slice_data_offset = 0;
1145 
1146 	/* whole slice is in this buffer */
1147 	slc_parms->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
1148 
1149 	/* bit offset from NAL start code to the beginning of slice data */
1150 	/* slc_parms->slice_data_bit_offset = bit;*/
1151 	slc_parms->slice_data_bit_offset = (byte + 4)* 8 + bit;
1152 
1153 #else
1154 	slc_parms->slice_data_size = slc_data->slice_size =
1155           pcontext->parser_cxt->list.data[index].edpos -
1156           pcontext->parser_cxt->list.data[index].stpos;
1157 
1158 	/* the offset to the NAL start code for this slice */
1159 	slc_data->slice_offset = cxt->list.data[index].stpos;
1160 	slc_parms->slice_data_offset = 0;
1161 
1162 	/* whole slice is in this buffer */
1163 	slc_parms->slice_data_flag = VA_SLICE_DATA_FLAG_ALL;
1164 
1165 	/* bit offset from NAL start code to the beginning of slice data */
1166 	slc_parms->slice_data_bit_offset = bit + byte * 8;
1167 #endif
1168 
1169 	if (is_emul)
1170 	{
1171 		WTRACE("next byte is emulation prevention byte.");
1172 		/*slc_parms->slice_data_bit_offset += 8; */
1173 	}
1174 
1175 	if (cxt->getbits.emulation_byte_counter != 0)
1176    	{
1177    		slc_parms->slice_data_bit_offset -= cxt->getbits.emulation_byte_counter * 8;
1178    	}
1179 
1180 	slice_header = &(h264_parser->info.SliceHeader);
1181 	slc_parms->first_mb_in_slice = slice_header->first_mb_in_slice;
1182 
1183 	if(h264_parser->info.active_SPS.sps_disp.mb_adaptive_frame_field_flag &
1184 		(!(h264_parser->info.SliceHeader.field_pic_flag)))
1185 	{
1186 			slc_parms->first_mb_in_slice /= 2;
1187 	}
1188 
1189 	slc_parms->slice_type = slice_header->slice_type;
1190 
1191 	slc_parms->direct_spatial_mv_pred_flag = slice_header->direct_spatial_mv_pred_flag;
1192 
1193 	slc_parms->num_ref_idx_l0_active_minus1 = 0;
1194 	slc_parms->num_ref_idx_l1_active_minus1 = 0;
1195 	if (slice_header->slice_type == h264_PtypeI)
1196 	{
1197 	}
1198 	else if (slice_header->slice_type == h264_PtypeP)
1199 	{
1200 		slc_parms->num_ref_idx_l0_active_minus1 = slice_header->num_ref_idx_l0_active - 1;
1201 	}
1202 	else if (slice_header->slice_type == h264_PtypeB)
1203 	{
1204 		slc_parms->num_ref_idx_l0_active_minus1 = slice_header->num_ref_idx_l0_active - 1;
1205 		slc_parms->num_ref_idx_l1_active_minus1 = slice_header->num_ref_idx_l1_active - 1;
1206 	}
1207 	else
1208 	{
1209 		WTRACE("slice type %d is not supported.", slice_header->slice_type);
1210 	}
1211 
1212 	slc_parms->cabac_init_idc = slice_header->cabac_init_idc;
1213 	slc_parms->slice_qp_delta = slice_header->slice_qp_delta;
1214 	slc_parms->disable_deblocking_filter_idc = slice_header->disable_deblocking_filter_idc;
1215 	slc_parms->slice_alpha_c0_offset_div2 = slice_header->slice_alpha_c0_offset_div2;
1216 	slc_parms->slice_beta_offset_div2 = slice_header->slice_beta_offset_div2;
1217 
1218 
1219 	vbp_set_pre_weight_table_h264(h264_parser, slc_parms);
1220 	vbp_set_slice_ref_list_h264(h264_parser, slc_parms);
1221 
1222 
1223 	pic_data->num_slices++;
1224 
1225 	//vbp_update_reference_frames_h264_methodB(pic_data);
1226 	if (pic_data->num_slices > MAX_NUM_SLICES)
1227 	{
1228 		ETRACE("number of slices per picture exceeds the limit (%d).", MAX_NUM_SLICES);
1229 		return VBP_DATA;
1230 	}
1231 	return VBP_OK;
1232 }
1233 
1234 /**
1235 * parse decoder configuration data
1236 */
vbp_parse_init_data_h264(vbp_context * pcontext)1237 uint32 vbp_parse_init_data_h264(vbp_context* pcontext)
1238 {
1239 	/* parsing AVCDecoderConfigurationRecord structure (see MPEG-4 part 15 spec) */
1240 
1241   	uint8 configuration_version = 0;
1242 	uint8 AVC_profile_indication = 0;
1243   	uint8 profile_compatibility = 0;
1244  	uint8 AVC_level_indication = 0;
1245   	uint8 length_size_minus_one = 0;
1246   	uint8 num_of_sequence_parameter_sets = 0;
1247   	uint8 num_of_picture_parameter_sets = 0;
1248   	uint16 sequence_parameter_set_length = 0;
1249   	uint16 picture_parameter_set_length = 0;
1250 
1251   	int i = 0;
1252 	viddec_pm_cxt_t *cxt = pcontext->parser_cxt;
1253 	uint8* cur_data = cxt->parse_cubby.buf;
1254 
1255 
1256 	if (cxt->parse_cubby.size < 6)
1257 	{
1258 		/* need at least 6 bytes to start parsing the structure, see spec 15 */
1259 		return VBP_DATA;
1260 	}
1261 
1262   	configuration_version = *cur_data++;
1263   	AVC_profile_indication = *cur_data++;
1264 
1265 	/*ITRACE("Profile indication: %d", AVC_profile_indication); */
1266 
1267   	profile_compatibility = *cur_data++;
1268   	AVC_level_indication = *cur_data++;
1269 
1270 	/* ITRACE("Level indication: %d", AVC_level_indication);*/
1271   	/* 2 bits of length_size_minus_one, 6 bits of reserved (11111) */
1272   	length_size_minus_one = (*cur_data) & 0x3;
1273 
1274 	if (length_size_minus_one != 3)
1275 	{
1276 		WTRACE("length size (%d) is not equal to 4.", length_size_minus_one + 1);
1277 	}
1278 
1279 	NAL_length_size = length_size_minus_one + 1;
1280 
1281   	cur_data++;
1282 
1283   	/* 3 bits of reserved (111) and 5 bits of num_of_sequence_parameter_sets */
1284   	num_of_sequence_parameter_sets = (*cur_data) & 0x1f;
1285 	if (num_of_sequence_parameter_sets > 1)
1286 	{
1287 		WTRACE("num_of_sequence_parameter_sets is %d.", num_of_sequence_parameter_sets);
1288 	}
1289 	if (num_of_sequence_parameter_sets > MAX_NUM_SPS)
1290 	{
1291 		/* this would never happen as MAX_NUM_SPS = 32 */
1292 		WTRACE("num_of_sequence_parameter_sets (%d) exceeds the limit (%d).", num_of_sequence_parameter_sets, MAX_NUM_SPS);
1293 	}
1294   	cur_data++;
1295 
1296   	cxt->list.num_items = 0;
1297   	for (i = 0; i < num_of_sequence_parameter_sets; i++)
1298   	{
1299 		if (cur_data - cxt->parse_cubby.buf + 2 > cxt->parse_cubby.size)
1300 		{
1301 			/* need at least 2 bytes to parse sequence_parameter_set_length */
1302 			return VBP_DATA;
1303 		}
1304 
1305   		/* 16 bits */
1306   		sequence_parameter_set_length = vbp_utils_ntohs(cur_data);
1307 
1308 
1309   		cur_data += 2;
1310 
1311 		if (cur_data - cxt->parse_cubby.buf + sequence_parameter_set_length > cxt->parse_cubby.size)
1312 		{
1313 			/* need at least sequence_parameter_set_length bytes for SPS */
1314 			return VBP_DATA;
1315 		}
1316 
1317 		cxt->list.data[cxt->list.num_items].stpos = cur_data - cxt->parse_cubby.buf;
1318 
1319     	/* end pos is exclusive */
1320     	cxt->list.data[cxt->list.num_items].edpos =
1321     		cxt->list.data[cxt->list.num_items].stpos + sequence_parameter_set_length;
1322 
1323     	cxt->list.num_items++;
1324 
1325   		cur_data += sequence_parameter_set_length;
1326   	}
1327 
1328 	if (cur_data - cxt->parse_cubby.buf + 1 > cxt->parse_cubby.size)
1329 	{
1330 		/* need at least one more byte to parse num_of_picture_parameter_sets */
1331 		return VBP_DATA;
1332 	}
1333 
1334   	num_of_picture_parameter_sets = *cur_data++;
1335 	if (num_of_picture_parameter_sets > 1)
1336 	{
1337 		/* g_warning("num_of_picture_parameter_sets is %d.", num_of_picture_parameter_sets); */
1338 	}
1339 
1340   	for (i = 0; i < num_of_picture_parameter_sets; i++)
1341   	{
1342 		if (cur_data - cxt->parse_cubby.buf + 2 > cxt->parse_cubby.size)
1343 		{
1344 			/* need at least 2 bytes to parse picture_parameter_set_length */
1345 			return VBP_DATA;
1346 		}
1347 
1348 		/* 16 bits */
1349   		picture_parameter_set_length = vbp_utils_ntohs(cur_data);
1350 
1351   		cur_data += 2;
1352 
1353 		if (cur_data - cxt->parse_cubby.buf + picture_parameter_set_length > cxt->parse_cubby.size)
1354 		{
1355 			/* need at least picture_parameter_set_length bytes for PPS */
1356 			return VBP_DATA;
1357 		}
1358 
1359     	cxt->list.data[cxt->list.num_items].stpos = cur_data - cxt->parse_cubby.buf;
1360 
1361     	/* end pos is exclusive */
1362     	cxt->list.data[cxt->list.num_items].edpos =
1363     		cxt->list.data[cxt->list.num_items].stpos + picture_parameter_set_length;
1364 
1365     	cxt->list.num_items++;
1366 
1367   		cur_data += picture_parameter_set_length;
1368   	}
1369 
1370   	if ((cur_data - cxt->parse_cubby.buf) !=  cxt->parse_cubby.size)
1371   	{
1372   		WTRACE("Not all initialization data is parsed. Size = %d, parsed = %d.",
1373   			cxt->parse_cubby.size, (cur_data - cxt->parse_cubby.buf));
1374   	}
1375 
1376  	return VBP_OK;
1377 }
1378 
vbp_get_NAL_length_h264(uint8_t * p)1379 static inline uint32_t vbp_get_NAL_length_h264(uint8_t* p)
1380 {
1381 	switch (NAL_length_size)
1382 	{
1383 		case 4:
1384 			return vbp_utils_ntohl(p);
1385 
1386 		case 3:
1387 		{
1388 			uint32_t i = ((*p) << 16) + ((*(p+1)) << 8) + ((*(p+2)));
1389 			return i;
1390 		}
1391 
1392 		case 2:
1393 			return vbp_utils_ntohs(p);
1394 
1395 		case 1:
1396 			return *p;
1397 
1398 		default:
1399 			WTRACE("invalid NAL_length_size: %d.", NAL_length_size);
1400 			/* default to 4 bytes for length */
1401 			NAL_length_size = 4;
1402 			return vbp_utils_ntohl(p);
1403 	}
1404 }
1405 
1406 /**
1407 ** H.264 elementary stream does not have start code.
1408 * instead, it is comprised of size of NAL unit and payload
1409 * of NAL unit. See spec 15 (Sample format)
1410 */
vbp_parse_start_code_h264(vbp_context * pcontext)1411 uint32 vbp_parse_start_code_h264(vbp_context *pcontext)
1412 {
1413 	viddec_pm_cxt_t *cxt = pcontext->parser_cxt;
1414   	int32_t size_left = 0;
1415   	int32_t size_parsed = 0;
1416   	int32_t NAL_length = 0;
1417   	viddec_sc_parse_cubby_cxt_t* cubby = NULL;
1418 
1419 	/* reset query data for the new sample buffer */
1420 	vbp_data_h264* query_data = (vbp_data_h264*)pcontext->query_data;
1421 	int i;
1422 
1423 	for (i = 0; i < MAX_NUM_PICTURES; i++)
1424 	{
1425 		query_data->pic_data[i].num_slices = 0;
1426 	}
1427 	query_data->num_pictures = 0;
1428 
1429 
1430   	cubby = &(cxt->parse_cubby);
1431 
1432   	cxt->list.num_items = 0;
1433 
1434 	/* start code emulation prevention byte is present in NAL */
1435 	cxt->getbits.is_emul_reqd = 1;
1436 
1437   	size_left = cubby->size;
1438 
1439   	while (size_left >= NAL_length_size)
1440   	{
1441     	NAL_length = vbp_get_NAL_length_h264(cubby->buf + size_parsed);
1442 
1443     	size_parsed += NAL_length_size;
1444     	cxt->list.data[cxt->list.num_items].stpos = size_parsed;
1445     	size_parsed += NAL_length; /* skip NAL bytes */
1446     	/* end position is exclusive */
1447     	cxt->list.data[cxt->list.num_items].edpos = size_parsed;
1448     	cxt->list.num_items++;
1449     	if (cxt->list.num_items >= MAX_IBUFS_PER_SC)
1450       	{
1451       		ETRACE("num of list items exceeds the limit (%d).", MAX_IBUFS_PER_SC);
1452       		break;
1453       	}
1454 
1455     	size_left = cubby->size - size_parsed;
1456    	}
1457 
1458   	if (size_left != 0)
1459   	{
1460     	WTRACE("Elementary stream is not aligned (%d).", size_left);
1461   	}
1462   	return VBP_OK;
1463 }
1464 
1465 /**
1466 *
1467 * process parsing result after a NAL unit is parsed
1468 *
1469 */
vbp_process_parsing_result_h264(vbp_context * pcontext,int i)1470 uint32 vbp_process_parsing_result_h264( vbp_context *pcontext, int i)
1471 {
1472 	if (i >= MAX_NUM_SLICES)
1473 	{
1474 		return VBP_PARM;
1475 	}
1476 
1477 	uint32 error = VBP_OK;
1478 
1479   	struct h264_viddec_parser* parser = NULL;
1480 	parser = (struct h264_viddec_parser *)&( pcontext->parser_cxt->codec_data[0]);
1481 	switch (parser->info.nal_unit_type)
1482     {
1483 		case h264_NAL_UNIT_TYPE_SLICE:
1484        	/* ITRACE("slice header is parsed."); */
1485        	error = vbp_add_pic_data_h264(pcontext, i);
1486        	if (VBP_OK == error)
1487        	{
1488        		error = vbp_add_slice_data_h264(pcontext, i);
1489        	}
1490        	break;
1491 
1492        	case  h264_NAL_UNIT_TYPE_IDR:
1493        	/* ITRACE("IDR header is parsed."); */
1494        	error = vbp_add_pic_data_h264(pcontext, i);
1495        	if (VBP_OK == error)
1496        	{
1497        		error = vbp_add_slice_data_h264(pcontext, i);
1498        	}
1499        	break;
1500 
1501        	case h264_NAL_UNIT_TYPE_SEI:
1502 		/* ITRACE("SEI header is parsed."); */
1503        	break;
1504 
1505      	case h264_NAL_UNIT_TYPE_SPS:
1506  		/*ITRACE("SPS header is parsed."); */
1507  		break;
1508 
1509        	case h264_NAL_UNIT_TYPE_PPS:
1510        	/* ITRACE("PPS header is parsed."); */
1511        	break;
1512 
1513       	case h264_NAL_UNIT_TYPE_Acc_unit_delimiter:
1514        	/* ITRACE("ACC unit delimiter is parsed."); */
1515        	break;
1516 
1517       	case h264_NAL_UNIT_TYPE_EOSeq:
1518        	/* ITRACE("EOSeq is parsed."); */
1519       	break;
1520 
1521      	case h264_NAL_UNIT_TYPE_EOstream:
1522       	/* ITRACE("EOStream is parsed."); */
1523        	break;
1524 
1525      	default:
1526 	     WTRACE("unknown header %d is parsed.", parser->info.nal_unit_type);
1527        	break;
1528 	}
1529 	return error;
1530 }
1531 
1532 /*
1533 *
1534 * fill query data structure after sample buffer is parsed
1535 *
1536 */
vbp_populate_query_data_h264(vbp_context * pcontext)1537 uint32 vbp_populate_query_data_h264(vbp_context *pcontext)
1538 {
1539   	vbp_data_h264 *query_data = NULL;
1540   	struct h264_viddec_parser *parser = NULL;
1541 
1542    	parser = (struct h264_viddec_parser *)pcontext->parser_cxt->codec_data;
1543   	query_data = (vbp_data_h264 *)pcontext->query_data;
1544 
1545   	vbp_set_codec_data_h264(parser, query_data->codec_data);
1546 
1547   	/* buffer number */
1548   	query_data->buf_number = buffer_counter;
1549 
1550   	/* VQIAMatrixBufferH264 */
1551   	vbp_set_scaling_list_h264(parser, query_data->IQ_matrix_buf);
1552 
1553 	if (query_data->num_pictures > 0)
1554 	{
1555 		/*
1556 		* picture parameter buffer and slice parameter buffer have been populated
1557 		*/
1558 	}
1559 	else
1560 	{
1561 		/**
1562 		* add a dummy picture that contains picture parameters parsed
1563 		  from SPS and PPS.
1564 		*/
1565 		vbp_add_pic_data_h264(pcontext, 0);
1566 	}
1567   	return VBP_OK;
1568 }
1569