Example #1
0
File: pps.c Project: janieltec/svc
/**
Parses first data of pps.
*/
void PpsSliceGroupHeader(unsigned char *data, int *Position, PPS *pt_pps, unsigned char *SliceGroupId)
{
	int i;
	int	iGroup;

	if ( pt_pps -> num_slice_groups_minus1 > 0 ) {
		pt_pps -> slice_group_map_type = (unsigned char) read_ue(data, Position);
		if ( pt_pps -> slice_group_map_type == 0 ) 
			for ( iGroup = 0 ; iGroup <= pt_pps -> num_slice_groups_minus1 ; iGroup++ ) 
				pt_pps -> run_length_minus1 [iGroup] = (short) read_ue(data, Position);
		else if ( pt_pps -> slice_group_map_type == 2 ) 
			for ( iGroup = 0 ; iGroup < pt_pps -> num_slice_groups_minus1 ; iGroup++ ) {
				pt_pps -> top_left_tab [iGroup] = (short) read_ue(data, Position);//
				pt_pps -> bottom_right_tab [iGroup] = (short) read_ue(data, Position);//
			}
		else if ( pt_pps -> slice_group_map_type == 3 || pt_pps -> slice_group_map_type == 4
			|| pt_pps -> slice_group_map_type == 5 ) {
				pt_pps -> slice_group_change_direction_flag = (unsigned char) getNbits(data, Position, 1);
				pt_pps -> slice_group_change_rate_minus1 = (short) read_ue(data, Position) + 1;
		} else if ( pt_pps -> slice_group_map_type == 6 ) {
			short log2_num_slice_groups_minus1 = (short) log_base2(pt_pps -> num_slice_groups_minus1 + 1);
			short pic_size_in_map_units_minus1 = (short) read_ue(data, Position);
			for ( i = 0 ; i <= pic_size_in_map_units_minus1 ; i++ ) {
				SliceGroupId [i] = (unsigned char) getNbits(data, Position, log2_num_slice_groups_minus1);
			}
		}
	}
}
Example #2
0
/*!
 * \param *dc The current DecodingContext.
 * \param *slice structure.
 * \return *rplm_t initialized data structure.
 */
static rplm_t *decodeRPLM(DecodingContext_t *dc, slice_t *slice)
{
    TRACE_INFO(SLICE, "  > " BLD_GREEN "decodeRPLM()\n" CLR_RESET);

    // RPLM allocation
    ////////////////////////////////////////////////////////////////////////////

    rplm_t *rplm = (rplm_t*)calloc(1, sizeof(rplm_t));
    if (rplm == NULL)
    {
        TRACE_ERROR(SLICE, "Unable to alloc new RPLM!\n");
    }
    else
    {
        // RPLM decoding
        ////////////////////////////////////////////////////////////////////////

        if (slice->slice_type % 5 != 2 && slice->slice_type % 5 != 4)
        {
            rplm->ref_pic_list_modification_flag_l0 = read_bit(dc->bitstr);
            if (rplm->ref_pic_list_modification_flag_l0)
            {
                do {
                    rplm->modification_of_pic_nums_idc = read_ue(dc->bitstr);
                    if (rplm->modification_of_pic_nums_idc == 0 ||
                        rplm->modification_of_pic_nums_idc == 1)
                    {
                        rplm->abs_diff_pic_num_minus1 = read_ue(dc->bitstr);
                    }
                    else if (rplm->modification_of_pic_nums_idc == 2)
                    {
                        rplm->long_term_pic_num = read_ue(dc->bitstr);
                    }
                } while (rplm->modification_of_pic_nums_idc != 3);
            }
        }

        if (slice->slice_type % 5 == 1)
        {
            rplm->ref_pic_list_modification_flag_l1 = read_bit(dc->bitstr);
            if (rplm->ref_pic_list_modification_flag_l1)
            {
                do {
                    rplm->modification_of_pic_nums_idc = read_ue(dc->bitstr);
                    if (rplm->modification_of_pic_nums_idc == 0 ||
                        rplm->modification_of_pic_nums_idc == 1)
                    {
                        rplm->abs_diff_pic_num_minus1 = read_ue(dc->bitstr);
                    }
                    else if (rplm->modification_of_pic_nums_idc == 2)
                    {
                        rplm->long_term_pic_num = read_ue(dc->bitstr);
                    }
                } while (rplm->modification_of_pic_nums_idc != 3);
            }
        }
    }

    return rplm;
}
Example #3
0
/*!
 * \param *dc The current DecodingContext.
 * \param mbAddr The current macroblock address.
 * \return 0 if macroblock decoding fail, 1 otherwise.
 *
 * This function extract one macroblock from the bitstream, handle intra/inter
 * prediction for its blocks.
 */
int macroblock_layer(DecodingContext_t *dc, const int mbAddr)
{
    TRACE_INFO(MB, "<> " BLD_GREEN "macroblock_layer(" CLR_RESET "%i" BLD_GREEN ")\n" CLR_RESET, mbAddr);
    int retcode = FAILURE;

    // Macroblock allocation
    ////////////////////////////////////////////////////////////////////////////

    dc->mb_array[mbAddr] = (Macroblock_t*)calloc(1, sizeof(Macroblock_t));

    if (dc->mb_array[mbAddr] == NULL)
    {
        TRACE_ERROR(MB, "Unable to alloc new macroblock!\n");
    }
    else
    {
        // Set macroblock address
        dc->mb_array[mbAddr]->mbAddr = mbAddr;

        // Shortcuts
        pps_t *pps = dc->pps_array[dc->active_slice->pic_parameter_set_id];
        sps_t *sps = dc->sps_array[pps->seq_parameter_set_id];
        slice_t *slice = dc->active_slice;
        Macroblock_t *mb = dc->mb_array[mbAddr];

        // Macroblock decoding
        ////////////////////////////////////////////////////////////////////////

#if ENABLE_DEBUG
        mb->mbFileAddrStart = bitstream_get_absolute_bit_offset(dc->bitstr);
#endif // ENABLE_DEBUG

        deriv_macroblockneighbours_availability(dc, mbAddr);
        MbPosition(mb, sps);

        if (pps->entropy_coding_mode_flag)
            mb->mb_type = read_ae(dc, SE_mb_type);
        else
            mb->mb_type = read_ue(dc->bitstr);

        mb->MbPartPredMode[0] = MbPartPredMode(mb, slice->slice_type, 0);
        mb->NumMbPart = NumMbPart(slice->slice_type, mb->mb_type);

        if (mb->mb_type == I_PCM)
        {
#if ENABLE_IPCM
            TRACE_3(MB, "---- macroblock_layer - I PCM macroblock\n");

            while (bitstream_check_alignment(dc->bitstr) == false)
            {
                if (read_bit(dc->bitstr) != 0) // pcm_alignment_zero_bit
                {
                    TRACE_ERROR(MB, "  Error while reading pcm_alignment_zero_bit: must be 0!\n");
                    return FAILURE;
                }
            }

            // CABAC initialization process //FIXME needed? See 'ITU-T H.264' recommendation 9.3.1.2
            initCabacDecodingEngine(dc);

            int i = 0;
            for (i = 0; i < 256; i++)
            {
                mb->pcm_sample_luma[i] = (uint8_t)read_bits(dc->bitstr, sps->BitDepthY);
            }

            // CABAC initialization process //FIXME needed? See 'ITU-T H.264' recommendation 9.3.1.2
            initCabacDecodingEngine(dc);

            for (i = 0; i < 2 * sps->MbWidthC * sps->MbHeightC; i++)
            {
                mb->pcm_sample_chroma[i] = (uint8_t)read_bits(dc->bitstr, sps->BitDepthC);
            }

            // CABAC initialization process //FIXME needed? See 'ITU-T H.264' recommendation 9.3.1.2
            initCabacDecodingEngine(dc);
#else // ENABLE_IPCM
            TRACE_ERROR(MB, "I_PCM decoding is currently disabled!\n");
            return UNSUPPORTED;
#endif // ENABLE_IPCM
        }
        else
        {
#if ENABLE_INTER_PRED
            bool noSubMbPartSizeLessThan8x8Flag = true;

            if (mb->mb_type != I_NxN &&
                mb->MbPartPredMode[0] != Intra_16x16 &&
                mb->NumMbPart == 4)
            {
                TRACE_3(MB, "---- macroblock_layer - mb partition & related\n");

                int mbPartIdx = 0;
                for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
                {
                    if (mb->sub_mb_type[mbPartIdx] != B_Direct_8x8)
                    {
                        if (NumSubMbPart(slice->slice_type, mb->sub_mb_type[mbPartIdx]) > 1)
                        {
                            noSubMbPartSizeLessThan8x8Flag = false;
                        }
                    }
                    else if (sps->direct_8x8_inference_flag == false)
                    {
                        noSubMbPartSizeLessThan8x8Flag = false;
                    }
                }

                // Read sub macroblock prediction mode
                sub_mb_pred(dc, mb->mb_type, mb->sub_mb_type);
            }
            else
#endif // ENABLE_INTER_PRED
            {
                TRACE_3(MB, "---- macroblock_layer - transform_size_8x8_flag & prediction modes\n");

                if (pps->transform_8x8_mode_flag == true && mb->mb_type == I_NxN)
                {
                    if (pps->entropy_coding_mode_flag)
                        mb->transform_size_8x8_flag = read_ae(dc, SE_transform_size_8x8_flag);
                    else
                        mb->transform_size_8x8_flag = read_bit(dc->bitstr);

                    // Need to update MbPartPredMode in order to detect I_8x8 prediction mode
                    mb->MbPartPredMode[0] = MbPartPredMode(mb, slice->slice_type, 0);
                }

                // Read macroblock prediction mode
                mb_pred(dc, mb);
            }

            if (mb->MbPartPredMode[0] != Intra_16x16)
            {
                TRACE_3(MB, "---- macroblock_layer - coded block pattern & transform_size_8x8_flag\n");

                if (pps->entropy_coding_mode_flag)
                    mb->coded_block_pattern = read_ae(dc, SE_coded_block_pattern);
                else
                    mb->coded_block_pattern = read_me(dc->bitstr, sps->ChromaArrayType, dc->IdrPicFlag);

                mb->CodedBlockPatternLuma = mb->coded_block_pattern % 16;
                mb->CodedBlockPatternChroma = mb->coded_block_pattern / 16;
#if ENABLE_INTER_PRED
                if (mb->CodedBlockPatternLuma > 0 &&
                    pps->transform_8x8_mode_flag == true &&
                    mb->mb_type != I_NxN &&
                    noSubMbPartSizeLessThan8x8Flag == true &&
                    (mb->mb_type != B_Direct_16x16 || sps->direct_8x8_inference_flag == true))
                {
                    if (pps->entropy_coding_mode_flag)
                        mb->transform_size_8x8_flag = read_ae(dc, SE_transform_size_8x8_flag);
                    else
                        mb->transform_size_8x8_flag = read_bit(dc->bitstr);

                    // Need to update MbPartPredMode in order to account for I_8x8 prediction mode
                    if (transform_size_8x8_flag)
                        mb->MbPartPredMode[0] = MbPartPredMode(mb, slice->slice_type, 0);
                }
#endif // ENABLE_INTER_PRED
            }

            if (mb->CodedBlockPatternLuma > 0 ||
                mb->CodedBlockPatternChroma > 0 ||
                mb->MbPartPredMode[0] == Intra_16x16)
            {
                TRACE_3(MB, "---- macroblock_layer - quantization parameter & residual datas\n");

                // Read QP delta
                if (pps->entropy_coding_mode_flag)
                    mb->mb_qp_delta = read_ae(dc, SE_mb_qp_delta);
                else
                    mb->mb_qp_delta = read_se(dc->bitstr);

                // Parse the residual coefficients
                ////////////////////////////////////////////////////////////////

                // Luma levels
                residual_luma(dc, 0, 15);

                // Chroma levels
                residual_chroma(dc, 0, 15);
            }
            else
            {
                TRACE_3(MB, "---- macroblock_layer - No residual datas to decode in this macroblock\n");
            }

            // Compute luma Quantization Parameters
            if (mb->mb_qp_delta)
                mb->QPY = ((slice->QPYprev + mb->mb_qp_delta + 52 + sps->QpBdOffsetY*2) % (52 + sps->QpBdOffsetY)) - sps->QpBdOffsetY;
            else
                mb->QPY = slice->QPYprev;

            mb->QPprimeY = mb->QPY + sps->QpBdOffsetY;
            slice->QPYprev = mb->QPY;

            // Set Transform Bypass Mode
            if (sps->qpprime_y_zero_transform_bypass_flag == true && mb->QPprimeY == 0)
                mb->TransformBypassModeFlag = true;

            // Prediction process (include quantization and transformation stages)
            ////////////////////////////////////////////////////////////////

            if (dc->IdrPicFlag)
            {
                retcode = intra_prediction_process(dc, mb);
            }
            else
            {
                retcode = inter_prediction_process(dc, mb);
            }

            // Print macroblock(s) header and block data ?
            ////////////////////////////////////////////////////////////////

#if ENABLE_DEBUG
            mb->mbFileAddrStop = bitstream_get_absolute_bit_offset(dc->bitstr) - 1;

            int frame_debug_range[2] = {-1, -1}; // Range of (idr) frame(s) to debug/analyse
            int mb_debug_range[2] = {-1, -1}; // Range of macroblock(s) to debug/analyse

            if (dc->idrCounter >= frame_debug_range[0] && dc->idrCounter <= frame_debug_range[1])
            {
                if (mb->mbAddr >= mb_debug_range[0] && mb->mbAddr <= mb_debug_range[1])
                {
                    print_macroblock_layer(dc, mb);
                    print_macroblock_pixel_residual(mb);
                    print_macroblock_pixel_predicted(mb);
                    print_macroblock_pixel_final(mb);
                }
            }
#endif // ENABLE_DEBUG
        }

        TRACE_3(MB, "---- macroblock_layer - the end\n\n");
    }

    return retcode;
}
Example #4
0
/*!
 * \param *dc The current DecodingContext.
 * \param mb_type The macroblock prediction type.
 * \param *sub_mb_type The sub macroblock prediction type.
 *
 * Find the sub macroblock prediction type (intra prediction mode or motion vectors exctraction).
 */
static void sub_mb_pred(DecodingContext_t *dc, const unsigned int mb_type, unsigned int *sub_mb_type)
{
    TRACE_INFO(MB, "  > " BLD_GREEN "sub_mb_pred()\n" CLR_RESET);

    // Shortcut
    Macroblock_t *mb = dc->mb_array[dc->CurrMbAddr];
    slice_t *slice = dc->active_slice;

    // Read sub_mb_type
    int mbPartIdx = 0;
    for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
    {
        if (dc->entropy_coding_mode_flag)
            sub_mb_type[mbPartIdx] = read_ae(dc, SE_sub_mb_type);
        else
            sub_mb_type[mbPartIdx] = read_ue(dc->bitstr);
    }

    // ref_idx_l0
    for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
    {
        if ((slice->num_ref_idx_l0_active_minus1 > 0 ||
             slice->mb_field_decoding_flag != slice->field_pic_flag) &&
            mb_type != P_8x8ref0 &&
            sub_mb_type[mbPartIdx] != B_Direct_8x8 &&
            SubMbPredMode(slice->slice_type, sub_mb_type[mbPartIdx]) != Pred_L1)
        {
            if (dc->entropy_coding_mode_flag)
                mb->ref_idx_l0[mbPartIdx] = read_ae(dc, SE_ref_idx_lx);
            else
                mb->ref_idx_l0[mbPartIdx] = read_te(dc->bitstr, 0);
        }
    }

    // ref_idx_l1
    for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
    {
        if ((slice->num_ref_idx_l1_active_minus1 > 0 ||
             slice->mb_field_decoding_flag != slice->field_pic_flag) &&
            sub_mb_type[mbPartIdx] != B_Direct_8x8 &&
            SubMbPredMode(slice->slice_type, sub_mb_type[mbPartIdx]) != Pred_L0)
        {
            if (dc->entropy_coding_mode_flag)
                mb->ref_idx_l1[mbPartIdx] = read_ae(dc, SE_ref_idx_lx);
            else
                mb->ref_idx_l1[mbPartIdx] = read_te(dc->bitstr, 0);
        }
    }

    // mvd_l0
    for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
    {
        if (sub_mb_type[mbPartIdx] != B_Direct_8x8 &&
            SubMbPredMode(slice->slice_type, sub_mb_type[mbPartIdx]) != Pred_L1)
        {
            int subMbPartIdx = 0;
            for (subMbPartIdx = 0; subMbPartIdx < NumSubMbPart(slice->slice_type, sub_mb_type[mbPartIdx]); subMbPartIdx++)
            {
                if (dc->entropy_coding_mode_flag)
                {
                    mb->mvd_l0[mbPartIdx][subMbPartIdx][0] = read_ae(dc, SE_mvd_lx0);
                    mb->mvd_l0[mbPartIdx][subMbPartIdx][1] = read_ae(dc, SE_mvd_lx1);
                }
                else
                {
                    mb->mvd_l0[mbPartIdx][subMbPartIdx][0] = read_se(dc->bitstr);
                    mb->mvd_l0[mbPartIdx][subMbPartIdx][1] = read_se(dc->bitstr);
                }
            }
        }
    }

    // mvd_l1
    for (mbPartIdx = 0; mbPartIdx < 4; mbPartIdx++)
    {
        if (sub_mb_type[mbPartIdx] != B_Direct_8x8 &&
            SubMbPredMode(slice->slice_type, sub_mb_type[mbPartIdx]) != Pred_L0)
        {
            int subMbPartIdx = 0;
            for (subMbPartIdx = 0; subMbPartIdx < NumSubMbPart(slice->slice_type, sub_mb_type[mbPartIdx]); subMbPartIdx++)
            {
                if (dc->entropy_coding_mode_flag)
                {
                    mb->mvd_l1[mbPartIdx][subMbPartIdx][0] = read_ae(dc, SE_mvd_lx0);
                    mb->mvd_l1[mbPartIdx][subMbPartIdx][1] = read_ae(dc, SE_mvd_lx1);
                }
                else
                {
                    mb->mvd_l1[mbPartIdx][subMbPartIdx][0] = read_se(dc->bitstr);
                    mb->mvd_l1[mbPartIdx][subMbPartIdx][1] = read_se(dc->bitstr);
                }
            }
        }
    }
}
Example #5
0
/*!
 * \brief Read prediction informations for current macroblock.
 * \param *dc The current DecodingContext.
 * \param *mb The current macroblock.
 *
 * Intra prediction infos are a table containing prediction mode for each blocks.
 * Inter prediction infos are motion vectors.
 */
static void mb_pred(DecodingContext_t *dc, Macroblock_t *mb)
{
    TRACE_INFO(MB, "  > " BLD_GREEN "mb_pred()\n" CLR_RESET);

    if (mb->MbPartPredMode[0] == Intra_4x4 ||
        mb->MbPartPredMode[0] == Intra_8x8 ||
        mb->MbPartPredMode[0] == Intra_16x16)
    {
        if (mb->MbPartPredMode[0] == Intra_4x4)
        {
            // Read intra prediction mode for all 16 4x4 luma blocks
            unsigned int luma4x4BlkIdx = 0;
            for (luma4x4BlkIdx = 0; luma4x4BlkIdx < 16; luma4x4BlkIdx++)
            {
                if (dc->entropy_coding_mode_flag)
                    mb->prev_intra4x4_pred_mode_flag[luma4x4BlkIdx] = read_ae(dc, SE_prev_intraxxx_pred_mode_flag);
                else
                    mb->prev_intra4x4_pred_mode_flag[luma4x4BlkIdx] = read_bit(dc->bitstr);

                if (mb->prev_intra4x4_pred_mode_flag[luma4x4BlkIdx] == false)
                {
                    if (dc->entropy_coding_mode_flag)
                        mb->rem_intra4x4_pred_mode[luma4x4BlkIdx] = read_ae(dc, SE_rem_intraxxx_pred_mode);
                    else
                        mb->rem_intra4x4_pred_mode[luma4x4BlkIdx] = read_bits(dc->bitstr, 3);
                }
            }
        }
        else if (mb->MbPartPredMode[0] == Intra_8x8)
        {
            // Read intra prediction mode for all 4 8x8 luma blocks
            unsigned int luma8x8BlkIdx = 0;
            for (luma8x8BlkIdx = 0; luma8x8BlkIdx < 4; luma8x8BlkIdx++)
            {
                if (dc->entropy_coding_mode_flag)
                    mb->prev_intra8x8_pred_mode_flag[luma8x8BlkIdx] = read_ae(dc, SE_prev_intraxxx_pred_mode_flag);
                else
                    mb->prev_intra8x8_pred_mode_flag[luma8x8BlkIdx] = read_bit(dc->bitstr);

                if (mb->prev_intra8x8_pred_mode_flag[luma8x8BlkIdx] == false)
                {
                    if (dc->entropy_coding_mode_flag)
                        mb->rem_intra8x8_pred_mode[luma8x8BlkIdx] = read_ae(dc, SE_rem_intraxxx_pred_mode);
                    else
                        mb->rem_intra8x8_pred_mode[luma8x8BlkIdx] = read_bits(dc->bitstr, 3);
                }
            }
        }

        // Read intra prediction mode for chroma blocks
        if (dc->ChromaArrayType == 1 || dc->ChromaArrayType == 2)
        {
            if (dc->entropy_coding_mode_flag)
                mb->IntraChromaPredMode = read_ae(dc, SE_intra_chroma_pred_mode);
            else
                mb->IntraChromaPredMode = read_ue(dc->bitstr);
        }
    }
    else if (mb->MbPartPredMode[0] != Direct)
    {
        // ref_idx_l0
        unsigned int mbPartIdx = 0;
        for (mbPartIdx = 0; mbPartIdx < mb->NumMbPart; mbPartIdx++)
        {
            if ((dc->active_slice->num_ref_idx_l0_active_minus1 > 0 ||
                 dc->active_slice->mb_field_decoding_flag != dc->active_slice->field_pic_flag) &&
                MbPartPredMode(mb, dc->active_slice->slice_type, mbPartIdx) != Pred_L1)
            {
                if (dc->entropy_coding_mode_flag)
                    mb->ref_idx_l0[mbPartIdx] = read_ae(dc, SE_ref_idx_lx);
                else
                    mb->ref_idx_l0[mbPartIdx] = read_te(dc->bitstr, 0);
            }
        }

        // ref_idx_l1
        for (mbPartIdx = 0; mbPartIdx < mb->NumMbPart; mbPartIdx++)
        {
            if ((dc->active_slice->num_ref_idx_l1_active_minus1 > 0 ||
                 dc->active_slice->mb_field_decoding_flag != dc->active_slice->field_pic_flag) &&
                MbPartPredMode(mb, dc->active_slice->slice_type, mbPartIdx) != Pred_L0)
            {
                if (dc->entropy_coding_mode_flag)
                    mb->ref_idx_l1[mbPartIdx] = read_ae(dc, SE_ref_idx_lx);
                else
                    mb->ref_idx_l1[mbPartIdx] = read_te(dc->bitstr, 0);
            }
        }

        // mvd_l0
        for (mbPartIdx = 0; mbPartIdx < mb->NumMbPart; mbPartIdx++)
        {
            if (MbPartPredMode(mb, dc->active_slice->slice_type, mbPartIdx) != Pred_L1)
            {
                if (dc->entropy_coding_mode_flag)
                {
                    mb->mvd_l0[mbPartIdx][0][0] = read_ae(dc, SE_mvd_lx0);
                    mb->mvd_l0[mbPartIdx][0][1] = read_ae(dc, SE_mvd_lx1);
                }
                else
                {
                    mb->mvd_l0[mbPartIdx][0][0] = read_te(dc->bitstr, 0);
                    mb->mvd_l0[mbPartIdx][0][1] = read_te(dc->bitstr, 0);
                }
            }
        }

        // mvd_l1
        for (mbPartIdx = 0; mbPartIdx < mb->NumMbPart; mbPartIdx++)
        {
            if (MbPartPredMode(mb, dc->active_slice->slice_type, mbPartIdx) != Pred_L0)
            {
                if (dc->entropy_coding_mode_flag)
                {
                    mb->mvd_l1[mbPartIdx][0][0] = read_ae(dc, SE_mvd_lx0);
                    mb->mvd_l1[mbPartIdx][0][1] = read_ae(dc, SE_mvd_lx1);
                }
                else
                {
                    mb->mvd_l1[mbPartIdx][0][0] = read_te(dc->bitstr, 0);
                    mb->mvd_l1[mbPartIdx][0][1] = read_te(dc->bitstr, 0);
                }
            }
        }
    }
}
Example #6
0
File: pps.c Project: janieltec/svc
/**
Parses first data of pps.
*/
void PpsFirstHeader(unsigned char *data, int *Position, PPS *pt_pps)
{
	pt_pps -> entropy_coding_mode_flag = (unsigned char) getNbits(data, Position, 1);
	pt_pps -> pic_order_present_flag = (unsigned char) getNbits(data, Position, 1);
	pt_pps -> num_slice_groups_minus1 = (unsigned char) read_ue(data, Position);
}
Example #7
0
/*!
 * \param *dc The current DecodingContext.
 * \param *slice structre.
 * \return *drpm_t initialized data structure.
 */
static drpm_t *decodeDRPM(DecodingContext_t *dc, slice_t *slice)
{
    TRACE_INFO(SLICE, "  > " BLD_GREEN "decodeDRPM()\n" CLR_RESET);

    // DRPM allocation
    ////////////////////////////////////////////////////////////////////////////

    drpm_t *drpm = (drpm_t*)calloc(1, sizeof(drpm_t));
    if (drpm == NULL)
    {
        TRACE_ERROR(SLICE, "Unable to alloc new DRPM!\n");
    }
    else
    {
        // DRPM decoding
        ////////////////////////////////////////////////////////////////////////

        if (dc->IdrPicFlag)
        {
            drpm->no_output_of_prior_pics_flag = read_bit(dc->bitstr);
            drpm->long_term_reference_flag = read_bit(dc->bitstr);
        }
        else
        {
            drpm->adaptive_ref_pic_marking_mode_flag = read_bit(dc->bitstr);
            if (drpm->adaptive_ref_pic_marking_mode_flag)
            {
                do {
                    drpm->memory_management_control_operation = read_ue(dc->bitstr);
                    if (drpm->memory_management_control_operation == 1 ||
                        drpm->memory_management_control_operation == 3)
                    {
                        drpm->difference_of_pic_nums_minus1 = read_ue(dc->bitstr);
                    }
                    else if (drpm->memory_management_control_operation == 2)
                    {
                        drpm->long_term_pic_num = read_ue(dc->bitstr);
                    }
                    else if (drpm->memory_management_control_operation == 3 ||
                             drpm->memory_management_control_operation == 6)
                    {
                        drpm->long_term_frame_idx = read_ue(dc->bitstr);
                    }
                    else if (drpm->memory_management_control_operation == 4)
                    {
                        drpm->max_long_term_frame_idx_plus1 = read_ue(dc->bitstr);
                        if (drpm->max_long_term_frame_idx_plus1 > 0)
                        {
                            drpm->MaxLongTermFrameIdx = drpm->max_long_term_frame_idx_plus1 - 1;
                        }
                        else
                        {
                            //FIXME 8.2.5.4.4 Decoding process for MaxLongTermFrameIdx
                        }
                    }
                } while (drpm->memory_management_control_operation != 0);
            }
        }
    }

    return drpm;
}
Example #8
0
/*!
 * \param *dc The current DecodingContext.
 * \param *slice The current Slice.
 */
static int decodeSliceHeader(DecodingContext_t *dc, slice_t *slice)
{
    TRACE_INFO(SLICE, "> " BLD_GREEN "decodeSliceHeader()\n" CLR_RESET);

    // Slice header decoding
    ////////////////////////////////////////////////////////////////////////////

    slice->first_mb_in_slice = read_ue(dc->bitstr);
    slice->slice_type = read_ue(dc->bitstr);
    slice->pic_parameter_set_id = read_ue(dc->bitstr);

    // Shortcuts
    pps_t *pps = dc->pps_array[slice->pic_parameter_set_id];
    sps_t *sps = dc->sps_array[pps->seq_parameter_set_id];

    if (sps->separate_colour_plane_flag)
    {
        slice->colour_plane_id = read_bits(dc->bitstr, 2);
    }

    slice->frame_num = read_bits(dc->bitstr, sps->log2_max_frame_num_minus4 + 4);

    if (sps->frame_mbs_only_flag == false)
    {
        slice->field_pic_flag = read_bit(dc->bitstr);
        if (slice->field_pic_flag)
        {
            slice->bottom_field_flag = read_bit(dc->bitstr);

            slice->MaxPicNum = sps->MaxFrameNum*2;
            slice->CurrPicNum = slice->frame_num*2 + 1;
        }
        else
        {
            slice->MaxPicNum = sps->MaxFrameNum;
            slice->CurrPicNum = slice->frame_num;
        }
    }

    slice->MbaffFrameFlag = sps->mb_adaptive_frame_field_flag && !slice->field_pic_flag;
    slice->PicHeightInMbs = sps->FrameHeightInMbs / (1 + slice->field_pic_flag);
    slice->PicHeightInSamplesL = slice->PicHeightInMbs * 16;
    slice->PicHeightInSamplesC = slice->PicHeightInMbs * sps->MbHeightC;
    slice->PicSizeInMbs = sps->PicWidthInMbs * slice->PicHeightInMbs;

    if (dc->IdrPicFlag)
    {
        slice->PrevRefFrameNum = 0;
        slice->idr_pic_id = read_ue(dc->bitstr);
    }

    if (sps->pic_order_cnt_type == 0)
    {
        slice->pic_order_cnt_lsb = read_bits(dc->bitstr, sps->log2_max_pic_order_cnt_lsb_minus4 + 4);
        if (pps->bottom_field_pic_order_in_frame_present_flag && slice->field_pic_flag == false)
        {
            slice->delta_pic_order_cnt_bottom = read_se(dc->bitstr);
        }
    }
    else if (sps->pic_order_cnt_type == 1 && sps->delta_pic_order_always_zero_flag == false)
    {
        slice->delta_pic_order_cnt[0] = read_se(dc->bitstr);
        if (pps->bottom_field_pic_order_in_frame_present_flag && slice->field_pic_flag == false)
        {
            slice->delta_pic_order_cnt[1] = read_se(dc->bitstr);
        }
    }

    if (pps->redundant_pic_cnt_present_flag)
    {
        slice->redundant_pic_cnt = read_ue(dc->bitstr);
    }

    if (slice->slice_type == 1 || slice->slice_type == 6) // B frame
    {
        TRACE_ERROR(SLICE, ">>> UNSUPPORTED (B frame)\n");
        return UNSUPPORTED;

        slice->direct_spatial_mv_pred_flag = read_bit(dc->bitstr);
    }

    if (slice->slice_type == 0 || slice->slice_type == 5 ||
        slice->slice_type == 3 || slice->slice_type == 8 ||
        slice->slice_type == 1 || slice->slice_type == 6) // P, SP, B frame
    {
        TRACE_ERROR(SLICE, ">>> UNSUPPORTED (P, SP, B frame)\n");
        return UNSUPPORTED;
/*
        slice->num_ref_idx_active_override_flag = read_bit(dc->bitstr);

        if (slice->num_ref_idx_active_override_flag)
        {
            slice->num_ref_idx_l0_active_minus1 = read_ue(dc->bitstr);

            if (slice->slice_type == 1 || slice->slice_type == 6) // B frame
            {
                slice->num_ref_idx_l1_active_minus1 = read_ue(dc->bitstr);
            }
        }
*/
    }

    if (dc->active_nalu->nal_unit_type == 20)
    {
        TRACE_ERROR(SLICE, ">>> UNSUPPORTED (unit_type == 20: MVC extension)\n");
        return UNSUPPORTED;
    }
    else
    {
        // RPLM
        slice->rplm = decodeRPLM(dc, slice);
    }

    if ((pps->weighted_pred_flag == true &&
         (slice->slice_type == 0 || slice->slice_type == 5 ||
          slice->slice_type == 3 || slice->slice_type == 8)) ||
        (pps->weighted_bipred_idc == 1  &&
         (slice->slice_type == 1 || slice->slice_type == 6))) // P, SP, B frame
    {
        // PWT
        slice->pwt = decodePWT(dc, slice);
    }

    if (dc->active_nalu->nal_ref_idc != 0)
    {
        // DRPM
        slice->drpm = decodeDRPM(dc, slice);
    }

    if (pps->entropy_coding_mode_flag == true &&
        ((slice->slice_type != 2 && slice->slice_type != 7) &&
         (slice->slice_type != 4 && slice->slice_type != 9))) // Not I or SI frame
    {
        slice->cabac_init_idc = read_ue(dc->bitstr);
    }

    slice->slice_qp_delta = read_se(dc->bitstr);
    slice->SliceQPY = 26 + pps->pic_init_qp_minus26 + slice->slice_qp_delta;
    slice->QPYprev = slice->SliceQPY; // Set QPYprev value to use it in the first macroblock

    if (slice->slice_type == 3 || slice->slice_type == 8 ||
        slice->slice_type == 4 || slice->slice_type == 9) // SP, SI frame
    {
#if ENABLE_SWITCHING_SLICE
        if (slice->slice_type == 4 || slice->slice_type == 9)
        {
            slice->sp_for_switch_flag = read_bit(dc->bitstr);
        }

        slice->slice_qs_delta = read_se(dc->bitstr);
        slice->SliceQSY = 26 + pps->pic_init_qs_minus26 + slice->slice_qs_delta;
#else /* ENABLE_SWITCHING_SLICE */
        TRACE_ERROR(SLICE, ">>> UNSUPPORTED (slice_type == SP || slice_type == SI)\n");
        return UNSUPPORTED;
#endif /* ENABLE_SWITCHING_SLICE */
    }

    if (pps->deblocking_filter_control_present_flag)
    {
        slice->disable_deblocking_filter_idc = read_ue(dc->bitstr);
        if (slice->disable_deblocking_filter_idc != 1)
        {
            slice->slice_alpha_c0_offset_div2 = read_se(dc->bitstr);
            slice->slice_beta_offset_div2 = read_se(dc->bitstr);

            slice->FilterOffsetA = slice->slice_alpha_c0_offset_div2 << 1;
            slice->FilterOffsetB = slice->slice_beta_offset_div2 << 1;
        }
    }

    if (pps->num_slice_groups_minus1 > 0 && pps->slice_group_map_type >= 3 && pps->slice_group_map_type <= 5)
    {
        TRACE_ERROR(SLICE, ">>> UNSUPPORTED (FMO)\n");
        return UNSUPPORTED;
    }

    // Check content
    return checkSliceHeader(dc);
}
Example #9
0
/*!
 * \param *dc The current DecodingContext.
 * \param *slice The current Slice.
 * \return 0 if an error occurred while decoding slice datas, 1 otherwise.
 */
static int decodeSliceData(DecodingContext_t *dc, slice_t *slice)
{
    TRACE_INFO(SLICE, "> " BLD_GREEN "decodeSliceData()\n" CLR_RESET);

    // Initialization
    int retcode = SUCCESS;
    dc->CurrMbAddr = 0;
    slice->moreDataFlag = true;
    slice->prevMbSkipped = false;

    // Shortcut
    pps_t *pps = dc->pps_array[slice->pic_parameter_set_id];

    // Slice data decoding
    ////////////////////////////////////////////////////////////////////////////

    if (pps->entropy_coding_mode_flag)
    {
        // CABAC alignment
        while (bitstream_check_alignment(dc->bitstr) == false)
        {
            if (read_bit(dc->bitstr) == 0) // cabac_alignment_one_bit
            {
                TRACE_ERROR(SLICE, "cabac_alignment_one_bit must be 1\n");
                return FAILURE;
            }
        }

        // CABAC initialization process
        initCabacContextVariables(dc);
        initCabacDecodingEngine(dc);
    }

    while ((retcode == SUCCESS) &&
           (slice->moreDataFlag == true) &&
           (dc->CurrMbAddr < dc->PicSizeInMbs))
    {
#if ENABLE_INTER_PRED
        // Only I frames are supported anyway
        if (slice->slice_type != 2 && slice->slice_type != 7 &&
            slice->slice_type != 4 && slice->slice_type != 9) // Not I or SI slice
        {
            if (pps->entropy_coding_mode_flag)
            {
                slice->mb_skip_flag = read_ae(dc, SE_mb_skip_flag);
                slice->moreDataFlag = !slice->mb_skip_flag;
            }
            else
            {
                int i = 0;
                slice->mb_skip_run = read_ue(dc->bitstr);
                slice->prevMbSkipped = (slice->mb_skip_run > 0);

                for (i = 0; i < slice->mb_skip_run; i++)
                {
                    dc->CurrMbAddr = NextMbAddress(dc, dc->CurrMbAddr);
                }

                if (slice->mb_skip_run > 0)
                {
                    slice->moreDataFlag = h264_more_rbsp_data(dc->bitstr);
                }
            }
        }

        // If there is still some data in the slice
        if (slice->moreDataFlag)
        {
#if ENABLE_MBAFF
            if (slice->MbaffFrameFlag == true &&
                (dc->CurrMbAddr % 2 == 0 || (dc->CurrMbAddr % 2 == 1 && slice->prevMbSkipped == true)))
            {
                if (pps->entropy_coding_mode_flag)
                    slice->mb_field_decoding_flag = read_ae(dc, SE_mb_field_decoding_flag);
                else
                    slice->mb_field_decoding_flag = read_bit(dc->bitstr);

                TRACE_ERROR(DSLICE, ">>> UNSUPPORTED (interlaced mode)\n");
                return UNSUPPORTED;
            }
#endif /* ENABLE_MBAFF */

            // Macroblock decoding
            retcode = macroblock_layer(dc, dc->CurrMbAddr);
        }
#endif /* ENABLE_INTER_PRED */

        // Macroblock decoding
        retcode = macroblock_layer(dc, dc->CurrMbAddr);

        // Check for end of slice
        if (pps->entropy_coding_mode_flag)
        {
#if ENABLE_INTER_PRED
            // Only I frames are supported anyway
            if (slice->slice_type != 2 && slice->slice_type != 7 &&
                slice->slice_type != 4 && slice->slice_type != 9) // Not I or SI slice
            {
                slice->prevMbSkipped = slice->mb_skip_flag;
            }

#if ENABLE_MBAFF
            // MbaffFrameFlag is unsupported, so always "false"
            if (slice->MbaffFrameFlag == true && dc->CurrMbAddr % 2 == 0)
            {
                slice->moreDataFlag = true;
            }
            else
#endif /* ENABLE_MBAFF */
#endif /* ENABLE_INTER_PRED */
            {
                slice->end_of_slice_flag = read_ae(dc, SE_end_of_slice_flag);
                if (slice->end_of_slice_flag)
                {
                    TRACE_INFO(SLICE, "end_of_slice_flag detected!\n");
                    slice->moreDataFlag = false;
                }
            }
        }
        else
        {
            slice->moreDataFlag = h264_more_rbsp_data(dc->bitstr);
        }

        // Get next macroblock address
        dc->CurrMbAddr = NextMbAddress(dc, dc->CurrMbAddr);
    }

    return retcode;
}
//for init access unit
int slice_header_svc_cut(unsigned char *data, SPS *sps, PPS *pps, int *position, 
						 SLICE *Slice, NAL *Nal)
{
		PPS *pt_pps_id ;
		SPS *pt_sps_id ;	
		int PicParameterId;
		int SeqParameterId;

		//Read header data
		Slice -> first_mb_in_slice = read_ue(data, position);

		Slice -> slice_type = read_ue(data, position);
		if ( Slice -> slice_type > 4 ) {
			Slice -> slice_type -= 5 ;
		}

		PicParameterId = read_ue(data, position);
		Nal -> pic_parameter_id[Nal -> LayerId] = PicParameterId = CLIP3(0, PPS_BUF_SIZE - 1, PicParameterId);
		pt_pps_id = &pps[PicParameterId];
		//Should be in slice header
		//Sometimes Subset SPS are after PPS (rtsp)
		if(pt_pps_id -> seq_parameter_set_id > sps[0] . MaxSpsId){
			pt_pps_id -> seq_parameter_set_id = sps[0] . MaxSpsId;
		}

		



		SeqParameterId = pt_pps_id -> seq_parameter_set_id + (Nal -> LayerId ? 16: 0);
		pt_sps_id = &sps[SeqParameterId];


		Slice -> frame_num = getNbits(data, position, pt_sps_id -> log2_max_frame_num );
		//Read Frame parameter
		if ( !pt_sps_id -> frame_mbs_only_flag ) {
			Slice -> field_pic_flag = getNbits(data, position, 1);
			if ( Slice -> field_pic_flag ) {
				Slice->bottom_field_flag = getNbits(data, position, 1);
			}
		}
		else
		{
			Slice->field_pic_flag = 0;
		}
		if ( 1 == Nal -> IdrFlag) {
			Slice->idr_pic_id = read_ue(data, position);//idr_pic_id =	
		}
		if ( pt_sps_id -> pic_order_cnt_type == 0 ) {
			Slice -> pic_order_cnt_lsb = getNbits(data, position, pt_sps_id -> log2_max_pic_order_cnt_lsb ); 
			if ( pt_pps_id -> pic_order_present_flag && !Slice -> field_pic_flag ) 
				Slice -> delta_pic_order_cnt_bottom = read_se(data, position);
		}

		if ( pt_sps_id -> pic_order_cnt_type == 1 && !pt_sps_id -> delta_pic_order_always_zero_flag ) {
			Slice -> delta_pic_order_cnt [0] = read_se(data, position); 
			if ( pt_pps_id -> pic_order_present_flag && !Slice -> field_pic_flag ) 
				Slice -> delta_pic_order_cnt [1] = read_se(data, position);
		}

		if ( pt_pps_id -> redundant_pic_cnt_present_flag ) {
			read_ue(data, position);//redundant_pic_cnt =
		}


	return 0;
}
Example #11
0
int macroblock_layer_in_scalable_extension(const NAL *Nal, const PPS *Pps, RESIDU *Current_residu, RESIDU *BaseResidu, 
										   const unsigned char *ai_pcData,   int *position,  const SLICE *ai_pstSlice, 
										   DATA Tab_Block[], const VLC_TABLES *vlc, unsigned char aio_tiNon_zero_count_cache [ ], 
										   unsigned char aio_tiSlice_table [ ],  const short iMb_x, const short iMb_y, 
										   int direct_8x8_inference_flag, int *last_QP)

{  




	int  noSubMbPartSizeLessThan8x8;
	int BaseModeFlag = 0;
	const int iCurrMbAddr = iMb_x + iMb_y * (short)(ai_pstSlice -> mb_stride);
	short  intra4x4_pred_mode_cache[40];
	DATA * aio_pstBlock = &Tab_Block[iCurrMbAddr];

	//TODO
	if( ai_pstSlice -> AdaptiveBaseModeFlag && Current_residu -> InCropWindow)  {
		Current_residu -> BaseModeFlag = BaseModeFlag = getNbits(ai_pcData, position, 1); //u(1)   
	}else if (ai_pstSlice -> DefaultBaseModeFlag){
		Current_residu -> BaseModeFlag = BaseModeFlag = 1;
	}

	if(!BaseModeFlag){
		int mb_type = read_ue(ai_pcData, position);

		//According to the slice type and the macroblock type  
		//the parameters are adjusted
		switch ( ai_pstSlice -> slice_type ) 
		{
		case EI : 
#ifdef ERROR_DETECTION
			//Error detection
			if(ErrorsCheckMbType(mb_type, I_BL)){
				return 1;
			}
#endif
			aio_pstBlock -> MbPartPredMode [0] = i_mb_type_info[mb_type] . type;
			Current_residu -> MbType = i_mb_type_info[mb_type] . type;
			Current_residu -> Cbp = i_mb_type_info[mb_type] . Cbp;
			Current_residu -> Intra16x16PredMode = i_mb_type_info[mb_type] . pred_mode;
			break ;
		case EP :
			if (mb_type < 5){
#ifdef ERROR_DETECTION
				//Error detection
				if(ErrorsCheckMbType(mb_type, P_BL)){
					return 1;
				}
#endif
				aio_pstBlock -> NumMbPart = p_mb_type_info[mb_type] . partcount;
				aio_pstBlock -> MbPartPredMode [0] = p_mb_type_info[mb_type] . type_0;
				aio_pstBlock -> MbPartPredMode [1] = p_mb_type_info[mb_type] . type_1;
				Current_residu -> MbType = p_mb_type_info[mb_type] . name;
				Current_residu -> Mode = p_mb_type_info[mb_type] . Mode;
			} 
			else {
				mb_type -= 5;
#ifdef ERROR_DETECTION
				//Error detection
				if(ErrorsCheckMbType(mb_type, I_BL)){
					return 1;
				}
#endif
				aio_pstBlock -> MbPartPredMode [0] = i_mb_type_info[mb_type] . type;
				Current_residu -> MbType = i_mb_type_info[mb_type] . type;
				Current_residu -> Cbp = i_mb_type_info[mb_type] . Cbp;
				Current_residu -> Intra16x16PredMode = i_mb_type_info[mb_type] . pred_mode;		
			}
			break ;
		case EB :
			if (mb_type < 23)	{
#ifdef ERROR_DETECTION
				//Error detection
				if(ErrorsCheckMbType(mb_type, B_BL)){
					return 1;
				}
#endif
				aio_pstBlock -> NumMbPart = b_mb_type_info[mb_type] . partcount;
				aio_pstBlock -> MbPartPredMode [0] = b_mb_type_info[mb_type] . type_0;
				aio_pstBlock -> MbPartPredMode [1] = b_mb_type_info[mb_type] . type_1;
				Current_residu -> MbType = b_mb_type_info[mb_type] . name;
				Current_residu -> Mode = b_mb_type_info[mb_type] . Mode;
			}
			else	{
				mb_type -= 23;
#ifdef ERROR_DETECTION
			//Error detection
			if(ErrorsCheckMbType(mb_type, I_BL)){
				return 1;
			}
#endif
				aio_pstBlock -> MbPartPredMode [0] = i_mb_type_info[mb_type] . type;
				Current_residu -> MbType = i_mb_type_info[mb_type] . type;
				Current_residu -> Cbp = i_mb_type_info[mb_type] . Cbp;
				Current_residu -> Intra16x16PredMode = i_mb_type_info[mb_type] . pred_mode;		
			}
			break;
		}
		//Initialize base macroblock address
		GetBaseMbAddr(Nal, aio_pstBlock, iMb_x << 4, iMb_y << 4);
	}
	else{
		aio_pstBlock -> MbPartPredMode [0] = Current_residu -> MbType = GetBaseType(Nal, BaseResidu, aio_pstBlock, iMb_x, iMb_y);
	}


	//Updating the slice table in order to save in which slice each macroblock belong to
	Current_residu -> SliceNum = aio_tiSlice_table [iCurrMbAddr] = ai_pstSlice -> slice_num ;


	if ( !BaseModeFlag && Current_residu -> MbType == INTRA_PCM )   {
		while ( !bytes_aligned(*position) ) {
			getNbits(ai_pcData, position, 1);//pcm_alignment_zero_bit = 
		}
		ParseIPCM(ai_pcData, position, Current_residu, aio_tiNon_zero_count_cache);
	} 
	else     {
		//Updating the parameter in order to decode the VLC
		fill_caches_svc( ai_pstSlice, Current_residu, BaseResidu, 0, aio_tiNon_zero_count_cache, aio_tiSlice_table, 
			aio_pstBlock, intra4x4_pred_mode_cache, iMb_x, iMb_y, Pps -> constrained_intra_pred_flag, Nal -> TCoeffPrediction);

		if (!BaseModeFlag){
			//Recovery of the motion vectors for the sub_macroblock 
			if ( !IS_I(Current_residu -> MbType) && (aio_pstBlock -> NumMbPart == 4))    {
				int mbPartIdx;
				if(sub_mb_pred_svc(ai_pcData, position, ai_pstSlice, aio_pstBlock, Current_residu)){
					return 1;
				}
				noSubMbPartSizeLessThan8x8 = 0;
				if ( direct_8x8_inference_flag ){
					noSubMbPartSizeLessThan8x8 = 1;
				}
				for ( mbPartIdx = 0;  mbPartIdx < 4; mbPartIdx ++){
					if ( sub_mb_type_name[ai_pstSlice -> slice_type][Current_residu -> SubMbType[mbPartIdx]] != B_direct){
						if ( sub_num_part[ai_pstSlice -> slice_type][Current_residu -> SubMbType[mbPartIdx]] > 1 )
							noSubMbPartSizeLessThan8x8 = 0;
					}
				}
			}
			else
			{ 
				noSubMbPartSizeLessThan8x8 = 1;
				if ( Pps -> transform_8x8_mode_flag && Current_residu -> MbType == INTRA_4x4 && getNbits(ai_pcData, position, 1)){
					Current_residu -> MbType = Current_residu -> Transform8x8 = aio_pstBlock -> Transform8x8 = aio_pstBlock -> MbPartPredMode[0] = INTRA_8x8;
				}

				//Recovery of the prediction mode and the motion vectors for the macroblock 
				if(mb_pred_svc(ai_pcData, position, ai_pstSlice, aio_pstBlock, Current_residu, intra4x4_pred_mode_cache)){
					return 1;
				}
			}
		}

		//Decoding process of the VLC 
		if( ai_pstSlice -> AdaptiveResidualPredictionFlag && ai_pstSlice -> slice_type != EI && (BaseModeFlag || ( !IS_I( Current_residu -> MbType) && Current_residu -> InCropWindow ))){
			Current_residu -> ResidualPredictionFlag = getNbits(ai_pcData, position, 1);
		}else{
			Current_residu -> ResidualPredictionFlag = ai_pstSlice -> DefaultResidualPredictionFlag;
		}



		if ( BaseModeFlag || aio_pstBlock -> MbPartPredMode[0] != INTRA_16x16 ){
			Current_residu -> Cbp = read_me_svc(ai_pcData, position, aio_pstBlock -> MbPartPredMode[0],Current_residu, iCurrMbAddr, ai_pstSlice, iMb_x);

			if ( (Current_residu -> Cbp & 15) && Pps -> transform_8x8_mode_flag && (BaseModeFlag || (!IS_I(Current_residu -> MbType) &&
				noSubMbPartSizeLessThan8x8 && ( Current_residu -> MbType == B_direct || direct_8x8_inference_flag))) && 
				getNbits(ai_pcData, position, 1)){
					Current_residu -> Transform8x8 = aio_pstBlock -> Transform8x8 = INTRA_8x8;
			}
		} 



		if ( Current_residu -> Cbp > 0 || (Current_residu -> MbType == INTRA_16x16)) {
			int mb_qp_delta = read_se(ai_pcData, position);

			residual(ai_pcData, position, Current_residu, vlc, aio_tiNon_zero_count_cache);

			//In case of cbp is equal to zéro, we check if there is a DC level 
			if (Current_residu -> Cbp == 0 && aio_tiNon_zero_count_cache[0] != 0){
				Current_residu -> Cbp = 15;
			}

			if ( Current_residu -> MbType == INTRA_16x16 && !(Current_residu -> Cbp & 15) && (Current_residu -> Cbp & 0x30) && aio_tiNon_zero_count_cache[0]){
				Current_residu -> Cbp += 15;
			}

#ifdef TI_OPTIM
			*last_QP = Current_residu -> Qp = divide(*last_QP + mb_qp_delta + 52, 52) >> 8 ;
#else
			*last_QP = Current_residu -> Qp = (*last_QP + mb_qp_delta + 52) % 52;
#endif

		}else { 
Example #12
0
/**
   This function permits to decode from the bitstream the Sequence Parameter Set NAL unit. 
   All the parameters decoded will be stored in the sps structure.
   
   @param data The NAL unit.
   @param position The current position in the NAL.
   @param NalBytesInNalunit The sizes of the NAL unit in bytes.
   @param sps The sps structure which contains all parameters decoded in this NAL.
   */
void seq_parameter_set_data ( unsigned char *data, int *position,  SPS *pt_sps){
    
	
	
	int     i = 0 ;
	
	if( pt_sps -> profile_idc  ==  100  || pt_sps ->  profile_idc  ==  110  ||	
		pt_sps -> profile_idc  ==  122  || pt_sps ->  profile_idc  ==  244  ||
		pt_sps -> profile_idc  ==  44 ||  pt_sps ->  profile_idc  ==  83 ||	pt_sps -> profile_idc  ==  86 ) {
		pt_sps -> chroma_format_idc = read_ue(data, position);
		if( pt_sps -> chroma_format_idc  ==  3 ){
			getNbits(data, position, 1);//separate_colour_plane_flag
		}
		pt_sps -> bit_depth_luma = read_ue(data, position) + 8; 
		pt_sps -> bit_depth_chroma = read_ue(data, position) + 8;
		getNbits(data, position, 1);//qpprime_y_zero_transform_bypass_flag
		decode_scaling_matrices(data, position, pt_sps,1, pt_sps -> scaling_matrix4	, pt_sps -> scaling_matrix8);
	}



    pt_sps -> log2_max_frame_num = read_ue(data, position) + 4;
    pt_sps -> pic_order_cnt_type = read_ue(data, position);

    if ( pt_sps -> pic_order_cnt_type == 0 ) {
        pt_sps -> log2_max_pic_order_cnt_lsb = read_ue(data, position) + 4;
    } else if ( pt_sps -> pic_order_cnt_type == 1 ) {
        pt_sps -> delta_pic_order_always_zero_flag = getNbits(data, position, 1);
        pt_sps -> offset_for_non_ref_pic = read_se(data, position); 
        pt_sps -> offset_for_top_to_bottom_field = read_se(data, position);
        pt_sps -> num_ref_frames_in_pic_order_cnt_cycle =  read_ue(data, position);

        for (; i < pt_sps -> num_ref_frames_in_pic_order_cnt_cycle ; i++ ) {
            pt_sps -> offset_for_ref_frame [i] = read_se(data, position);
        }
    }

    pt_sps -> num_ref_frames = read_ue(data, position);// 
    getNbits(data, position, 1);//gaps_in_frame_num_value_allowed_flag = 
    pt_sps -> pic_width_in_mbs = read_ue(data, position) + 1;
    pt_sps -> pic_height_in_map_units = read_ue(data, position) + 1;
    pt_sps -> frame_mbs_only_flag = getNbits(data, position, 1);
	pt_sps -> PicSizeInMbs =  pt_sps -> pic_width_in_mbs * pt_sps -> pic_height_in_map_units;

    if ( !pt_sps -> frame_mbs_only_flag ) {
        pt_sps -> MbAdaptiveFrameFieldFlag = getNbits(data, position, 1);
    }
	
	//To initialize the number of decoded frame before displaying.
	get_max_dpb(pt_sps);

    pt_sps -> direct_8x8_inference_flag = getNbits(data, position, 1);

    if ( getNbits(data, position, 1)) {//frame_cropping_flag 
        pt_sps -> CropLeft = (read_ue(data, position)) << 1;//frame_crop_left_offset = 
        pt_sps -> CropRight = (read_ue(data, position)) << 1;//frame_crop_right_offset = 
        pt_sps -> CropTop = (read_ue(data, position)) << 1;//frame_crop_top_offset = 
        pt_sps -> CropBottom = (read_ue(data, position)) << 1;//frame_crop_bottom_offset = 
    }
  
	if ( getNbits(data, position, 1) ) {
        vui_parameters(data, position, pt_sps);
	}
}
Example #13
0
/**
   This function permits to get from the NAL unit additional parameters. 
   VUI parameters are not required for constructing the luma and chroma samples by teh decoding process.
   
   @param data The NAL unit.
   @param position The current position in the NAL.
   */
void vui_parameters ( unsigned char *data, int *position, SPS *sps )
{

    int    overscan_info_present_flag ;
    int    video_signal_type_present_flag ;
    int    bitstream_restriction_flag ;


    int aspect_ratio_info_present_flag = getNbits(data, position, 1);
    if ( aspect_ratio_info_present_flag ) {
       int  aspect_ratio_idc = getNbits(data, position, 8);
        if ( aspect_ratio_idc == Extended_SAR ) {
            getNbits(data, position, 16);//sar_width = 
            getNbits(data, position, 16);// sar_height = 
        }
    }
    //scanner dans ffmpeg mais pas pris en compte
    overscan_info_present_flag = getNbits(data, position, 1);
    if ( overscan_info_present_flag ) 
        getNbits(data, position, 1);// overscan_appropriate_flag =

    video_signal_type_present_flag = getNbits(data, position, 1);
    if ( video_signal_type_present_flag ) {
        getNbits(data, position, 3);//video_format =
        getNbits(data, position, 1);// video_full_range_flag =
        if (getNbits(data, position, 1)) {
           getNbits(data, position, 8);// colour_primaries = 
           getNbits(data, position, 8);// transfer_characteristics =
           getNbits(data, position, 8);//  matrix_coefficients = 
        }
    }

    if (getNbits(data, position, 1)) {
        read_ue(data, position);//chroma_sample_loc_type_top_field =
        read_ue(data, position);// chroma_sample_loc_type_bottom_field =
    }


    //******************************************
    if (getNbits(data, position, 1)) {
       get32bits(data, position);// num_units_in_tick = 
       get32bits(data, position);//time_scale = 
       getNbits(data, position, 1);// fixed_frame_rate_flag =
    }


    sps -> nal_hrd_parameters_present_flag = getNbits(data, position, 1);
    if ( sps -> nal_hrd_parameters_present_flag ) 
        hrd_parameters(data, position,sps);

    sps -> vlc_hrd_parameters_present_flag = getNbits(data, position, 1);
    if ( sps -> vlc_hrd_parameters_present_flag ) 
        hrd_parameters(data, position,sps);

    //scanner dans ffmpeg mais pas pris en compte
    if ( sps -> nal_hrd_parameters_present_flag ||  sps -> vlc_hrd_parameters_present_flag ) 
        getNbits(data, position, 1);//low_delay_hrd_flag = 

    //********************************************
    sps -> pic_present_flag = getNbits(data, position, 1);//  =
    bitstream_restriction_flag = getNbits(data, position, 1);
    if ( bitstream_restriction_flag ) {
        //scanner dans ffmpeg mais pas pris en compte
        getNbits(data, position, 1);// motion_vectors_over_pic_boundaries_flag =
        read_ue(data, position);//max_bytes_per_pic_denom =
        read_ue(data, position);//max_bits_per_mb_denom = 
        read_ue(data, position);//log2_max_mv_length_horizontal = 
        read_ue(data, position);//log2_max_mv_length_vertical =
        //******************************************
        read_ue(data, position);//num_reorder_frames = 
        read_ue(data, position);//max_dec_frame_buffering =
    }
}