Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- int encoder_x264_init(Encoder_t *encoder, Image_t *image) {
- encoder->sps_data = NULL;
- encoder->sps_data_size = 0;
- encoder->pps_data = NULL;
- encoder->pps_data_size = 0;
- encoder->hwenc.sts = MFX_ERR_NONE;
- const mfxIMPL hwimpl[] = {MFX_IMPL_HARDWARE_ANY, MFX_IMPL_HARDWARE};;
- mfxVersion vers = {
- .Minor = 0,
- .Major = 1}; //Legacy support
- mfxU16 target_width = (image->width > 1920 ? 1920 : image->width);
- mfxU16 target_height = (image->height > 1080 ? 1080 : image->height);
- //Initialization of Intel Media SDK ENCODER session
- for(int i=0; i < sizeof(hwimpl)/sizeof(hwimpl[0]);i++)
- {
- encoder->hwenc.sts = MFXInit(hwimpl[i], &vers, &encoder->hwenc.ENCses);
- MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
- if(encoder->hwenc.sts == MFX_ERR_NONE)
- {
- MFXQueryVersion(encoder->hwenc.ENCses,&encoder->hwenc.ver);
- printf("Asked for version %d.%d.\n",vers.Major,vers.Minor);
- printf("SDK version loaded for the ENCODER session is %d.%d.\n",encoder->hwenc.ver.Major,encoder->hwenc.ver.Minor);
- break;
- }
- }
- //Initialization of VPP session for format conversion and potential scaling
- for(int i=0; i < sizeof(hwimpl)/sizeof(hwimpl[0]);i++)
- {
- encoder->hwenc.sts = MFXInit(hwimpl[i], &vers,&encoder->hwenc.VPPses);
- MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
- if(encoder->hwenc.sts == MFX_ERR_NONE)
- {
- MFXQueryVersion(encoder->hwenc.ENCses,&encoder->hwenc.ver);
- printf("SDK version loaded for the VPP session is %d.%d.\n",encoder->hwenc.ver.Major,encoder->hwenc.ver.Minor);
- break;
- }
- }
- //Initialization of encoder parameters
- memset(&encoder->hwenc.ENCParams,0,sizeof(encoder->hwenc.ENCParams));
- encoder->hwenc.ENCParams.mfx.CodecId = MFX_CODEC_AVC;
- encoder->hwenc.ENCParams.mfx.TargetUsage = MFX_TARGETUSAGE_BALANCED;
- encoder->hwenc.ENCParams.mfx.TargetKbps = 2000; //Investigation required
- encoder->hwenc.ENCParams.mfx.RateControlMethod = MFX_RATECONTROL_VBR;
- encoder->hwenc.ENCParams.mfx.FrameInfo.FrameRateExtN = 30;
- encoder->hwenc.ENCParams.mfx.FrameInfo.FrameRateExtD = 1;
- encoder->hwenc.ENCParams.mfx.FrameInfo.FourCC = MFX_FOURCC_NV12;
- encoder->hwenc.ENCParams.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
- encoder->hwenc.ENCParams.mfx.FrameInfo.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
- encoder->hwenc.ENCParams.mfx.FrameInfo.CropX = 0;
- encoder->hwenc.ENCParams.mfx.FrameInfo.CropY = 0;
- encoder->hwenc.ENCParams.mfx.FrameInfo.CropW = target_width;
- encoder->hwenc.ENCParams.mfx.FrameInfo.CropH = target_height;
- //Width is aligned as a multiple of 16
- encoder->hwenc.ENCParams.mfx.FrameInfo.Width = MSDK_ALIGN16(target_width);
- //Same applies for height unless it's a field picture so it is a multiple of 32
- encoder->hwenc.ENCParams.mfx.FrameInfo.Height = (MFX_PICSTRUCT_PROGRESSIVE == encoder->hwenc.ENCParams.mfx.FrameInfo.PicStruct)?
- MSDK_ALIGN16(target_height) : MSDK_ALIGN32(target_height);
- encoder->hwenc.ENCParams.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY;
- //Additional ENCODER configuration for low latency
- encoder->hwenc.ENCParams.AsyncDepth = 1;
- encoder->hwenc.ENCParams.mfx.GopRefDist = 1;//B-frames disabled
- mfxExtCodingOption extras;
- memset(&extras,0,sizeof(extras));
- extras.Header.BufferId = MFX_EXTBUFF_CODING_OPTION;
- extras.Header.BufferSz = sizeof(extras);
- extras.MaxDecFrameBuffering = 1;
- mfxExtBuffer *extrasBuf[1];
- extrasBuf[0] = (mfxExtBuffer*)&extras;
- encoder->hwenc.ENCParams.ExtParam = extrasBuf;
- encoder->hwenc.ENCParams.NumExtParam = 1;
- //Initialization of VPP parameters (input)
- memset(&encoder->hwenc.VPPParams,0,sizeof(encoder->hwenc.VPPParams));
- encoder->hwenc.VPPParams.vpp.In.FourCC = MFX_FOURCC_RGB4;
- encoder->hwenc.VPPParams.vpp.In.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
- encoder->hwenc.VPPParams.vpp.In.CropX = 0;
- encoder->hwenc.VPPParams.vpp.In.CropY = 0;
- encoder->hwenc.VPPParams.vpp.In.CropW = image->width;
- encoder->hwenc.VPPParams.vpp.In.CropH = image->height;
- encoder->hwenc.VPPParams.vpp.In.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
- encoder->hwenc.VPPParams.vpp.In.FrameRateExtN = 30;
- encoder->hwenc.VPPParams.vpp.In.FrameRateExtD = 1;
- //Width is aligned as a multiple of 16
- encoder->hwenc.VPPParams.vpp.In.Width = MSDK_ALIGN16(image->width);
- //Same applies for height unless it's a field picture so it is a multiple of 32
- encoder->hwenc.VPPParams.vpp.In.Height = (MFX_PICSTRUCT_PROGRESSIVE == encoder->hwenc.VPPParams.vpp.In.PicStruct) ?
- MSDK_ALIGN16(image->width) : MSDK_ALIGN32(image->height);
- //Initialization of VPP parameters (output)
- encoder->hwenc.VPPParams.vpp.Out.FourCC = MFX_FOURCC_NV12;
- encoder->hwenc.VPPParams.vpp.Out.ChromaFormat = MFX_CHROMAFORMAT_YUV420;
- encoder->hwenc.VPPParams.vpp.Out.CropX = 0;
- encoder->hwenc.VPPParams.vpp.Out.CropY = 0;
- encoder->hwenc.VPPParams.vpp.Out.CropW = target_width;
- encoder->hwenc.VPPParams.vpp.Out.CropH = target_height;
- encoder->hwenc.VPPParams.vpp.Out.PicStruct = MFX_PICSTRUCT_PROGRESSIVE;
- encoder->hwenc.VPPParams.vpp.Out.FrameRateExtN = 30;
- encoder->hwenc.VPPParams.vpp.Out.FrameRateExtD = 1;
- //Width is aligned as a multiple of 16
- encoder->hwenc.VPPParams.vpp.Out.Width = MSDK_ALIGN16(image->width);
- //Same applies for height unless it's a field picture so it is a multiple of 32
- encoder->hwenc.VPPParams.vpp.Out.Height = (MFX_PICSTRUCT_PROGRESSIVE == encoder->hwenc.VPPParams.vpp.Out.PicStruct) ?
- MSDK_ALIGN16(image->width) : MSDK_ALIGN32(image->height);
- encoder->hwenc.VPPParams.AsyncDepth = 1;
- encoder->hwenc.VPPParams.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY | MFX_IOPATTERN_OUT_SYSTEM_MEMORY;
- //Disabling VPP enabled by default ops
- mfxExtVPPDoNotUse dnu;
- memset(&dnu,0,sizeof(mfxExtVPPDoNotUse));
- dnu.Header.BufferId = MFX_EXTBUFF_VPP_DONOTUSE;
- dnu.Header.BufferSz = sizeof(mfxExtVPPDoNotUse);
- dnu.NumAlg = 4;
- dnu.AlgList = malloc(sizeof(mfxU32)*dnu.NumAlg);
- MSDK_CHECK_POINTER(dnu.AlgList, MFX_ERR_MEMORY_ALLOC);
- dnu.AlgList[0] = MFX_EXTBUFF_VPP_DENOISE;
- dnu.AlgList[1] = MFX_EXTBUFF_VPP_SCENE_ANALYSIS;
- dnu.AlgList[2] = MFX_EXTBUFF_VPP_DETAIL;
- dnu.AlgList[3] = MFX_EXTBUFF_VPP_PROCAMP;
- //Add the extended buffers
- mfxExtBuffer *dnuBuf[1];
- dnuBuf[0] = (mfxExtBuffer*)&dnu;
- encoder->hwenc.VPPParams.ExtParam = dnuBuf;
- encoder->hwenc.VPPParams.NumExtParam = 1;
- //Check VPPParams validity. Adjust if necessary.
- encoder->hwenc.sts = MFXVideoVPP_Query(encoder->hwenc.VPPses,&encoder->hwenc.VPPParams,&encoder->hwenc.VPPParams);
- //MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);
- MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
- //Validation of encoder parameters
- //If parameters are not valid the encoder will adjust the parameters as close as possible to the requested configuration
- encoder->hwenc.sts = MFXVideoENCODE_Query(encoder->hwenc.ENCses,&encoder->hwenc.ENCParams,&encoder->hwenc.ENCParams);
- //MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_WRN_INCOMPATIBLE_VIDEO_PARAM);
- MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
- //Ask the encoder how many surfaces it needs with this configuration
- mfxFrameAllocRequest ENCsurfReq;
- memset(&ENCsurfReq,0,sizeof(ENCsurfReq));
- encoder->hwenc.sts = MFXVideoENCODE_QueryIOSurf(encoder->hwenc.ENCses, &encoder->hwenc.ENCParams, &ENCsurfReq);
- MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
- encoder->hwenc.nENCSurfs = ENCsurfReq.NumFrameSuggested;
- printf("%d surfaces are needed for ENC input.\n",encoder->hwenc.nENCSurfs);
- //Allocate memory to the encoder for required surfaces (surfaces will be shared with VPP output)
- mfxU16 width = (mfxU16)MSDK_ALIGN32(ENCsurfReq.Info.Width);
- mfxU16 height = (mfxU16)MSDK_ALIGN32(ENCsurfReq.Info.Height);
- mfxU8 bitsPerPixel = 12; // NV12 format is a 12 bits per pixel format
- mfxU32 surfSize = (width * height * bitsPerPixel)>>3;
- //Surface ENCODER pointers housekeeping
- encoder->hwenc.ENCsurfbuffs = (mfxU8*)malloc(sizeof(surfSize)*encoder->hwenc.nENCSurfs);
- encoder->hwenc.ptrENCSurfs = malloc(sizeof(mfxFrameSurface1*)*encoder->hwenc.nENCSurfs);//This is equivalent to mfxFrameSurface1*[encoder->hwenc.nENCSurfs]
- MSDK_CHECK_POINTER(encoder->hwenc.ptrENCSurfs, MFX_ERR_MEMORY_ALLOC);
- for(int i=0; i<encoder->hwenc.nENCSurfs; i++)
- {
- encoder->hwenc.ptrENCSurfs[i] = malloc(sizeof(mfxFrameSurface1));
- memset(encoder->hwenc.ptrENCSurfs[i],0,sizeof(mfxFrameSurface1));
- memcpy(&(encoder->hwenc.ptrENCSurfs[i]->Info), &(encoder->hwenc.ENCParams.mfx.FrameInfo), sizeof(mfxFrameInfo));
- encoder->hwenc.ptrENCSurfs[i]->Data.Y = &encoder->hwenc.ENCsurfbuffs[surfSize * i];
- encoder->hwenc.ptrENCSurfs[i]->Data.U = encoder->hwenc.ptrENCSurfs[i]->Data.Y + target_width * target_height;
- encoder->hwenc.ptrENCSurfs[i]->Data.V = encoder->hwenc.ptrENCSurfs[i]->Data.U + 1;
- encoder->hwenc.ptrENCSurfs[i]->Data.Pitch = target_width;
- }
- //Creation of the VPP component and querying for surface buffers
- mfxFrameAllocRequest VPPsurfReq[2];//An array structure where position [0] is for input and [1] is for output
- memset(&VPPsurfReq,0,sizeof(mfxFrameAllocRequest) * 2);
- encoder->hwenc.sts = MFXVideoVPP_QueryIOSurf(encoder->hwenc.VPPses,&encoder->hwenc.VPPParams,VPPsurfReq);
- MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
- encoder->hwenc.nVPPSurfs[0] = VPPsurfReq[0].NumFrameSuggested;
- encoder->hwenc.nVPPSurfs[1] = VPPsurfReq[1].NumFrameSuggested;
- printf("%d surfaces are needed for VPP input.\n",encoder->hwenc.nVPPSurfs[0]);
- printf("%d surfaces are needed for VPP output.\n",encoder->hwenc.nVPPSurfs[1]);
- //Allocate memory to vpp for input surfaces
- //Both width and height must be 32-bit aligned
- width = (mfxU16)MSDK_ALIGN32(encoder->hwenc.VPPParams.vpp.In.Width);
- height = (mfxU16)MSDK_ALIGN32(encoder->hwenc.VPPParams.vpp.In.Height);
- bitsPerPixel = 32;
- surfSize = (width * height * bitsPerPixel)>>3;
- //Surface VPP pointers housekeeping
- encoder->hwenc.VPPsurfbuffsIN = (mfxU8*)malloc(sizeof(surfSize)*encoder->hwenc.nVPPSurfs[0]);
- encoder->hwenc.ptrVPPSurfsIN = malloc(sizeof(mfxFrameSurface1*)*encoder->hwenc.nVPPSurfs[0]);
- MSDK_CHECK_POINTER(encoder->hwenc.ptrVPPSurfsIN,MFX_ERR_MEMORY_ALLOC);
- for(int i=0; i<encoder->hwenc.nVPPSurfs[0]; i++)
- {
- encoder->hwenc.ptrVPPSurfsIN[i] = malloc(sizeof(mfxFrameSurface1));
- memset(encoder->hwenc.ptrVPPSurfsIN[i],0,sizeof(mfxFrameSurface1));
- memcpy(&(encoder->hwenc.ptrVPPSurfsIN[i]->Info), &(encoder->hwenc.VPPParams.vpp.In), sizeof(mfxFrameInfo));
- encoder->hwenc.ptrVPPSurfsIN[i]->Data.B = &encoder->hwenc.VPPsurfbuffsIN[surfSize * i];//Assuming Top-Down layout and little-endian
- encoder->hwenc.ptrVPPSurfsIN[i]->Data.G = encoder->hwenc.ptrVPPSurfsIN[i]->Data.B + 1;
- encoder->hwenc.ptrVPPSurfsIN[i]->Data.R = encoder->hwenc.ptrVPPSurfsIN[i]->Data.G + 1;
- encoder->hwenc.ptrVPPSurfsIN[i]->Data.A = encoder->hwenc.ptrVPPSurfsIN[i]->Data.R + 1;
- encoder->hwenc.ptrVPPSurfsIN[i]->Data.Pitch = image->width*bitsPerPixel>>3;
- }
- //Allocate memory to vpp for output surfaces
- //This is a shared resource because this acts as an intermediate buffer between VPP and ENCODE operations
- encoder->hwenc.VPPsurfbuffsOUT = encoder->hwenc.ENCsurfbuffs;
- encoder->hwenc.ptrVPPSurfsOUT = encoder->hwenc.ptrENCSurfs;
- MSDK_CHECK_POINTER(encoder->hwenc.ptrVPPSurfsOUT, MFX_ERR_MEMORY_ALLOC);
- //Initialize Intel SDK Encoder
- encoder->hwenc.sts = MFXVideoENCODE_Init(encoder->hwenc.ENCses,&encoder->hwenc.ENCParams);
- //MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_WRN_PARTIAL_ACCELERATION);
- MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
- //Retrieve selected settings by encoder
- mfxVideoParam params;
- memset(¶ms, 0, sizeof(params));
- encoder->hwenc.sts = MFXVideoENCODE_GetVideoParam(encoder->hwenc.ENCses, ¶ms);
- MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
- //Prepare the buffer for the H.264 bitstream
- memset(&encoder->hwenc.bitstr, 0, sizeof(encoder->hwenc.bitstr));
- //Assignment of MaxLength parameter is mandatory.
- encoder->hwenc.bitstr.MaxLength = params.mfx.BufferSizeInKB * 1000;
- encoder->hwenc.bitstr.Data = malloc(sizeof(mfxU8)*encoder->hwenc.bitstr.MaxLength);
- MSDK_CHECK_POINTER(encoder->hwenc.bitstr.Data, MFX_ERR_MEMORY_ALLOC);
- //Initialize Intel SDK VPP
- encoder->hwenc.sts = MFXVideoVPP_Init(encoder->hwenc.VPPses,&encoder->hwenc.VPPParams);
- //MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_WRN_PARTIAL_ACCELERATION);
- MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
- encoder->image = image;
- encoder->width = (int)target_width;//Safe casting
- encoder->height = (int)target_height;//Safe casting
- printf("End of initialization.\n");
- return 1;
- }
- int encoder_x264_encode(Encoder_t *encoder) {
- #ifdef BENCHMARK.
- #ifdef _WIN32
- LARGE_INTEGER tStart, tEnd;
- QueryPerformanceFrequency(&tStart);
- double freq = (double)tStart.QuadPart;
- QueryPerformanceCounter(&tStart);
- #endif
- #endif
- int surfVPPindexIN = 0, surfVPPindexOUT = 0, surfENCindex = 0;
- mfxSyncPoint VPPsync,ENCsync;
- encoder->hwenc.nENCFrame = 0;
- uint8_t* data;
- uint32_t len;
- if(encoder->image->bpp == 32)
- len = 4 * encoder->image->width * encoder->image->height;
- else
- len = 3 * encoder->image->width * encoder->image->height;
- if (cb_is_empty(&encoder->image->cb))
- return 0;
- printf("Expecting raw frame with size %d.\n",len);
- data = cb_read_direct(&encoder->image->cb, &len);//Or if this doesn't work assign directly to pool
- printf("Got a frame %p, size: %d\n", data, len);
- //Main VPPprocess loop
- while (MFX_ERR_NONE <= encoder->hwenc.sts || MFX_ERR_MORE_DATA == encoder->hwenc.sts)
- {
- printf("Entering VPP while loop.\n");
- surfVPPindexIN = alloc_surfpool(encoder->hwenc.ptrVPPSurfsIN, encoder->hwenc.nVPPSurfs[0]);
- MSDK_CHECK_ERROR(MFX_ERR_NOT_FOUND, surfVPPindexIN, MFX_ERR_MEMORY_ALLOC);
- //encoder->hwenc.ptrVPPSurfsIN[surfVPPindexIN]->Data.A = (mfxU8*)data;//maybe memcpy is needed here
- cb_read(&encoder->image->cb, &encoder->hwenc.ptrVPPSurfsIN[surfVPPindexIN]->Data.B, &len);
- surfVPPindexOUT = alloc_surfpool(encoder->hwenc.ptrVPPSurfsOUT, encoder->hwenc.nVPPSurfs[1]);
- MSDK_CHECK_ERROR(MFX_ERR_NOT_FOUND, surfVPPindexOUT, MFX_ERR_MEMORY_ALLOC);
- for(;;)
- {
- printf("Entering VPP for loop.\n");
- encoder->hwenc.sts = MFXVideoVPP_RunFrameVPPAsync(encoder->hwenc.VPPses, encoder->hwenc.ptrVPPSurfsIN[surfVPPindexIN], encoder->hwenc.ptrVPPSurfsOUT[surfVPPindexOUT],NULL,&VPPsync);
- if (MFX_WRN_DEVICE_BUSY == encoder->hwenc.sts)
- {
- printf("Device is busy, retrying...\n");
- Sleep(1); // Wait if device is busy, then repeat the same call
- }
- else
- {
- printf("Exiting VPP for loop.\n");
- break;
- }
- }
- if (MFX_ERR_MORE_DATA == encoder->hwenc.sts) // More data is needed
- {
- printf("More data is needed for VPP.\n");
- continue;
- }
- MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
- MSDK_BREAK_ON_ERROR(encoder->hwenc.sts);
- encoder->hwenc.sts = MFXVideoCORE_SyncOperation(encoder->hwenc.VPPses, VPPsync, 10);
- MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
- printf("Exiting VPP while loop.\n");
- }
- //Main ENCODERprocess loop
- while (MFX_ERR_NONE <= encoder->hwenc.sts || MFX_ERR_MORE_DATA == encoder->hwenc.sts)
- {
- printf("Entering ENCODER while loop.\n");
- surfENCindex = alloc_surfpool(encoder->hwenc.ptrENCSurfs, encoder->hwenc.nENCSurfs);
- MSDK_CHECK_ERROR(MFX_ERR_NOT_FOUND, surfENCindex, MFX_ERR_MEMORY_ALLOC);
- //if(surfVPPindexOUT != surfENCindex)
- //surfENCindex = surfVPPindexOUT;//Sync of indices
- //Not need to load anything since data appeared to the encoder's input from the VPP's output.
- for(;;)
- {
- printf("Entering ENCODER for loop.\n");
- encoder->hwenc.sts = MFXVideoENCODE_EncodeFrameAsync(encoder->hwenc.ENCses,encoder->hwenc.ptrENCSurfs[surfENCindex], &encoder->hwenc.bitstr,NULL,&ENCsync);
- if (MFX_ERR_NONE < encoder->hwenc.sts && !ENCsync)
- {
- if (MFX_WRN_DEVICE_BUSY == encoder->hwenc.sts)
- Sleep(1); // Wait if device is busy, then repeat the same call
- }
- else if (MFX_ERR_NONE < encoder->hwenc.sts && ENCsync)
- {
- encoder->hwenc.sts = MFX_ERR_NONE; //Ignore warnings
- break;
- }
- else if (MFX_ERR_NOT_ENOUGH_BUFFER == encoder->hwenc.sts)
- {
- printf("Must allocate more memory for output bitstream.\n");
- //Consider allocating more memory for bitstream output
- break;
- }
- else
- {
- printf("Exiting ENCODER for loop.\n");
- break;
- }
- }
- if(MFX_ERR_NONE == encoder->hwenc.sts)
- {
- encoder->hwenc.sts = MFXVideoCORE_SyncOperation(encoder->hwenc.ENCses, ENCsync, 10); // Synchronize. Wait until encoded frame is ready
- MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
- //Must send bitstream now
- ++encoder->hwenc.nENCFrame;
- encoder->hwenc.sts = send_h264stream(&encoder->hwenc.bitstr,encoder);
- MSDK_BREAK_ON_ERROR(encoder->hwenc.sts);
- }
- }
- printf("Exiting ENCODER while loop.\n");
- MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_ERR_MORE_DATA);
- MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
- //Draining VPP buffers
- while(MFX_ERR_NONE <= encoder->hwenc.sts)
- {
- surfVPPindexOUT = alloc_surfpool(encoder->hwenc.ptrVPPSurfsOUT, encoder->hwenc.nVPPSurfs[1]);
- MSDK_CHECK_ERROR(MFX_ERR_NOT_FOUND, surfVPPindexOUT, MFX_ERR_MEMORY_ALLOC);
- for(;;)
- {
- encoder->hwenc.sts = MFXVideoVPP_RunFrameVPPAsync(encoder->hwenc.VPPses, NULL, encoder->hwenc.ptrVPPSurfsOUT[surfVPPindexOUT],NULL,&VPPsync);
- if (MFX_WRN_DEVICE_BUSY == encoder->hwenc.sts)
- Sleep(1); // Wait if device is busy, then repeat the same call
- else
- break;
- }
- MSDK_IGNORE_MFX_STS(encoder->hwenc.sts, MFX_ERR_MORE_SURFACE);
- MSDK_BREAK_ON_ERROR(encoder->hwenc.sts);
- encoder->hwenc.sts = MFXVideoCORE_SyncOperation(encoder->hwenc.VPPses, VPPsync, 10);
- MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
- }
- //Draining ENCODER buffers
- while (MFX_ERR_NONE <= encoder->hwenc.sts)
- {
- for (;;)
- {
- // Encode a frame asychronously (returns immediately)
- encoder->hwenc.sts = MFXVideoENCODE_EncodeFrameAsync(encoder->hwenc.ENCses,NULL, &encoder->hwenc.bitstr,NULL,&ENCsync);
- if (MFX_ERR_NONE < encoder->hwenc.sts && !ENCsync) // Repeat the call if warning and no output
- {
- if (MFX_WRN_DEVICE_BUSY == encoder->hwenc.sts)
- Sleep(1); // Wait if device is busy, then repeat the same call
- }
- else if (MFX_ERR_NONE < encoder->hwenc.sts && ENCsync)
- {
- encoder->hwenc.sts = MFX_ERR_NONE; // Ignore warnings if output is available
- break;
- }
- else
- break;
- }
- if(MFX_ERR_NONE == encoder->hwenc.sts)
- {
- encoder->hwenc.sts = MFXVideoCORE_SyncOperation(encoder->hwenc.ENCses, ENCsync, 10); // Synchronize. Wait until encoded frame is ready
- MSDK_CHECK_RESULT(encoder->hwenc.sts, MFX_ERR_NONE, encoder->hwenc.sts);
- ++encoder->hwenc.nENCFrame;
- encoder->hwenc.sts = send_h264stream(&encoder->hwenc.bitstr,encoder);
- MSDK_BREAK_ON_ERROR(encoder->hwenc.sts);
- }
- }
- #ifdef BENCHMARK
- QueryPerformanceCounter(&tEnd);
- double duration = ((double)tEnd.QuadPart - (double)tStart.QuadPart) / freq;
- printf("\nExecution time: %3.2fs (%3.2ffps)\n", duration, ++encoder->hwenc.nENCFrame/duration);
- #endif
- return 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement