- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Dear all,
I try to write a very simple example of the sample_encode. Reading the same YUV file, NV12, using the same parameters. But after m_mfxSession.SyncOperation( encSync, MSDK_WAIT_INTERVAL); the mfxBitstream isn't updated.
sample_encode return and sync after the first 5 calls to m_pmfxENC->EncodeFrameAsync(NULL, &frameSurface1, &bitStream, &encSync); in sample encode and in my program:
0, 0x400 0, 0x400
-10, 0xC00 -10, 0xC02
0, 0x1000 0, 0x1003
0, 0x1400 0, 0x1404
0, 0x1800 0, 0x1805
DataLength isn't filled after the first call in my program. So sync seems to be the problem.
#include "stdafx.h"
#include "erzeugen.h"
//#include"GdiplusEnv.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
// Das einzige Anwendungsobjekt
CWinApp theApp;
using namespace std;
// Einstellungen - Verzeichnisse - header....
#include "mfxcommon.h"
#include "mfxmvc.h"
#include "mfxvideo.h"
#include "mfxvp8.h"
#include "mfxvideo++.h"
#include "mfxplugin.h"
#include "mfxplugin++.h"
#define IMG_WIDTH 1024
#define IMG_HEIGHT 1224
#define MSDK_ALIGN16(value) (((value + 15) >> 4) << 4) // round up to a multiple of 16
#define MSDK_ALIGN32(value) (((value + 31) >> 5) << 5) // round up to a multiple of 32
#define MSDK_DEC_WAIT_INTERVAL 60000
#define MSDK_ENC_WAIT_INTERVAL 10000
#define MSDK_VPP_WAIT_INTERVAL 60000
#define MSDK_WAIT_INTERVAL MSDK_DEC_WAIT_INTERVAL+3*MSDK_VPP_WAIT_INTERVAL+MSDK_ENC_WAIT_INTERVAL // an estimate for the longest pipeline we have in samples
#pragma comment(lib, "libmfx.lib")
// Linker - Eingabe - Standard Bib ingnorieren -> msvcrt.lib;msvcrtd.lib;libcmt.lib
class CSmplBitstreamWriter
{
public :
CSmplBitstreamWriter();
virtual ~CSmplBitstreamWriter();
virtual mfxStatus Init(const wchar_t *strFileName);
virtual mfxStatus WriteNextFrame(mfxBitstream *pMfxBitstream, bool isPrint = true);
virtual void Close();
mfxU32 m_nProcessedFramesNum;
protected:
HANDLE m_fSource;
bool m_bInited;
};
CSmplBitstreamWriter::CSmplBitstreamWriter()
{
m_fSource = INVALID_HANDLE_VALUE;
m_bInited = false;
m_nProcessedFramesNum = 0;
}
CSmplBitstreamWriter::~CSmplBitstreamWriter()
{
Close();
}
void CSmplBitstreamWriter::Close()
{
if( m_fSource != INVALID_HANDLE_VALUE )
{
CloseHandle(m_fSource);
m_fSource = INVALID_HANDLE_VALUE;
}
m_bInited = false;
m_nProcessedFramesNum = 0;
}
mfxStatus CSmplBitstreamWriter::Init(const wchar_t *strFileName)
{
Close();
//init file to write encoded data
m_fSource= CreateFile( strFileName, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL, NULL);
//set init state to true in case of success
m_bInited = true;
return MFX_ERR_NONE;
}
mfxStatus CSmplBitstreamWriter::WriteNextFrame(mfxBitstream *pMfxBitstream, bool isPrint)
{
// check if writer is initialized
DWORD nBytesWritten = 0;
WriteFile( m_fSource, pMfxBitstream->Data + pMfxBitstream->DataOffset, pMfxBitstream->DataLength, &nBytesWritten, NULL);
//nBytesWritten = (mfxU32)fwrite(pMfxBitstream->Data + pMfxBitstream->DataOffset, 1, pMfxBitstream->DataLength, m_fSource);
//MSDK_CHECK_NOT_EQUAL(nBytesWritten, pMfxBitstream->DataLength, MFX_ERR_UNDEFINED_BEHAVIOR);
// mark that we don't need bit stream data any more
pMfxBitstream->DataLength = 0;
m_nProcessedFramesNum++;
// print encoding progress to console every certain number of frames (not to affect performance too much)
if (isPrint && (1 == m_nProcessedFramesNum || (0 == (m_nProcessedFramesNum % 100))))
{
//msdk_printf(MSDK_STRING("Frame number: %u\r"), m_nProcessedFramesNum);
}
return MFX_ERR_NONE;
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
HMODULE hModule = ::GetModuleHandle(NULL);
if (hModule == NULL)
return -1;
if (!AfxWinInit(hModule, NULL, ::GetCommandLine(), 0))
return -2;
mfxVideoParam m_mfxEncParams;
mfxVideoParam m_mfxVppParams;
memset( &m_mfxEncParams, 0, sizeof(m_mfxEncParams));
memset( &m_mfxVppParams, 0, sizeof(m_mfxVppParams));
m_mfxEncParams.mfx.CodecId= MFX_CODEC_AVC;
m_mfxEncParams.mfx.TargetUsage= 4; // trade-off between quality and speed
m_mfxEncParams.mfx.TargetKbps= 16960; // in Kbps
m_mfxEncParams.mfx.RateControlMethod= 1;
m_mfxEncParams.mfx.FrameInfo.FrameRateExtN= 30;
m_mfxEncParams.mfx.FrameInfo.FrameRateExtD= 1;
m_mfxEncParams.mfx.EncodedOrder= 0; // binary flag, 0 signals encoder to take frames in display order
m_mfxEncParams.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
m_mfxEncParams.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
m_mfxEncParams.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
m_mfxEncParams.mfx.FrameInfo.PicStruct = 2;
// set frame size and crops
// width must be a multiple of 16
// height must be a multiple of 16 in case of frame picture and a multiple of 32 in case of field picture
m_mfxEncParams.mfx.FrameInfo.Width = MSDK_ALIGN16( IMG_WIDTH);
m_mfxEncParams.mfx.FrameInfo.Height = (MFX_PICSTRUCT_PROGRESSIVE == m_mfxEncParams.mfx.FrameInfo.PicStruct)?
MSDK_ALIGN16(IMG_HEIGHT) : MSDK_ALIGN32(IMG_HEIGHT);
m_mfxEncParams.mfx.FrameInfo.CropX = 0;
m_mfxEncParams.mfx.FrameInfo.CropY = 0;
m_mfxEncParams.mfx.FrameInfo.CropW = IMG_WIDTH;
m_mfxEncParams.mfx.FrameInfo.CropH = IMG_HEIGHT;
m_mfxEncParams.AsyncDepth= 4;
// Vpp?
m_mfxVppParams.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY | MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
m_mfxVppParams.vpp.In.FourCC = MFX_FOURCC_NV12;
m_mfxVppParams.vpp.In.PicStruct = 2;
m_mfxVppParams.vpp.In.FrameRateExtN= 30;
m_mfxVppParams.vpp.In.FrameRateExtD= 1;
mfxStatus sts = MFX_ERR_NONE;
mfxVersion min_version;
mfxVersion version; // real API version with which library is initialized
memset( &min_version, 0, sizeof(min_version));
// we set version to 1.0 and later we will query actual version of the library which will got leaded
min_version.Major = 1;
min_version.Minor = 0;
MFXVideoSession m_mfxSession;
// create a session for the second vpp and encode
sts= m_mfxSession.Init( MFX_IMPL_SOFTWARE, &min_version);
MFXQueryVersion(m_mfxSession , &version);
MFXVideoENCODE *m_pmfxENC = new MFXVideoENCODE(m_mfxSession);
m_pmfxENC->Close();
sts= m_pmfxENC->Init(&m_mfxEncParams);
CSmplBitstreamWriter *pWriter = new CSmplBitstreamWriter;
pWriter->Init( L"test.mp4");
mfxBitstream bitStream;
memset( &bitStream, 0, sizeof(bitStream));
bitStream.Data= (mfxU8*)malloc( IMG_WIDTH*IMG_HEIGHT*4);
bitStream.MaxLength= IMG_WIDTH*IMG_HEIGHT*4;
bitStream.PicStruct= 2;
bitStream.FrameType= 17089;
mfxSyncPoint encSync;
memset( &encSync, 0, sizeof(encSync));
mfxFrameSurface1 frameSurface1;
mfxFrameSurface1 frameSurface2;
memset( &frameSurface1, 0, sizeof(frameSurface1));
memset( &frameSurface2, 0, sizeof(frameSurface2));
frameSurface1.Info.FourCC= MFX_FOURCC_NV12;
frameSurface1.Info.Width= 1024;
frameSurface1.Info.Height= 1248;
frameSurface1.Info.CropX= 0;
frameSurface1.Info.CropY= 0;
frameSurface1.Info.CropW= 1024;
frameSurface1.Info.CropH= 1224;
frameSurface1.Info.PicStruct = 2;
frameSurface1.Info.FrameRateExtN= 30;
frameSurface1.Info.FrameRateExtD= 1;
frameSurface1.Info.ChromaFormat= MFX_CHROMAFORMAT_YUV420;
// Datei einlesen
// Datei ist 1024x1224, keine Padbytes
mfxU8* yptr1= (mfxU8*)malloc( 1024*1224);
mfxU8* uvptr1= (mfxU8*)malloc( 1024*1224/2);
mfxU8* yptr2= (mfxU8*)malloc( 1024*1224);
mfxU8* uvptr2= (mfxU8*)malloc( 1024*1224/2);
BOOL usefirst= TRUE;
frameSurface1.Data.Y= (mfxU8*)yptr1;
frameSurface1.Data.UV= (mfxU8*)uvptr1;
frameSurface1.Data.Pitch= 1024;
frameSurface1.Data.PitchLow= 1024;
memcpy( &frameSurface2, &frameSurface1, sizeof(frameSurface1));
frameSurface2.Data.Y= (mfxU8*)yptr2;
frameSurface2.Data.UV= (mfxU8*)uvptr2;
int count= 0;
HANDLE hFile= CreateFile( L"test.yuv", GENERIC_READ, 0, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL);
if( hFile != INVALID_HANDLE_VALUE )
{
DWORD dwRead1, dwRead2;
if( frameSurface1.Data.Locked == 0 )
{
ReadFile( hFile, yptr1, 1024*1224, &dwRead1, NULL);
ReadFile( hFile, uvptr1, 1024*1224/2, &dwRead2, NULL);
}
else
{
ReadFile( hFile, yptr2, 1024*1224, &dwRead1, NULL);
ReadFile( hFile, uvptr2, 1024*1224/2, &dwRead2, NULL);
}
if( dwRead1 == (1024*1224) && dwRead2 == (1024*1224/2) )
{
do
{
count++;
encSync= 0;
sts = MFX_ERR_NONE;
if( frameSurface1.Data.Locked == 0 )
{
sts= m_pmfxENC->EncodeFrameAsync(NULL, &frameSurface1, &bitStream, &encSync);
frameSurface2.Data.Locked= 0;
}
else
{
sts= m_pmfxENC->EncodeFrameAsync(NULL, &frameSurface2, &bitStream, &encSync);
frameSurface1.Data.Locked= 0;
}
m_mfxSession.DoWork();
m_mfxSession.SyncOperation( encSync, MSDK_WAIT_INTERVAL);
//MFXVideoCORE_SyncOperation(m_mfxSession, encSync, MSDK_WAIT_INTERVAL);
if( bitStream.DataLength > 0 )
sts= MFX_ERR_NONE;
sts= MFX_ERR_NONE;
if( frameSurface1.Data.Locked == 0 )
{
ReadFile( hFile, yptr1, 1024*1224, &dwRead1, NULL);
ReadFile( hFile, uvptr1, 1024*1224/2, &dwRead2, NULL);
}
else
{
ReadFile( hFile, yptr2, 1024*1224, &dwRead1, NULL);
ReadFile( hFile, uvptr2, 1024*1224/2, &dwRead2, NULL);
}
} while( dwRead1 == (1024*1224) && dwRead2 == (1024*1224/2) );
}
CloseHandle( hFile);
}
// aufräumen
free( bitStream.Data);
free( yptr1);
free( uvptr1);
free( yptr2);
free( uvptr2);
delete pWriter;
delete m_pmfxENC;
return 0;
}
Many thanks for your help
Link Copied
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
The YUV buffers must be large enough for the uncropped frame size.
Changed the mallocs to 1024*1248 and 1024*1248/2 and it works.
- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page