📄 umc_avs_dec_bit_stream.cpp
字号:
/*
//
// INTEL CORPORATION PROPRIETARY INFORMATION
// This software is supplied under the terms of a license agreement or
// nondisclosure agreement with Intel Corporation and may not be copied
// or disclosed except in accordance with the terms of that agreement.
// Copyright (c) 2007 Intel Corporation. All Rights Reserved.
//
//
*/
#include "umc_defs.h"
#if defined(UMC_ENABLE_AVS_VIDEO_DECODER)
#include "umc_avs_dec_bit_stream.h"
#include "umc_avs_sequence_header.h"
#include "umc_avs_picture_header.h"
#include "umc_avs_slice_header.h"
namespace UMC
{
void DecodePicHeader(AVS_BIT_STREAM_CONTEXT *pCtx,
AVS_SEQUENCE_HEADER *pSeqHeader,
AVS_PICTURE_HEADER *pPicHeader)
{
// reset header
memset(pPicHeader, 0, sizeof(AVS_PICTURE_HEADER));
// read the start code
SkipBits(pCtx, 24);
// get picture type
pPicHeader->picture_start_code = GetBits(pCtx, 8);
// read information about I frame
if (I_PICTURE_START_CODE == pPicHeader->picture_start_code)
{
pPicHeader->PictureType = AVS_I_PICTURE;
pPicHeader->bbv_delay = GetBits(pCtx, 16);
pPicHeader->time_code_flag = GetBit(pCtx);
if (pPicHeader->time_code_flag)
pPicHeader->time_code = GetBits(pCtx, 24);
// NOTE: it is absent in standard, but
// reference code has the following 1 bit skipping
SkipBits(pCtx, 1);
pPicHeader->picture_distance = GetBits(pCtx, 8);
if (pSeqHeader->low_delay)
pPicHeader->bbv_check_times = GetUE(pCtx);
pPicHeader->progressive_frame = GetBit(pCtx);
if (0 == pPicHeader->progressive_frame)
pPicHeader->picture_structure = GetBit(pCtx);
else
pPicHeader->picture_structure = 1;
pPicHeader->top_field_first = GetBit(pCtx);
pPicHeader->repeat_first_field = GetBit(pCtx);
pPicHeader->fixed_picture_qp = GetBit(pCtx);
pPicHeader->picture_qp = GetBits(pCtx, 6);
if ((0 == pPicHeader->progressive_frame) &&
(0 == pPicHeader->picture_structure))
pPicHeader->skip_mode_flag = GetBit(pCtx);
SkipBits(pCtx, 4);
pPicHeader->loop_filter_disable = GetBit(pCtx);
if (0 == pPicHeader->loop_filter_disable)
{
pPicHeader->loop_filter_parameter_flag = GetBit(pCtx);
if (pPicHeader->loop_filter_parameter_flag)
{
pPicHeader->alpha_c_offset = GetSE(pCtx);
pPicHeader->beta_offset = GetSE(pCtx);
}
}
}
// read information about P,B frame
else
{
pPicHeader->bbv_delay = GetBits(pCtx, 16);
pPicHeader->picture_coding_type = GetBits(pCtx, 2);
pPicHeader->PictureType = (1 == pPicHeader->picture_coding_type) ? (AVS_P_PICTURE) : (AVS_B_PICTURE);
pPicHeader->picture_distance = GetBits(pCtx, 8);
if (pSeqHeader->low_delay)
pPicHeader->bbv_check_times = GetUE(pCtx);
pPicHeader->progressive_frame = GetBit(pCtx);
if (0 == pPicHeader->progressive_frame)
{
pPicHeader->picture_structure = GetBit(pCtx);
if (0 == pPicHeader->picture_structure)
pPicHeader->advanced_pred_mode_disable = GetBit(pCtx);
}
else
pPicHeader->picture_structure = 1;
pPicHeader->top_field_first = GetBit(pCtx);
pPicHeader->repeat_first_field = GetBit(pCtx);
pPicHeader->fixed_picture_qp = GetBit(pCtx);
pPicHeader->picture_qp = GetBits(pCtx, 6);
if ((AVS_P_PICTURE == pPicHeader->PictureType) ||
(0 == pPicHeader->picture_structure))
pPicHeader->picture_reference_flag = GetBit(pCtx);
pPicHeader->no_forward_reference_flag = GetBit(pCtx);
SkipBits(pCtx, 3);
pPicHeader->skip_mode_flag = GetBit(pCtx);
pPicHeader->loop_filter_disable = GetBit(pCtx);
if (0 == pPicHeader->loop_filter_disable)
{
pPicHeader->loop_filter_parameter_flag = GetBit(pCtx);
if (pPicHeader->loop_filter_parameter_flag)
{
pPicHeader->alpha_c_offset = GetSE(pCtx);
pPicHeader->beta_offset = GetSE(pCtx);
}
}
}
} // void DecodePicHeader(AVS_BIT_STREAM_CONTEXT *pCtx,
void DecodeSlcHeader(AVS_BIT_STREAM_CONTEXT *pCtx,
AVS_SEQUENCE_HEADER *pSeqHeader,
AVS_PICTURE_HEADER *pPicHeader,
AVS_SLICE_HEADER *pSlcHeader)
{
Ipp32s MbRow, MbIndex, MbWidth, MbHeight;
// reset header
memset(pSlcHeader, 0, sizeof(AVS_SLICE_HEADER));
// read the start code
SkipBits(pCtx, 24);
// read information
pSlcHeader->slice_vertical_position = GetBits(pCtx, 8);
if (2800 < pSeqHeader->vertical_size)
pSlcHeader->slice_vertical_position_extension = GetBits(pCtx, 3);
if (0 == pPicHeader->fixed_picture_qp)
{
pSlcHeader->fixed_slice_qp = GetBit(pCtx);
pSlcHeader->slice_qp = GetBits(pCtx, 6);
}
// calculate frame dimensions
MbWidth = (pSeqHeader->horizontal_size + 15) / 16;
if (pPicHeader->picture_structure)
MbHeight = ((pSeqHeader->vertical_size + 15) / 16);
else
MbHeight = 2 * ((pSeqHeader->vertical_size + 31) / 32);
// calculate the slice position
MbRow = pSlcHeader->slice_vertical_position;
if (2800 < pSeqHeader->vertical_size)
MbRow += (pSlcHeader->slice_vertical_position_extension << 7);
MbIndex = MbRow * MbWidth;
pSlcHeader->first_mb = MbIndex;
// correct first mb number when the second field is decoded
if ((0 == pPicHeader->picture_structure) &&
(MbWidth * MbHeight / 2 <= MbIndex))
{
pSlcHeader->first_mb -= MbWidth * MbHeight / 2;
pSlcHeader->isSecondField = 1;
}
if (AVS_I_PICTURE != pPicHeader->PictureType)
{
pSlcHeader->slice_weighting_flag = GetBit(pCtx);
if (pSlcHeader->slice_weighting_flag)
{
Ipp32s i, NumberOfReferenceFwd, NumberOfReferenceBwd;
// calculate number of references
NumberOfReferenceFwd = 0;
NumberOfReferenceBwd = 0;
// second field of I frame is always P field
if (I_PICTURE_START_CODE == pPicHeader->picture_start_code)
{
NumberOfReferenceFwd = 1;
}
else if (AVS_P_PICTURE == pPicHeader->PictureType)
{
if (pPicHeader->picture_structure)
NumberOfReferenceFwd = 2;
else
NumberOfReferenceFwd = 4;
}
else
{
if (pPicHeader->picture_structure)
{
NumberOfReferenceFwd = 1;
NumberOfReferenceBwd = 1;
}
else
{
NumberOfReferenceFwd = 2;
NumberOfReferenceBwd = 2;
}
}
// read forward weighting parameters
for (i = 0; i < NumberOfReferenceFwd; i += 1)
{
pSlcHeader->luma_scale[AVS_FORWARD][i] = GetBits(pCtx, 8);
pSlcHeader->luma_shift[AVS_FORWARD][i] = GetSignedBits(pCtx, 8);
SkipBits(pCtx, 1);
pSlcHeader->chroma_scale[AVS_FORWARD][i] = GetBits(pCtx, 8);
pSlcHeader->chroma_shift[AVS_FORWARD][i] = GetSignedBits(pCtx, 8);
SkipBits(pCtx, 1);
}
// read backward weighting parameters
for (i = 0; i < NumberOfReferenceBwd; i += 1)
{
pSlcHeader->luma_scale[AVS_BACKWARD][i] = GetBits(pCtx, 8);
pSlcHeader->luma_shift[AVS_BACKWARD][i] = GetSignedBits(pCtx, 8);
SkipBits(pCtx, 1);
pSlcHeader->chroma_scale[AVS_BACKWARD][i] = GetBits(pCtx, 8);
pSlcHeader->chroma_shift[AVS_BACKWARD][i] = GetSignedBits(pCtx, 8);
SkipBits(pCtx, 1);
}
pSlcHeader->mb_weighting_flag = GetBit(pCtx);
}
}
} // void DecodeSlcHeader(AVS_BIT_STREAM_CONTEXT *pCtx,
Ipp32s GetFieldNum(Ipp32u *pSlcData,
AVS_SEQUENCE_HEADER *pSeqHeader,
AVS_PICTURE_HEADER *pPicHeader)
{
AVS_BIT_STREAM_CONTEXT ctx;
Ipp32u slice_vertical_position;
Ipp32u slice_vertical_position_extension;
Ipp32u MbHeight, MbRow;
// this is a frame, there are no fields
if (pPicHeader->picture_structure)
return 0;
ctx.src = pSlcData;
ctx.offset = 31;
// read the start code
SkipBits(&ctx, 24);
// read information
slice_vertical_position = GetBits(&ctx, 8);
if (2800 < pSeqHeader->vertical_size)
slice_vertical_position_extension = GetBits(&ctx, 3);
else
slice_vertical_position_extension = 0;
// calculate frame dimensions
if (pPicHeader->picture_structure)
MbHeight = ((pSeqHeader->vertical_size + 15) / 16);
else
MbHeight = 2 * ((pSeqHeader->vertical_size + 31) / 32);
// calculate the slice position
MbRow = slice_vertical_position;
if (2800 < pSeqHeader->vertical_size)
MbRow += (slice_vertical_position_extension << 7);
if (MbHeight / 2 <= MbRow)
return 1;
else
return 0;
} // Ipp32s GetFieldNum(Ipp32u *pSlcData,
} // namespace UMC
#endif // #if defined(UMC_ENABLE_AVS_VIDEO_DECODER)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -