header.cpp revision 29a84457aed4c45bc900998b5e11c03023264208
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(),
23if we have to send another SPS, the ranges should be verified first before
24users call PVAVCEncodeSPS() */
25AVCEnc_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
113void 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
200void 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().
225If we have to send another SPS, the ranges should be verified first before
226users call PVAVCEncodeSPS()*/
227AVCEnc_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 */
316AVCEnc_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 */
506AVCEnc_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 */
587AVCEnc_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.
647See also PostPOC() for initialization of some variables. */
648AVCEnc_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 */
881AVCEnc_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