Home | History | Annotate | Download | only in src
      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() */
     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 
    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 
    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()*/
    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 */
    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 */
    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 */
    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. */
    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 */
    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