1 /* ------------------------------------------------------------------
2  * Copyright (C) 1998-2009 PacketVideo
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13  * express or implied.
14  * See the License for the specific language governing permissions
15  * and limitations under the License.
16  * -------------------------------------------------------------------
17  */
18 #include "avcenc_lib.h"
19 #include "avcenc_api.h"
20 
21 /** see subclause 7.4.2.1 */
22 /* no need for checking the valid range , already done in SetEncodeParam(),
23 if we have to send another SPS, the ranges should be verified first before
24 users call PVAVCEncodeSPS() */
EncodeSPS(AVCEncObject * encvid,AVCEncBitstream * stream)25 AVCEnc_Status EncodeSPS(AVCEncObject *encvid, AVCEncBitstream *stream)
26 {
27     AVCCommonObj *video = encvid->common;
28     AVCSeqParamSet *seqParam = video->currSeqParams;
29     AVCVUIParams *vui = &(seqParam->vui_parameters);
30     int i;
31     AVCEnc_Status status = AVCENC_SUCCESS;
32 
33     //DEBUG_LOG(userData,AVC_LOGTYPE_INFO,"EncodeSPS",-1,-1);
34 
35     status = BitstreamWriteBits(stream, 8, seqParam->profile_idc);
36     status = BitstreamWrite1Bit(stream, seqParam->constrained_set0_flag);
37     status = BitstreamWrite1Bit(stream, seqParam->constrained_set1_flag);
38     status = BitstreamWrite1Bit(stream, seqParam->constrained_set2_flag);
39     status = BitstreamWrite1Bit(stream, seqParam->constrained_set3_flag);
40     status = BitstreamWriteBits(stream, 4, 0);  /* forbidden zero bits */
41     if (status != AVCENC_SUCCESS)  /* we can check after each write also */
42     {
43         return status;
44     }
45 
46     status = BitstreamWriteBits(stream, 8, seqParam->level_idc);
47     status = ue_v(stream, seqParam->seq_parameter_set_id);
48     status = ue_v(stream, seqParam->log2_max_frame_num_minus4);
49     status = ue_v(stream, seqParam->pic_order_cnt_type);
50     if (status != AVCENC_SUCCESS)
51     {
52         return status;
53     }
54 
55     if (seqParam->pic_order_cnt_type == 0)
56     {
57         status = ue_v(stream, seqParam->log2_max_pic_order_cnt_lsb_minus4);
58     }
59     else if (seqParam->pic_order_cnt_type == 1)
60     {
61         status = BitstreamWrite1Bit(stream, seqParam->delta_pic_order_always_zero_flag);
62         status = se_v(stream, seqParam->offset_for_non_ref_pic); /* upto 32 bits */
63         status = se_v(stream, seqParam->offset_for_top_to_bottom_field); /* upto 32 bits */
64         status = ue_v(stream, seqParam->num_ref_frames_in_pic_order_cnt_cycle);
65 
66         for (i = 0; i < (int)(seqParam->num_ref_frames_in_pic_order_cnt_cycle); i++)
67         {
68             status = se_v(stream, seqParam->offset_for_ref_frame[i]); /* upto 32 bits */
69         }
70     }
71     if (status != AVCENC_SUCCESS)
72     {
73         return status;
74     }
75 
76     status = ue_v(stream, seqParam->num_ref_frames);
77     status = BitstreamWrite1Bit(stream, seqParam->gaps_in_frame_num_value_allowed_flag);
78     status = ue_v(stream, seqParam->pic_width_in_mbs_minus1);
79     status = ue_v(stream, seqParam->pic_height_in_map_units_minus1);
80     status = BitstreamWrite1Bit(stream, seqParam->frame_mbs_only_flag);
81     if (status != AVCENC_SUCCESS)
82     {
83         return status;
84     }
85     /* if frame_mbs_only_flag is 0, then write, mb_adaptive_frame_field_frame here */
86 
87     status = BitstreamWrite1Bit(stream, seqParam->direct_8x8_inference_flag);
88     status = BitstreamWrite1Bit(stream, seqParam->frame_cropping_flag);
89     if (seqParam->frame_cropping_flag)
90     {
91         status = ue_v(stream, seqParam->frame_crop_left_offset);
92         status = ue_v(stream, seqParam->frame_crop_right_offset);
93         status = ue_v(stream, seqParam->frame_crop_top_offset);
94         status = ue_v(stream, seqParam->frame_crop_bottom_offset);
95     }
96     if (status != AVCENC_SUCCESS)
97     {
98         return status;
99     }
100 
101     status = BitstreamWrite1Bit(stream, seqParam->vui_parameters_present_flag);
102     if (seqParam->vui_parameters_present_flag)
103     {
104         /* not supported */
105         //return AVCENC_SPS_FAIL;
106         EncodeVUI(stream, vui);
107     }
108 
109     return status;
110 }
111 
112 
EncodeVUI(AVCEncBitstream * stream,AVCVUIParams * vui)113 void EncodeVUI(AVCEncBitstream* stream, AVCVUIParams* vui)
114 {
115     int temp;
116 
117     temp = vui->aspect_ratio_info_present_flag;
118     BitstreamWrite1Bit(stream, temp);
119     if (temp)
120     {
121         BitstreamWriteBits(stream, 8, vui->aspect_ratio_idc);
122         if (vui->aspect_ratio_idc == 255)
123         {
124             BitstreamWriteBits(stream, 16, vui->sar_width);
125             BitstreamWriteBits(stream, 16, vui->sar_height);
126         }
127     }
128     temp = vui->overscan_info_present_flag;
129     BitstreamWrite1Bit(stream, temp);
130     if (temp)
131     {
132         BitstreamWrite1Bit(stream, vui->overscan_appropriate_flag);
133     }
134     temp = vui->video_signal_type_present_flag;
135     BitstreamWrite1Bit(stream, temp);
136     if (temp)
137     {
138         BitstreamWriteBits(stream, 3, vui->video_format);
139         BitstreamWrite1Bit(stream, vui->video_full_range_flag);
140         temp = vui->colour_description_present_flag;
141         BitstreamWrite1Bit(stream, temp);
142         if (temp)
143         {
144             BitstreamWriteBits(stream, 8, vui->colour_primaries);
145             BitstreamWriteBits(stream, 8, vui->transfer_characteristics);
146             BitstreamWriteBits(stream, 8, vui->matrix_coefficients);
147         }
148     }
149     temp = vui->chroma_location_info_present_flag;
150     BitstreamWrite1Bit(stream, temp);
151     if (temp)
152     {
153         ue_v(stream, vui->chroma_sample_loc_type_top_field);
154         ue_v(stream, vui->chroma_sample_loc_type_bottom_field);
155     }
156 
157     temp = vui->timing_info_present_flag;
158     BitstreamWrite1Bit(stream, temp);
159     if (temp)
160     {
161         BitstreamWriteBits(stream, 32, vui->num_units_in_tick);
162         BitstreamWriteBits(stream, 32, vui->time_scale);
163         BitstreamWrite1Bit(stream, vui->fixed_frame_rate_flag);
164     }
165 
166     temp = vui->nal_hrd_parameters_present_flag;
167     BitstreamWrite1Bit(stream, temp);
168     if (temp)
169     {
170         EncodeHRD(stream, &(vui->nal_hrd_parameters));
171     }
172     temp = vui->vcl_hrd_parameters_present_flag;
173     BitstreamWrite1Bit(stream, temp);
174     if (temp)
175     {
176         EncodeHRD(stream, &(vui->vcl_hrd_parameters));
177     }
178     if (vui->nal_hrd_parameters_present_flag || vui->vcl_hrd_parameters_present_flag)
179     {
180         BitstreamWrite1Bit(stream, vui->low_delay_hrd_flag);
181     }
182     BitstreamWrite1Bit(stream, vui->pic_struct_present_flag);
183     temp = vui->bitstream_restriction_flag;
184     BitstreamWrite1Bit(stream, temp);
185     if (temp)
186     {
187         BitstreamWrite1Bit(stream, vui->motion_vectors_over_pic_boundaries_flag);
188         ue_v(stream, vui->max_bytes_per_pic_denom);
189         ue_v(stream, vui->max_bits_per_mb_denom);
190         ue_v(stream, vui->log2_max_mv_length_horizontal);
191         ue_v(stream, vui->log2_max_mv_length_vertical);
192         ue_v(stream, vui->max_dec_frame_reordering);
193         ue_v(stream, vui->max_dec_frame_buffering);
194     }
195 
196     return ;
197 }
198 
199 
EncodeHRD(AVCEncBitstream * stream,AVCHRDParams * hrd)200 void EncodeHRD(AVCEncBitstream* stream, AVCHRDParams* hrd)
201 {
202     int i;
203 
204     ue_v(stream, hrd->cpb_cnt_minus1);
205     BitstreamWriteBits(stream, 4, hrd->bit_rate_scale);
206     BitstreamWriteBits(stream, 4, hrd->cpb_size_scale);
207     for (i = 0; i <= (int)hrd->cpb_cnt_minus1; i++)
208     {
209         ue_v(stream, hrd->bit_rate_value_minus1[i]);
210         ue_v(stream, hrd->cpb_size_value_minus1[i]);
211         ue_v(stream, hrd->cbr_flag[i]);
212     }
213     BitstreamWriteBits(stream, 5, hrd->initial_cpb_removal_delay_length_minus1);
214     BitstreamWriteBits(stream, 5, hrd->cpb_removal_delay_length_minus1);
215     BitstreamWriteBits(stream, 5, hrd->dpb_output_delay_length_minus1);
216     BitstreamWriteBits(stream, 5, hrd->time_offset_length);
217 
218     return ;
219 }
220 
221 
222 
223 /** see subclause 7.4.2.2 */
224 /* no need for checking the valid range , already done in SetEncodeParam().
225 If we have to send another SPS, the ranges should be verified first before
226 users call PVAVCEncodeSPS()*/
EncodePPS(AVCEncObject * encvid,AVCEncBitstream * stream)227 AVCEnc_Status EncodePPS(AVCEncObject *encvid, AVCEncBitstream *stream)
228 {
229     AVCCommonObj *video = encvid->common;
230     AVCEnc_Status status = AVCENC_SUCCESS;
231     AVCPicParamSet *picParam = video->currPicParams;
232     int i, iGroup, numBits;
233     uint temp;
234 
235     status = ue_v(stream, picParam->pic_parameter_set_id);
236     status = ue_v(stream, picParam->seq_parameter_set_id);
237     status = BitstreamWrite1Bit(stream, picParam->entropy_coding_mode_flag);
238     status = BitstreamWrite1Bit(stream, picParam->pic_order_present_flag);
239     if (status != AVCENC_SUCCESS)
240     {
241         return status;
242     }
243 
244     status = ue_v(stream, picParam->num_slice_groups_minus1);
245     if (picParam->num_slice_groups_minus1 > 0)
246     {
247         status = ue_v(stream, picParam->slice_group_map_type);
248         if (picParam->slice_group_map_type == 0)
249         {
250             for (iGroup = 0; iGroup <= (int)picParam->num_slice_groups_minus1; iGroup++)
251             {
252                 status = ue_v(stream, picParam->run_length_minus1[iGroup]);
253             }
254         }
255         else if (picParam->slice_group_map_type == 2)
256         {
257             for (iGroup = 0; iGroup < (int)picParam->num_slice_groups_minus1; iGroup++)
258             {
259                 status = ue_v(stream, picParam->top_left[iGroup]);
260                 status = ue_v(stream, picParam->bottom_right[iGroup]);
261             }
262         }
263         else if (picParam->slice_group_map_type == 3 ||
264                  picParam->slice_group_map_type == 4 ||
265                  picParam->slice_group_map_type == 5)
266         {
267             status = BitstreamWrite1Bit(stream, picParam->slice_group_change_direction_flag);
268             status = ue_v(stream, picParam->slice_group_change_rate_minus1);
269         }
270         else /*if(picParam->slice_group_map_type == 6)*/
271         {
272             status = ue_v(stream, picParam->pic_size_in_map_units_minus1);
273 
274             numBits = 0;/* ceil(log2(num_slice_groups_minus1+1)) bits */
275             i = picParam->num_slice_groups_minus1;
276             while (i > 0)
277             {
278                 numBits++;
279                 i >>= 1;
280             }
281 
282             for (i = 0; i <= (int)picParam->pic_size_in_map_units_minus1; i++)
283             {
284                 status = BitstreamWriteBits(stream, numBits, picParam->slice_group_id[i]);
285             }
286         }
287     }
288     if (status != AVCENC_SUCCESS)
289     {
290         return status;
291     }
292 
293     status = ue_v(stream, picParam->num_ref_idx_l0_active_minus1);
294     status = ue_v(stream, picParam->num_ref_idx_l1_active_minus1);
295     status = BitstreamWrite1Bit(stream, picParam->weighted_pred_flag);
296     status = BitstreamWriteBits(stream, 2, picParam->weighted_bipred_idc);
297     if (status != AVCENC_SUCCESS)
298     {
299         return status;
300     }
301 
302     status = se_v(stream, picParam->pic_init_qp_minus26);
303     status = se_v(stream, picParam->pic_init_qs_minus26);
304     status = se_v(stream, picParam->chroma_qp_index_offset);
305 
306     temp = picParam->deblocking_filter_control_present_flag << 2;
307     temp |= (picParam->constrained_intra_pred_flag << 1);
308     temp |= picParam->redundant_pic_cnt_present_flag;
309 
310     status = BitstreamWriteBits(stream, 3, temp);
311 
312     return status;
313 }
314 
315 /** see subclause 7.4.3 */
EncodeSliceHeader(AVCEncObject * encvid,AVCEncBitstream * stream)316 AVCEnc_Status EncodeSliceHeader(AVCEncObject *encvid, AVCEncBitstream *stream)
317 {
318     AVCCommonObj *video = encvid->common;
319     AVCSliceHeader *sliceHdr = video->sliceHdr;
320     AVCPicParamSet *currPPS = video->currPicParams;
321     AVCSeqParamSet *currSPS = video->currSeqParams;
322     AVCEnc_Status status = AVCENC_SUCCESS;
323     int slice_type, temp, i;
324     int num_bits;
325 
326     num_bits = (stream->write_pos << 3) - stream->bit_left;
327 
328     status = ue_v(stream, sliceHdr->first_mb_in_slice);
329 
330     slice_type = video->slice_type;
331 
332     if (video->mbNum == 0) /* first mb in frame */
333     {
334         status = ue_v(stream, sliceHdr->slice_type);
335     }
336     else
337     {
338         status = ue_v(stream, slice_type);
339     }
340 
341     status = ue_v(stream, sliceHdr->pic_parameter_set_id);
342 
343     status = BitstreamWriteBits(stream, currSPS->log2_max_frame_num_minus4 + 4, sliceHdr->frame_num);
344 
345     if (status != AVCENC_SUCCESS)
346     {
347         return status;
348     }
349     /* if frame_mbs_only_flag is 0, encode field_pic_flag, bottom_field_flag here */
350 
351     if (video->nal_unit_type == AVC_NALTYPE_IDR)
352     {
353         status = ue_v(stream, sliceHdr->idr_pic_id);
354     }
355 
356     if (currSPS->pic_order_cnt_type == 0)
357     {
358         status = BitstreamWriteBits(stream, currSPS->log2_max_pic_order_cnt_lsb_minus4 + 4,
359                                     sliceHdr->pic_order_cnt_lsb);
360 
361         if (currPPS->pic_order_present_flag && !sliceHdr->field_pic_flag)
362         {
363             status = se_v(stream, sliceHdr->delta_pic_order_cnt_bottom); /* 32 bits */
364         }
365     }
366     if (currSPS->pic_order_cnt_type == 1 && !currSPS->delta_pic_order_always_zero_flag)
367     {
368         status = se_v(stream, sliceHdr->delta_pic_order_cnt[0]);    /* 32 bits */
369         if (currPPS->pic_order_present_flag && !sliceHdr->field_pic_flag)
370         {
371             status = se_v(stream, sliceHdr->delta_pic_order_cnt[1]); /* 32 bits */
372         }
373     }
374 
375     if (currPPS->redundant_pic_cnt_present_flag)
376     {
377         status = ue_v(stream, sliceHdr->redundant_pic_cnt);
378     }
379 
380     if (slice_type == AVC_B_SLICE)
381     {
382         status = BitstreamWrite1Bit(stream, sliceHdr->direct_spatial_mv_pred_flag);
383     }
384 
385     if (status != AVCENC_SUCCESS)
386     {
387         return status;
388     }
389 
390     if (slice_type == AVC_P_SLICE || slice_type == AVC_SP_SLICE || slice_type == AVC_B_SLICE)
391     {
392         status = BitstreamWrite1Bit(stream, sliceHdr->num_ref_idx_active_override_flag);
393         if (sliceHdr->num_ref_idx_active_override_flag)
394         {
395             /* we shouldn't enter this part at all */
396             status = ue_v(stream, sliceHdr->num_ref_idx_l0_active_minus1);
397             if (slice_type == AVC_B_SLICE)
398             {
399                 status = ue_v(stream, sliceHdr->num_ref_idx_l1_active_minus1);
400             }
401         }
402     }
403     if (status != AVCENC_SUCCESS)
404     {
405         return status;
406     }
407 
408     /* ref_pic_list_reordering() */
409     status = ref_pic_list_reordering(video, stream, sliceHdr, slice_type);
410     if (status != AVCENC_SUCCESS)
411     {
412         return status;
413     }
414 
415     if ((currPPS->weighted_pred_flag && (slice_type == AVC_P_SLICE || slice_type == AVC_SP_SLICE)) ||
416             (currPPS->weighted_bipred_idc == 1 && slice_type == AVC_B_SLICE))
417     {
418         //      pred_weight_table(); // not supported !!
419         return AVCENC_PRED_WEIGHT_TAB_FAIL;
420     }
421 
422     if (video->nal_ref_idc != 0)
423     {
424         status = dec_ref_pic_marking(video, stream, sliceHdr);
425         if (status != AVCENC_SUCCESS)
426         {
427             return status;
428         }
429     }
430 
431     if (currPPS->entropy_coding_mode_flag && slice_type != AVC_I_SLICE && slice_type != AVC_SI_SLICE)
432     {
433         return AVCENC_CABAC_FAIL;
434         /*      ue_v(stream,&(sliceHdr->cabac_init_idc));
435                 if(sliceHdr->cabac_init_idc > 2){
436                     // not supported !!!!
437                 }*/
438     }
439 
440     status = se_v(stream, sliceHdr->slice_qp_delta);
441     if (status != AVCENC_SUCCESS)
442     {
443         return status;
444     }
445 
446     if (slice_type == AVC_SP_SLICE || slice_type == AVC_SI_SLICE)
447     {
448         if (slice_type == AVC_SP_SLICE)
449         {
450             status = BitstreamWrite1Bit(stream, sliceHdr->sp_for_switch_flag);
451             /* if sp_for_switch_flag is 0, P macroblocks in SP slice is decoded using
452             SP decoding process for non-switching pictures in 8.6.1 */
453             /* else, P macroblocks in SP slice is decoded using SP and SI decoding
454             process for switching picture in 8.6.2 */
455         }
456         status = se_v(stream, sliceHdr->slice_qs_delta);
457         if (status != AVCENC_SUCCESS)
458         {
459             return status;
460         }
461     }
462 
463     if (currPPS->deblocking_filter_control_present_flag)
464     {
465 
466         status = ue_v(stream, sliceHdr->disable_deblocking_filter_idc);
467 
468         if (sliceHdr->disable_deblocking_filter_idc != 1)
469         {
470             status = se_v(stream, sliceHdr->slice_alpha_c0_offset_div2);
471 
472             status = se_v(stream, sliceHdr->slice_beta_offset_div_2);
473         }
474         if (status != AVCENC_SUCCESS)
475         {
476             return status;
477         }
478     }
479 
480     if (currPPS->num_slice_groups_minus1 > 0 && currPPS->slice_group_map_type >= 3
481             && currPPS->slice_group_map_type <= 5)
482     {
483         /* Ceil(Log2(PicSizeInMapUnits/(float)SliceGroupChangeRate + 1)) */
484         temp = video->PicSizeInMapUnits / video->SliceGroupChangeRate;
485         if (video->PicSizeInMapUnits % video->SliceGroupChangeRate)
486         {
487             temp++;
488         }
489         i = 0;
490         while (temp > 1)
491         {
492             temp >>= 1;
493             i++;
494         }
495 
496         BitstreamWriteBits(stream, i, sliceHdr->slice_group_change_cycle);
497     }
498 
499 
500     encvid->rateCtrl->NumberofHeaderBits += (stream->write_pos << 3) - stream->bit_left - num_bits;
501 
502     return AVCENC_SUCCESS;
503 }
504 
505 /** see subclause 7.4.3.1 */
ref_pic_list_reordering(AVCCommonObj * video,AVCEncBitstream * stream,AVCSliceHeader * sliceHdr,int slice_type)506 AVCEnc_Status ref_pic_list_reordering(AVCCommonObj *video, AVCEncBitstream *stream, AVCSliceHeader *sliceHdr, int slice_type)
507 {
508     (void)(video);
509     int i;
510     AVCEnc_Status status = AVCENC_SUCCESS;
511 
512     if (slice_type != AVC_I_SLICE && slice_type != AVC_SI_SLICE)
513     {
514         status = BitstreamWrite1Bit(stream, sliceHdr->ref_pic_list_reordering_flag_l0);
515         if (sliceHdr->ref_pic_list_reordering_flag_l0)
516         {
517             i = 0;
518             do
519             {
520                 status = ue_v(stream, sliceHdr->reordering_of_pic_nums_idc_l0[i]);
521                 if (sliceHdr->reordering_of_pic_nums_idc_l0[i] == 0 ||
522                         sliceHdr->reordering_of_pic_nums_idc_l0[i] == 1)
523                 {
524                     status = ue_v(stream, sliceHdr->abs_diff_pic_num_minus1_l0[i]);
525                     /* this check should be in InitSlice(), if we ever use it */
526                     /*if(sliceHdr->reordering_of_pic_nums_idc_l0[i] == 0 &&
527                         sliceHdr->abs_diff_pic_num_minus1_l0[i] > video->MaxPicNum/2 -1)
528                     {
529                         return AVCENC_REF_PIC_REORDER_FAIL; // out of range
530                     }
531                     if(sliceHdr->reordering_of_pic_nums_idc_l0[i] == 1 &&
532                         sliceHdr->abs_diff_pic_num_minus1_l0[i] > video->MaxPicNum/2 -2)
533                     {
534                         return AVCENC_REF_PIC_REORDER_FAIL; // out of range
535                     }*/
536                 }
537                 else if (sliceHdr->reordering_of_pic_nums_idc_l0[i] == 2)
538                 {
539                     status = ue_v(stream, sliceHdr->long_term_pic_num_l0[i]);
540                 }
541                 i++;
542             }
543             while (sliceHdr->reordering_of_pic_nums_idc_l0[i] != 3
544                     && i <= (int)sliceHdr->num_ref_idx_l0_active_minus1 + 1) ;
545         }
546     }
547     if (slice_type == AVC_B_SLICE)
548     {
549         status = BitstreamWrite1Bit(stream, sliceHdr->ref_pic_list_reordering_flag_l1);
550         if (sliceHdr->ref_pic_list_reordering_flag_l1)
551         {
552             i = 0;
553             do
554             {
555                 status = ue_v(stream, sliceHdr->reordering_of_pic_nums_idc_l1[i]);
556                 if (sliceHdr->reordering_of_pic_nums_idc_l1[i] == 0 ||
557                         sliceHdr->reordering_of_pic_nums_idc_l1[i] == 1)
558                 {
559                     status = ue_v(stream, sliceHdr->abs_diff_pic_num_minus1_l1[i]);
560                     /* This check should be in InitSlice() if we ever use it
561                     if(sliceHdr->reordering_of_pic_nums_idc_l1[i] == 0 &&
562                         sliceHdr->abs_diff_pic_num_minus1_l1[i] > video->MaxPicNum/2 -1)
563                     {
564                         return AVCENC_REF_PIC_REORDER_FAIL; // out of range
565                     }
566                     if(sliceHdr->reordering_of_pic_nums_idc_l1[i] == 1 &&
567                         sliceHdr->abs_diff_pic_num_minus1_l1[i] > video->MaxPicNum/2 -2)
568                     {
569                         return AVCENC_REF_PIC_REORDER_FAIL; // out of range
570                     }*/
571                 }
572                 else if (sliceHdr->reordering_of_pic_nums_idc_l1[i] == 2)
573                 {
574                     status = ue_v(stream, sliceHdr->long_term_pic_num_l1[i]);
575                 }
576                 i++;
577             }
578             while (sliceHdr->reordering_of_pic_nums_idc_l1[i] != 3
579                     && i <= (int)sliceHdr->num_ref_idx_l1_active_minus1 + 1) ;
580         }
581     }
582 
583     return status;
584 }
585 
586 /** see subclause 7.4.3.3 */
dec_ref_pic_marking(AVCCommonObj * video,AVCEncBitstream * stream,AVCSliceHeader * sliceHdr)587 AVCEnc_Status dec_ref_pic_marking(AVCCommonObj *video, AVCEncBitstream *stream, AVCSliceHeader *sliceHdr)
588 {
589     int i;
590     AVCEnc_Status status = AVCENC_SUCCESS;
591 
592     if (video->nal_unit_type == AVC_NALTYPE_IDR)
593     {
594         status = BitstreamWrite1Bit(stream, sliceHdr->no_output_of_prior_pics_flag);
595         status = BitstreamWrite1Bit(stream, sliceHdr->long_term_reference_flag);
596         if (sliceHdr->long_term_reference_flag == 0) /* used for short-term */
597         {
598             video->MaxLongTermFrameIdx = -1; /* no long-term frame indx */
599         }
600         else /* used for long-term */
601         {
602             video->MaxLongTermFrameIdx = 0;
603             video->LongTermFrameIdx = 0;
604         }
605     }
606     else
607     {
608         status = BitstreamWrite1Bit(stream, sliceHdr->adaptive_ref_pic_marking_mode_flag); /* default to zero */
609         if (sliceHdr->adaptive_ref_pic_marking_mode_flag)
610         {
611             i = 0;
612             do
613             {
614                 status = ue_v(stream, sliceHdr->memory_management_control_operation[i]);
615                 if (sliceHdr->memory_management_control_operation[i] == 1 ||
616                         sliceHdr->memory_management_control_operation[i] == 3)
617                 {
618                     status = ue_v(stream, sliceHdr->difference_of_pic_nums_minus1[i]);
619                 }
620                 if (sliceHdr->memory_management_control_operation[i] == 2)
621                 {
622                     status = ue_v(stream, sliceHdr->long_term_pic_num[i]);
623                 }
624                 if (sliceHdr->memory_management_control_operation[i] == 3 ||
625                         sliceHdr->memory_management_control_operation[i] == 6)
626                 {
627                     status = ue_v(stream, sliceHdr->long_term_frame_idx[i]);
628                 }
629                 if (sliceHdr->memory_management_control_operation[i] == 4)
630                 {
631                     status = ue_v(stream, sliceHdr->max_long_term_frame_idx_plus1[i]);
632                 }
633                 i++;
634             }
635             while (sliceHdr->memory_management_control_operation[i] != 0 && i < MAX_DEC_REF_PIC_MARKING);
636             if (i >= MAX_DEC_REF_PIC_MARKING && sliceHdr->memory_management_control_operation[i] != 0)
637             {
638                 return AVCENC_DEC_REF_PIC_MARK_FAIL; /* we're screwed!!, not enough memory */
639             }
640         }
641     }
642 
643     return status;
644 }
645 
646 /* see subclause 8.2.1 Decoding process for picture order count.
647 See also PostPOC() for initialization of some variables. */
InitPOC(AVCEncObject * encvid)648 AVCEnc_Status InitPOC(AVCEncObject *encvid)
649 {
650     AVCCommonObj *video = encvid->common;
651     AVCSeqParamSet *currSPS = video->currSeqParams;
652     AVCSliceHeader *sliceHdr = video->sliceHdr;
653     AVCFrameIO  *currInput = encvid->currInput;
654     int i;
655 
656     switch (currSPS->pic_order_cnt_type)
657     {
658         case 0: /* POC MODE 0 , subclause 8.2.1.1 */
659             /* encoding part */
660             if (video->nal_unit_type == AVC_NALTYPE_IDR)
661             {
662                 encvid->dispOrdPOCRef = currInput->disp_order;
663             }
664             while (currInput->disp_order < encvid->dispOrdPOCRef)
665             {
666                 encvid->dispOrdPOCRef -= video->MaxPicOrderCntLsb;
667             }
668             sliceHdr->pic_order_cnt_lsb = currInput->disp_order - encvid->dispOrdPOCRef;
669             while (sliceHdr->pic_order_cnt_lsb >= video->MaxPicOrderCntLsb)
670             {
671                 sliceHdr->pic_order_cnt_lsb -= video->MaxPicOrderCntLsb;
672             }
673             /* decoding part */
674             /* Calculate the MSBs of current picture */
675             if (video->nal_unit_type == AVC_NALTYPE_IDR)
676             {
677                 video->prevPicOrderCntMsb = 0;
678                 video->prevPicOrderCntLsb = 0;
679             }
680             if (sliceHdr->pic_order_cnt_lsb  <  video->prevPicOrderCntLsb  &&
681                     (video->prevPicOrderCntLsb - sliceHdr->pic_order_cnt_lsb)  >= (video->MaxPicOrderCntLsb / 2))
682                 video->PicOrderCntMsb = video->prevPicOrderCntMsb + video->MaxPicOrderCntLsb;
683             else if (sliceHdr->pic_order_cnt_lsb  >  video->prevPicOrderCntLsb  &&
684                      (sliceHdr->pic_order_cnt_lsb - video->prevPicOrderCntLsb)  > (video->MaxPicOrderCntLsb / 2))
685                 video->PicOrderCntMsb = video->prevPicOrderCntMsb - video->MaxPicOrderCntLsb;
686             else
687                 video->PicOrderCntMsb = video->prevPicOrderCntMsb;
688 
689             /* JVT-I010 page 81 is different from JM7.3 */
690             if (!sliceHdr->field_pic_flag || !sliceHdr->bottom_field_flag)
691             {
692                 video->PicOrderCnt = video->TopFieldOrderCnt = video->PicOrderCntMsb + sliceHdr->pic_order_cnt_lsb;
693             }
694 
695             if (!sliceHdr->field_pic_flag)
696             {
697                 video->BottomFieldOrderCnt = video->TopFieldOrderCnt + sliceHdr->delta_pic_order_cnt_bottom;
698             }
699             else if (sliceHdr->bottom_field_flag)
700             {
701                 video->PicOrderCnt = video->BottomFieldOrderCnt = video->PicOrderCntMsb + sliceHdr->pic_order_cnt_lsb;
702             }
703 
704             if (!sliceHdr->field_pic_flag)
705             {
706                 video->PicOrderCnt = AVC_MIN(video->TopFieldOrderCnt, video->BottomFieldOrderCnt);
707             }
708 
709             if (video->currPicParams->pic_order_present_flag && !sliceHdr->field_pic_flag)
710             {
711                 sliceHdr->delta_pic_order_cnt_bottom = 0; /* defaulted to zero */
712             }
713 
714             break;
715         case 1: /* POC MODE 1, subclause 8.2.1.2 */
716             /* calculate FrameNumOffset */
717             if (video->nal_unit_type == AVC_NALTYPE_IDR)
718             {
719                 encvid->dispOrdPOCRef = currInput->disp_order;  /* reset the reference point */
720                 video->prevFrameNumOffset = 0;
721                 video->FrameNumOffset = 0;
722             }
723             else if (video->prevFrameNum > sliceHdr->frame_num)
724             {
725                 video->FrameNumOffset = video->prevFrameNumOffset + video->MaxFrameNum;
726             }
727             else
728             {
729                 video->FrameNumOffset = video->prevFrameNumOffset;
730             }
731             /* calculate absFrameNum */
732             if (currSPS->num_ref_frames_in_pic_order_cnt_cycle)
733             {
734                 video->absFrameNum = video->FrameNumOffset + sliceHdr->frame_num;
735             }
736             else
737             {
738                 video->absFrameNum = 0;
739             }
740 
741             if (video->absFrameNum > 0 && video->nal_ref_idc == 0)
742             {
743                 video->absFrameNum--;
744             }
745 
746             /* derive picOrderCntCycleCnt and frameNumInPicOrderCntCycle */
747             if (video->absFrameNum > 0)
748             {
749                 video->picOrderCntCycleCnt = (video->absFrameNum - 1) / currSPS->num_ref_frames_in_pic_order_cnt_cycle;
750                 video->frameNumInPicOrderCntCycle = (video->absFrameNum - 1) % currSPS->num_ref_frames_in_pic_order_cnt_cycle;
751             }
752             /* derive expectedDeltaPerPicOrderCntCycle, this value can be computed up front. */
753             video->expectedDeltaPerPicOrderCntCycle = 0;
754             for (i = 0; i < (int)currSPS->num_ref_frames_in_pic_order_cnt_cycle; i++)
755             {
756                 video->expectedDeltaPerPicOrderCntCycle += currSPS->offset_for_ref_frame[i];
757             }
758             /* derive expectedPicOrderCnt */
759             if (video->absFrameNum)
760             {
761                 video->expectedPicOrderCnt = video->picOrderCntCycleCnt * video->expectedDeltaPerPicOrderCntCycle;
762                 for (i = 0; i <= video->frameNumInPicOrderCntCycle; i++)
763                 {
764                     video->expectedPicOrderCnt += currSPS->offset_for_ref_frame[i];
765                 }
766             }
767             else
768             {
769                 video->expectedPicOrderCnt = 0;
770             }
771 
772             if (video->nal_ref_idc == 0)
773             {
774                 video->expectedPicOrderCnt += currSPS->offset_for_non_ref_pic;
775             }
776             /* derive TopFieldOrderCnt and BottomFieldOrderCnt */
777             /* encoding part */
778             if (!currSPS->delta_pic_order_always_zero_flag)
779             {
780                 sliceHdr->delta_pic_order_cnt[0] = currInput->disp_order - encvid->dispOrdPOCRef - video->expectedPicOrderCnt;
781 
782                 if (video->currPicParams->pic_order_present_flag && !sliceHdr->field_pic_flag)
783                 {
784                     sliceHdr->delta_pic_order_cnt[1] = sliceHdr->delta_pic_order_cnt[0]; /* should be calculated from currInput->bottom_field->disp_order */
785                 }
786                 else
787                 {
788                     sliceHdr->delta_pic_order_cnt[1] = 0;
789                 }
790             }
791             else
792             {
793                 sliceHdr->delta_pic_order_cnt[0] = sliceHdr->delta_pic_order_cnt[1] = 0;
794             }
795 
796             if (sliceHdr->field_pic_flag == 0)
797             {
798                 video->TopFieldOrderCnt = video->expectedPicOrderCnt + sliceHdr->delta_pic_order_cnt[0];
799                 video->BottomFieldOrderCnt = video->TopFieldOrderCnt + currSPS->offset_for_top_to_bottom_field + sliceHdr->delta_pic_order_cnt[1];
800 
801                 video->PicOrderCnt = AVC_MIN(video->TopFieldOrderCnt, video->BottomFieldOrderCnt);
802             }
803             else if (sliceHdr->bottom_field_flag == 0)
804             {
805                 video->TopFieldOrderCnt = video->expectedPicOrderCnt + sliceHdr->delta_pic_order_cnt[0];
806                 video->PicOrderCnt = video->TopFieldOrderCnt;
807             }
808             else
809             {
810                 video->BottomFieldOrderCnt = video->expectedPicOrderCnt + currSPS->offset_for_top_to_bottom_field + sliceHdr->delta_pic_order_cnt[0];
811                 video->PicOrderCnt = video->BottomFieldOrderCnt;
812             }
813             break;
814 
815 
816         case 2: /* POC MODE 2, subclause 8.2.1.3 */
817             /* decoding order must be the same as display order */
818             /* we don't check for that. The decoder will just output in decoding order. */
819             /* Check for 2 consecutive non-reference frame */
820             if (video->nal_ref_idc == 0)
821             {
822                 if (encvid->dispOrdPOCRef == 1)
823                 {
824                     return AVCENC_CONSECUTIVE_NONREF;
825                 }
826                 encvid->dispOrdPOCRef = 1;  /* act as a flag for non ref */
827             }
828             else
829             {
830                 encvid->dispOrdPOCRef = 0;
831             }
832 
833 
834             if (video->nal_unit_type == AVC_NALTYPE_IDR)
835             {
836                 video->FrameNumOffset = 0;
837             }
838             else if (video->prevFrameNum > sliceHdr->frame_num)
839             {
840                 video->FrameNumOffset = video->prevFrameNumOffset + video->MaxFrameNum;
841             }
842             else
843             {
844                 video->FrameNumOffset = video->prevFrameNumOffset;
845             }
846             /* derive tempPicOrderCnt, we just use PicOrderCnt */
847             if (video->nal_unit_type == AVC_NALTYPE_IDR)
848             {
849                 video->PicOrderCnt = 0;
850             }
851             else if (video->nal_ref_idc == 0)
852             {
853                 video->PicOrderCnt = 2 * (video->FrameNumOffset + sliceHdr->frame_num) - 1;
854             }
855             else
856             {
857                 video->PicOrderCnt = 2 * (video->FrameNumOffset + sliceHdr->frame_num);
858             }
859             /* derive TopFieldOrderCnt and BottomFieldOrderCnt */
860             if (sliceHdr->field_pic_flag == 0)
861             {
862                 video->TopFieldOrderCnt = video->BottomFieldOrderCnt = video->PicOrderCnt;
863             }
864             else if (sliceHdr->bottom_field_flag)
865             {
866                 video->BottomFieldOrderCnt = video->PicOrderCnt;
867             }
868             else
869             {
870                 video->TopFieldOrderCnt = video->PicOrderCnt;
871             }
872             break;
873         default:
874             return AVCENC_POC_FAIL;
875     }
876 
877     return AVCENC_SUCCESS;
878 }
879 
880 /** see subclause 8.2.1 */
PostPOC(AVCCommonObj * video)881 AVCEnc_Status PostPOC(AVCCommonObj *video)
882 {
883     AVCSliceHeader *sliceHdr = video->sliceHdr;
884     AVCSeqParamSet *currSPS = video->currSeqParams;
885 
886     video->prevFrameNum = sliceHdr->frame_num;
887 
888     switch (currSPS->pic_order_cnt_type)
889     {
890         case 0: /* subclause 8.2.1.1 */
891             if (video->mem_mgr_ctrl_eq_5)
892             {
893                 video->prevPicOrderCntMsb = 0;
894                 video->prevPicOrderCntLsb = video->TopFieldOrderCnt;
895             }
896             else
897             {
898                 video->prevPicOrderCntMsb = video->PicOrderCntMsb;
899                 video->prevPicOrderCntLsb = sliceHdr->pic_order_cnt_lsb;
900             }
901             break;
902         case 1:  /* subclause 8.2.1.2 and 8.2.1.3 */
903         case 2:
904             if (video->mem_mgr_ctrl_eq_5)
905             {
906                 video->prevFrameNumOffset = 0;
907             }
908             else
909             {
910                 video->prevFrameNumOffset = video->FrameNumOffset;
911             }
912             break;
913     }
914 
915     return AVCENC_SUCCESS;
916 }
917 
918