// CodecDemo.cpp : This file contains the 'main' function. Program execution begins and ends there. // #include #include "vpl/mfx.h" #include #include #include #include #define TARGETKBPS 4000 #define BITSTREAM_BUFFER_SIZE 2000000 int main() { // First get a single frame from the default system webcam. cv::VideoCapture cap = cv::VideoCapture(0); cv::Mat image; if (!cap.isOpened()) return 1; cap >> image; cap.release(); mfxStatus status; mfxLoader loader = MFXLoad(); mfxConfig loaderConfig = MFXCreateConfig(loader); mfxVariant implValue; implValue.Type = MFX_VARIANT_TYPE_U32; implValue.Data.U32 = MFX_IMPL_TYPE_HARDWARE; // Enforce HW-accelerated implementation. MFXSetConfigFilterProperty(loaderConfig, (const mfxU8*)"mfxImplDescription.Impl", implValue); // Use loader config to find the first-available HW-accelerated implementation, and make a session. mfxSession session; status = MFXCreateSession(loader, 0, &session); if (status != mfxStatus::MFX_ERR_NONE) std::cout << "Error creating session: " << status << std::endl; // Config for the encoder. mfxVideoParam encodeParams = {}; encodeParams.mfx.CodecId = MFX_CODEC_JPEG; encodeParams.mfx.Quality = 100; encodeParams.mfx.TargetUsage = MFX_TARGETUSAGE_BALANCED; encodeParams.mfx.TargetKbps = TARGETKBPS; encodeParams.mfx.RateControlMethod = MFX_RATECONTROL_VBR; encodeParams.mfx.FrameInfo.FrameRateExtN = 1; encodeParams.mfx.FrameInfo.FrameRateExtD = 1; encodeParams.mfx.FrameInfo.ChromaFormat = MFX_CHROMAFORMAT_YUV444; // Support RGB. encodeParams.mfx.FrameInfo.FourCC = MFX_FOURCC_RGB4; // Support RGB. encodeParams.mfx.FrameInfo.CropW = image.cols; encodeParams.mfx.FrameInfo.CropH = image.rows; encodeParams.mfx.FrameInfo.Width = image.cols; encodeParams.mfx.FrameInfo.Height = image.rows; encodeParams.IOPattern = MFX_IOPATTERN_IN_SYSTEM_MEMORY; mfxVideoParam outputParams = {}; // Query encoding params. status = MFXVideoENCODE_Query(session, &encodeParams, &outputParams); if (status != mfxStatus::MFX_ERR_NONE) std::cout << "Error querying encoder: " << status << std::endl; // Initialize the video encoder. status = MFXVideoENCODE_Init(session, &encodeParams); if (status != mfxStatus::MFX_ERR_NONE) std::cout << "Error initializing encoder: " << status << std::endl; // Prepare output bitstream mfxBitstream bitStream = {}; bitStream.MaxLength = BITSTREAM_BUFFER_SIZE; bitStream.Data = (mfxU8*)calloc(bitStream.MaxLength, sizeof(mfxU8)); // Prepare input surface - this will contain the frame to be encoded. mfxFrameSurface1* encSurfaceIn = NULL; status = MFXMemory_GetSurfaceForEncode(session, &encSurfaceIn); if (status != mfxStatus::MFX_ERR_NONE) std::cout << "Error getting surface: " << status << std::endl; // Map makes surface writable by CPU for all implementations status = encSurfaceIn->FrameInterface->Map(encSurfaceIn, MFX_MAP_WRITE); if (status != mfxStatus::MFX_ERR_NONE) std::cout << "Error mapping surface for write: " << status << std::endl; // Fill the surface with data. mfxU16 pitch = encSurfaceIn->Data.Pitch; for (auto row = 0; row < image.rows; row++) { // Start of the row in the surface data buffer. mfxU8* rowStart = encSurfaceIn->Data.B + (row * pitch); // Copy webcam image row data to surface. // N.B. this probably doesn't fill the surface correctly since cv image has no alpha channel. memcpy(rowStart, image.row(row).data, image.cols * 4); } // Rescind CPU access to surface data. status = encSurfaceIn->FrameInterface->Unmap(encSurfaceIn); if (status != mfxStatus::MFX_ERR_NONE) std::cout << "Error unmapping surface: " << status << std::endl; // Create a point for synchronization. mfxSyncPoint syncP = {}; status = MFXVideoENCODE_EncodeFrameAsync(session, NULL, encSurfaceIn, &bitStream, &syncP); if (status != mfxStatus::MFX_ERR_NONE) std::cout << "Error encoding async: " << status << std::endl; // Release surface via FrameInterface. status = encSurfaceIn->FrameInterface->Release(encSurfaceIn); if (status != mfxStatus::MFX_ERR_NONE) std::cout << "Error releasing surface: " << status << std::endl; // Wait for encoding to finish? if (syncP) { status = MFXVideoCORE_SyncOperation(session, syncP, 100); if (status != mfxStatus::MFX_ERR_NONE) std::cout << "Error with sync operation: " << status << std::endl; } // Bitstream contains encoded image - represent it? std::cout << "Bistream codeic ID:" << bitStream.CodecId << std::endl; std::cout << "Bitstream datalength:" << bitStream.DataLength << std::endl; status = MFXVideoENCODE_Close(session); if (status != mfxStatus::MFX_ERR_NONE) std::cout << "Error closing encoder: " << status << std::endl; status = MFXClose(session); if (status != mfxStatus::MFX_ERR_NONE) std::cout << "Error closing session: " << status << std::endl; MFXUnload(loader); }