From aa480d700ade297906790e3fb469dfd75b6e0129 Mon Sep 17 00:00:00 2001 From: Shao-Feng Date: Thu, 25 Jul 2024 07:36:13 +0000 Subject: [PATCH] Make hello-encode example to run with VP9 and H264 For validating VP9 max resolution, make the example tool 'hello-encode' to run with different codec format, including VP9, H264 and H265. Also increase the size of BS buffer for supporting 8K BitStream. Tracked-On: OAM-125594 Signed-off-by: Shao-Feng (cherry picked from commit c17d02508e9d898d401176031ab7356a5aee0eec) Tracked-On: OAM-128364 Signed-off-by: Lina Sun --- .../api2x/hello-encode/src/hello-encode.cpp | 40 +++++++++--- examples/api2x/hello-encode/src/util.hpp | 61 ++++++++++++++++++- 2 files changed, 90 insertions(+), 11 deletions(-) diff --git a/examples/api2x/hello-encode/src/hello-encode.cpp b/examples/api2x/hello-encode/src/hello-encode.cpp index d3508c46..89f1e9e0 100644 --- a/examples/api2x/hello-encode/src/hello-encode.cpp +++ b/examples/api2x/hello-encode/src/hello-encode.cpp @@ -10,12 +10,15 @@ /// /// @file +#include #include "util.hpp" #define TARGETKBPS 4000 #define FRAMERATE 30 -#define OUTPUT_FILE "out.h265" -#define BITSTREAM_BUFFER_SIZE 2000000 +#define HEVC_OUTPUT_FILE "out.hevc" +#define AVC_OUTPUT_FILE "out.avc" +#define VP9_OUTPUT_FILE "out.vp9" +#define BITSTREAM_BUFFER_SIZE 20000000 #define MAJOR_API_VERSION_REQUIRED 2 #define MINOR_API_VERSION_REQUIRED 2 @@ -25,9 +28,11 @@ void Usage(void) { printf(" -i input file name (NV12 raw frames)\n"); printf(" -w input width\n"); printf(" -h input height\n\n"); - printf(" Example: hello-encode -i in.NV12 -w 320 -h 240\n"); - printf(" To view: ffplay %s\n\n", OUTPUT_FILE); - printf(" * Encode raw frames to HEVC/H265 elementary stream in %s\n\n", OUTPUT_FILE); + printf(" -v encoder format: vp9, h264, and h265. By default, H265 is used.\n\n"); + printf(" Example: hello-encode -i in.NV12 -w 320 -h 240 -v h265\n"); + printf(" To view: ffplay %s/%s/%s\n\n", HEVC_OUTPUT_FILE, AVC_OUTPUT_FILE, VP9_OUTPUT_FILE); + printf(" * Encode raw frames to VP9/AVC/HEVC elementary stream in %s/%s/%s\n\n", + HEVC_OUTPUT_FILE, AVC_OUTPUT_FILE, VP9_OUTPUT_FILE); printf(" GPU native color format is " "NV12\n"); return; @@ -61,10 +66,26 @@ int main(int argc, char *argv[]) { return 1; // return 1 as error code } + uint32_t codecFormat = 0; + std::string outputFile; + switch (cliParams.codecFormat) { + case AVC_FORMAT: + codecFormat = MFX_CODEC_AVC; + outputFile = AVC_OUTPUT_FILE; + break; + case VP9_FORMAT: + codecFormat = MFX_CODEC_VP9; + outputFile = VP9_OUTPUT_FILE; + break; + default: + codecFormat = MFX_CODEC_HEVC; + outputFile = HEVC_OUTPUT_FILE; + } + source = fopen(cliParams.infileName, "rb"); VERIFY(source, "Could not open input file"); - sink = fopen(OUTPUT_FILE, "wb"); + sink = fopen(outputFile.c_str(), "wb"); VERIFY(sink, "Could not create output file"); // Initialize session @@ -83,7 +104,7 @@ int main(int argc, char *argv[]) { cfg[1] = MFXCreateConfig(loader); VERIFY(NULL != cfg[1], "MFXCreateConfig failed") cfgVal[1].Type = MFX_VARIANT_TYPE_U32; - cfgVal[1].Data.U32 = MFX_CODEC_HEVC; + cfgVal[1].Data.U32 = codecFormat; sts = MFXSetConfigFilterProperty( cfg[1], (mfxU8 *)"mfxImplDescription.mfxEncoderDescription.encoder.CodecID", @@ -108,7 +129,7 @@ int main(int argc, char *argv[]) { ShowImplementationInfo(loader, 0); // Initialize encode parameters - encodeParams.mfx.CodecId = MFX_CODEC_HEVC; + encodeParams.mfx.CodecId = codecFormat; encodeParams.mfx.TargetUsage = MFX_TARGETUSAGE_BALANCED; encodeParams.mfx.TargetKbps = TARGETKBPS; encodeParams.mfx.RateControlMethod = MFX_RATECONTROL_VBR; @@ -141,7 +162,7 @@ int main(int argc, char *argv[]) { bitstream.MaxLength = BITSTREAM_BUFFER_SIZE; bitstream.Data = (mfxU8 *)calloc(bitstream.MaxLength, sizeof(mfxU8)); - printf("Encoding %s -> %s\n", cliParams.infileName, OUTPUT_FILE); + printf("Encoding %s(%dx%d) -> %s\n", cliParams.infileName, cliParams.srcWidth, cliParams.srcHeight, outputFile.c_str()); printf("Input colorspace: "); switch (encodeParams.mfx.FrameInfo.FourCC) { @@ -167,6 +188,7 @@ int main(int argc, char *argv[]) { sts = ReadRawFrame_InternalMem(encSurfaceIn, source); if (sts != MFX_ERR_NONE) isDraining = true; + printf("Read surface with size: %dx%d\n", encSurfaceIn->Info.Width, encSurfaceIn->Info.Height); } sts = MFXVideoENCODE_EncodeFrameAsync(session, diff --git a/examples/api2x/hello-encode/src/util.hpp b/examples/api2x/hello-encode/src/util.hpp index a4c3bdf3..b2f265fe 100644 --- a/examples/api2x/hello-encode/src/util.hpp +++ b/examples/api2x/hello-encode/src/util.hpp @@ -47,6 +47,12 @@ enum { #define MAX_HEIGHT 2160 #define IS_ARG_EQ(a, b) (!strcmp((a), (b))) +#define VP9_MAX_WIDTH 8192 +#define VP9_MAX_HEIGHT 8192 + +#define HEVC_MAX_WIDTH 16384 +#define HEVC_MAX_HEIGHT 12288 + #define VERIFY(x, y) \ if (!(x)) { \ printf("%s\n", y); \ @@ -67,9 +73,16 @@ enum ParamGroup { PARAMS_TRANSCODE }; +enum FormatGroup { + HEVC_FORMAT = 0, + AVC_FORMAT, + VP9_FORMAT +}; + typedef struct _Params { char *infileName; char *inmodelName; + int codecFormat; mfxU16 srcWidth; mfxU16 srcHeight; @@ -95,6 +108,23 @@ bool ValidateSize(char *in, mfxU16 *vsize, mfxU32 vmax) { return false; } +int ValidateFormat(char *in) { + int format = HEVC_FORMAT; + if (in) { + if (!(strcmp(in, "h265") && strcmp(in, "H265"))) { + format = HEVC_FORMAT; + } + else if (!(strcmp(in, "h264") && strcmp(in, "H264"))) { + format = AVC_FORMAT; + } + else if (!(strcmp(in, "vp9") && strcmp(in, "VP9"))) { + format = VP9_FORMAT; + } + } + + return format; +} + bool ParseArgsAndValidate(int argc, char *argv[], Params *params, ParamGroup group) { int idx; char *s; @@ -126,12 +156,16 @@ bool ParseArgsAndValidate(int argc, char *argv[], Params *params, ParamGroup gro return false; } } + else if (IS_ARG_EQ(s, "v")) { + params->codecFormat = ValidateFormat(argv[idx++]); + printf("DEBUG - using encoder %d\n", params->codecFormat); + } else if (IS_ARG_EQ(s, "w")) { - if (!ValidateSize(argv[idx++], ¶ms->srcWidth, MAX_WIDTH)) + if (!ValidateSize(argv[idx++], ¶ms->srcWidth, HEVC_MAX_WIDTH)) return false; } else if (IS_ARG_EQ(s, "h")) { - if (!ValidateSize(argv[idx++], ¶ms->srcHeight, MAX_HEIGHT)) + if (!ValidateSize(argv[idx++], ¶ms->srcHeight, HEVC_MAX_HEIGHT)) return false; } } @@ -150,6 +184,29 @@ bool ParseArgsAndValidate(int argc, char *argv[], Params *params, ParamGroup gro } } + switch(params->codecFormat) { + case AVC_FORMAT: + if (params->srcWidth > MAX_WIDTH || params->srcHeight > MAX_HEIGHT) { + printf("ERROR - MAX AVC width/height is %dx%d\n", MAX_WIDTH, MAX_HEIGHT); + return false; + } + break; + case VP9_FORMAT: + if (params->srcWidth > VP9_MAX_WIDTH || params->srcHeight > VP9_MAX_HEIGHT) { + printf("ERROR - MAX VP9 width/height is %dx%d\n", VP9_MAX_WIDTH, VP9_MAX_HEIGHT); + return false; + } + break; + case HEVC_FORMAT: + if (params->srcWidth > HEVC_MAX_WIDTH || params->srcHeight > HEVC_MAX_HEIGHT) { + printf("ERROR - MAX HEVC width/height is %dx%d\n", HEVC_MAX_WIDTH, HEVC_MAX_HEIGHT); + return false; + } + break; + default: + printf("ERROR - UNKNOWN format: %d", params->codecFormat); + } + return true; }