1 /* |
|
2 * Copyright (c) 2010 Ixonos Plc. |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of the "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - Initial contribution |
|
11 * |
|
12 * Contributors: |
|
13 * Ixonos Plc |
|
14 * |
|
15 * Description: |
|
16 * |
|
17 */ |
|
18 |
|
19 |
|
20 #include <string.h> |
|
21 #include "globals.h" |
|
22 #include "bitbuffer.h" |
|
23 #include "vld.h" |
|
24 #include "macroblock.h" |
|
25 #include "parameterset.h" |
|
26 #include "framebuffer.h" |
|
27 #include "dpb.h" |
|
28 #include "slice.h" |
|
29 #include "sequence.h" |
|
30 |
|
31 |
|
32 #define MIN_ALPHA_BETA_OFFSET -6 |
|
33 #define MAX_ALPHA_BETA_OFFSET 6 |
|
34 |
|
35 /* |
|
36 * AVC syntax functions as specified in specification |
|
37 */ |
|
38 |
|
39 |
|
40 /* |
|
41 * Static functions |
|
42 */ |
|
43 |
|
44 static int getRefPicListReorderingCmds(slice_s *slice, unsigned int numRefFrames, |
|
45 bitbuffer_s *bitbuf); |
|
46 |
|
47 static int getDecRefPicMarkingCmds(slice_s *slice, unsigned int numRefFrames, |
|
48 bitbuffer_s *bitbuf); |
|
49 |
|
50 static int refPicListReordering(slice_s *slice, dpb_s *dpb, |
|
51 frmBuf_s *refPicList[], int numRefPicActive, |
|
52 sliceRefPicListReorderCmd_s reorderCmdList[]); |
|
53 |
|
54 |
|
55 |
|
56 /* |
|
57 * AVC syntax functions as specified in specification |
|
58 */ |
|
59 |
|
60 /* Return fixed length code */ |
|
61 static int u_n(bitbuffer_s *bitbuf, int len, unsigned int *val) |
|
62 { |
|
63 *val = vldGetFLC(bitbuf, len); |
|
64 |
|
65 if (bibGetStatus(bitbuf) < 0) |
|
66 return SLICE_ERROR; |
|
67 |
|
68 return SLICE_OK; |
|
69 } |
|
70 |
|
71 /* Return unsigned UVLC code */ |
|
72 static int ue_v(bitbuffer_s *bitbuf, unsigned int *val, unsigned int maxVal) |
|
73 { |
|
74 *val = vldGetUVLC(bitbuf); |
|
75 |
|
76 if (bibGetStatus(bitbuf) < 0) |
|
77 return SLICE_ERROR; |
|
78 |
|
79 if (*val > maxVal) |
|
80 return SLICE_ERR_ILLEGAL_VALUE; |
|
81 |
|
82 return SLICE_OK; |
|
83 } |
|
84 |
|
85 /* Return signed UVLC code */ |
|
86 static int se_v(bitbuffer_s *bitbuf, int *val, int minVal, int maxVal) |
|
87 { |
|
88 *val = vldGetSignedUVLC(bitbuf); |
|
89 |
|
90 if (bibGetStatus(bitbuf) < 0) |
|
91 return SLICE_ERROR; |
|
92 |
|
93 if (*val < minVal || *val > maxVal) |
|
94 return SLICE_ERR_ILLEGAL_VALUE; |
|
95 |
|
96 return SLICE_OK; |
|
97 } |
|
98 |
|
99 /* Return long signed UVLC code */ |
|
100 static int se_v_long(bitbuffer_s *bitbuf, int32 *val) |
|
101 { |
|
102 *val = vldGetSignedUVLClong(bitbuf); |
|
103 |
|
104 if (bibGetStatus(bitbuf) < 0) |
|
105 return SLICE_ERROR; |
|
106 |
|
107 return SLICE_OK; |
|
108 } |
|
109 |
|
110 |
|
111 /* |
|
112 * |
|
113 * sliceOpen: |
|
114 * |
|
115 * Parameters: |
|
116 * |
|
117 * Function: |
|
118 * Allocate and initialize a slice. |
|
119 * |
|
120 * Returns: |
|
121 * Pointer to slice |
|
122 * |
|
123 */ |
|
124 slice_s *sliceOpen() |
|
125 { |
|
126 slice_s *slice; |
|
127 |
|
128 slice = (slice_s *)User::Alloc(sizeof(slice_s)); |
|
129 |
|
130 if (slice != NULL) |
|
131 memset(slice, 0, sizeof(slice_s)); |
|
132 |
|
133 return slice; |
|
134 } |
|
135 |
|
136 |
|
137 /* |
|
138 * |
|
139 * sliceClose: |
|
140 * |
|
141 * Parameters: |
|
142 * slice Slice object |
|
143 * |
|
144 * Function: |
|
145 * Deallocate slice |
|
146 * |
|
147 * Returns: |
|
148 * Nothing |
|
149 * |
|
150 */ |
|
151 void sliceClose(slice_s *slice) |
|
152 { |
|
153 User::Free(slice); |
|
154 } |
|
155 |
|
156 |
|
157 /* |
|
158 * getRefPicListReorderingCmds: |
|
159 * |
|
160 * Parameters: |
|
161 * slice Slice object |
|
162 * bitbuf Bitbuffer object |
|
163 * numRefFrames Number of reference frames in used |
|
164 * |
|
165 * Function: |
|
166 * Parse and store the ref pic reordering commands |
|
167 * |
|
168 * Return: |
|
169 * The number of bits being parsed |
|
170 */ |
|
171 static int getRefPicListReorderingCmds(slice_s *slice, unsigned int numRefFrames, |
|
172 bitbuffer_s *bitbuf) |
|
173 { |
|
174 int i; |
|
175 unsigned int reordering_of_pic_nums_idc; |
|
176 int retCode; |
|
177 |
|
178 if (!IS_SLICE_I(slice->slice_type)) { |
|
179 |
|
180 if ((retCode = u_n(bitbuf, 1, &slice->ref_pic_list_reordering_flag0)) < 0) |
|
181 return retCode; |
|
182 |
|
183 if (slice->ref_pic_list_reordering_flag0) { |
|
184 |
|
185 i = 0; |
|
186 do { |
|
187 /* Get command */ |
|
188 if ((retCode = ue_v(bitbuf, &reordering_of_pic_nums_idc, 3)) < 0) |
|
189 return retCode; |
|
190 |
|
191 slice->reorderCmdList[i].reordering_of_pic_nums_idc = reordering_of_pic_nums_idc; |
|
192 |
|
193 /* Get command parameters */ |
|
194 if (reordering_of_pic_nums_idc == 0 || reordering_of_pic_nums_idc == 1) { |
|
195 unsigned int maxDiff = slice->maxFrameNum/2-1; |
|
196 if (reordering_of_pic_nums_idc == 1) |
|
197 maxDiff = maxDiff - 1; |
|
198 if ((retCode = ue_v(bitbuf, &slice->reorderCmdList[i].abs_diff_pic_num_minus1, maxDiff)) < 0) |
|
199 return retCode; |
|
200 } |
|
201 else if (reordering_of_pic_nums_idc == 2) { |
|
202 /* longTermPicNum be in the range of 0 to num_ref_frames, inclusive. */ |
|
203 if ((retCode = ue_v(bitbuf, &slice->reorderCmdList[i].long_term_pic_num, numRefFrames)) < 0) |
|
204 return retCode; |
|
205 } |
|
206 |
|
207 i++; |
|
208 } while (reordering_of_pic_nums_idc != 3 && i < MAX_NUM_OF_REORDER_CMDS); |
|
209 } |
|
210 } |
|
211 |
|
212 return SLICE_OK; |
|
213 } |
|
214 |
|
215 |
|
216 /* |
|
217 * getDecRefPicMarkingCmds: |
|
218 * |
|
219 * Parameters: |
|
220 * slice Slice object |
|
221 * bitbuf Bitbuffer object |
|
222 * numRefFrames Number of reference frames in used |
|
223 * |
|
224 * Function: |
|
225 * Parse and store the MMCO commands |
|
226 * |
|
227 * Return: |
|
228 * The number of bits being parsed |
|
229 */ |
|
230 static int getDecRefPicMarkingCmds(slice_s *slice, unsigned int numRefFrames, |
|
231 bitbuffer_s *bitbuf) |
|
232 { |
|
233 int i; |
|
234 unsigned int mmco; |
|
235 int retCode; |
|
236 |
|
237 /* MMCO commands can exist only in slice header of a reference picture */ |
|
238 if (slice->nalRefIdc != 0) { |
|
239 if (slice->isIDR) { |
|
240 if ((retCode = u_n(bitbuf, 1, &slice->no_output_of_prior_pics_flag)) < 0) |
|
241 return retCode; |
|
242 if ((retCode = u_n(bitbuf, 1, &slice->long_term_reference_flag)) < 0) |
|
243 return retCode; |
|
244 } |
|
245 else { |
|
246 if ((retCode = u_n(bitbuf, 1, &slice->adaptive_ref_pic_marking_mode_flag)) < 0) |
|
247 return retCode; |
|
248 |
|
249 if (slice->adaptive_ref_pic_marking_mode_flag) { |
|
250 |
|
251 i = 0; |
|
252 do { |
|
253 /* Get MMCO command */ |
|
254 if ((retCode = ue_v(bitbuf, &mmco, 6)) < 0) |
|
255 return retCode; |
|
256 |
|
257 slice->mmcoCmdList[i].memory_management_control_operation = mmco; |
|
258 |
|
259 /* Get command parameter (if any) */ |
|
260 if (mmco == 1 || mmco == 3) { |
|
261 if ((retCode = ue_v(bitbuf, &slice->mmcoCmdList[i].difference_of_pic_nums_minus1, 65535)) < 0) |
|
262 return retCode; |
|
263 } |
|
264 if (mmco == 2) { |
|
265 if ((retCode = ue_v(bitbuf, &slice->mmcoCmdList[i].long_term_pic_num, numRefFrames)) < 0) |
|
266 return retCode; |
|
267 } |
|
268 if (mmco == 3 || mmco == 6) { |
|
269 if ((retCode = ue_v(bitbuf, &slice->mmcoCmdList[i].long_term_frame_idx, numRefFrames)) < 0) |
|
270 return retCode; |
|
271 } |
|
272 if (mmco == 4) { |
|
273 if ((retCode = ue_v(bitbuf, &slice->mmcoCmdList[i].max_long_term_frame_idx_plus1, numRefFrames)) < 0) |
|
274 return retCode; |
|
275 } |
|
276 if (mmco == 5) { |
|
277 slice->picHasMMCO5 = 1; |
|
278 } |
|
279 |
|
280 i++; |
|
281 } while (mmco != 0 && i < MAX_NUM_OF_MMCO_OPS); |
|
282 } |
|
283 } |
|
284 } |
|
285 else |
|
286 slice->adaptive_ref_pic_marking_mode_flag = 0; |
|
287 |
|
288 return 1; |
|
289 } |
|
290 |
|
291 |
|
292 /* |
|
293 * sliceInitRefPicList: |
|
294 * |
|
295 * Parameters: |
|
296 * dpb DPB buffer |
|
297 * refPicList Reference picture list (output) |
|
298 * |
|
299 * Fucntion: |
|
300 * Initialize reference picture list. |
|
301 * |
|
302 * Return: |
|
303 * Number of reference frames in the list |
|
304 */ |
|
305 int sliceInitRefPicList(dpb_s *dpb, frmBuf_s *refPicList[]) |
|
306 { |
|
307 int numRef, numShort; |
|
308 frmBuf_s *refTmp; |
|
309 int i, j; |
|
310 |
|
311 /* |
|
312 * Select the reference pictures from the DPB |
|
313 */ |
|
314 j = 0; |
|
315 /* Put short term pictures first in the list */ |
|
316 for (i = 0; i < dpb->fullness; i++) { |
|
317 if (dpb->buffers[i]->refType == FRM_SHORT_TERM_PIC) |
|
318 refPicList[j++] = dpb->buffers[i]; |
|
319 } |
|
320 numShort = j; |
|
321 /* Put long term pictures after the short term pictures */ |
|
322 for (i = 0; i < dpb->fullness; i++) { |
|
323 if (dpb->buffers[i]->refType == FRM_LONG_TERM_PIC) |
|
324 refPicList[j++] = dpb->buffers[i]; |
|
325 } |
|
326 numRef = j; |
|
327 /* numLong = numRef - numShort; */ |
|
328 |
|
329 /* |
|
330 * Initialisation process for reference picture lists |
|
331 */ |
|
332 /* Sort short term pictures in the order of descending picNum */ |
|
333 for (i = 0; i < numShort; i++) { |
|
334 for (j = i+1; j < numShort; j++) { |
|
335 if (refPicList[i]->picNum < refPicList[j]->picNum) { |
|
336 /* exchange refPicList[i] and refPicList[j] */ |
|
337 refTmp = refPicList[i]; |
|
338 refPicList[i] = refPicList[j]; |
|
339 refPicList[j] = refTmp; |
|
340 } |
|
341 } |
|
342 } |
|
343 /* Sort long term pictures in the order of ascending longTermPicNum */ |
|
344 for (i = numShort; i < numRef; i++) { |
|
345 for (j = i+1; j < numRef; j++) { |
|
346 if (refPicList[i]->longTermPicNum > refPicList[j]->longTermPicNum) { |
|
347 /* exchange refPicList[i] and refPicList[j] */ |
|
348 refTmp = refPicList[i]; |
|
349 refPicList[i] = refPicList[j]; |
|
350 refPicList[j] = refTmp; |
|
351 } |
|
352 } |
|
353 } |
|
354 |
|
355 return numRef; |
|
356 } |
|
357 |
|
358 |
|
359 /* |
|
360 * sliceFixRefPicList: |
|
361 * |
|
362 * Parameters: |
|
363 * dpb DPB buffer |
|
364 * refPicList Reference picture list (output) |
|
365 * numRefPicActive Number of active reference frames |
|
366 * numExistingRefFrames Number of reference frames in refPicList |
|
367 * |
|
368 * Fucntion: |
|
369 * If numExistingRefFrames < numRefPicActive, try to fill up the |
|
370 * reference frame list |
|
371 * |
|
372 * Return: |
|
373 * 0 for no pictures exist in reference frame list |
|
374 * 1 for pictures exist in reference frame list |
|
375 */ |
|
376 int sliceFixRefPicList(dpb_s *dpb, frmBuf_s *refPicList[], |
|
377 int numRefPicActive, int numExistingRefFrames, |
|
378 int width, int height) |
|
379 { |
|
380 int i; |
|
381 |
|
382 if (numExistingRefFrames == 0) { |
|
383 /* Try to find any picture in DPB, even non-reference frame */ |
|
384 for (i = 0; i < dpb->size; i++) { |
|
385 if (dpb->buffers[i] != NULL && dpb->buffers[i]->width == width && dpb->buffers[i]->height == height) |
|
386 break; |
|
387 } |
|
388 |
|
389 if (i < dpb->size) { |
|
390 refPicList[0] = dpb->buffers[i]; |
|
391 numExistingRefFrames = 1; |
|
392 } |
|
393 else |
|
394 return 0; |
|
395 } |
|
396 |
|
397 /* Duplicate last extry of the reference frame list so that list becomes full */ |
|
398 for (i = numExistingRefFrames; i < numRefPicActive; i++) |
|
399 refPicList[i] = refPicList[numExistingRefFrames-1]; |
|
400 |
|
401 return 1; |
|
402 } |
|
403 |
|
404 /* |
|
405 * refPicListReordering: |
|
406 * |
|
407 * Parameters: |
|
408 * slice Current slice object |
|
409 * dpb DPB buffer |
|
410 * refPicList Reference picture list (modified by this function) |
|
411 * numRefPicActive Number of active reference frames |
|
412 * reorderCmdList Reordering command list |
|
413 * |
|
414 * Fucntion: |
|
415 * Reorder the reference picture list for current slice |
|
416 * |
|
417 * Return: |
|
418 * SLICE_OK for no error and negative value for error |
|
419 */ |
|
420 static int refPicListReordering(slice_s *slice, dpb_s *dpb, |
|
421 frmBuf_s *refPicList[], int numRefPicActive, |
|
422 sliceRefPicListReorderCmd_s reorderCmdList[]) |
|
423 { |
|
424 int i; |
|
425 int reordering_of_pic_nums_idc, longTermPicNum; |
|
426 int32 absDiffPicNum; |
|
427 int refIdx; |
|
428 int32 currPicNum, picNumPred, picNumNoWrap; |
|
429 int32 maxPicNum, picNum; |
|
430 int cmdNum; |
|
431 int cIdx, nIdx; |
|
432 |
|
433 /* |
|
434 * 3. Reordering process for reference picture list |
|
435 */ |
|
436 |
|
437 maxPicNum = slice->maxFrameNum; /* for frame coding only */ |
|
438 currPicNum = slice->frame_num; |
|
439 picNumPred = currPicNum; |
|
440 refIdx = 0; |
|
441 cmdNum = 0; |
|
442 |
|
443 do { |
|
444 reordering_of_pic_nums_idc = reorderCmdList[cmdNum].reordering_of_pic_nums_idc; |
|
445 |
|
446 if (reordering_of_pic_nums_idc == 0 || reordering_of_pic_nums_idc == 1) { |
|
447 |
|
448 /* |
|
449 * reorder short-term ref pic -subclause 8.2.4.3.1 |
|
450 */ |
|
451 |
|
452 absDiffPicNum = reorderCmdList[cmdNum].abs_diff_pic_num_minus1 + 1; |
|
453 |
|
454 /* Derive picNumNoWrap */ |
|
455 if (reordering_of_pic_nums_idc == 0) { |
|
456 if (picNumPred - absDiffPicNum < 0) |
|
457 picNumNoWrap = picNumPred - absDiffPicNum + maxPicNum; |
|
458 else |
|
459 picNumNoWrap = picNumPred - absDiffPicNum; |
|
460 } |
|
461 else { /* reordering_of_pic_nums_idc == 1 */ |
|
462 if (picNumPred + absDiffPicNum >= maxPicNum) |
|
463 picNumNoWrap = picNumPred + absDiffPicNum - maxPicNum; |
|
464 else |
|
465 picNumNoWrap = picNumPred + absDiffPicNum; |
|
466 } |
|
467 |
|
468 /* Derive picNum */ |
|
469 if (picNumNoWrap > currPicNum) |
|
470 picNum = picNumNoWrap - maxPicNum; |
|
471 else |
|
472 picNum = picNumNoWrap; |
|
473 |
|
474 /* Find short term picture with picture number picNum */ |
|
475 for (i = 0; i < dpb->fullness; i++) { |
|
476 if (!dpb->buffers[i]->nonExisting && |
|
477 dpb->buffers[i]->refType == FRM_SHORT_TERM_PIC && |
|
478 dpb->buffers[i]->picNum == picNum) |
|
479 break; |
|
480 } |
|
481 |
|
482 /* If picNum was not found */ |
|
483 if (i == dpb->fullness) { |
|
484 PRINT((_L("The short term ref pic(%d) is not found!\n"), picNum)); |
|
485 return SLICE_ERR_ILLEGAL_VALUE; |
|
486 } |
|
487 |
|
488 /* Shift remaining pictures later in the list */ |
|
489 for (cIdx = numRefPicActive; cIdx > refIdx; cIdx--) |
|
490 refPicList[cIdx] = refPicList[cIdx - 1]; |
|
491 |
|
492 /* Place picture with number picNum into the index position refIdx */ |
|
493 refPicList[refIdx++] = dpb->buffers[i]; |
|
494 |
|
495 /* Remove duplicate of the inserted picture */ |
|
496 nIdx = refIdx; |
|
497 for (cIdx = refIdx; cIdx <= numRefPicActive; cIdx++) |
|
498 if (refPicList[cIdx]->refType == FRM_LONG_TERM_PIC || refPicList[cIdx]->picNum != picNum) |
|
499 refPicList[nIdx++] = refPicList[cIdx]; |
|
500 |
|
501 picNumPred = picNumNoWrap; |
|
502 } |
|
503 |
|
504 else if (reordering_of_pic_nums_idc == 2) { |
|
505 |
|
506 /* |
|
507 * reorder long-term ref pic -subclause 8.2.4.3.2 |
|
508 */ |
|
509 |
|
510 /* Get long-term picture number */ |
|
511 longTermPicNum = reorderCmdList[cmdNum].long_term_pic_num; |
|
512 |
|
513 /* Find long-term picture with picture number longTermPicNum */ |
|
514 for (i = 0; i < dpb->fullness; i++) |
|
515 if (dpb->buffers[i]->refType == FRM_LONG_TERM_PIC && |
|
516 dpb->buffers[i]->longTermPicNum == longTermPicNum) |
|
517 break; |
|
518 |
|
519 if (i == dpb->fullness) { |
|
520 // something wrong ! |
|
521 PRINT((_L("The long term ref pic(%d) is not found!\n"), longTermPicNum)); |
|
522 return SLICE_ERR_ILLEGAL_VALUE; |
|
523 } |
|
524 |
|
525 /* Shift remaining pictures later in the list */ |
|
526 for (cIdx = numRefPicActive; cIdx > refIdx; cIdx--) |
|
527 refPicList[cIdx] = refPicList[cIdx - 1]; |
|
528 |
|
529 /* Place picture with number longTermPicNum into the index position refIdx */ |
|
530 refPicList[refIdx++] = dpb->buffers[i]; |
|
531 |
|
532 /* Remove duplicate of the inserted picture */ |
|
533 nIdx = refIdx; |
|
534 for (cIdx = refIdx; cIdx <= numRefPicActive; cIdx++) |
|
535 if (refPicList[cIdx]->refType == FRM_SHORT_TERM_PIC || |
|
536 refPicList[cIdx]->longTermPicNum != longTermPicNum) |
|
537 { |
|
538 refPicList[nIdx++] = refPicList[cIdx]; |
|
539 } |
|
540 } |
|
541 |
|
542 cmdNum++; |
|
543 |
|
544 } while (reordering_of_pic_nums_idc != 3 && cmdNum < MAX_NUM_OF_REORDER_CMDS); |
|
545 |
|
546 |
|
547 refPicList[numRefPicActive] = 0; |
|
548 |
|
549 return SLICE_OK; |
|
550 } |
|
551 |
|
552 |
|
553 // sliceParseMacroblocks |
|
554 // Parses the macroblocks one by one in the input slice. |
|
555 TInt sliceParseMacroblocks(slice_s *slice, frmBuf_s *recoBuf, dpb_s *dpb, |
|
556 pic_parameter_set_s *pps, |
|
557 mbAttributes_s *mbData, TInt sliceID, |
|
558 bitbuffer_s *bitbuf, |
|
559 TBool aBitShiftInSlice) |
|
560 { |
|
561 frmBuf_s *refPicList0[DPB_MAX_SIZE+1]; |
|
562 macroblock_s mb; |
|
563 TInt numRefFrames; |
|
564 TInt numExistingRefFrames; |
|
565 // TInt refFramesExist; |
|
566 TInt mbIdxY; |
|
567 TInt mbIdxX; |
|
568 TInt mbksPerLine; |
|
569 TInt mbksPerCol; |
|
570 TInt picSizeInMbs; |
|
571 TInt currMbAddr; |
|
572 TInt sliceGroupNum; |
|
573 void *stream; |
|
574 TInt retCode; |
|
575 |
|
576 // Choose number of reference frames and build reference picture list |
|
577 numRefFrames = 0; |
|
578 // refFramesExist = 0; |
|
579 if (!IS_SLICE_I(slice->slice_type)) |
|
580 { |
|
581 if (slice->num_ref_idx_active_override_flag) |
|
582 numRefFrames = slice->num_ref_idx_l0_active_minus1 + 1; |
|
583 else |
|
584 numRefFrames = pps->num_ref_idx_l0_active_minus1 + 1; |
|
585 |
|
586 numExistingRefFrames = sliceInitRefPicList(dpb, refPicList0); |
|
587 |
|
588 if (numExistingRefFrames < numRefFrames) |
|
589 { |
|
590 // refFramesExist = sliceFixRefPicList(dpb, refPicList0, numRefFrames, numExistingRefFrames, |
|
591 // recoBuf->width, recoBuf->height); |
|
592 } |
|
593 else |
|
594 // refFramesExist = 1; |
|
595 |
|
596 if (slice->ref_pic_list_reordering_flag0 && numExistingRefFrames > 0) |
|
597 { |
|
598 retCode = refPicListReordering(slice, dpb, refPicList0, numRefFrames, slice->reorderCmdList); |
|
599 |
|
600 if (retCode < 0) |
|
601 return retCode; |
|
602 } |
|
603 } |
|
604 |
|
605 mbksPerLine = recoBuf->width/MBK_SIZE; |
|
606 mbksPerCol = recoBuf->height/MBK_SIZE; |
|
607 picSizeInMbs = mbksPerLine*mbksPerCol; |
|
608 |
|
609 currMbAddr = slice->first_mb_in_slice; |
|
610 sliceGroupNum = sliceID & 0xF; |
|
611 |
|
612 mbIdxY = currMbAddr / mbksPerLine; |
|
613 mbIdxX = currMbAddr - mbIdxY*mbksPerLine; |
|
614 |
|
615 mbkSetInitialQP(&mb, slice->qp, pps->chroma_qp_index_offset); |
|
616 |
|
617 stream = bitbuf; |
|
618 |
|
619 // Loop until all macroblocks in current slice have been decoded |
|
620 // If there has been a bitshift in the slice, we must go through |
|
621 // the macroblocks to see if any PCM coded MB are used. |
|
622 if(aBitShiftInSlice) |
|
623 { |
|
624 |
|
625 do |
|
626 { |
|
627 |
|
628 // Store slice ID for current macroblock |
|
629 mbData->sliceMap[currMbAddr] = sliceID; |
|
630 |
|
631 // Store loopfilter mode |
|
632 mbData->filterModeTab[currMbAddr] = (int8) slice->disable_deblocking_filter_idc; |
|
633 mbData->alphaOffset[currMbAddr] = (int8) (slice->slice_alpha_c0_offset_div2*2); |
|
634 mbData->betaOffset[currMbAddr] = (int8) (slice->slice_beta_offset_div2*2); |
|
635 |
|
636 retCode = mbkParse(&mb, numRefFrames, |
|
637 mbData, recoBuf->width, |
|
638 slice->slice_type, pps->constrained_intra_pred_flag, |
|
639 pps->chroma_qp_index_offset, |
|
640 mbIdxX, mbIdxY, stream, slice->bitOffset); |
|
641 |
|
642 if (retCode == MBK_PCM_FOUND) |
|
643 { |
|
644 // We can stop parsing this slice |
|
645 // Check later if this is the case also if we have slices in more than one NAL (is it even possible?)!!! |
|
646 return SLICE_OK; |
|
647 } |
|
648 |
|
649 if (retCode < 0) |
|
650 return SLICE_ERROR; |
|
651 |
|
652 // If end of slice data has been reached and there are no |
|
653 // skipped macroblocks left, stop decoding slice. |
|
654 if (!bibMoreRbspData(bitbuf) && mb.numSkipped <= 0) |
|
655 break; |
|
656 |
|
657 // Find next mb address in the current slice group |
|
658 do |
|
659 { |
|
660 // Next mb address |
|
661 currMbAddr++; |
|
662 |
|
663 // If end of frame was reached, stop search |
|
664 if (currMbAddr == picSizeInMbs) |
|
665 break; |
|
666 |
|
667 // Update mb location |
|
668 mbIdxX++; |
|
669 if (mbIdxX == mbksPerLine) |
|
670 { |
|
671 mbIdxX = 0; |
|
672 mbIdxY++; |
|
673 } |
|
674 |
|
675 } while ((mbData->sliceMap[currMbAddr] & 0xF) != sliceGroupNum); |
|
676 |
|
677 // If end of frame was reached, stop decoding slice |
|
678 } while (currMbAddr < picSizeInMbs); |
|
679 } |
|
680 |
|
681 return SLICE_OK; |
|
682 } |
|
683 |
|
684 |
|
685 // EncodeUnsignedNBits |
|
686 // Encodes the input aValue to the bit buffer with aLength bits. |
|
687 void EncodeUnsignedNBits(bitbuffer_s *aBitBuffer, TUint aValue, TUint aLength) |
|
688 { |
|
689 TUint tempValue; |
|
690 TInt i; |
|
691 TUint8 byteValue; |
|
692 |
|
693 if(aBitBuffer->bitpos == 0) |
|
694 { |
|
695 // Get the next byte |
|
696 aBitBuffer->currentBits = aBitBuffer->data[aBitBuffer->bytePos]; |
|
697 aBitBuffer->bytePos++; |
|
698 aBitBuffer->bitpos = 8; |
|
699 } |
|
700 |
|
701 // Write aValue bit by bit to the bit buffer |
|
702 for (i=aLength-1; i>=0; i--) |
|
703 { |
|
704 // Get the ith bit from aValue |
|
705 tempValue = (aValue & (1 << i)) >> i; |
|
706 |
|
707 // Zero out the bitpos bit |
|
708 byteValue = aBitBuffer->data[aBitBuffer->bytePos-1] & ~(1<<(aBitBuffer->bitpos-1)); |
|
709 byteValue |= tempValue << (aBitBuffer->bitpos-1); |
|
710 |
|
711 aBitBuffer->data[aBitBuffer->bytePos-1] = byteValue; |
|
712 aBitBuffer->bitpos--; |
|
713 |
|
714 if(aBitBuffer->bitpos == 0) |
|
715 { |
|
716 // Get the next byte |
|
717 aBitBuffer->currentBits = aBitBuffer->data[aBitBuffer->bytePos]; |
|
718 |
|
719 aBitBuffer->bytePos++; |
|
720 aBitBuffer->bitpos = 8; |
|
721 } |
|
722 } |
|
723 |
|
724 // Make sure the bit buffer currentBits is up-to-date |
|
725 aBitBuffer->currentBits = aBitBuffer->data[aBitBuffer->bytePos-1]; |
|
726 } |
|
727 |
|
728 |
|
729 // ParseSliceHeader |
|
730 // Parses the input slice header. PPS Id, frame numbering and POC LSB are modified if required. |
|
731 TInt ParseSliceHeader(slice_s *slice, seq_parameter_set_s *spsList[], |
|
732 pic_parameter_set_s *ppsList[], bitbuffer_s *bitbuf, |
|
733 TUint* aFrameNumber, TUint aFrameFromEncoder) |
|
734 { |
|
735 seq_parameter_set_s *sps; |
|
736 pic_parameter_set_s *pps; |
|
737 TUint picSizeInMapUnits; |
|
738 TUint temp, temp2; |
|
739 TInt sliceQp, len1; |
|
740 TInt retCode; |
|
741 TInt shiftedBits = 0; |
|
742 |
|
743 |
|
744 slice->picHasMMCO5 = 0; |
|
745 |
|
746 // Initialize the bit offset to zero |
|
747 slice->bitOffset = 0; |
|
748 |
|
749 // First macroblock in slice |
|
750 if ((retCode = ue_v(bitbuf, &slice->first_mb_in_slice, 65535)) < 0) |
|
751 return retCode; |
|
752 |
|
753 // Slice type |
|
754 if ((retCode = ue_v(bitbuf, &slice->slice_type, SLICE_MAX)) < 0) |
|
755 return retCode; |
|
756 |
|
757 // PPS id |
|
758 if ((retCode = ue_v(bitbuf, &slice->pic_parameter_set_id, PS_MAX_NUM_OF_PPS-1)) < 0) |
|
759 return retCode; |
|
760 |
|
761 pps = ppsList[slice->pic_parameter_set_id]; |
|
762 |
|
763 if (pps == NULL) |
|
764 { |
|
765 PRINT((_L("Error: referring to non-existing PPS.\n"))); |
|
766 return SLICE_ERR_NON_EXISTING_PPS; |
|
767 } |
|
768 |
|
769 syncBitBufferBitpos(bitbuf); |
|
770 |
|
771 // If the index has been changed the new index must be coded instead of |
|
772 // the old one to the slice header |
|
773 if (pps->indexChanged) |
|
774 { |
|
775 // We have to encode the new PPS Id to the bitbuffer |
|
776 TUint oldPPSId = slice->pic_parameter_set_id; |
|
777 TUint newPPSId; |
|
778 |
|
779 if ( aFrameFromEncoder ) |
|
780 newPPSId = pps->encPPSId; |
|
781 else |
|
782 newPPSId = pps->origPPSId; |
|
783 |
|
784 TUint trailingBits = GetNumTrailingBits(bitbuf); |
|
785 TInt diff = 0; |
|
786 |
|
787 TUint oldIdLength = ReturnUnsignedExpGolombCodeLength(oldPPSId); |
|
788 TUint newIdLength = ReturnUnsignedExpGolombCodeLength(newPPSId); |
|
789 |
|
790 // Signal that the slice data has been modified |
|
791 slice->sliceDataModified = 1; |
|
792 |
|
793 // Get the new pps |
|
794 pps = ppsList[newPPSId]; |
|
795 |
|
796 if(trailingBits > 8) |
|
797 { |
|
798 trailingBits = 8; |
|
799 } |
|
800 |
|
801 if ( oldIdLength == newIdLength ) |
|
802 { |
|
803 // Just encode the new Id on top of the old Id |
|
804 bitbuf->bitpos += oldIdLength; |
|
805 |
|
806 if(bitbuf->bitpos > 8) |
|
807 { |
|
808 // Go to the right byte and bit position |
|
809 bitbuf->bytePos -= bitbuf->bitpos / 8; |
|
810 bitbuf->bitpos = bitbuf->bitpos % 8; |
|
811 } |
|
812 |
|
813 EncodeUnsignedExpGolombCode(bitbuf, newPPSId); |
|
814 } |
|
815 else if ( oldIdLength < newIdLength ) |
|
816 { |
|
817 diff = newIdLength - oldIdLength; |
|
818 |
|
819 // Positive bit offset indicates bit-wise shift to right |
|
820 slice->bitOffset = (diff % 8); |
|
821 |
|
822 ShiftBufferRight(bitbuf, diff, trailingBits, oldIdLength); |
|
823 |
|
824 // After shifting, encode the new value to the bit buffer |
|
825 EncodeUnsignedExpGolombCode(bitbuf, newPPSId); |
|
826 } |
|
827 else |
|
828 { |
|
829 // New id's length is smaller than old id's length |
|
830 diff = oldIdLength - newIdLength; |
|
831 |
|
832 // Negative bit offset indicates bit-wise shift to left |
|
833 slice->bitOffset = -(diff % 8); |
|
834 |
|
835 ShiftBufferLeft(bitbuf, diff, oldIdLength); |
|
836 |
|
837 // After shifting, encode the new value to the bit buffer |
|
838 EncodeUnsignedExpGolombCode(bitbuf, newPPSId); |
|
839 } |
|
840 |
|
841 shiftedBits = diff; |
|
842 } |
|
843 |
|
844 sps = spsList[pps->seq_parameter_set_id]; |
|
845 |
|
846 if (sps == NULL) |
|
847 { |
|
848 PRINT((_L("Error: referring to non-existing SPS.\n"))); |
|
849 return SLICE_ERR_NON_EXISTING_SPS; |
|
850 } |
|
851 |
|
852 picSizeInMapUnits = (sps->pic_width_in_mbs_minus1+1) * (sps->pic_height_in_map_units_minus1+1); |
|
853 |
|
854 if (slice->first_mb_in_slice >= picSizeInMapUnits) |
|
855 return SLICE_ERR_ILLEGAL_VALUE; |
|
856 |
|
857 // Maximum frame number |
|
858 slice->maxFrameNum = (TUint)1 << (sps->log2_max_frame_num_minus4+4); |
|
859 |
|
860 // IDR type NAL unit shall have frame number as zero |
|
861 if ( slice->nalType == NAL_TYPE_CODED_SLICE_IDR ) |
|
862 { |
|
863 // Reset frame number for an IDR slice |
|
864 *aFrameNumber = 0; |
|
865 } |
|
866 else if ( *aFrameNumber == (slice->maxFrameNum - 1 ) ) |
|
867 { |
|
868 // Reset frame number if maximum frame number has been reached |
|
869 *aFrameNumber = 0; |
|
870 } |
|
871 else if( !slice->first_mb_in_slice ) |
|
872 { |
|
873 (*aFrameNumber)++; // Increment frame number only if this is the first mb in slice |
|
874 } |
|
875 |
|
876 |
|
877 if (sps->maxFrameNumChanged) |
|
878 { |
|
879 // Frame number field size |
|
880 TUint oldFrameNum; |
|
881 TUint newFrameNum = sps->log2_max_frame_num_minus4+4; |
|
882 |
|
883 if ( aFrameFromEncoder ) |
|
884 oldFrameNum = sps->encMaxFrameNum+4; |
|
885 else |
|
886 oldFrameNum = sps->origMaxFrameNum+4; |
|
887 |
|
888 TUint trailingBits = GetNumTrailingBits(bitbuf); |
|
889 TInt diff = 0; |
|
890 |
|
891 // Signal that the slice data has been modified |
|
892 slice->sliceDataModified = 1; |
|
893 |
|
894 if(trailingBits > 8) |
|
895 { |
|
896 trailingBits = 8; |
|
897 } |
|
898 |
|
899 // If the size of the frame number field has changed then shift bits in the buffer |
|
900 if ( oldFrameNum < newFrameNum ) |
|
901 { |
|
902 diff = newFrameNum - oldFrameNum; |
|
903 |
|
904 // Positive bit offset indicates bit-wise shift to right |
|
905 slice->bitOffset += (diff % 8); |
|
906 |
|
907 ShiftBufferRight(bitbuf, diff, trailingBits, 0); |
|
908 } |
|
909 else if ( oldFrameNum > newFrameNum ) |
|
910 { |
|
911 // New id's length is smaller than old id's length |
|
912 diff = oldFrameNum - newFrameNum; |
|
913 |
|
914 // Negative bit offset indicates bit-wise shift to left |
|
915 slice->bitOffset -= (diff % 8); |
|
916 |
|
917 ShiftBufferLeft(bitbuf, diff, 0); |
|
918 } |
|
919 |
|
920 shiftedBits += diff; |
|
921 } |
|
922 |
|
923 // Encode the new frame number here |
|
924 EncodeUnsignedNBits(bitbuf, *aFrameNumber, sps->log2_max_frame_num_minus4+4); |
|
925 |
|
926 slice->frame_num = *aFrameNumber; |
|
927 |
|
928 // IDR picture |
|
929 if (slice->isIDR) |
|
930 { |
|
931 if ((retCode = ue_v(bitbuf, &slice->idr_pic_id, 65535)) < 0) |
|
932 return retCode; |
|
933 } |
|
934 |
|
935 syncBitBufferBitpos(bitbuf); |
|
936 |
|
937 // POC parameters |
|
938 if (sps->pic_order_cnt_type == 0) |
|
939 { |
|
940 if (sps->maxPOCNumChanged) |
|
941 { |
|
942 // POC lsb number |
|
943 TUint oldPOCNum; |
|
944 TUint newPOCNum = sps->log2_max_pic_order_cnt_lsb_minus4+4; |
|
945 |
|
946 if ( aFrameFromEncoder ) |
|
947 oldPOCNum = sps->encMaxPOCNum+4; |
|
948 else |
|
949 oldPOCNum = sps->origMaxPOCNum+4; |
|
950 |
|
951 TUint trailingBits = GetNumTrailingBits(bitbuf); |
|
952 TInt diff = 0; |
|
953 |
|
954 // Signal that the slice data has been modified |
|
955 slice->sliceDataModified = 1; |
|
956 |
|
957 if (trailingBits > 8) |
|
958 { |
|
959 trailingBits = 8; |
|
960 } |
|
961 |
|
962 // If the size of the POC lsb field has changed then shift bits in the buffer |
|
963 if ( oldPOCNum < newPOCNum ) |
|
964 { |
|
965 diff = newPOCNum - oldPOCNum; |
|
966 |
|
967 // Positive bit offset indicates bit-wise shift to right |
|
968 slice->bitOffset += (diff % 8); |
|
969 |
|
970 ShiftBufferRight(bitbuf, diff, trailingBits, 0); |
|
971 |
|
972 } |
|
973 else if ( oldPOCNum > newPOCNum ) |
|
974 { |
|
975 // New id's length is smaller than old id's length |
|
976 diff = oldPOCNum - newPOCNum; |
|
977 |
|
978 // Negative bit offset indicates bit-wise shift to left |
|
979 slice->bitOffset -= (diff % 8); |
|
980 |
|
981 ShiftBufferLeft(bitbuf, diff, 0); |
|
982 |
|
983 } |
|
984 |
|
985 shiftedBits += diff; |
|
986 } |
|
987 |
|
988 // For now encode the POC as the frame number |
|
989 EncodeUnsignedNBits(bitbuf, *aFrameNumber, sps->log2_max_pic_order_cnt_lsb_minus4+4); |
|
990 |
|
991 slice->delta_pic_order_cnt_bottom = 0; |
|
992 |
|
993 if (pps->pic_order_present_flag) |
|
994 { // && !field_pic_flag |
|
995 if ((retCode = se_v_long(bitbuf, &slice->delta_pic_order_cnt_bottom)) < 0) |
|
996 return retCode; |
|
997 } |
|
998 } |
|
999 else if (sps->pic_order_cnt_type == 1) |
|
1000 { |
|
1001 slice->delta_pic_order_cnt_0 = 0; |
|
1002 slice->delta_pic_order_cnt_1 = 0; |
|
1003 // Read delta_pic_order_cnt[ 0 ] and delta_pic_order_cnt[ 1 ] |
|
1004 if (!sps->delta_pic_order_always_zero_flag) |
|
1005 { |
|
1006 // delta_pic_order_cnt[ 0 ] |
|
1007 if ((retCode = se_v_long(bitbuf, &slice->delta_pic_order_cnt_0)) < 0) |
|
1008 return retCode; |
|
1009 if (pps->pic_order_present_flag) |
|
1010 { // delta_pic_order_cnt[ 1 ] |
|
1011 if ((retCode = se_v_long(bitbuf, &slice->delta_pic_order_cnt_1)) < 0) |
|
1012 return retCode; |
|
1013 } |
|
1014 } |
|
1015 } |
|
1016 |
|
1017 // If we don't have to do any bit shifting (left or right) with the slice header, |
|
1018 // we can just stop parsing the header and return. |
|
1019 if (shiftedBits == 0) |
|
1020 { |
|
1021 return SLICE_STOP_PARSING; |
|
1022 } |
|
1023 |
|
1024 // Redundant picture count |
|
1025 if (pps->redundant_pic_cnt_present_flag) |
|
1026 { |
|
1027 if ((retCode = ue_v(bitbuf, &slice->redundant_pic_cnt, 127)) < 0) |
|
1028 return retCode; |
|
1029 } |
|
1030 else |
|
1031 slice->redundant_pic_cnt = 0; |
|
1032 |
|
1033 // Reference picture management |
|
1034 if (IS_SLICE_P(slice->slice_type)) |
|
1035 { |
|
1036 if ((retCode = u_n(bitbuf, 1, &slice->num_ref_idx_active_override_flag)) < 0) |
|
1037 return retCode; |
|
1038 if (slice->num_ref_idx_active_override_flag) |
|
1039 { |
|
1040 if ((retCode = ue_v(bitbuf, &slice->num_ref_idx_l0_active_minus1, DPB_MAX_SIZE-1)) < 0) |
|
1041 return retCode; |
|
1042 } |
|
1043 } |
|
1044 |
|
1045 // Reordering the reference picture list |
|
1046 retCode = getRefPicListReorderingCmds(slice, sps->num_ref_frames, bitbuf); |
|
1047 |
|
1048 if (retCode < 0) |
|
1049 return retCode; |
|
1050 |
|
1051 // Read the MMCO commands, but not do the operations until all the slices in current picture are decoded |
|
1052 if (slice->nalRefIdc) |
|
1053 { |
|
1054 retCode = getDecRefPicMarkingCmds(slice, sps->num_ref_frames, bitbuf); |
|
1055 if (retCode < 0) |
|
1056 return retCode; |
|
1057 } |
|
1058 |
|
1059 // Slice quant |
|
1060 if ((retCode = se_v(bitbuf, &slice->slice_qp_delta, -MAX_QP, MAX_QP)) < 0) |
|
1061 return retCode; |
|
1062 |
|
1063 sliceQp = pps->pic_init_qp_minus26 + 26 + slice->slice_qp_delta; |
|
1064 if (sliceQp < MIN_QP || sliceQp > MAX_QP) |
|
1065 { |
|
1066 PRINT((_L("Error: illegal slice quant.\n"))); |
|
1067 return SLICE_ERR_ILLEGAL_VALUE; |
|
1068 } |
|
1069 |
|
1070 slice->qp = sliceQp; |
|
1071 |
|
1072 // Deblocking filter |
|
1073 slice->disable_deblocking_filter_idc = 0; |
|
1074 slice->slice_alpha_c0_offset_div2 = 0; |
|
1075 slice->slice_beta_offset_div2 = 0; |
|
1076 |
|
1077 if (pps->deblocking_filter_parameters_present_flag == 1) |
|
1078 { |
|
1079 |
|
1080 if ((retCode = ue_v(bitbuf, &slice->disable_deblocking_filter_idc, 2)) < 0) |
|
1081 return retCode; |
|
1082 |
|
1083 if (slice->disable_deblocking_filter_idc != 1) |
|
1084 { |
|
1085 if ((retCode = se_v(bitbuf, &slice->slice_alpha_c0_offset_div2, MIN_ALPHA_BETA_OFFSET, MAX_ALPHA_BETA_OFFSET)) < 0) |
|
1086 return retCode; |
|
1087 if ((retCode = se_v(bitbuf, &slice->slice_beta_offset_div2, MIN_ALPHA_BETA_OFFSET, MAX_ALPHA_BETA_OFFSET)) < 0) |
|
1088 return retCode; |
|
1089 } |
|
1090 } |
|
1091 |
|
1092 // Read slice_group_change_cycle |
|
1093 if (pps->num_slice_groups_minus1 > 0 && pps->slice_group_map_type >= 3 && |
|
1094 pps->slice_group_map_type <= 5) |
|
1095 { |
|
1096 // len = Ceil( Log2( PicSizeInMapUnits / SliceGroupChangeRate + 1 ) ) |
|
1097 // PicSizeInMapUnits / SliceGroupChangeRate |
|
1098 temp = picSizeInMapUnits / (pps->slice_group_change_rate_minus1+1); |
|
1099 |
|
1100 // Calculate Log2 |
|
1101 temp2 = (temp + 1) >> 1; |
|
1102 for (len1 = 0; len1 < 16 && temp2 != 0; len1++) |
|
1103 temp2 >>= 1; |
|
1104 |
|
1105 // Calculate Ceil |
|
1106 if ( (((unsigned)1) << len1) < (temp + 1) ) |
|
1107 len1++; |
|
1108 |
|
1109 if ((retCode = u_n(bitbuf, len1, &slice->slice_group_change_cycle)) < 0) |
|
1110 return retCode; |
|
1111 |
|
1112 // Ceil( PicSizeInMapUnits/SliceGroupChangeRate ) |
|
1113 if (temp * (pps->slice_group_change_rate_minus1+1) != picSizeInMapUnits) |
|
1114 temp++; |
|
1115 |
|
1116 // The value of slice_group_change_cycle shall be in the range of |
|
1117 // 0 to Ceil( PicSizeInMapUnits/SliceGroupChangeRate ), inclusive. |
|
1118 if (slice->slice_group_change_cycle > temp) |
|
1119 return SLICE_ERR_ILLEGAL_VALUE; |
|
1120 } |
|
1121 |
|
1122 return SLICE_OK; |
|
1123 } |
|
1124 |
|