📄 umc_dv100_video_encoder.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) 2006-2007 Intel Corporation. All Rights Reserved.
//
*/
#include "umc_dv100_video_encoder.h"
#include "umc_dv100_enc_1080_60i_segment_reader.h"
#include "umc_dv100_enc_1080_50i_segment_reader.h"
#include "umc_dv100_enc_720_60p_segment_reader.h"
#include "umc_dv100_enc_segment_compressor.h"
#include "umc_dv_enc_segment_writer.h"
#include "umc_video_processing.h"
#include <ipps.h>
namespace UMC
{
enum
{
DV100_SYSTEM_720_WIDTH = 1280,
DV100_SYSTEM_1080_WIDTH = 1920,
DV100_SYSTEM_720_60P_WIDTH_DOWNSAMPLED = 960,
DV100_SYSTEM_720_HEIGHT = 720,
DV100_SYSTEM_1080_60I_WIDTH_DOWNSAMPLED = 1280,
DV100_SYSTEM_1080_50I_WIDTH_DOWNSAMPLED = 1440,
DV100_SYSTEM_1080_HEIGHT = 1080
};
DV100VideoEncoder::DV100VideoEncoder(void) :
m_DownsampledFrameBufferMID(0),
m_nSystem720_LastDecodedChannel(0)
{
}
DV100VideoEncoder::~DV100VideoEncoder(void)
{
Close();
}
Status DV100VideoEncoder::Init(BaseCodecParams* pBaseParams)
{
VideoEncoderParams *pParams = DynamicCast<VideoEncoderParams> (pBaseParams);
Ipp32s LumaDataSize;
if (pParams == NULL)
return UMC_ERR_NULL_PTR;
if (m_bIsInit)
Close();
//init Huffman Tables
//377 ENCODE_ELEMENT entries
//63 Ipp16s elements in TableMaxAmpOnRun table
//62 (ENCODE_ELEMENT*) entries for encode table
//4096 - reserved for alignment
newHuffmanTablesBuffer = ippsMalloc_8u(377 * 4 + 63 * 2 + 62 * 4 + 4096);
InitHuffmanTables(newHuffmanTablesBuffer);
if( !( (pParams->info.clip_info.width == DV100_SYSTEM_1080_WIDTH && pParams->info.clip_info.height == DV100_SYSTEM_1080_HEIGHT) ||
(pParams->info.clip_info.width == DV100_SYSTEM_720_WIDTH && pParams->info.clip_info.height == DV100_SYSTEM_720_HEIGHT) ||
(pParams->info.clip_info.width == 960 && pParams->info.clip_info.height == DV100_SYSTEM_720_HEIGHT) ||
(pParams->info.clip_info.width == 1280 && pParams->info.clip_info.height == DV100_SYSTEM_1080_HEIGHT)) ||
(pParams->info.clip_info.width == 1440 && pParams->info.clip_info.height == DV100_SYSTEM_1080_HEIGHT))
return UMC_ERR_NULL_PTR;
if( (pParams->info.clip_info.width == DV100_SYSTEM_720_WIDTH ) || ( 960 == pParams->info.clip_info.width))
{
//m_VideoFormat = mSystem720_60p;
m_nSystem720_LastDecodedChannel = 0;
if ((59.94 == pParams->info.framerate) || (60 == pParams->info.framerate) )
m_VideoFormat = mSystem720_60p;
else if (50 == pParams->info.framerate )
m_VideoFormat = mSystem720_50p;
else
return UMC_ERR_INVALID_PARAMS;
}
else
{
if(pParams->info.framerate == SYSTEM_1080_60I_FRAMERATE)
m_VideoFormat = mSystem1080_60i;
else if(pParams->info.framerate == SYSTEM_1080_50I_FRAMERATE)
m_VideoFormat = mSystem1080_50i;
else
return UMC_ERR_INVALID_PARAMS;
}
if(UMC_OK != BaseCodec::Init(pBaseParams))
return UMC_ERR_INIT;
m_Params = *pParams;
m_Params.info.stream_type = DIGITAL_VIDEO_HD;
m_iMaxI = ((mSystem1080_50i == m_VideoFormat) || (mSystem720_50p == m_VideoFormat)) ? 12 : 10;
// create DV segment writer
m_pDVWriter = new DVSegmentWriter;
if (NULL == m_pDVWriter)
return UMC_ERR_ALLOC ;
if (m_pDVWriter->InitWriter( (m_VideoFormat == mSystem1080_50i) ? 1 : 0, 0) )
return UMC_ERR_NOT_IMPLEMENTED;
// create segment compressor
m_pSCompressor = new DV100SegmentCompressor;
if (NULL == m_pSCompressor)
return UMC_ERR_ALLOC ;
if (m_pSCompressor->InitCompressor(8, m_pMemoryAllocator))
return UMC_ERR_FAILED;
switch(m_VideoFormat)
{
case mSystem1080_60i:
{
m_pSReader = new DV100_1080_60i_SegmentReader();
m_nDownsampledFrameWidth = DV100_SYSTEM_1080_60I_WIDTH_DOWNSAMPLED;
m_nEncodedFrameSize = 480000;
m_FrameTimeLength = 2.0/59.96;
}break;
case mSystem1080_50i:
{
m_pSReader = new DV100_1080_50i_SegmentReader();
m_nDownsampledFrameWidth = DV100_SYSTEM_1080_50I_WIDTH_DOWNSAMPLED;
m_nEncodedFrameSize = 576000;
m_FrameTimeLength = 1.0/25;
}break;
case mSystem720_60p:
{
m_pSReader = new DV100_720_60p_SegmentReader();
m_nDownsampledFrameWidth = DV100_SYSTEM_720_60P_WIDTH_DOWNSAMPLED;
m_nEncodedFrameSize = 240000;
m_FrameTimeLength = 1.0/59.96;
}break;
case mSystem720_50p:
{
m_pSReader = new DV100_720_60p_SegmentReader();
m_nDownsampledFrameWidth = DV100_SYSTEM_720_60P_WIDTH_DOWNSAMPLED;
m_nEncodedFrameSize = 288000;
m_FrameTimeLength = 1.0/50;
}break;
}
((DV100SegmentCompressor*)m_pSCompressor)->m_VideoFormat = m_VideoFormat;
if (NULL == m_pSReader)
return UMC_ERR_FAILED;
LumaDataSize = m_nDownsampledFrameWidth * pParams->info.clip_info.height;
if(UMC_OK != m_pMemoryAllocator->Alloc(&m_DownsampledFrameBufferMID, LumaDataSize*2, UMC_ALLOC_PERSISTENT))
return UMC_ERR_ALLOC;
m_DownsampledFrame.Init(m_nDownsampledFrameWidth, pParams->info.clip_info.height, YUV422);
m_PostProcessing = createVideoProcessing();
m_bIsInit = true;
return UMC_OK;
}
Status DV100VideoEncoder::Close()
{
Status Res = DVVideoEncoder::Close();
if (Res != UMC_OK)
return Res;
if(m_DownsampledFrameBufferMID)
m_pMemoryAllocator->DeallocateMem(m_DownsampledFrameBufferMID);
m_DownsampledFrameBufferMID = 0;
m_nSystem720_LastDecodedChannel = 0;
m_PostProcessing->Close();
m_PostProcessing = NULL;
BaseCodec::Close();
return UMC_OK;
}
Status DV100VideoEncoder::GetFrame(MediaData *pVideoDataIn, MediaData *pEncodedFrame)
{
Ipp8u Channel, DIFSeqNum, nChannelsInFrame, DIFSeqAbsOrder;
Ipp16s VSegmentNum;
DV_SEGMENT *lpDVSegment;
V_SEGMENT *lpVSegment;
Ipp32s LumaDataSize;
if (!m_bIsInit)
return UMC_ERR_NOT_INITIALIZED;
VideoData* pSrcFrame = DynamicCast<VideoData> (pVideoDataIn);
if (!pSrcFrame || !pEncodedFrame)
return UMC_ERR_NOT_ENOUGH_DATA;
if( pEncodedFrame->GetBufferSize() < m_nEncodedFrameSize )
return UMC_ERR_NOT_ENOUGH_BUFFER;
if ((m_VideoFormat == mSystem720_60p)|| (m_VideoFormat == mSystem720_50p))
nChannelsInFrame = 2;
else
nChannelsInFrame = 4;
m_pDVWriter->m_pDest = (Ipp8u *) pEncodedFrame->GetDataPointer();
LumaDataSize = m_nDownsampledFrameWidth * m_Params.info.clip_info.height;
Ipp8u *pDownsampledFrameBuffer = (Ipp8u*)m_pMemoryAllocator->Lock(m_DownsampledFrameBufferMID);
m_DownsampledFrame.SetPlanePointer(pDownsampledFrameBuffer, 0);
m_DownsampledFrame.SetPlanePointer(pDownsampledFrameBuffer+ LumaDataSize, 1);
m_DownsampledFrame.SetPlanePointer(pDownsampledFrameBuffer + LumaDataSize + LumaDataSize/2, 2);
m_DownsampledFrame.SetPlanePitch(m_nDownsampledFrameWidth, 0);
m_DownsampledFrame.SetPlanePitch(m_nDownsampledFrameWidth/2, 1);
m_DownsampledFrame.SetPlanePitch(m_nDownsampledFrameWidth/2, 2);
//m_VideoResizing.GetFrame(pSrcFrame, &m_DownsampledFrame);
m_PostProcessing->GetFrame(pSrcFrame, &m_DownsampledFrame);
m_pSReader->m_lpSourceFrame = &m_DownsampledFrame;
m_pSCompressor->LockWorkBuffers();
lpVSegment = &(m_pSCompressor->m_VSegment);
for(Channel=0; Channel<nChannelsInFrame; Channel++)
{
for (DIFSeqNum = 0; DIFSeqNum < m_iMaxI; DIFSeqNum++)
{
if( (m_VideoFormat == mSystem1080_50i) && (Channel > 0) && (DIFSeqNum == 11))
{
//Skip 12-th DIF sequence in 2, 3 and 4 channels
m_pDVWriter->m_pDest += 12000;
continue;
}
if( (m_VideoFormat == mSystem720_50p) && ((DIFSeqNum == 10) || (DIFSeqNum == 11)) )
{
//Skip 10, 11-th DIF sequence in channel
m_pDVWriter->m_pDest += 12000;
continue;
}
Ipp8u byte_STYPE = 0;
Ipp8u FSC = Channel%2;
Ipp8u FSP = 1 - (Channel/2);
if (mSystem1080_50i == m_VideoFormat)
byte_STYPE = 0xf4;
else if (mSystem1080_60i == m_VideoFormat)
byte_STYPE = 0xD4;
else if (mSystem720_50p == m_VideoFormat)
byte_STYPE = 0xf8;
else if (mSystem720_60p == m_VideoFormat)
byte_STYPE = 0xD8;
m_pDVWriter->StartDIFSequence(DIFSeqNum, FSC, FSP);
m_pDVWriter->m_pDest -= sizeof(DV_BLOCK);
m_pDVWriter->m_pDest[48] = 0x60;
m_pDVWriter->m_pDest[48 + 3] = byte_STYPE;
m_pDVWriter->m_pDest += sizeof(DV_BLOCK);
if ((m_VideoFormat == mSystem720_60p)|| (m_VideoFormat == mSystem720_50p))
//DIFSeqAbsOrder = (Ipp8u)( DIFSeqNum + m_iMaxI*(Channel+m_nSystem720_LastDecodedChannel) );
DIFSeqAbsOrder = (Ipp8u)( DIFSeqNum + 10*(Channel+m_nSystem720_LastDecodedChannel) );
else
DIFSeqAbsOrder = (Ipp8u)( DIFSeqNum + m_iMaxI*Channel );
for (VSegmentNum = 0; VSegmentNum < 27; VSegmentNum++)
{
m_pDVWriter->SetDVSegment(&lpDVSegment);
m_pSReader->ReadSegment(lpVSegment, DIFSeqAbsOrder, VSegmentNum);
m_pSCompressor->CompressSegment(lpDVSegment);
}
}
}
m_pSCompressor->UnlockWorkBuffers();
m_pMemoryAllocator->Unlock(m_DownsampledFrameBufferMID);
if ((m_VideoFormat == mSystem720_60p)|| (m_VideoFormat == mSystem720_50p))
{
if(m_nSystem720_LastDecodedChannel == 0)
m_nSystem720_LastDecodedChannel = 2;
else
m_nSystem720_LastDecodedChannel = 0;
}
pEncodedFrame->SetDataSize( m_nEncodedFrameSize );
pEncodedFrame->SetTime(pSrcFrame->GetTime(), pSrcFrame->GetTime() + m_FrameTimeLength);
return UMC_OK;
}
}//namespace UMC
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -