📄 umc_h264_enc_cpb.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) 2004 - 2005 Intel Corporation. All Rights Reserved.#include "umc_h264_video_encoder.h"#include "umc_h264_enc_cpb.h"#include "umc_h264_tables.h"using namespace UMC_H264_ENCODER;namespace UMC{ IppStatus ippiExpandPlane_H264 (Ipp8u *StartPtr, Ipp32u uFrameWidth, Ipp32u uFrameHeight, Ipp32u uPitch, Ipp32u uPels, IppvcFrameFieldFlag uFrameFieldFlag) { Ipp32u i; Ipp8u *pSrcDst; /* check error(s) */ if ((uFrameHeight & 1) || (2 > uFrameHeight)) return ippStsSizeErr; if (0 == uFrameWidth) return ippStsSizeErr; if (0 == uPels) return ippStsNoErr; switch (uFrameFieldFlag) { case IPPVC_FRAME: /* Area (2) - sides */ pSrcDst = StartPtr; for (i = 0; i < uFrameHeight + uPels; i += 1) { /* set left site */ ippsSet_8u(pSrcDst[0], pSrcDst - uPels, uPels); /* set right site */ ippsSet_8u(pSrcDst[uFrameWidth - 1], pSrcDst + uFrameWidth, uPels); pSrcDst += uPitch; } break; case IPPVC_TOP_FIELD: /* Area (2) - sides */ pSrcDst = StartPtr; for (i = 0; i < (uFrameHeight>>1) + uPels; i++) { /* set left site */ ippsSet_8u(pSrcDst[0], pSrcDst - uPels, uPels); /* set right site */ ippsSet_8u(pSrcDst[uFrameWidth - 1], pSrcDst + uFrameWidth, uPels); pSrcDst += uPitch * 2; } break; case IPPVC_BOTTOM_FIELD: /* Area (2) - sides */ pSrcDst = StartPtr + uPitch; for (i = 0; i < (uFrameHeight>>1) + uPels; i++) { /* set left site */ ippsSet_8u(pSrcDst[0], pSrcDst - uPels, uPels); /* set right site */ ippsSet_8u(pSrcDst[uFrameWidth - 1], pSrcDst + uFrameWidth, uPels); pSrcDst += uPitch * 2; } break; default: return ippStsBadArgErr; } return ippStsNoErr; } /* IPPFUN(IppStatus, ippiExpandPlane_H264_8u_C1R, (Ipp8u *StartPtr, */ H264EncYUVBufferPadded::H264EncYUVBufferPadded() : m_pAllocatedBuffer(0) , m_allocatedSize(0) , m_pBuffer(0) , m_lumaSize(0, 0) , m_pitch(0) { } H264EncYUVBufferPadded::~H264EncYUVBufferPadded() { deallocate(); } void H264EncYUVBufferPadded::deallocate() { m_allocatedSize = 0; m_pBuffer = 0; clear(); m_lumaSize = sDimensions(0, 0); m_pitch = 0; if (m_pAllocatedBuffer) { ippsFree(m_pAllocatedBuffer); m_pAllocatedBuffer = 0; } } void H264EncYUVBufferPadded::conditionalDeallocate(const sDimensions &dim) { if (dim != lumaSize()) deallocate(); } Status H264EncYUVBufferPadded::ExchangePointers(H264EncYUVBufferPadded *src) { Ipp8u *temp = src->m_pAllocatedBuffer; src->m_pAllocatedBuffer = m_pAllocatedBuffer; m_pAllocatedBuffer = temp; temp = src->m_pYPlane; src->m_pYPlane = m_pYPlane; m_pYPlane = temp; temp = src->m_pUPlane; src->m_pUPlane = m_pUPlane; m_pUPlane = temp; temp = src->m_pVPlane; src->m_pVPlane = m_pVPlane; m_pVPlane = temp; return UMC_OK; } Status H264EncYUVBufferPadded::allocate(const sDimensions &lumaSize,Ipp32s) { Ipp32u newSize; Ipp32u nPitch; // Y plane dimensions better be even, so width/2 correctly gives U,V size // YUV_ALIGNMENT must be a power of 2. Since this is unlikely to change, // and since checking for a power of 2 is painful, let's just put a simple // VM_ASSERT here, that can be updated as needed for other powers of 2. nPitch = CalcPitchFromWidth(lumaSize.width); newSize = nPitch * (lumaSize.height + LUMA_PADDING * 2) + nPitch * (lumaSize.height / 2 + CHROMA_PADDING * 2); if (m_pAllocatedBuffer) ippsFree(m_pAllocatedBuffer); m_pAllocatedBuffer = (Ipp8u *) ippsMalloc_8u(MAX(1, newSize + DATA_ALIGN * 2)); if (!m_pAllocatedBuffer) { // Reset all our state variables deallocate(); return UMC_ALLOC; } m_allocatedSize = newSize; m_lumaSize = lumaSize; m_pitch = nPitch; m_pYPlane = align_pointer<Ipp8u *> (m_pAllocatedBuffer + LUMA_PADDING * (1 + nPitch), DATA_ALIGN); m_pUPlane = align_pointer<Ipp8u *> (m_pAllocatedBuffer + nPitch * (lumaSize.height + LUMA_PADDING * 2) + CHROMA_PADDING * (1 + nPitch), DATA_ALIGN); m_pVPlane = m_pUPlane + nPitch / 2; return UMC_OK; } Status H264EncYUVWorkSpace::allocate(const sDimensions &lumaSize,Ipp32s num_slices) { sDimensions paddedSize; // rounded up to an integral number of macroblocks paddedSize.width = (lumaSize.width + 15) & ~15; paddedSize.height = (lumaSize.height + 15) & ~15; clearState(); Status ps = H264EncYUVBufferPadded::allocate(paddedSize,num_slices); if (ps == UMC_OK) { m_macroBlockSize.width = paddedSize.width >> 4; m_macroBlockSize.height = paddedSize.height >> 4; } return ps; } void H264EncYUVWorkSpace::conditionalDeallocate(const sDimensions &dim) { sDimensions paddedSize; // rounded up to an integral number of macroblocks paddedSize.width = (dim.width + 15) & ~15; paddedSize.height = (dim.height + 15) & ~15; H264EncYUVBufferPadded::conditionalDeallocate(paddedSize); } void H264EncYUVWorkSpace::expand(bool is_field_flag, Ipp8u is_bottom_field) { IppvcFrameFieldFlag flag; if(!is_field_flag) { flag = IPPVC_FRAME; } else { if(!is_bottom_field) { flag = IPPVC_TOP_FIELD; } else { flag = IPPVC_BOTTOM_FIELD; } } if (!isExpanded()) { ippiExpandPlane_H264(m_pYPlane, lumaSize().width, lumaSize().height, pitch(), YUV_Y_PADDING, flag); ippiExpandPlane_H264(m_pVPlane, lumaSize().width >> 1, lumaSize().height >> 1, pitch(), YUV_UV_PADDING, flag); ippiExpandPlane_H264(m_pUPlane, lumaSize().width >> 1, lumaSize().height >> 1, pitch(), YUV_UV_PADDING, flag); } }H264EncoderFrame::H264EncoderFrame(): m_wasEncoded(false), m_bIsIDRPic(false), m_pParsedFrameData(0), m_paddedParsedFrameDataSize(sDimensions(0,0)), m_pRefPicList(0), m_num_slice_start(0), m_dFrameTime(-1.0), m_pAllocatedMBEncodeBuffer(NULL), m_pAllocatedMVBuffer(NULL), m_pAllocatedRefIdxBuffer(NULL), m_pAllocatedAIBuffer(NULL), m_pAllocatedNCBuffer(NULL) // NumCoeffs, m_pAllocatedMBDataBuffer(NULL), m_pAllocatedSliceDataBase(NULL), pMBOffsets (NULL), m_FrameNum(0){ m_pParsedFrameDataNew = NULL; m_isShortTermRef[0] = m_isShortTermRef[1] = false; m_isLongTermRef[0] = m_isLongTermRef[1] = false; m_FrameNumWrap = m_FrameNum = -1; m_LongTermFrameIdx = -1; m_RefPicListResetCount[0] = m_RefPicListResetCount[1] = 0; m_PicNum[0] = m_PicNum[1] = -1; m_LongTermPicNum[0] = m_PicNum[1] = -1;}H264EncoderFrame::H264EncoderFrame( Ipp32u , // pageoffset, Ipp32u width, Ipp32u height, Ipp32u , // wrap_around, Ipp32s num_slices, Status& // ctor_status ) : m_wasEncoded(false) , m_bIsIDRPic(false) , m_pParsedFrameData(0) , m_paddedParsedFrameDataSize(sDimensions(0,0)) , m_pRefPicList(0) , m_num_slice_start(0) , m_dFrameTime(-1.0) , m_sequence_number(0) , m_heightInMBs(0) , m_widthInMBs(0) , m_pAllocatedMBEncodeBuffer(NULL) , m_pAllocatedMVBuffer(NULL) , m_pAllocatedRefIdxBuffer(NULL) , m_pAllocatedAIBuffer(NULL) , m_pAllocatedNCBuffer(NULL) // NumCoeffs , m_pAllocatedMBDataBuffer(NULL) , m_pAllocatedSliceDataBase(NULL) , pMBOffsets (NULL) , m_FrameNum(0){ m_pParsedFrameDataNew = NULL; m_isShortTermRef[0] = m_isShortTermRef[1] = false; m_isLongTermRef[0] = m_isLongTermRef[1] = false; m_FrameNumWrap = m_FrameNum = -1; m_LongTermFrameIdx = -1; m_RefPicListResetCount[0] = m_RefPicListResetCount[1] = 0; m_PicNum[0] = m_PicNum[1] = -1; m_LongTermPicNum[0] = m_PicNum[1] = -1; sDimensions Size(width,height); allocate(Size,num_slices);}void H264EncoderFrame::deallocateParsedFrameData(){ if (m_pAllocatedMBEncodeBuffer) { H264_Free(m_pAllocatedMBEncodeBuffer); m_pAllocatedMBEncodeBuffer = NULL; } if (m_pAllocatedMVBuffer) { H264_Free(m_pAllocatedMVBuffer); m_pAllocatedMVBuffer = NULL; } if (m_pAllocatedRefIdxBuffer) { H264_Free(m_pAllocatedRefIdxBuffer); m_pAllocatedRefIdxBuffer = NULL; } if (m_pAllocatedAIBuffer) { H264_Free(m_pAllocatedAIBuffer); m_pAllocatedAIBuffer = NULL; } if (m_pAllocatedNCBuffer) { H264_Free(m_pAllocatedNCBuffer); m_pAllocatedNCBuffer = NULL; } if (m_pAllocatedMBDataBuffer) { H264_Free(m_pAllocatedMBDataBuffer); m_pAllocatedMBDataBuffer = NULL; } if (m_pAllocatedSliceDataBase) { H264_Free(m_pAllocatedSliceDataBase); m_pAllocatedSliceDataBase = NULL; } if (m_pParsedFrameData) { // Free the old buffer. ippsFree(m_pParsedFrameData); m_pParsedFrameData = 0; m_pRefPicList = 0; } // new structure(s) hold pointer if (m_pParsedFrameDataNew) { ippsFree(m_pParsedFrameDataNew); m_pParsedFrameDataNew = NULL; } m_paddedParsedFrameDataSize = sDimensions(0,0); if (pMBOffsets) { delete pMBOffsets; pMBOffsets = NULL; } pMVL0 = NULL; pMVL1 = NULL; pPred4DirectB = NULL; pPred4BiPred = NULL; pTempBuff4DirectB = NULL; pAIMode = NULL; pYNumCoeffs = NULL; pUNumCoeffs = NULL; pVNumCoeffs = NULL; pMBData = NULL; pMBEncodeBuffer = NULL; pDMVL0 = NULL; pDMVL1 = NULL;} // deallocateParsedFrameDataStatusH264EncoderFrame::allocateParsedFrameData(const sDimensions &size,Ipp32s num_slices){ Status ps = UMC_OK; sDimensions desiredPaddedSize; desiredPaddedSize.width = (size.width + 15) & ~15; desiredPaddedSize.height = (size.height + 15) & ~15; // If our buffer and internal pointers are already set up for this // image size, then there's nothing more to do. if (m_paddedParsedFrameDataSize != desiredPaddedSize) { // // Determine how much space we need // Ipp32u MB_Frame_Width = desiredPaddedSize.width >> 4; Ipp32u MB_Frame_Height = desiredPaddedSize.height >> 4; Ipp32u uMaxNumSlices = MAX_SLICE_NUM <0?MB_Frame_Width * MB_Frame_Height:MIN(MAX_SLICE_NUM,MB_Frame_Width * MB_Frame_Height); Ipp32u uRefPicListSize = uMaxNumSlices * sizeof(EncoderRefPicList); Ipp32u totalSize = Ipp32u( + uRefPicListSize + 7 + YUV_ALIGNMENT); deallocateParsedFrameData(); int len = MAX(1, totalSize); m_pParsedFrameData = ippsMalloc_8u(len); if (!m_pParsedFrameData) return UMC_FAILED_TO_ALLOCATE_BUFFER; ippsZero_8u(m_pParsedFrameData, len); // Reassign our internal pointers { m_paddedParsedFrameDataSize = desiredPaddedSize; Ipp8u *pAlignedParsedData; Ipp32u offset = 0; pAlignedParsedData = H264_ALIGN(m_pParsedFrameData, YUV_ALIGNMENT); // align to 8-byte boundary if (offset & 0x7) offset = (offset + 7) & ~7; m_pRefPicList = (EncoderRefPicList*)(pAlignedParsedData + offset); offset += uRefPicListSize; VM_ASSERT(offset <= totalSize); }#if 0 // allocate new MB structure(s) size_t nMBCount = (desiredPaddedSize.width>>4) * (desiredPaddedSize.height>>4); // allocate buffer int len = (sizeof(H264DecoderMacroblockMVs) + sizeof(H264DecoderMacroblockMVs) + sizeof(H264DecoderMacroblockRefIdxs) + sizeof(H264DecoderMacroblockRefIdxs) + sizeof(H264DecoderMacroblockGlobalInfo)) * nMBCount + 16 * 5; // allocate buffer m_pParsedFrameDataNew = ippsMalloc_8u(len); if (NULL == m_pParsedFrameDataNew) return UMC_FAILED_TO_ALLOCATE_BUFFER; ippsZero_8u(m_pParsedFrameDataNew, len); // set pointer(s) m_mbinfo.MV[0] = align_pointer<H264DecoderMacroblockMVs *> (m_pParsedFrameDataNew, ALIGN_VALUE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -