129a84457aed4c45bc900998b5e11c03023264208James Dong/* ------------------------------------------------------------------
229a84457aed4c45bc900998b5e11c03023264208James Dong * Copyright (C) 1998-2009 PacketVideo
329a84457aed4c45bc900998b5e11c03023264208James Dong *
429a84457aed4c45bc900998b5e11c03023264208James Dong * Licensed under the Apache License, Version 2.0 (the "License");
529a84457aed4c45bc900998b5e11c03023264208James Dong * you may not use this file except in compliance with the License.
629a84457aed4c45bc900998b5e11c03023264208James Dong * You may obtain a copy of the License at
729a84457aed4c45bc900998b5e11c03023264208James Dong *
829a84457aed4c45bc900998b5e11c03023264208James Dong *      http://www.apache.org/licenses/LICENSE-2.0
929a84457aed4c45bc900998b5e11c03023264208James Dong *
1029a84457aed4c45bc900998b5e11c03023264208James Dong * Unless required by applicable law or agreed to in writing, software
1129a84457aed4c45bc900998b5e11c03023264208James Dong * distributed under the License is distributed on an "AS IS" BASIS,
1229a84457aed4c45bc900998b5e11c03023264208James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
1329a84457aed4c45bc900998b5e11c03023264208James Dong * express or implied.
1429a84457aed4c45bc900998b5e11c03023264208James Dong * See the License for the specific language governing permissions
1529a84457aed4c45bc900998b5e11c03023264208James Dong * and limitations under the License.
1629a84457aed4c45bc900998b5e11c03023264208James Dong * -------------------------------------------------------------------
1729a84457aed4c45bc900998b5e11c03023264208James Dong */
1829a84457aed4c45bc900998b5e11c03023264208James Dong#include "avcenc_lib.h"
1929a84457aed4c45bc900998b5e11c03023264208James Dong#include "avcenc_api.h"
2029a84457aed4c45bc900998b5e11c03023264208James Dong
2129a84457aed4c45bc900998b5e11c03023264208James Dong/** see subclause 7.4.2.1 */
2229a84457aed4c45bc900998b5e11c03023264208James Dong/* no need for checking the valid range , already done in SetEncodeParam(),
2329a84457aed4c45bc900998b5e11c03023264208James Dongif we have to send another SPS, the ranges should be verified first before
2429a84457aed4c45bc900998b5e11c03023264208James Dongusers call PVAVCEncodeSPS() */
2529a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status EncodeSPS(AVCEncObject *encvid, AVCEncBitstream *stream)
2629a84457aed4c45bc900998b5e11c03023264208James Dong{
2729a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
2829a84457aed4c45bc900998b5e11c03023264208James Dong    AVCSeqParamSet *seqParam = video->currSeqParams;
2929a84457aed4c45bc900998b5e11c03023264208James Dong    AVCVUIParams *vui = &(seqParam->vui_parameters);
3029a84457aed4c45bc900998b5e11c03023264208James Dong    int i;
3129a84457aed4c45bc900998b5e11c03023264208James Dong    AVCEnc_Status status = AVCENC_SUCCESS;
3229a84457aed4c45bc900998b5e11c03023264208James Dong
3329a84457aed4c45bc900998b5e11c03023264208James Dong    //DEBUG_LOG(userData,AVC_LOGTYPE_INFO,"EncodeSPS",-1,-1);
3429a84457aed4c45bc900998b5e11c03023264208James Dong
3529a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWriteBits(stream, 8, seqParam->profile_idc);
3629a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWrite1Bit(stream, seqParam->constrained_set0_flag);
3729a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWrite1Bit(stream, seqParam->constrained_set1_flag);
3829a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWrite1Bit(stream, seqParam->constrained_set2_flag);
3929a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWrite1Bit(stream, seqParam->constrained_set3_flag);
4029a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWriteBits(stream, 4, 0);  /* forbidden zero bits */
4129a84457aed4c45bc900998b5e11c03023264208James Dong    if (status != AVCENC_SUCCESS)  /* we can check after each write also */
4229a84457aed4c45bc900998b5e11c03023264208James Dong    {
4329a84457aed4c45bc900998b5e11c03023264208James Dong        return status;
4429a84457aed4c45bc900998b5e11c03023264208James Dong    }
4529a84457aed4c45bc900998b5e11c03023264208James Dong
4629a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWriteBits(stream, 8, seqParam->level_idc);
4729a84457aed4c45bc900998b5e11c03023264208James Dong    status = ue_v(stream, seqParam->seq_parameter_set_id);
4829a84457aed4c45bc900998b5e11c03023264208James Dong    status = ue_v(stream, seqParam->log2_max_frame_num_minus4);
4929a84457aed4c45bc900998b5e11c03023264208James Dong    status = ue_v(stream, seqParam->pic_order_cnt_type);
5029a84457aed4c45bc900998b5e11c03023264208James Dong    if (status != AVCENC_SUCCESS)
5129a84457aed4c45bc900998b5e11c03023264208James Dong    {
5229a84457aed4c45bc900998b5e11c03023264208James Dong        return status;
5329a84457aed4c45bc900998b5e11c03023264208James Dong    }
5429a84457aed4c45bc900998b5e11c03023264208James Dong
5529a84457aed4c45bc900998b5e11c03023264208James Dong    if (seqParam->pic_order_cnt_type == 0)
5629a84457aed4c45bc900998b5e11c03023264208James Dong    {
5729a84457aed4c45bc900998b5e11c03023264208James Dong        status = ue_v(stream, seqParam->log2_max_pic_order_cnt_lsb_minus4);
5829a84457aed4c45bc900998b5e11c03023264208James Dong    }
5929a84457aed4c45bc900998b5e11c03023264208James Dong    else if (seqParam->pic_order_cnt_type == 1)
6029a84457aed4c45bc900998b5e11c03023264208James Dong    {
6129a84457aed4c45bc900998b5e11c03023264208James Dong        status = BitstreamWrite1Bit(stream, seqParam->delta_pic_order_always_zero_flag);
6229a84457aed4c45bc900998b5e11c03023264208James Dong        status = se_v(stream, seqParam->offset_for_non_ref_pic); /* upto 32 bits */
6329a84457aed4c45bc900998b5e11c03023264208James Dong        status = se_v(stream, seqParam->offset_for_top_to_bottom_field); /* upto 32 bits */
6429a84457aed4c45bc900998b5e11c03023264208James Dong        status = ue_v(stream, seqParam->num_ref_frames_in_pic_order_cnt_cycle);
6529a84457aed4c45bc900998b5e11c03023264208James Dong
6629a84457aed4c45bc900998b5e11c03023264208James Dong        for (i = 0; i < (int)(seqParam->num_ref_frames_in_pic_order_cnt_cycle); i++)
6729a84457aed4c45bc900998b5e11c03023264208James Dong        {
6829a84457aed4c45bc900998b5e11c03023264208James Dong            status = se_v(stream, seqParam->offset_for_ref_frame[i]); /* upto 32 bits */
6929a84457aed4c45bc900998b5e11c03023264208James Dong        }
7029a84457aed4c45bc900998b5e11c03023264208James Dong    }
7129a84457aed4c45bc900998b5e11c03023264208James Dong    if (status != AVCENC_SUCCESS)
7229a84457aed4c45bc900998b5e11c03023264208James Dong    {
7329a84457aed4c45bc900998b5e11c03023264208James Dong        return status;
7429a84457aed4c45bc900998b5e11c03023264208James Dong    }
7529a84457aed4c45bc900998b5e11c03023264208James Dong
7629a84457aed4c45bc900998b5e11c03023264208James Dong    status = ue_v(stream, seqParam->num_ref_frames);
7729a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWrite1Bit(stream, seqParam->gaps_in_frame_num_value_allowed_flag);
7829a84457aed4c45bc900998b5e11c03023264208James Dong    status = ue_v(stream, seqParam->pic_width_in_mbs_minus1);
7929a84457aed4c45bc900998b5e11c03023264208James Dong    status = ue_v(stream, seqParam->pic_height_in_map_units_minus1);
8029a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWrite1Bit(stream, seqParam->frame_mbs_only_flag);
8129a84457aed4c45bc900998b5e11c03023264208James Dong    if (status != AVCENC_SUCCESS)
8229a84457aed4c45bc900998b5e11c03023264208James Dong    {
8329a84457aed4c45bc900998b5e11c03023264208James Dong        return status;
8429a84457aed4c45bc900998b5e11c03023264208James Dong    }
8529a84457aed4c45bc900998b5e11c03023264208James Dong    /* if frame_mbs_only_flag is 0, then write, mb_adaptive_frame_field_frame here */
8629a84457aed4c45bc900998b5e11c03023264208James Dong
8729a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWrite1Bit(stream, seqParam->direct_8x8_inference_flag);
8829a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWrite1Bit(stream, seqParam->frame_cropping_flag);
8929a84457aed4c45bc900998b5e11c03023264208James Dong    if (seqParam->frame_cropping_flag)
9029a84457aed4c45bc900998b5e11c03023264208James Dong    {
9129a84457aed4c45bc900998b5e11c03023264208James Dong        status = ue_v(stream, seqParam->frame_crop_left_offset);
9229a84457aed4c45bc900998b5e11c03023264208James Dong        status = ue_v(stream, seqParam->frame_crop_right_offset);
9329a84457aed4c45bc900998b5e11c03023264208James Dong        status = ue_v(stream, seqParam->frame_crop_top_offset);
9429a84457aed4c45bc900998b5e11c03023264208James Dong        status = ue_v(stream, seqParam->frame_crop_bottom_offset);
9529a84457aed4c45bc900998b5e11c03023264208James Dong    }
9629a84457aed4c45bc900998b5e11c03023264208James Dong    if (status != AVCENC_SUCCESS)
9729a84457aed4c45bc900998b5e11c03023264208James Dong    {
9829a84457aed4c45bc900998b5e11c03023264208James Dong        return status;
9929a84457aed4c45bc900998b5e11c03023264208James Dong    }
10029a84457aed4c45bc900998b5e11c03023264208James Dong
10129a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWrite1Bit(stream, seqParam->vui_parameters_present_flag);
10229a84457aed4c45bc900998b5e11c03023264208James Dong    if (seqParam->vui_parameters_present_flag)
10329a84457aed4c45bc900998b5e11c03023264208James Dong    {
10429a84457aed4c45bc900998b5e11c03023264208James Dong        /* not supported */
10529a84457aed4c45bc900998b5e11c03023264208James Dong        //return AVCENC_SPS_FAIL;
10629a84457aed4c45bc900998b5e11c03023264208James Dong        EncodeVUI(stream, vui);
10729a84457aed4c45bc900998b5e11c03023264208James Dong    }
10829a84457aed4c45bc900998b5e11c03023264208James Dong
10929a84457aed4c45bc900998b5e11c03023264208James Dong    return status;
11029a84457aed4c45bc900998b5e11c03023264208James Dong}
11129a84457aed4c45bc900998b5e11c03023264208James Dong
11229a84457aed4c45bc900998b5e11c03023264208James Dong
11329a84457aed4c45bc900998b5e11c03023264208James Dongvoid EncodeVUI(AVCEncBitstream* stream, AVCVUIParams* vui)
11429a84457aed4c45bc900998b5e11c03023264208James Dong{
11529a84457aed4c45bc900998b5e11c03023264208James Dong    int temp;
11629a84457aed4c45bc900998b5e11c03023264208James Dong
11729a84457aed4c45bc900998b5e11c03023264208James Dong    temp = vui->aspect_ratio_info_present_flag;
11829a84457aed4c45bc900998b5e11c03023264208James Dong    BitstreamWrite1Bit(stream, temp);
11929a84457aed4c45bc900998b5e11c03023264208James Dong    if (temp)
12029a84457aed4c45bc900998b5e11c03023264208James Dong    {
12129a84457aed4c45bc900998b5e11c03023264208James Dong        BitstreamWriteBits(stream, 8, vui->aspect_ratio_idc);
12229a84457aed4c45bc900998b5e11c03023264208James Dong        if (vui->aspect_ratio_idc == 255)
12329a84457aed4c45bc900998b5e11c03023264208James Dong        {
12429a84457aed4c45bc900998b5e11c03023264208James Dong            BitstreamWriteBits(stream, 16, vui->sar_width);
12529a84457aed4c45bc900998b5e11c03023264208James Dong            BitstreamWriteBits(stream, 16, vui->sar_height);
12629a84457aed4c45bc900998b5e11c03023264208James Dong        }
12729a84457aed4c45bc900998b5e11c03023264208James Dong    }
12829a84457aed4c45bc900998b5e11c03023264208James Dong    temp = vui->overscan_info_present_flag;
12929a84457aed4c45bc900998b5e11c03023264208James Dong    BitstreamWrite1Bit(stream, temp);
13029a84457aed4c45bc900998b5e11c03023264208James Dong    if (temp)
13129a84457aed4c45bc900998b5e11c03023264208James Dong    {
13229a84457aed4c45bc900998b5e11c03023264208James Dong        BitstreamWrite1Bit(stream, vui->overscan_appropriate_flag);
13329a84457aed4c45bc900998b5e11c03023264208James Dong    }
13429a84457aed4c45bc900998b5e11c03023264208James Dong    temp = vui->video_signal_type_present_flag;
13529a84457aed4c45bc900998b5e11c03023264208James Dong    BitstreamWrite1Bit(stream, temp);
13629a84457aed4c45bc900998b5e11c03023264208James Dong    if (temp)
13729a84457aed4c45bc900998b5e11c03023264208James Dong    {
13829a84457aed4c45bc900998b5e11c03023264208James Dong        BitstreamWriteBits(stream, 3, vui->video_format);
13929a84457aed4c45bc900998b5e11c03023264208James Dong        BitstreamWrite1Bit(stream, vui->video_full_range_flag);
14029a84457aed4c45bc900998b5e11c03023264208James Dong        temp = vui->colour_description_present_flag;
14129a84457aed4c45bc900998b5e11c03023264208James Dong        BitstreamWrite1Bit(stream, temp);
14229a84457aed4c45bc900998b5e11c03023264208James Dong        if (temp)
14329a84457aed4c45bc900998b5e11c03023264208James Dong        {
14429a84457aed4c45bc900998b5e11c03023264208James Dong            BitstreamWriteBits(stream, 8, vui->colour_primaries);
14529a84457aed4c45bc900998b5e11c03023264208James Dong            BitstreamWriteBits(stream, 8, vui->transfer_characteristics);
14629a84457aed4c45bc900998b5e11c03023264208James Dong            BitstreamWriteBits(stream, 8, vui->matrix_coefficients);
14729a84457aed4c45bc900998b5e11c03023264208James Dong        }
14829a84457aed4c45bc900998b5e11c03023264208James Dong    }
14929a84457aed4c45bc900998b5e11c03023264208James Dong    temp = vui->chroma_location_info_present_flag;
15029a84457aed4c45bc900998b5e11c03023264208James Dong    BitstreamWrite1Bit(stream, temp);
15129a84457aed4c45bc900998b5e11c03023264208James Dong    if (temp)
15229a84457aed4c45bc900998b5e11c03023264208James Dong    {
15329a84457aed4c45bc900998b5e11c03023264208James Dong        ue_v(stream, vui->chroma_sample_loc_type_top_field);
15429a84457aed4c45bc900998b5e11c03023264208James Dong        ue_v(stream, vui->chroma_sample_loc_type_bottom_field);
15529a84457aed4c45bc900998b5e11c03023264208James Dong    }
15629a84457aed4c45bc900998b5e11c03023264208James Dong
15729a84457aed4c45bc900998b5e11c03023264208James Dong    temp = vui->timing_info_present_flag;
15829a84457aed4c45bc900998b5e11c03023264208James Dong    BitstreamWrite1Bit(stream, temp);
15929a84457aed4c45bc900998b5e11c03023264208James Dong    if (temp)
16029a84457aed4c45bc900998b5e11c03023264208James Dong    {
16129a84457aed4c45bc900998b5e11c03023264208James Dong        BitstreamWriteBits(stream, 32, vui->num_units_in_tick);
16229a84457aed4c45bc900998b5e11c03023264208James Dong        BitstreamWriteBits(stream, 32, vui->time_scale);
16329a84457aed4c45bc900998b5e11c03023264208James Dong        BitstreamWrite1Bit(stream, vui->fixed_frame_rate_flag);
16429a84457aed4c45bc900998b5e11c03023264208James Dong    }
16529a84457aed4c45bc900998b5e11c03023264208James Dong
16629a84457aed4c45bc900998b5e11c03023264208James Dong    temp = vui->nal_hrd_parameters_present_flag;
16729a84457aed4c45bc900998b5e11c03023264208James Dong    BitstreamWrite1Bit(stream, temp);
16829a84457aed4c45bc900998b5e11c03023264208James Dong    if (temp)
16929a84457aed4c45bc900998b5e11c03023264208James Dong    {
17029a84457aed4c45bc900998b5e11c03023264208James Dong        EncodeHRD(stream, &(vui->nal_hrd_parameters));
17129a84457aed4c45bc900998b5e11c03023264208James Dong    }
17229a84457aed4c45bc900998b5e11c03023264208James Dong    temp = vui->vcl_hrd_parameters_present_flag;
17329a84457aed4c45bc900998b5e11c03023264208James Dong    BitstreamWrite1Bit(stream, temp);
17429a84457aed4c45bc900998b5e11c03023264208James Dong    if (temp)
17529a84457aed4c45bc900998b5e11c03023264208James Dong    {
17629a84457aed4c45bc900998b5e11c03023264208James Dong        EncodeHRD(stream, &(vui->vcl_hrd_parameters));
17729a84457aed4c45bc900998b5e11c03023264208James Dong    }
17829a84457aed4c45bc900998b5e11c03023264208James Dong    if (vui->nal_hrd_parameters_present_flag || vui->vcl_hrd_parameters_present_flag)
17929a84457aed4c45bc900998b5e11c03023264208James Dong    {
18029a84457aed4c45bc900998b5e11c03023264208James Dong        BitstreamWrite1Bit(stream, vui->low_delay_hrd_flag);
18129a84457aed4c45bc900998b5e11c03023264208James Dong    }
18229a84457aed4c45bc900998b5e11c03023264208James Dong    BitstreamWrite1Bit(stream, vui->pic_struct_present_flag);
18329a84457aed4c45bc900998b5e11c03023264208James Dong    temp = vui->bitstream_restriction_flag;
18429a84457aed4c45bc900998b5e11c03023264208James Dong    BitstreamWrite1Bit(stream, temp);
18529a84457aed4c45bc900998b5e11c03023264208James Dong    if (temp)
18629a84457aed4c45bc900998b5e11c03023264208James Dong    {
18729a84457aed4c45bc900998b5e11c03023264208James Dong        BitstreamWrite1Bit(stream, vui->motion_vectors_over_pic_boundaries_flag);
18829a84457aed4c45bc900998b5e11c03023264208James Dong        ue_v(stream, vui->max_bytes_per_pic_denom);
18929a84457aed4c45bc900998b5e11c03023264208James Dong        ue_v(stream, vui->max_bits_per_mb_denom);
19029a84457aed4c45bc900998b5e11c03023264208James Dong        ue_v(stream, vui->log2_max_mv_length_horizontal);
19129a84457aed4c45bc900998b5e11c03023264208James Dong        ue_v(stream, vui->log2_max_mv_length_vertical);
19229a84457aed4c45bc900998b5e11c03023264208James Dong        ue_v(stream, vui->max_dec_frame_reordering);
19329a84457aed4c45bc900998b5e11c03023264208James Dong        ue_v(stream, vui->max_dec_frame_buffering);
19429a84457aed4c45bc900998b5e11c03023264208James Dong    }
19529a84457aed4c45bc900998b5e11c03023264208James Dong
19629a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
19729a84457aed4c45bc900998b5e11c03023264208James Dong}
19829a84457aed4c45bc900998b5e11c03023264208James Dong
19929a84457aed4c45bc900998b5e11c03023264208James Dong
20029a84457aed4c45bc900998b5e11c03023264208James Dongvoid EncodeHRD(AVCEncBitstream* stream, AVCHRDParams* hrd)
20129a84457aed4c45bc900998b5e11c03023264208James Dong{
20229a84457aed4c45bc900998b5e11c03023264208James Dong    int i;
20329a84457aed4c45bc900998b5e11c03023264208James Dong
20429a84457aed4c45bc900998b5e11c03023264208James Dong    ue_v(stream, hrd->cpb_cnt_minus1);
20529a84457aed4c45bc900998b5e11c03023264208James Dong    BitstreamWriteBits(stream, 4, hrd->bit_rate_scale);
20629a84457aed4c45bc900998b5e11c03023264208James Dong    BitstreamWriteBits(stream, 4, hrd->cpb_size_scale);
20729a84457aed4c45bc900998b5e11c03023264208James Dong    for (i = 0; i <= (int)hrd->cpb_cnt_minus1; i++)
20829a84457aed4c45bc900998b5e11c03023264208James Dong    {
20929a84457aed4c45bc900998b5e11c03023264208James Dong        ue_v(stream, hrd->bit_rate_value_minus1[i]);
21029a84457aed4c45bc900998b5e11c03023264208James Dong        ue_v(stream, hrd->cpb_size_value_minus1[i]);
21129a84457aed4c45bc900998b5e11c03023264208James Dong        ue_v(stream, hrd->cbr_flag[i]);
21229a84457aed4c45bc900998b5e11c03023264208James Dong    }
21329a84457aed4c45bc900998b5e11c03023264208James Dong    BitstreamWriteBits(stream, 5, hrd->initial_cpb_removal_delay_length_minus1);
21429a84457aed4c45bc900998b5e11c03023264208James Dong    BitstreamWriteBits(stream, 5, hrd->cpb_removal_delay_length_minus1);
21529a84457aed4c45bc900998b5e11c03023264208James Dong    BitstreamWriteBits(stream, 5, hrd->dpb_output_delay_length_minus1);
21629a84457aed4c45bc900998b5e11c03023264208James Dong    BitstreamWriteBits(stream, 5, hrd->time_offset_length);
21729a84457aed4c45bc900998b5e11c03023264208James Dong
21829a84457aed4c45bc900998b5e11c03023264208James Dong    return ;
21929a84457aed4c45bc900998b5e11c03023264208James Dong}
22029a84457aed4c45bc900998b5e11c03023264208James Dong
22129a84457aed4c45bc900998b5e11c03023264208James Dong
22229a84457aed4c45bc900998b5e11c03023264208James Dong
22329a84457aed4c45bc900998b5e11c03023264208James Dong/** see subclause 7.4.2.2 */
22429a84457aed4c45bc900998b5e11c03023264208James Dong/* no need for checking the valid range , already done in SetEncodeParam().
22529a84457aed4c45bc900998b5e11c03023264208James DongIf we have to send another SPS, the ranges should be verified first before
22629a84457aed4c45bc900998b5e11c03023264208James Dongusers call PVAVCEncodeSPS()*/
22729a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status EncodePPS(AVCEncObject *encvid, AVCEncBitstream *stream)
22829a84457aed4c45bc900998b5e11c03023264208James Dong{
22929a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
23029a84457aed4c45bc900998b5e11c03023264208James Dong    AVCEnc_Status status = AVCENC_SUCCESS;
23129a84457aed4c45bc900998b5e11c03023264208James Dong    AVCPicParamSet *picParam = video->currPicParams;
23229a84457aed4c45bc900998b5e11c03023264208James Dong    int i, iGroup, numBits;
23329a84457aed4c45bc900998b5e11c03023264208James Dong    uint temp;
23429a84457aed4c45bc900998b5e11c03023264208James Dong
23529a84457aed4c45bc900998b5e11c03023264208James Dong    status = ue_v(stream, picParam->pic_parameter_set_id);
23629a84457aed4c45bc900998b5e11c03023264208James Dong    status = ue_v(stream, picParam->seq_parameter_set_id);
23729a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWrite1Bit(stream, picParam->entropy_coding_mode_flag);
23829a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWrite1Bit(stream, picParam->pic_order_present_flag);
23929a84457aed4c45bc900998b5e11c03023264208James Dong    if (status != AVCENC_SUCCESS)
24029a84457aed4c45bc900998b5e11c03023264208James Dong    {
24129a84457aed4c45bc900998b5e11c03023264208James Dong        return status;
24229a84457aed4c45bc900998b5e11c03023264208James Dong    }
24329a84457aed4c45bc900998b5e11c03023264208James Dong
24429a84457aed4c45bc900998b5e11c03023264208James Dong    status = ue_v(stream, picParam->num_slice_groups_minus1);
24529a84457aed4c45bc900998b5e11c03023264208James Dong    if (picParam->num_slice_groups_minus1 > 0)
24629a84457aed4c45bc900998b5e11c03023264208James Dong    {
24729a84457aed4c45bc900998b5e11c03023264208James Dong        status = ue_v(stream, picParam->slice_group_map_type);
24829a84457aed4c45bc900998b5e11c03023264208James Dong        if (picParam->slice_group_map_type == 0)
24929a84457aed4c45bc900998b5e11c03023264208James Dong        {
25029a84457aed4c45bc900998b5e11c03023264208James Dong            for (iGroup = 0; iGroup <= (int)picParam->num_slice_groups_minus1; iGroup++)
25129a84457aed4c45bc900998b5e11c03023264208James Dong            {
25229a84457aed4c45bc900998b5e11c03023264208James Dong                status = ue_v(stream, picParam->run_length_minus1[iGroup]);
25329a84457aed4c45bc900998b5e11c03023264208James Dong            }
25429a84457aed4c45bc900998b5e11c03023264208James Dong        }
25529a84457aed4c45bc900998b5e11c03023264208James Dong        else if (picParam->slice_group_map_type == 2)
25629a84457aed4c45bc900998b5e11c03023264208James Dong        {
25729a84457aed4c45bc900998b5e11c03023264208James Dong            for (iGroup = 0; iGroup < (int)picParam->num_slice_groups_minus1; iGroup++)
25829a84457aed4c45bc900998b5e11c03023264208James Dong            {
25929a84457aed4c45bc900998b5e11c03023264208James Dong                status = ue_v(stream, picParam->top_left[iGroup]);
26029a84457aed4c45bc900998b5e11c03023264208James Dong                status = ue_v(stream, picParam->bottom_right[iGroup]);
26129a84457aed4c45bc900998b5e11c03023264208James Dong            }
26229a84457aed4c45bc900998b5e11c03023264208James Dong        }
26329a84457aed4c45bc900998b5e11c03023264208James Dong        else if (picParam->slice_group_map_type == 3 ||
26429a84457aed4c45bc900998b5e11c03023264208James Dong                 picParam->slice_group_map_type == 4 ||
26529a84457aed4c45bc900998b5e11c03023264208James Dong                 picParam->slice_group_map_type == 5)
26629a84457aed4c45bc900998b5e11c03023264208James Dong        {
26729a84457aed4c45bc900998b5e11c03023264208James Dong            status = BitstreamWrite1Bit(stream, picParam->slice_group_change_direction_flag);
26829a84457aed4c45bc900998b5e11c03023264208James Dong            status = ue_v(stream, picParam->slice_group_change_rate_minus1);
26929a84457aed4c45bc900998b5e11c03023264208James Dong        }
27029a84457aed4c45bc900998b5e11c03023264208James Dong        else /*if(picParam->slice_group_map_type == 6)*/
27129a84457aed4c45bc900998b5e11c03023264208James Dong        {
27229a84457aed4c45bc900998b5e11c03023264208James Dong            status = ue_v(stream, picParam->pic_size_in_map_units_minus1);
27329a84457aed4c45bc900998b5e11c03023264208James Dong
27429a84457aed4c45bc900998b5e11c03023264208James Dong            numBits = 0;/* ceil(log2(num_slice_groups_minus1+1)) bits */
27529a84457aed4c45bc900998b5e11c03023264208James Dong            i = picParam->num_slice_groups_minus1;
27629a84457aed4c45bc900998b5e11c03023264208James Dong            while (i > 0)
27729a84457aed4c45bc900998b5e11c03023264208James Dong            {
27829a84457aed4c45bc900998b5e11c03023264208James Dong                numBits++;
27929a84457aed4c45bc900998b5e11c03023264208James Dong                i >>= 1;
28029a84457aed4c45bc900998b5e11c03023264208James Dong            }
28129a84457aed4c45bc900998b5e11c03023264208James Dong
28229a84457aed4c45bc900998b5e11c03023264208James Dong            for (i = 0; i <= (int)picParam->pic_size_in_map_units_minus1; i++)
28329a84457aed4c45bc900998b5e11c03023264208James Dong            {
28429a84457aed4c45bc900998b5e11c03023264208James Dong                status = BitstreamWriteBits(stream, numBits, picParam->slice_group_id[i]);
28529a84457aed4c45bc900998b5e11c03023264208James Dong            }
28629a84457aed4c45bc900998b5e11c03023264208James Dong        }
28729a84457aed4c45bc900998b5e11c03023264208James Dong    }
28829a84457aed4c45bc900998b5e11c03023264208James Dong    if (status != AVCENC_SUCCESS)
28929a84457aed4c45bc900998b5e11c03023264208James Dong    {
29029a84457aed4c45bc900998b5e11c03023264208James Dong        return status;
29129a84457aed4c45bc900998b5e11c03023264208James Dong    }
29229a84457aed4c45bc900998b5e11c03023264208James Dong
29329a84457aed4c45bc900998b5e11c03023264208James Dong    status = ue_v(stream, picParam->num_ref_idx_l0_active_minus1);
29429a84457aed4c45bc900998b5e11c03023264208James Dong    status = ue_v(stream, picParam->num_ref_idx_l1_active_minus1);
29529a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWrite1Bit(stream, picParam->weighted_pred_flag);
29629a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWriteBits(stream, 2, picParam->weighted_bipred_idc);
29729a84457aed4c45bc900998b5e11c03023264208James Dong    if (status != AVCENC_SUCCESS)
29829a84457aed4c45bc900998b5e11c03023264208James Dong    {
29929a84457aed4c45bc900998b5e11c03023264208James Dong        return status;
30029a84457aed4c45bc900998b5e11c03023264208James Dong    }
30129a84457aed4c45bc900998b5e11c03023264208James Dong
30229a84457aed4c45bc900998b5e11c03023264208James Dong    status = se_v(stream, picParam->pic_init_qp_minus26);
30329a84457aed4c45bc900998b5e11c03023264208James Dong    status = se_v(stream, picParam->pic_init_qs_minus26);
30429a84457aed4c45bc900998b5e11c03023264208James Dong    status = se_v(stream, picParam->chroma_qp_index_offset);
30529a84457aed4c45bc900998b5e11c03023264208James Dong
30629a84457aed4c45bc900998b5e11c03023264208James Dong    temp = picParam->deblocking_filter_control_present_flag << 2;
30729a84457aed4c45bc900998b5e11c03023264208James Dong    temp |= (picParam->constrained_intra_pred_flag << 1);
30829a84457aed4c45bc900998b5e11c03023264208James Dong    temp |= picParam->redundant_pic_cnt_present_flag;
30929a84457aed4c45bc900998b5e11c03023264208James Dong
31029a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWriteBits(stream, 3, temp);
31129a84457aed4c45bc900998b5e11c03023264208James Dong
31229a84457aed4c45bc900998b5e11c03023264208James Dong    return status;
31329a84457aed4c45bc900998b5e11c03023264208James Dong}
31429a84457aed4c45bc900998b5e11c03023264208James Dong
31529a84457aed4c45bc900998b5e11c03023264208James Dong/** see subclause 7.4.3 */
31629a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status EncodeSliceHeader(AVCEncObject *encvid, AVCEncBitstream *stream)
31729a84457aed4c45bc900998b5e11c03023264208James Dong{
31829a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
31929a84457aed4c45bc900998b5e11c03023264208James Dong    AVCSliceHeader *sliceHdr = video->sliceHdr;
32029a84457aed4c45bc900998b5e11c03023264208James Dong    AVCPicParamSet *currPPS = video->currPicParams;
32129a84457aed4c45bc900998b5e11c03023264208James Dong    AVCSeqParamSet *currSPS = video->currSeqParams;
32229a84457aed4c45bc900998b5e11c03023264208James Dong    AVCEnc_Status status = AVCENC_SUCCESS;
32329a84457aed4c45bc900998b5e11c03023264208James Dong    int slice_type, temp, i;
32429a84457aed4c45bc900998b5e11c03023264208James Dong    int num_bits;
32529a84457aed4c45bc900998b5e11c03023264208James Dong
32629a84457aed4c45bc900998b5e11c03023264208James Dong    num_bits = (stream->write_pos << 3) - stream->bit_left;
32729a84457aed4c45bc900998b5e11c03023264208James Dong
32829a84457aed4c45bc900998b5e11c03023264208James Dong    status = ue_v(stream, sliceHdr->first_mb_in_slice);
32929a84457aed4c45bc900998b5e11c03023264208James Dong
33029a84457aed4c45bc900998b5e11c03023264208James Dong    slice_type = video->slice_type;
33129a84457aed4c45bc900998b5e11c03023264208James Dong
33229a84457aed4c45bc900998b5e11c03023264208James Dong    if (video->mbNum == 0) /* first mb in frame */
33329a84457aed4c45bc900998b5e11c03023264208James Dong    {
33429a84457aed4c45bc900998b5e11c03023264208James Dong        status = ue_v(stream, sliceHdr->slice_type);
33529a84457aed4c45bc900998b5e11c03023264208James Dong    }
33629a84457aed4c45bc900998b5e11c03023264208James Dong    else
33729a84457aed4c45bc900998b5e11c03023264208James Dong    {
33829a84457aed4c45bc900998b5e11c03023264208James Dong        status = ue_v(stream, slice_type);
33929a84457aed4c45bc900998b5e11c03023264208James Dong    }
34029a84457aed4c45bc900998b5e11c03023264208James Dong
34129a84457aed4c45bc900998b5e11c03023264208James Dong    status = ue_v(stream, sliceHdr->pic_parameter_set_id);
34229a84457aed4c45bc900998b5e11c03023264208James Dong
34329a84457aed4c45bc900998b5e11c03023264208James Dong    status = BitstreamWriteBits(stream, currSPS->log2_max_frame_num_minus4 + 4, sliceHdr->frame_num);
34429a84457aed4c45bc900998b5e11c03023264208James Dong
34529a84457aed4c45bc900998b5e11c03023264208James Dong    if (status != AVCENC_SUCCESS)
34629a84457aed4c45bc900998b5e11c03023264208James Dong    {
34729a84457aed4c45bc900998b5e11c03023264208James Dong        return status;
34829a84457aed4c45bc900998b5e11c03023264208James Dong    }
34929a84457aed4c45bc900998b5e11c03023264208James Dong    /* if frame_mbs_only_flag is 0, encode field_pic_flag, bottom_field_flag here */
35029a84457aed4c45bc900998b5e11c03023264208James Dong
35129a84457aed4c45bc900998b5e11c03023264208James Dong    if (video->nal_unit_type == AVC_NALTYPE_IDR)
35229a84457aed4c45bc900998b5e11c03023264208James Dong    {
35329a84457aed4c45bc900998b5e11c03023264208James Dong        status = ue_v(stream, sliceHdr->idr_pic_id);
35429a84457aed4c45bc900998b5e11c03023264208James Dong    }
35529a84457aed4c45bc900998b5e11c03023264208James Dong
35629a84457aed4c45bc900998b5e11c03023264208James Dong    if (currSPS->pic_order_cnt_type == 0)
35729a84457aed4c45bc900998b5e11c03023264208James Dong    {
35829a84457aed4c45bc900998b5e11c03023264208James Dong        status = BitstreamWriteBits(stream, currSPS->log2_max_pic_order_cnt_lsb_minus4 + 4,
35929a84457aed4c45bc900998b5e11c03023264208James Dong                                    sliceHdr->pic_order_cnt_lsb);
36029a84457aed4c45bc900998b5e11c03023264208James Dong
36129a84457aed4c45bc900998b5e11c03023264208James Dong        if (currPPS->pic_order_present_flag && !sliceHdr->field_pic_flag)
36229a84457aed4c45bc900998b5e11c03023264208James Dong        {
36329a84457aed4c45bc900998b5e11c03023264208James Dong            status = se_v(stream, sliceHdr->delta_pic_order_cnt_bottom); /* 32 bits */
36429a84457aed4c45bc900998b5e11c03023264208James Dong        }
36529a84457aed4c45bc900998b5e11c03023264208James Dong    }
36629a84457aed4c45bc900998b5e11c03023264208James Dong    if (currSPS->pic_order_cnt_type == 1 && !currSPS->delta_pic_order_always_zero_flag)
36729a84457aed4c45bc900998b5e11c03023264208James Dong    {
36829a84457aed4c45bc900998b5e11c03023264208James Dong        status = se_v(stream, sliceHdr->delta_pic_order_cnt[0]);    /* 32 bits */
36929a84457aed4c45bc900998b5e11c03023264208James Dong        if (currPPS->pic_order_present_flag && !sliceHdr->field_pic_flag)
37029a84457aed4c45bc900998b5e11c03023264208James Dong        {
37129a84457aed4c45bc900998b5e11c03023264208James Dong            status = se_v(stream, sliceHdr->delta_pic_order_cnt[1]); /* 32 bits */
37229a84457aed4c45bc900998b5e11c03023264208James Dong        }
37329a84457aed4c45bc900998b5e11c03023264208James Dong    }
37429a84457aed4c45bc900998b5e11c03023264208James Dong
37529a84457aed4c45bc900998b5e11c03023264208James Dong    if (currPPS->redundant_pic_cnt_present_flag)
37629a84457aed4c45bc900998b5e11c03023264208James Dong    {
37729a84457aed4c45bc900998b5e11c03023264208James Dong        status = ue_v(stream, sliceHdr->redundant_pic_cnt);
37829a84457aed4c45bc900998b5e11c03023264208James Dong    }
37929a84457aed4c45bc900998b5e11c03023264208James Dong
38029a84457aed4c45bc900998b5e11c03023264208James Dong    if (slice_type == AVC_B_SLICE)
38129a84457aed4c45bc900998b5e11c03023264208James Dong    {
38229a84457aed4c45bc900998b5e11c03023264208James Dong        status = BitstreamWrite1Bit(stream, sliceHdr->direct_spatial_mv_pred_flag);
38329a84457aed4c45bc900998b5e11c03023264208James Dong    }
38429a84457aed4c45bc900998b5e11c03023264208James Dong
38529a84457aed4c45bc900998b5e11c03023264208James Dong    if (status != AVCENC_SUCCESS)
38629a84457aed4c45bc900998b5e11c03023264208James Dong    {
38729a84457aed4c45bc900998b5e11c03023264208James Dong        return status;
38829a84457aed4c45bc900998b5e11c03023264208James Dong    }
38929a84457aed4c45bc900998b5e11c03023264208James Dong
39029a84457aed4c45bc900998b5e11c03023264208James Dong    if (slice_type == AVC_P_SLICE || slice_type == AVC_SP_SLICE || slice_type == AVC_B_SLICE)
39129a84457aed4c45bc900998b5e11c03023264208James Dong    {
39229a84457aed4c45bc900998b5e11c03023264208James Dong        status = BitstreamWrite1Bit(stream, sliceHdr->num_ref_idx_active_override_flag);
39329a84457aed4c45bc900998b5e11c03023264208James Dong        if (sliceHdr->num_ref_idx_active_override_flag)
39429a84457aed4c45bc900998b5e11c03023264208James Dong        {
39529a84457aed4c45bc900998b5e11c03023264208James Dong            /* we shouldn't enter this part at all */
39629a84457aed4c45bc900998b5e11c03023264208James Dong            status = ue_v(stream, sliceHdr->num_ref_idx_l0_active_minus1);
39729a84457aed4c45bc900998b5e11c03023264208James Dong            if (slice_type == AVC_B_SLICE)
39829a84457aed4c45bc900998b5e11c03023264208James Dong            {
39929a84457aed4c45bc900998b5e11c03023264208James Dong                status = ue_v(stream, sliceHdr->num_ref_idx_l1_active_minus1);
40029a84457aed4c45bc900998b5e11c03023264208James Dong            }
40129a84457aed4c45bc900998b5e11c03023264208James Dong        }
40229a84457aed4c45bc900998b5e11c03023264208James Dong    }
40329a84457aed4c45bc900998b5e11c03023264208James Dong    if (status != AVCENC_SUCCESS)
40429a84457aed4c45bc900998b5e11c03023264208James Dong    {
40529a84457aed4c45bc900998b5e11c03023264208James Dong        return status;
40629a84457aed4c45bc900998b5e11c03023264208James Dong    }
40729a84457aed4c45bc900998b5e11c03023264208James Dong
40829a84457aed4c45bc900998b5e11c03023264208James Dong    /* ref_pic_list_reordering() */
40929a84457aed4c45bc900998b5e11c03023264208James Dong    status = ref_pic_list_reordering(video, stream, sliceHdr, slice_type);
41029a84457aed4c45bc900998b5e11c03023264208James Dong    if (status != AVCENC_SUCCESS)
41129a84457aed4c45bc900998b5e11c03023264208James Dong    {
41229a84457aed4c45bc900998b5e11c03023264208James Dong        return status;
41329a84457aed4c45bc900998b5e11c03023264208James Dong    }
41429a84457aed4c45bc900998b5e11c03023264208James Dong
41529a84457aed4c45bc900998b5e11c03023264208James Dong    if ((currPPS->weighted_pred_flag && (slice_type == AVC_P_SLICE || slice_type == AVC_SP_SLICE)) ||
41629a84457aed4c45bc900998b5e11c03023264208James Dong            (currPPS->weighted_bipred_idc == 1 && slice_type == AVC_B_SLICE))
41729a84457aed4c45bc900998b5e11c03023264208James Dong    {
41829a84457aed4c45bc900998b5e11c03023264208James Dong        //      pred_weight_table(); // not supported !!
41929a84457aed4c45bc900998b5e11c03023264208James Dong        return AVCENC_PRED_WEIGHT_TAB_FAIL;
42029a84457aed4c45bc900998b5e11c03023264208James Dong    }
42129a84457aed4c45bc900998b5e11c03023264208James Dong
42229a84457aed4c45bc900998b5e11c03023264208James Dong    if (video->nal_ref_idc != 0)
42329a84457aed4c45bc900998b5e11c03023264208James Dong    {
42429a84457aed4c45bc900998b5e11c03023264208James Dong        status = dec_ref_pic_marking(video, stream, sliceHdr);
42529a84457aed4c45bc900998b5e11c03023264208James Dong        if (status != AVCENC_SUCCESS)
42629a84457aed4c45bc900998b5e11c03023264208James Dong        {
42729a84457aed4c45bc900998b5e11c03023264208James Dong            return status;
42829a84457aed4c45bc900998b5e11c03023264208James Dong        }
42929a84457aed4c45bc900998b5e11c03023264208James Dong    }
43029a84457aed4c45bc900998b5e11c03023264208James Dong
43129a84457aed4c45bc900998b5e11c03023264208James Dong    if (currPPS->entropy_coding_mode_flag && slice_type != AVC_I_SLICE && slice_type != AVC_SI_SLICE)
43229a84457aed4c45bc900998b5e11c03023264208James Dong    {
43329a84457aed4c45bc900998b5e11c03023264208James Dong        return AVCENC_CABAC_FAIL;
43429a84457aed4c45bc900998b5e11c03023264208James Dong        /*      ue_v(stream,&(sliceHdr->cabac_init_idc));
43529a84457aed4c45bc900998b5e11c03023264208James Dong                if(sliceHdr->cabac_init_idc > 2){
43629a84457aed4c45bc900998b5e11c03023264208James Dong                    // not supported !!!!
43729a84457aed4c45bc900998b5e11c03023264208James Dong                }*/
43829a84457aed4c45bc900998b5e11c03023264208James Dong    }
43929a84457aed4c45bc900998b5e11c03023264208James Dong
44029a84457aed4c45bc900998b5e11c03023264208James Dong    status = se_v(stream, sliceHdr->slice_qp_delta);
44129a84457aed4c45bc900998b5e11c03023264208James Dong    if (status != AVCENC_SUCCESS)
44229a84457aed4c45bc900998b5e11c03023264208James Dong    {
44329a84457aed4c45bc900998b5e11c03023264208James Dong        return status;
44429a84457aed4c45bc900998b5e11c03023264208James Dong    }
44529a84457aed4c45bc900998b5e11c03023264208James Dong
44629a84457aed4c45bc900998b5e11c03023264208James Dong    if (slice_type == AVC_SP_SLICE || slice_type == AVC_SI_SLICE)
44729a84457aed4c45bc900998b5e11c03023264208James Dong    {
44829a84457aed4c45bc900998b5e11c03023264208James Dong        if (slice_type == AVC_SP_SLICE)
44929a84457aed4c45bc900998b5e11c03023264208James Dong        {
45029a84457aed4c45bc900998b5e11c03023264208James Dong            status = BitstreamWrite1Bit(stream, sliceHdr->sp_for_switch_flag);
45129a84457aed4c45bc900998b5e11c03023264208James Dong            /* if sp_for_switch_flag is 0, P macroblocks in SP slice is decoded using
45229a84457aed4c45bc900998b5e11c03023264208James Dong            SP decoding process for non-switching pictures in 8.6.1 */
45329a84457aed4c45bc900998b5e11c03023264208James Dong            /* else, P macroblocks in SP slice is decoded using SP and SI decoding
45429a84457aed4c45bc900998b5e11c03023264208James Dong            process for switching picture in 8.6.2 */
45529a84457aed4c45bc900998b5e11c03023264208James Dong        }
45629a84457aed4c45bc900998b5e11c03023264208James Dong        status = se_v(stream, sliceHdr->slice_qs_delta);
45729a84457aed4c45bc900998b5e11c03023264208James Dong        if (status != AVCENC_SUCCESS)
45829a84457aed4c45bc900998b5e11c03023264208James Dong        {
45929a84457aed4c45bc900998b5e11c03023264208James Dong            return status;
46029a84457aed4c45bc900998b5e11c03023264208James Dong        }
46129a84457aed4c45bc900998b5e11c03023264208James Dong    }
46229a84457aed4c45bc900998b5e11c03023264208James Dong
46329a84457aed4c45bc900998b5e11c03023264208James Dong    if (currPPS->deblocking_filter_control_present_flag)
46429a84457aed4c45bc900998b5e11c03023264208James Dong    {
46529a84457aed4c45bc900998b5e11c03023264208James Dong
46629a84457aed4c45bc900998b5e11c03023264208James Dong        status = ue_v(stream, sliceHdr->disable_deblocking_filter_idc);
46729a84457aed4c45bc900998b5e11c03023264208James Dong
46829a84457aed4c45bc900998b5e11c03023264208James Dong        if (sliceHdr->disable_deblocking_filter_idc != 1)
46929a84457aed4c45bc900998b5e11c03023264208James Dong        {
47029a84457aed4c45bc900998b5e11c03023264208James Dong            status = se_v(stream, sliceHdr->slice_alpha_c0_offset_div2);
47129a84457aed4c45bc900998b5e11c03023264208James Dong
47229a84457aed4c45bc900998b5e11c03023264208James Dong            status = se_v(stream, sliceHdr->slice_beta_offset_div_2);
47329a84457aed4c45bc900998b5e11c03023264208James Dong        }
47429a84457aed4c45bc900998b5e11c03023264208James Dong        if (status != AVCENC_SUCCESS)
47529a84457aed4c45bc900998b5e11c03023264208James Dong        {
47629a84457aed4c45bc900998b5e11c03023264208James Dong            return status;
47729a84457aed4c45bc900998b5e11c03023264208James Dong        }
47829a84457aed4c45bc900998b5e11c03023264208James Dong    }
47929a84457aed4c45bc900998b5e11c03023264208James Dong
48029a84457aed4c45bc900998b5e11c03023264208James Dong    if (currPPS->num_slice_groups_minus1 > 0 && currPPS->slice_group_map_type >= 3
48129a84457aed4c45bc900998b5e11c03023264208James Dong            && currPPS->slice_group_map_type <= 5)
48229a84457aed4c45bc900998b5e11c03023264208James Dong    {
48329a84457aed4c45bc900998b5e11c03023264208James Dong        /* Ceil(Log2(PicSizeInMapUnits/(float)SliceGroupChangeRate + 1)) */
48429a84457aed4c45bc900998b5e11c03023264208James Dong        temp = video->PicSizeInMapUnits / video->SliceGroupChangeRate;
48529a84457aed4c45bc900998b5e11c03023264208James Dong        if (video->PicSizeInMapUnits % video->SliceGroupChangeRate)
48629a84457aed4c45bc900998b5e11c03023264208James Dong        {
48729a84457aed4c45bc900998b5e11c03023264208James Dong            temp++;
48829a84457aed4c45bc900998b5e11c03023264208James Dong        }
48929a84457aed4c45bc900998b5e11c03023264208James Dong        i = 0;
49029a84457aed4c45bc900998b5e11c03023264208James Dong        while (temp > 1)
49129a84457aed4c45bc900998b5e11c03023264208James Dong        {
49229a84457aed4c45bc900998b5e11c03023264208James Dong            temp >>= 1;
49329a84457aed4c45bc900998b5e11c03023264208James Dong            i++;
49429a84457aed4c45bc900998b5e11c03023264208James Dong        }
49529a84457aed4c45bc900998b5e11c03023264208James Dong
49629a84457aed4c45bc900998b5e11c03023264208James Dong        BitstreamWriteBits(stream, i, sliceHdr->slice_group_change_cycle);
49729a84457aed4c45bc900998b5e11c03023264208James Dong    }
49829a84457aed4c45bc900998b5e11c03023264208James Dong
49929a84457aed4c45bc900998b5e11c03023264208James Dong
50029a84457aed4c45bc900998b5e11c03023264208James Dong    encvid->rateCtrl->NumberofHeaderBits += (stream->write_pos << 3) - stream->bit_left - num_bits;
50129a84457aed4c45bc900998b5e11c03023264208James Dong
50229a84457aed4c45bc900998b5e11c03023264208James Dong    return AVCENC_SUCCESS;
50329a84457aed4c45bc900998b5e11c03023264208James Dong}
50429a84457aed4c45bc900998b5e11c03023264208James Dong
50529a84457aed4c45bc900998b5e11c03023264208James Dong/** see subclause 7.4.3.1 */
50629a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status ref_pic_list_reordering(AVCCommonObj *video, AVCEncBitstream *stream, AVCSliceHeader *sliceHdr, int slice_type)
50729a84457aed4c45bc900998b5e11c03023264208James Dong{
50829a84457aed4c45bc900998b5e11c03023264208James Dong    (void)(video);
50929a84457aed4c45bc900998b5e11c03023264208James Dong    int i;
51029a84457aed4c45bc900998b5e11c03023264208James Dong    AVCEnc_Status status = AVCENC_SUCCESS;
51129a84457aed4c45bc900998b5e11c03023264208James Dong
51229a84457aed4c45bc900998b5e11c03023264208James Dong    if (slice_type != AVC_I_SLICE && slice_type != AVC_SI_SLICE)
51329a84457aed4c45bc900998b5e11c03023264208James Dong    {
51429a84457aed4c45bc900998b5e11c03023264208James Dong        status = BitstreamWrite1Bit(stream, sliceHdr->ref_pic_list_reordering_flag_l0);
51529a84457aed4c45bc900998b5e11c03023264208James Dong        if (sliceHdr->ref_pic_list_reordering_flag_l0)
51629a84457aed4c45bc900998b5e11c03023264208James Dong        {
51729a84457aed4c45bc900998b5e11c03023264208James Dong            i = 0;
51829a84457aed4c45bc900998b5e11c03023264208James Dong            do
51929a84457aed4c45bc900998b5e11c03023264208James Dong            {
52029a84457aed4c45bc900998b5e11c03023264208James Dong                status = ue_v(stream, sliceHdr->reordering_of_pic_nums_idc_l0[i]);
52129a84457aed4c45bc900998b5e11c03023264208James Dong                if (sliceHdr->reordering_of_pic_nums_idc_l0[i] == 0 ||
52229a84457aed4c45bc900998b5e11c03023264208James Dong                        sliceHdr->reordering_of_pic_nums_idc_l0[i] == 1)
52329a84457aed4c45bc900998b5e11c03023264208James Dong                {
52429a84457aed4c45bc900998b5e11c03023264208James Dong                    status = ue_v(stream, sliceHdr->abs_diff_pic_num_minus1_l0[i]);
52529a84457aed4c45bc900998b5e11c03023264208James Dong                    /* this check should be in InitSlice(), if we ever use it */
52629a84457aed4c45bc900998b5e11c03023264208James Dong                    /*if(sliceHdr->reordering_of_pic_nums_idc_l0[i] == 0 &&
52729a84457aed4c45bc900998b5e11c03023264208James Dong                        sliceHdr->abs_diff_pic_num_minus1_l0[i] > video->MaxPicNum/2 -1)
52829a84457aed4c45bc900998b5e11c03023264208James Dong                    {
52929a84457aed4c45bc900998b5e11c03023264208James Dong                        return AVCENC_REF_PIC_REORDER_FAIL; // out of range
53029a84457aed4c45bc900998b5e11c03023264208James Dong                    }
53129a84457aed4c45bc900998b5e11c03023264208James Dong                    if(sliceHdr->reordering_of_pic_nums_idc_l0[i] == 1 &&
53229a84457aed4c45bc900998b5e11c03023264208James Dong                        sliceHdr->abs_diff_pic_num_minus1_l0[i] > video->MaxPicNum/2 -2)
53329a84457aed4c45bc900998b5e11c03023264208James Dong                    {
53429a84457aed4c45bc900998b5e11c03023264208James Dong                        return AVCENC_REF_PIC_REORDER_FAIL; // out of range
53529a84457aed4c45bc900998b5e11c03023264208James Dong                    }*/
53629a84457aed4c45bc900998b5e11c03023264208James Dong                }
53729a84457aed4c45bc900998b5e11c03023264208James Dong                else if (sliceHdr->reordering_of_pic_nums_idc_l0[i] == 2)
53829a84457aed4c45bc900998b5e11c03023264208James Dong                {
53929a84457aed4c45bc900998b5e11c03023264208James Dong                    status = ue_v(stream, sliceHdr->long_term_pic_num_l0[i]);
54029a84457aed4c45bc900998b5e11c03023264208James Dong                }
54129a84457aed4c45bc900998b5e11c03023264208James Dong                i++;
54229a84457aed4c45bc900998b5e11c03023264208James Dong            }
54329a84457aed4c45bc900998b5e11c03023264208James Dong            while (sliceHdr->reordering_of_pic_nums_idc_l0[i] != 3
54429a84457aed4c45bc900998b5e11c03023264208James Dong                    && i <= (int)sliceHdr->num_ref_idx_l0_active_minus1 + 1) ;
54529a84457aed4c45bc900998b5e11c03023264208James Dong        }
54629a84457aed4c45bc900998b5e11c03023264208James Dong    }
54729a84457aed4c45bc900998b5e11c03023264208James Dong    if (slice_type == AVC_B_SLICE)
54829a84457aed4c45bc900998b5e11c03023264208James Dong    {
54929a84457aed4c45bc900998b5e11c03023264208James Dong        status = BitstreamWrite1Bit(stream, sliceHdr->ref_pic_list_reordering_flag_l1);
55029a84457aed4c45bc900998b5e11c03023264208James Dong        if (sliceHdr->ref_pic_list_reordering_flag_l1)
55129a84457aed4c45bc900998b5e11c03023264208James Dong        {
55229a84457aed4c45bc900998b5e11c03023264208James Dong            i = 0;
55329a84457aed4c45bc900998b5e11c03023264208James Dong            do
55429a84457aed4c45bc900998b5e11c03023264208James Dong            {
55529a84457aed4c45bc900998b5e11c03023264208James Dong                status = ue_v(stream, sliceHdr->reordering_of_pic_nums_idc_l1[i]);
55629a84457aed4c45bc900998b5e11c03023264208James Dong                if (sliceHdr->reordering_of_pic_nums_idc_l1[i] == 0 ||
55729a84457aed4c45bc900998b5e11c03023264208James Dong                        sliceHdr->reordering_of_pic_nums_idc_l1[i] == 1)
55829a84457aed4c45bc900998b5e11c03023264208James Dong                {
55929a84457aed4c45bc900998b5e11c03023264208James Dong                    status = ue_v(stream, sliceHdr->abs_diff_pic_num_minus1_l1[i]);
56029a84457aed4c45bc900998b5e11c03023264208James Dong                    /* This check should be in InitSlice() if we ever use it
56129a84457aed4c45bc900998b5e11c03023264208James Dong                    if(sliceHdr->reordering_of_pic_nums_idc_l1[i] == 0 &&
56229a84457aed4c45bc900998b5e11c03023264208James Dong                        sliceHdr->abs_diff_pic_num_minus1_l1[i] > video->MaxPicNum/2 -1)
56329a84457aed4c45bc900998b5e11c03023264208James Dong                    {
56429a84457aed4c45bc900998b5e11c03023264208James Dong                        return AVCENC_REF_PIC_REORDER_FAIL; // out of range
56529a84457aed4c45bc900998b5e11c03023264208James Dong                    }
56629a84457aed4c45bc900998b5e11c03023264208James Dong                    if(sliceHdr->reordering_of_pic_nums_idc_l1[i] == 1 &&
56729a84457aed4c45bc900998b5e11c03023264208James Dong                        sliceHdr->abs_diff_pic_num_minus1_l1[i] > video->MaxPicNum/2 -2)
56829a84457aed4c45bc900998b5e11c03023264208James Dong                    {
56929a84457aed4c45bc900998b5e11c03023264208James Dong                        return AVCENC_REF_PIC_REORDER_FAIL; // out of range
57029a84457aed4c45bc900998b5e11c03023264208James Dong                    }*/
57129a84457aed4c45bc900998b5e11c03023264208James Dong                }
57229a84457aed4c45bc900998b5e11c03023264208James Dong                else if (sliceHdr->reordering_of_pic_nums_idc_l1[i] == 2)
57329a84457aed4c45bc900998b5e11c03023264208James Dong                {
57429a84457aed4c45bc900998b5e11c03023264208James Dong                    status = ue_v(stream, sliceHdr->long_term_pic_num_l1[i]);
57529a84457aed4c45bc900998b5e11c03023264208James Dong                }
57629a84457aed4c45bc900998b5e11c03023264208James Dong                i++;
57729a84457aed4c45bc900998b5e11c03023264208James Dong            }
57829a84457aed4c45bc900998b5e11c03023264208James Dong            while (sliceHdr->reordering_of_pic_nums_idc_l1[i] != 3
57929a84457aed4c45bc900998b5e11c03023264208James Dong                    && i <= (int)sliceHdr->num_ref_idx_l1_active_minus1 + 1) ;
58029a84457aed4c45bc900998b5e11c03023264208James Dong        }
58129a84457aed4c45bc900998b5e11c03023264208James Dong    }
58229a84457aed4c45bc900998b5e11c03023264208James Dong
58329a84457aed4c45bc900998b5e11c03023264208James Dong    return status;
58429a84457aed4c45bc900998b5e11c03023264208James Dong}
58529a84457aed4c45bc900998b5e11c03023264208James Dong
58629a84457aed4c45bc900998b5e11c03023264208James Dong/** see subclause 7.4.3.3 */
58729a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status dec_ref_pic_marking(AVCCommonObj *video, AVCEncBitstream *stream, AVCSliceHeader *sliceHdr)
58829a84457aed4c45bc900998b5e11c03023264208James Dong{
58929a84457aed4c45bc900998b5e11c03023264208James Dong    int i;
59029a84457aed4c45bc900998b5e11c03023264208James Dong    AVCEnc_Status status = AVCENC_SUCCESS;
59129a84457aed4c45bc900998b5e11c03023264208James Dong
59229a84457aed4c45bc900998b5e11c03023264208James Dong    if (video->nal_unit_type == AVC_NALTYPE_IDR)
59329a84457aed4c45bc900998b5e11c03023264208James Dong    {
59429a84457aed4c45bc900998b5e11c03023264208James Dong        status = BitstreamWrite1Bit(stream, sliceHdr->no_output_of_prior_pics_flag);
59529a84457aed4c45bc900998b5e11c03023264208James Dong        status = BitstreamWrite1Bit(stream, sliceHdr->long_term_reference_flag);
59629a84457aed4c45bc900998b5e11c03023264208James Dong        if (sliceHdr->long_term_reference_flag == 0) /* used for short-term */
59729a84457aed4c45bc900998b5e11c03023264208James Dong        {
59829a84457aed4c45bc900998b5e11c03023264208James Dong            video->MaxLongTermFrameIdx = -1; /* no long-term frame indx */
59929a84457aed4c45bc900998b5e11c03023264208James Dong        }
60029a84457aed4c45bc900998b5e11c03023264208James Dong        else /* used for long-term */
60129a84457aed4c45bc900998b5e11c03023264208James Dong        {
60229a84457aed4c45bc900998b5e11c03023264208James Dong            video->MaxLongTermFrameIdx = 0;
60329a84457aed4c45bc900998b5e11c03023264208James Dong            video->LongTermFrameIdx = 0;
60429a84457aed4c45bc900998b5e11c03023264208James Dong        }
60529a84457aed4c45bc900998b5e11c03023264208James Dong    }
60629a84457aed4c45bc900998b5e11c03023264208James Dong    else
60729a84457aed4c45bc900998b5e11c03023264208James Dong    {
60829a84457aed4c45bc900998b5e11c03023264208James Dong        status = BitstreamWrite1Bit(stream, sliceHdr->adaptive_ref_pic_marking_mode_flag); /* default to zero */
60929a84457aed4c45bc900998b5e11c03023264208James Dong        if (sliceHdr->adaptive_ref_pic_marking_mode_flag)
61029a84457aed4c45bc900998b5e11c03023264208James Dong        {
61129a84457aed4c45bc900998b5e11c03023264208James Dong            i = 0;
61229a84457aed4c45bc900998b5e11c03023264208James Dong            do
61329a84457aed4c45bc900998b5e11c03023264208James Dong            {
61429a84457aed4c45bc900998b5e11c03023264208James Dong                status = ue_v(stream, sliceHdr->memory_management_control_operation[i]);
61529a84457aed4c45bc900998b5e11c03023264208James Dong                if (sliceHdr->memory_management_control_operation[i] == 1 ||
61629a84457aed4c45bc900998b5e11c03023264208James Dong                        sliceHdr->memory_management_control_operation[i] == 3)
61729a84457aed4c45bc900998b5e11c03023264208James Dong                {
61829a84457aed4c45bc900998b5e11c03023264208James Dong                    status = ue_v(stream, sliceHdr->difference_of_pic_nums_minus1[i]);
61929a84457aed4c45bc900998b5e11c03023264208James Dong                }
62029a84457aed4c45bc900998b5e11c03023264208James Dong                if (sliceHdr->memory_management_control_operation[i] == 2)
62129a84457aed4c45bc900998b5e11c03023264208James Dong                {
62229a84457aed4c45bc900998b5e11c03023264208James Dong                    status = ue_v(stream, sliceHdr->long_term_pic_num[i]);
62329a84457aed4c45bc900998b5e11c03023264208James Dong                }
62429a84457aed4c45bc900998b5e11c03023264208James Dong                if (sliceHdr->memory_management_control_operation[i] == 3 ||
62529a84457aed4c45bc900998b5e11c03023264208James Dong                        sliceHdr->memory_management_control_operation[i] == 6)
62629a84457aed4c45bc900998b5e11c03023264208James Dong                {
62729a84457aed4c45bc900998b5e11c03023264208James Dong                    status = ue_v(stream, sliceHdr->long_term_frame_idx[i]);
62829a84457aed4c45bc900998b5e11c03023264208James Dong                }
62929a84457aed4c45bc900998b5e11c03023264208James Dong                if (sliceHdr->memory_management_control_operation[i] == 4)
63029a84457aed4c45bc900998b5e11c03023264208James Dong                {
63129a84457aed4c45bc900998b5e11c03023264208James Dong                    status = ue_v(stream, sliceHdr->max_long_term_frame_idx_plus1[i]);
63229a84457aed4c45bc900998b5e11c03023264208James Dong                }
63329a84457aed4c45bc900998b5e11c03023264208James Dong                i++;
63429a84457aed4c45bc900998b5e11c03023264208James Dong            }
63529a84457aed4c45bc900998b5e11c03023264208James Dong            while (sliceHdr->memory_management_control_operation[i] != 0 && i < MAX_DEC_REF_PIC_MARKING);
63629a84457aed4c45bc900998b5e11c03023264208James Dong            if (i >= MAX_DEC_REF_PIC_MARKING && sliceHdr->memory_management_control_operation[i] != 0)
63729a84457aed4c45bc900998b5e11c03023264208James Dong            {
63829a84457aed4c45bc900998b5e11c03023264208James Dong                return AVCENC_DEC_REF_PIC_MARK_FAIL; /* we're screwed!!, not enough memory */
63929a84457aed4c45bc900998b5e11c03023264208James Dong            }
64029a84457aed4c45bc900998b5e11c03023264208James Dong        }
64129a84457aed4c45bc900998b5e11c03023264208James Dong    }
64229a84457aed4c45bc900998b5e11c03023264208James Dong
64329a84457aed4c45bc900998b5e11c03023264208James Dong    return status;
64429a84457aed4c45bc900998b5e11c03023264208James Dong}
64529a84457aed4c45bc900998b5e11c03023264208James Dong
64629a84457aed4c45bc900998b5e11c03023264208James Dong/* see subclause 8.2.1 Decoding process for picture order count.
64729a84457aed4c45bc900998b5e11c03023264208James DongSee also PostPOC() for initialization of some variables. */
64829a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status InitPOC(AVCEncObject *encvid)
64929a84457aed4c45bc900998b5e11c03023264208James Dong{
65029a84457aed4c45bc900998b5e11c03023264208James Dong    AVCCommonObj *video = encvid->common;
65129a84457aed4c45bc900998b5e11c03023264208James Dong    AVCSeqParamSet *currSPS = video->currSeqParams;
65229a84457aed4c45bc900998b5e11c03023264208James Dong    AVCSliceHeader *sliceHdr = video->sliceHdr;
65329a84457aed4c45bc900998b5e11c03023264208James Dong    AVCFrameIO  *currInput = encvid->currInput;
65429a84457aed4c45bc900998b5e11c03023264208James Dong    int i;
65529a84457aed4c45bc900998b5e11c03023264208James Dong
65629a84457aed4c45bc900998b5e11c03023264208James Dong    switch (currSPS->pic_order_cnt_type)
65729a84457aed4c45bc900998b5e11c03023264208James Dong    {
65829a84457aed4c45bc900998b5e11c03023264208James Dong        case 0: /* POC MODE 0 , subclause 8.2.1.1 */
65929a84457aed4c45bc900998b5e11c03023264208James Dong            /* encoding part */
66029a84457aed4c45bc900998b5e11c03023264208James Dong            if (video->nal_unit_type == AVC_NALTYPE_IDR)
66129a84457aed4c45bc900998b5e11c03023264208James Dong            {
66229a84457aed4c45bc900998b5e11c03023264208James Dong                encvid->dispOrdPOCRef = currInput->disp_order;
66329a84457aed4c45bc900998b5e11c03023264208James Dong            }
66429a84457aed4c45bc900998b5e11c03023264208James Dong            while (currInput->disp_order < encvid->dispOrdPOCRef)
66529a84457aed4c45bc900998b5e11c03023264208James Dong            {
66629a84457aed4c45bc900998b5e11c03023264208James Dong                encvid->dispOrdPOCRef -= video->MaxPicOrderCntLsb;
66729a84457aed4c45bc900998b5e11c03023264208James Dong            }
66829a84457aed4c45bc900998b5e11c03023264208James Dong            sliceHdr->pic_order_cnt_lsb = currInput->disp_order - encvid->dispOrdPOCRef;
66929a84457aed4c45bc900998b5e11c03023264208James Dong            while (sliceHdr->pic_order_cnt_lsb >= video->MaxPicOrderCntLsb)
67029a84457aed4c45bc900998b5e11c03023264208James Dong            {
67129a84457aed4c45bc900998b5e11c03023264208James Dong                sliceHdr->pic_order_cnt_lsb -= video->MaxPicOrderCntLsb;
67229a84457aed4c45bc900998b5e11c03023264208James Dong            }
67329a84457aed4c45bc900998b5e11c03023264208James Dong            /* decoding part */
67429a84457aed4c45bc900998b5e11c03023264208James Dong            /* Calculate the MSBs of current picture */
67529a84457aed4c45bc900998b5e11c03023264208James Dong            if (video->nal_unit_type == AVC_NALTYPE_IDR)
67629a84457aed4c45bc900998b5e11c03023264208James Dong            {
67729a84457aed4c45bc900998b5e11c03023264208James Dong                video->prevPicOrderCntMsb = 0;
67829a84457aed4c45bc900998b5e11c03023264208James Dong                video->prevPicOrderCntLsb = 0;
67929a84457aed4c45bc900998b5e11c03023264208James Dong            }
68029a84457aed4c45bc900998b5e11c03023264208James Dong            if (sliceHdr->pic_order_cnt_lsb  <  video->prevPicOrderCntLsb  &&
68129a84457aed4c45bc900998b5e11c03023264208James Dong                    (video->prevPicOrderCntLsb - sliceHdr->pic_order_cnt_lsb)  >= (video->MaxPicOrderCntLsb / 2))
68229a84457aed4c45bc900998b5e11c03023264208James Dong                video->PicOrderCntMsb = video->prevPicOrderCntMsb + video->MaxPicOrderCntLsb;
68329a84457aed4c45bc900998b5e11c03023264208James Dong            else if (sliceHdr->pic_order_cnt_lsb  >  video->prevPicOrderCntLsb  &&
68429a84457aed4c45bc900998b5e11c03023264208James Dong                     (sliceHdr->pic_order_cnt_lsb - video->prevPicOrderCntLsb)  > (video->MaxPicOrderCntLsb / 2))
68529a84457aed4c45bc900998b5e11c03023264208James Dong                video->PicOrderCntMsb = video->prevPicOrderCntMsb - video->MaxPicOrderCntLsb;
68629a84457aed4c45bc900998b5e11c03023264208James Dong            else
68729a84457aed4c45bc900998b5e11c03023264208James Dong                video->PicOrderCntMsb = video->prevPicOrderCntMsb;
68829a84457aed4c45bc900998b5e11c03023264208James Dong
68929a84457aed4c45bc900998b5e11c03023264208James Dong            /* JVT-I010 page 81 is different from JM7.3 */
69029a84457aed4c45bc900998b5e11c03023264208James Dong            if (!sliceHdr->field_pic_flag || !sliceHdr->bottom_field_flag)
69129a84457aed4c45bc900998b5e11c03023264208James Dong            {
69229a84457aed4c45bc900998b5e11c03023264208James Dong                video->PicOrderCnt = video->TopFieldOrderCnt = video->PicOrderCntMsb + sliceHdr->pic_order_cnt_lsb;
69329a84457aed4c45bc900998b5e11c03023264208James Dong            }
69429a84457aed4c45bc900998b5e11c03023264208James Dong
69529a84457aed4c45bc900998b5e11c03023264208James Dong            if (!sliceHdr->field_pic_flag)
69629a84457aed4c45bc900998b5e11c03023264208James Dong            {
69729a84457aed4c45bc900998b5e11c03023264208James Dong                video->BottomFieldOrderCnt = video->TopFieldOrderCnt + sliceHdr->delta_pic_order_cnt_bottom;
69829a84457aed4c45bc900998b5e11c03023264208James Dong            }
69929a84457aed4c45bc900998b5e11c03023264208James Dong            else if (sliceHdr->bottom_field_flag)
70029a84457aed4c45bc900998b5e11c03023264208James Dong            {
70129a84457aed4c45bc900998b5e11c03023264208James Dong                video->PicOrderCnt = video->BottomFieldOrderCnt = video->PicOrderCntMsb + sliceHdr->pic_order_cnt_lsb;
70229a84457aed4c45bc900998b5e11c03023264208James Dong            }
70329a84457aed4c45bc900998b5e11c03023264208James Dong
70429a84457aed4c45bc900998b5e11c03023264208James Dong            if (!sliceHdr->field_pic_flag)
70529a84457aed4c45bc900998b5e11c03023264208James Dong            {
70629a84457aed4c45bc900998b5e11c03023264208James Dong                video->PicOrderCnt = AVC_MIN(video->TopFieldOrderCnt, video->BottomFieldOrderCnt);
70729a84457aed4c45bc900998b5e11c03023264208James Dong            }
70829a84457aed4c45bc900998b5e11c03023264208James Dong
70929a84457aed4c45bc900998b5e11c03023264208James Dong            if (video->currPicParams->pic_order_present_flag && !sliceHdr->field_pic_flag)
71029a84457aed4c45bc900998b5e11c03023264208James Dong            {
71129a84457aed4c45bc900998b5e11c03023264208James Dong                sliceHdr->delta_pic_order_cnt_bottom = 0; /* defaulted to zero */
71229a84457aed4c45bc900998b5e11c03023264208James Dong            }
71329a84457aed4c45bc900998b5e11c03023264208James Dong
71429a84457aed4c45bc900998b5e11c03023264208James Dong            break;
71529a84457aed4c45bc900998b5e11c03023264208James Dong        case 1: /* POC MODE 1, subclause 8.2.1.2 */
71629a84457aed4c45bc900998b5e11c03023264208James Dong            /* calculate FrameNumOffset */
71729a84457aed4c45bc900998b5e11c03023264208James Dong            if (video->nal_unit_type == AVC_NALTYPE_IDR)
71829a84457aed4c45bc900998b5e11c03023264208James Dong            {
71929a84457aed4c45bc900998b5e11c03023264208James Dong                encvid->dispOrdPOCRef = currInput->disp_order;  /* reset the reference point */
72029a84457aed4c45bc900998b5e11c03023264208James Dong                video->prevFrameNumOffset = 0;
72129a84457aed4c45bc900998b5e11c03023264208James Dong                video->FrameNumOffset = 0;
72229a84457aed4c45bc900998b5e11c03023264208James Dong            }
72329a84457aed4c45bc900998b5e11c03023264208James Dong            else if (video->prevFrameNum > sliceHdr->frame_num)
72429a84457aed4c45bc900998b5e11c03023264208James Dong            {
72529a84457aed4c45bc900998b5e11c03023264208James Dong                video->FrameNumOffset = video->prevFrameNumOffset + video->MaxFrameNum;
72629a84457aed4c45bc900998b5e11c03023264208James Dong            }
72729a84457aed4c45bc900998b5e11c03023264208James Dong            else
72829a84457aed4c45bc900998b5e11c03023264208James Dong            {
72929a84457aed4c45bc900998b5e11c03023264208James Dong                video->FrameNumOffset = video->prevFrameNumOffset;
73029a84457aed4c45bc900998b5e11c03023264208James Dong            }
73129a84457aed4c45bc900998b5e11c03023264208James Dong            /* calculate absFrameNum */
73229a84457aed4c45bc900998b5e11c03023264208James Dong            if (currSPS->num_ref_frames_in_pic_order_cnt_cycle)
73329a84457aed4c45bc900998b5e11c03023264208James Dong            {
73429a84457aed4c45bc900998b5e11c03023264208James Dong                video->absFrameNum = video->FrameNumOffset + sliceHdr->frame_num;
73529a84457aed4c45bc900998b5e11c03023264208James Dong            }
73629a84457aed4c45bc900998b5e11c03023264208James Dong            else
73729a84457aed4c45bc900998b5e11c03023264208James Dong            {
73829a84457aed4c45bc900998b5e11c03023264208James Dong                video->absFrameNum = 0;
73929a84457aed4c45bc900998b5e11c03023264208James Dong            }
74029a84457aed4c45bc900998b5e11c03023264208James Dong
74129a84457aed4c45bc900998b5e11c03023264208James Dong            if (video->absFrameNum > 0 && video->nal_ref_idc == 0)
74229a84457aed4c45bc900998b5e11c03023264208James Dong            {
74329a84457aed4c45bc900998b5e11c03023264208James Dong                video->absFrameNum--;
74429a84457aed4c45bc900998b5e11c03023264208James Dong            }
74529a84457aed4c45bc900998b5e11c03023264208James Dong
74629a84457aed4c45bc900998b5e11c03023264208James Dong            /* derive picOrderCntCycleCnt and frameNumInPicOrderCntCycle */
74729a84457aed4c45bc900998b5e11c03023264208James Dong            if (video->absFrameNum > 0)
74829a84457aed4c45bc900998b5e11c03023264208James Dong            {
74929a84457aed4c45bc900998b5e11c03023264208James Dong                video->picOrderCntCycleCnt = (video->absFrameNum - 1) / currSPS->num_ref_frames_in_pic_order_cnt_cycle;
75029a84457aed4c45bc900998b5e11c03023264208James Dong                video->frameNumInPicOrderCntCycle = (video->absFrameNum - 1) % currSPS->num_ref_frames_in_pic_order_cnt_cycle;
75129a84457aed4c45bc900998b5e11c03023264208James Dong            }
75229a84457aed4c45bc900998b5e11c03023264208James Dong            /* derive expectedDeltaPerPicOrderCntCycle, this value can be computed up front. */
75329a84457aed4c45bc900998b5e11c03023264208James Dong            video->expectedDeltaPerPicOrderCntCycle = 0;
75429a84457aed4c45bc900998b5e11c03023264208James Dong            for (i = 0; i < (int)currSPS->num_ref_frames_in_pic_order_cnt_cycle; i++)
75529a84457aed4c45bc900998b5e11c03023264208James Dong            {
75629a84457aed4c45bc900998b5e11c03023264208James Dong                video->expectedDeltaPerPicOrderCntCycle += currSPS->offset_for_ref_frame[i];
75729a84457aed4c45bc900998b5e11c03023264208James Dong            }
75829a84457aed4c45bc900998b5e11c03023264208James Dong            /* derive expectedPicOrderCnt */
75929a84457aed4c45bc900998b5e11c03023264208James Dong            if (video->absFrameNum)
76029a84457aed4c45bc900998b5e11c03023264208James Dong            {
76129a84457aed4c45bc900998b5e11c03023264208James Dong                video->expectedPicOrderCnt = video->picOrderCntCycleCnt * video->expectedDeltaPerPicOrderCntCycle;
76229a84457aed4c45bc900998b5e11c03023264208James Dong                for (i = 0; i <= video->frameNumInPicOrderCntCycle; i++)
76329a84457aed4c45bc900998b5e11c03023264208James Dong                {
76429a84457aed4c45bc900998b5e11c03023264208James Dong                    video->expectedPicOrderCnt += currSPS->offset_for_ref_frame[i];
76529a84457aed4c45bc900998b5e11c03023264208James Dong                }
76629a84457aed4c45bc900998b5e11c03023264208James Dong            }
76729a84457aed4c45bc900998b5e11c03023264208James Dong            else
76829a84457aed4c45bc900998b5e11c03023264208James Dong            {
76929a84457aed4c45bc900998b5e11c03023264208James Dong                video->expectedPicOrderCnt = 0;
77029a84457aed4c45bc900998b5e11c03023264208James Dong            }
77129a84457aed4c45bc900998b5e11c03023264208James Dong
77229a84457aed4c45bc900998b5e11c03023264208James Dong            if (video->nal_ref_idc == 0)
77329a84457aed4c45bc900998b5e11c03023264208James Dong            {
77429a84457aed4c45bc900998b5e11c03023264208James Dong                video->expectedPicOrderCnt += currSPS->offset_for_non_ref_pic;
77529a84457aed4c45bc900998b5e11c03023264208James Dong            }
77629a84457aed4c45bc900998b5e11c03023264208James Dong            /* derive TopFieldOrderCnt and BottomFieldOrderCnt */
77729a84457aed4c45bc900998b5e11c03023264208James Dong            /* encoding part */
77829a84457aed4c45bc900998b5e11c03023264208James Dong            if (!currSPS->delta_pic_order_always_zero_flag)
77929a84457aed4c45bc900998b5e11c03023264208James Dong            {
78029a84457aed4c45bc900998b5e11c03023264208James Dong                sliceHdr->delta_pic_order_cnt[0] = currInput->disp_order - encvid->dispOrdPOCRef - video->expectedPicOrderCnt;
78129a84457aed4c45bc900998b5e11c03023264208James Dong
78229a84457aed4c45bc900998b5e11c03023264208James Dong                if (video->currPicParams->pic_order_present_flag && !sliceHdr->field_pic_flag)
78329a84457aed4c45bc900998b5e11c03023264208James Dong                {
78429a84457aed4c45bc900998b5e11c03023264208James Dong                    sliceHdr->delta_pic_order_cnt[1] = sliceHdr->delta_pic_order_cnt[0]; /* should be calculated from currInput->bottom_field->disp_order */
78529a84457aed4c45bc900998b5e11c03023264208James Dong                }
78629a84457aed4c45bc900998b5e11c03023264208James Dong                else
78729a84457aed4c45bc900998b5e11c03023264208James Dong                {
78829a84457aed4c45bc900998b5e11c03023264208James Dong                    sliceHdr->delta_pic_order_cnt[1] = 0;
78929a84457aed4c45bc900998b5e11c03023264208James Dong                }
79029a84457aed4c45bc900998b5e11c03023264208James Dong            }
79129a84457aed4c45bc900998b5e11c03023264208James Dong            else
79229a84457aed4c45bc900998b5e11c03023264208James Dong            {
79329a84457aed4c45bc900998b5e11c03023264208James Dong                sliceHdr->delta_pic_order_cnt[0] = sliceHdr->delta_pic_order_cnt[1] = 0;
79429a84457aed4c45bc900998b5e11c03023264208James Dong            }
79529a84457aed4c45bc900998b5e11c03023264208James Dong
79629a84457aed4c45bc900998b5e11c03023264208James Dong            if (sliceHdr->field_pic_flag == 0)
79729a84457aed4c45bc900998b5e11c03023264208James Dong            {
79829a84457aed4c45bc900998b5e11c03023264208James Dong                video->TopFieldOrderCnt = video->expectedPicOrderCnt + sliceHdr->delta_pic_order_cnt[0];
79929a84457aed4c45bc900998b5e11c03023264208James Dong                video->BottomFieldOrderCnt = video->TopFieldOrderCnt + currSPS->offset_for_top_to_bottom_field + sliceHdr->delta_pic_order_cnt[1];
80029a84457aed4c45bc900998b5e11c03023264208James Dong
80129a84457aed4c45bc900998b5e11c03023264208James Dong                video->PicOrderCnt = AVC_MIN(video->TopFieldOrderCnt, video->BottomFieldOrderCnt);
80229a84457aed4c45bc900998b5e11c03023264208James Dong            }
80329a84457aed4c45bc900998b5e11c03023264208James Dong            else if (sliceHdr->bottom_field_flag == 0)
80429a84457aed4c45bc900998b5e11c03023264208James Dong            {
80529a84457aed4c45bc900998b5e11c03023264208James Dong                video->TopFieldOrderCnt = video->expectedPicOrderCnt + sliceHdr->delta_pic_order_cnt[0];
80629a84457aed4c45bc900998b5e11c03023264208James Dong                video->PicOrderCnt = video->TopFieldOrderCnt;
80729a84457aed4c45bc900998b5e11c03023264208James Dong            }
80829a84457aed4c45bc900998b5e11c03023264208James Dong            else
80929a84457aed4c45bc900998b5e11c03023264208James Dong            {
81029a84457aed4c45bc900998b5e11c03023264208James Dong                video->BottomFieldOrderCnt = video->expectedPicOrderCnt + currSPS->offset_for_top_to_bottom_field + sliceHdr->delta_pic_order_cnt[0];
81129a84457aed4c45bc900998b5e11c03023264208James Dong                video->PicOrderCnt = video->BottomFieldOrderCnt;
81229a84457aed4c45bc900998b5e11c03023264208James Dong            }
81329a84457aed4c45bc900998b5e11c03023264208James Dong            break;
81429a84457aed4c45bc900998b5e11c03023264208James Dong
81529a84457aed4c45bc900998b5e11c03023264208James Dong
81629a84457aed4c45bc900998b5e11c03023264208James Dong        case 2: /* POC MODE 2, subclause 8.2.1.3 */
81729a84457aed4c45bc900998b5e11c03023264208James Dong            /* decoding order must be the same as display order */
81829a84457aed4c45bc900998b5e11c03023264208James Dong            /* we don't check for that. The decoder will just output in decoding order. */
81929a84457aed4c45bc900998b5e11c03023264208James Dong            /* Check for 2 consecutive non-reference frame */
82029a84457aed4c45bc900998b5e11c03023264208James Dong            if (video->nal_ref_idc == 0)
82129a84457aed4c45bc900998b5e11c03023264208James Dong            {
82229a84457aed4c45bc900998b5e11c03023264208James Dong                if (encvid->dispOrdPOCRef == 1)
82329a84457aed4c45bc900998b5e11c03023264208James Dong                {
82429a84457aed4c45bc900998b5e11c03023264208James Dong                    return AVCENC_CONSECUTIVE_NONREF;
82529a84457aed4c45bc900998b5e11c03023264208James Dong                }
82629a84457aed4c45bc900998b5e11c03023264208James Dong                encvid->dispOrdPOCRef = 1;  /* act as a flag for non ref */
82729a84457aed4c45bc900998b5e11c03023264208James Dong            }
82829a84457aed4c45bc900998b5e11c03023264208James Dong            else
82929a84457aed4c45bc900998b5e11c03023264208James Dong            {
83029a84457aed4c45bc900998b5e11c03023264208James Dong                encvid->dispOrdPOCRef = 0;
83129a84457aed4c45bc900998b5e11c03023264208James Dong            }
83229a84457aed4c45bc900998b5e11c03023264208James Dong
83329a84457aed4c45bc900998b5e11c03023264208James Dong
83429a84457aed4c45bc900998b5e11c03023264208James Dong            if (video->nal_unit_type == AVC_NALTYPE_IDR)
83529a84457aed4c45bc900998b5e11c03023264208James Dong            {
83629a84457aed4c45bc900998b5e11c03023264208James Dong                video->FrameNumOffset = 0;
83729a84457aed4c45bc900998b5e11c03023264208James Dong            }
83829a84457aed4c45bc900998b5e11c03023264208James Dong            else if (video->prevFrameNum > sliceHdr->frame_num)
83929a84457aed4c45bc900998b5e11c03023264208James Dong            {
84029a84457aed4c45bc900998b5e11c03023264208James Dong                video->FrameNumOffset = video->prevFrameNumOffset + video->MaxFrameNum;
84129a84457aed4c45bc900998b5e11c03023264208James Dong            }
84229a84457aed4c45bc900998b5e11c03023264208James Dong            else
84329a84457aed4c45bc900998b5e11c03023264208James Dong            {
84429a84457aed4c45bc900998b5e11c03023264208James Dong                video->FrameNumOffset = video->prevFrameNumOffset;
84529a84457aed4c45bc900998b5e11c03023264208James Dong            }
84629a84457aed4c45bc900998b5e11c03023264208James Dong            /* derive tempPicOrderCnt, we just use PicOrderCnt */
84729a84457aed4c45bc900998b5e11c03023264208James Dong            if (video->nal_unit_type == AVC_NALTYPE_IDR)
84829a84457aed4c45bc900998b5e11c03023264208James Dong            {
84929a84457aed4c45bc900998b5e11c03023264208James Dong                video->PicOrderCnt = 0;
85029a84457aed4c45bc900998b5e11c03023264208James Dong            }
85129a84457aed4c45bc900998b5e11c03023264208James Dong            else if (video->nal_ref_idc == 0)
85229a84457aed4c45bc900998b5e11c03023264208James Dong            {
85329a84457aed4c45bc900998b5e11c03023264208James Dong                video->PicOrderCnt = 2 * (video->FrameNumOffset + sliceHdr->frame_num) - 1;
85429a84457aed4c45bc900998b5e11c03023264208James Dong            }
85529a84457aed4c45bc900998b5e11c03023264208James Dong            else
85629a84457aed4c45bc900998b5e11c03023264208James Dong            {
85729a84457aed4c45bc900998b5e11c03023264208James Dong                video->PicOrderCnt = 2 * (video->FrameNumOffset + sliceHdr->frame_num);
85829a84457aed4c45bc900998b5e11c03023264208James Dong            }
85929a84457aed4c45bc900998b5e11c03023264208James Dong            /* derive TopFieldOrderCnt and BottomFieldOrderCnt */
86029a84457aed4c45bc900998b5e11c03023264208James Dong            if (sliceHdr->field_pic_flag == 0)
86129a84457aed4c45bc900998b5e11c03023264208James Dong            {
86229a84457aed4c45bc900998b5e11c03023264208James Dong                video->TopFieldOrderCnt = video->BottomFieldOrderCnt = video->PicOrderCnt;
86329a84457aed4c45bc900998b5e11c03023264208James Dong            }
86429a84457aed4c45bc900998b5e11c03023264208James Dong            else if (sliceHdr->bottom_field_flag)
86529a84457aed4c45bc900998b5e11c03023264208James Dong            {
86629a84457aed4c45bc900998b5e11c03023264208James Dong                video->BottomFieldOrderCnt = video->PicOrderCnt;
86729a84457aed4c45bc900998b5e11c03023264208James Dong            }
86829a84457aed4c45bc900998b5e11c03023264208James Dong            else
86929a84457aed4c45bc900998b5e11c03023264208James Dong            {
87029a84457aed4c45bc900998b5e11c03023264208James Dong                video->TopFieldOrderCnt = video->PicOrderCnt;
87129a84457aed4c45bc900998b5e11c03023264208James Dong            }
87229a84457aed4c45bc900998b5e11c03023264208James Dong            break;
87329a84457aed4c45bc900998b5e11c03023264208James Dong        default:
87429a84457aed4c45bc900998b5e11c03023264208James Dong            return AVCENC_POC_FAIL;
87529a84457aed4c45bc900998b5e11c03023264208James Dong    }
87629a84457aed4c45bc900998b5e11c03023264208James Dong
87729a84457aed4c45bc900998b5e11c03023264208James Dong    return AVCENC_SUCCESS;
87829a84457aed4c45bc900998b5e11c03023264208James Dong}
87929a84457aed4c45bc900998b5e11c03023264208James Dong
88029a84457aed4c45bc900998b5e11c03023264208James Dong/** see subclause 8.2.1 */
88129a84457aed4c45bc900998b5e11c03023264208James DongAVCEnc_Status PostPOC(AVCCommonObj *video)
88229a84457aed4c45bc900998b5e11c03023264208James Dong{
88329a84457aed4c45bc900998b5e11c03023264208James Dong    AVCSliceHeader *sliceHdr = video->sliceHdr;
88429a84457aed4c45bc900998b5e11c03023264208James Dong    AVCSeqParamSet *currSPS = video->currSeqParams;
88529a84457aed4c45bc900998b5e11c03023264208James Dong
88629a84457aed4c45bc900998b5e11c03023264208James Dong    video->prevFrameNum = sliceHdr->frame_num;
88729a84457aed4c45bc900998b5e11c03023264208James Dong
88829a84457aed4c45bc900998b5e11c03023264208James Dong    switch (currSPS->pic_order_cnt_type)
88929a84457aed4c45bc900998b5e11c03023264208James Dong    {
89029a84457aed4c45bc900998b5e11c03023264208James Dong        case 0: /* subclause 8.2.1.1 */
89129a84457aed4c45bc900998b5e11c03023264208James Dong            if (video->mem_mgr_ctrl_eq_5)
89229a84457aed4c45bc900998b5e11c03023264208James Dong            {
89329a84457aed4c45bc900998b5e11c03023264208James Dong                video->prevPicOrderCntMsb = 0;
89429a84457aed4c45bc900998b5e11c03023264208James Dong                video->prevPicOrderCntLsb = video->TopFieldOrderCnt;
89529a84457aed4c45bc900998b5e11c03023264208James Dong            }
89629a84457aed4c45bc900998b5e11c03023264208James Dong            else
89729a84457aed4c45bc900998b5e11c03023264208James Dong            {
89829a84457aed4c45bc900998b5e11c03023264208James Dong                video->prevPicOrderCntMsb = video->PicOrderCntMsb;
89929a84457aed4c45bc900998b5e11c03023264208James Dong                video->prevPicOrderCntLsb = sliceHdr->pic_order_cnt_lsb;
90029a84457aed4c45bc900998b5e11c03023264208James Dong            }
90129a84457aed4c45bc900998b5e11c03023264208James Dong            break;
90229a84457aed4c45bc900998b5e11c03023264208James Dong        case 1:  /* subclause 8.2.1.2 and 8.2.1.3 */
90329a84457aed4c45bc900998b5e11c03023264208James Dong        case 2:
90429a84457aed4c45bc900998b5e11c03023264208James Dong            if (video->mem_mgr_ctrl_eq_5)
90529a84457aed4c45bc900998b5e11c03023264208James Dong            {
90629a84457aed4c45bc900998b5e11c03023264208James Dong                video->prevFrameNumOffset = 0;
90729a84457aed4c45bc900998b5e11c03023264208James Dong            }
90829a84457aed4c45bc900998b5e11c03023264208James Dong            else
90929a84457aed4c45bc900998b5e11c03023264208James Dong            {
91029a84457aed4c45bc900998b5e11c03023264208James Dong                video->prevFrameNumOffset = video->FrameNumOffset;
91129a84457aed4c45bc900998b5e11c03023264208James Dong            }
91229a84457aed4c45bc900998b5e11c03023264208James Dong            break;
91329a84457aed4c45bc900998b5e11c03023264208James Dong    }
91429a84457aed4c45bc900998b5e11c03023264208James Dong
91529a84457aed4c45bc900998b5e11c03023264208James Dong    return AVCENC_SUCCESS;
91629a84457aed4c45bc900998b5e11c03023264208James Dong}
91729a84457aed4c45bc900998b5e11c03023264208James Dong
918