22 #include <wels/codec_api.h>
23 #include <wels/codec_ver.h>
42 #define OPENH264_VER_AT_LEAST(maj, min) \
43 ((OPENH264_MAJOR > (maj)) || \
44 (OPENH264_MAJOR == (maj) && OPENH264_MINOR >= (min)))
46 #define OFFSET(x) offsetof(SVCContext, x)
47 #define VE AV_OPT_FLAG_VIDEO_PARAM | AV_OPT_FLAG_ENCODING_PARAM
49 {
"slice_mode",
"Slice mode",
OFFSET(slice_mode),
AV_OPT_TYPE_INT, { .i64 = SM_AUTO_SLICE }, SM_SINGLE_SLICE, SM_RESERVED,
VE,
"slice_mode" },
50 {
"fixed",
"A fixed number of slices", 0,
AV_OPT_TYPE_CONST, { .i64 = SM_FIXEDSLCNUM_SLICE }, 0, 0,
VE,
"slice_mode" },
51 {
"rowmb",
"One slice per row of macroblocks", 0,
AV_OPT_TYPE_CONST, { .i64 = SM_ROWMB_SLICE }, 0, 0,
VE,
"slice_mode" },
52 {
"auto",
"Automatic number of slices according to number of threads", 0,
AV_OPT_TYPE_CONST, { .i64 = SM_AUTO_SLICE }, 0, 0,
VE,
"slice_mode" },
67 WelsDestroySVCEncoder(s->
encoder);
74 SEncParamExt param = { 0 };
80 #if !defined(_WIN32) || !defined(__GNUC__) || !ARCH_X86_32 || AV_GCC_VERSION_AT_LEAST(4, 7)
81 OpenH264Version libver = WelsGetCodecVersion();
82 if (memcmp(&libver, &g_stCodecVersion,
sizeof(libver))) {
88 if (WelsCreateSVCEncoder(&s->
encoder)) {
96 param.iPicWidth = avctx->
width;
97 param.iPicHeight = avctx->
height;
98 param.iTargetBitrate = avctx->
bit_rate;
100 param.iRCMode = RC_QUALITY_MODE;
101 param.iTemporalLayerNum = 1;
102 param.iSpatialLayerNum = 1;
103 param.bEnableDenoise = 0;
104 param.bEnableBackgroundDetection = 1;
105 param.bEnableAdaptiveQuant = 1;
106 param.bEnableFrameSkip = 0;
107 param.bEnableLongTermReference = 0;
108 param.iLtrMarkPeriod = 30;
109 param.uiIntraPeriod = avctx->
gop_size;
110 #if OPENH264_VER_AT_LEAST(1, 4)
111 param.eSpsPpsIdStrategy = CONSTANT_ID;
113 param.bEnableSpsPpsIdAddition = 0;
115 param.bPrefixNalAddingCtrl = 0;
117 param.iEntropyCodingModeFlag = 0;
120 param.iEntropyCodingModeFlag = 1;
122 param.iEntropyCodingModeFlag = 1;
124 param.sSpatialLayers[0].iVideoWidth = param.iPicWidth;
125 param.sSpatialLayers[0].iVideoHeight = param.iPicHeight;
126 param.sSpatialLayers[0].fFrameRate = param.fMaxFrameRate;
127 param.sSpatialLayers[0].iSpatialBitrate = param.iTargetBitrate;
128 param.sSpatialLayers[0].iMaxSpatialBitrate = param.iMaxBitrate;
132 param.sSpatialLayers[0].sSliceCfg.uiSliceMode = s->
slice_mode;
133 param.sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceNum = avctx->
slices;
135 if ((*s->
encoder)->InitializeExt(s->
encoder, ¶m) != cmResultSuccess) {
141 SFrameBSInfo fbi = { 0 };
144 for (i = 0; i < fbi.sLayerInfo[0].iNalCount; i++)
145 size += fbi.sLayerInfo[0].pNalLengthInByte[i];
152 memcpy(avctx->
extradata, fbi.sLayerInfo[0].pBsBuf, size);
166 SFrameBSInfo fbi = { 0 };
169 SSourcePicture
sp = { 0 };
170 int size = 0, layer, first_layer = 0;
171 int layer_size[MAX_LAYER_NUM_OF_FRAME] = { 0 };
173 sp.iColorFormat = videoFormatI420;
174 for (i = 0; i < 3; i++) {
176 sp.pData[i] = frame->
data[i];
178 sp.iPicWidth = avctx->
width;
179 sp.iPicHeight = avctx->
height;
182 if (encoded != cmResultSuccess) {
186 if (fbi.eFrameType == videoFrameTypeSkip) {
196 first_layer = fbi.iLayerNum - 1;
198 for (layer = first_layer; layer < fbi.iLayerNum; layer++) {
199 for (i = 0; i < fbi.sLayerInfo[layer].iNalCount; i++)
200 layer_size[layer] += fbi.sLayerInfo[layer].pNalLengthInByte[i];
201 size += layer_size[layer];
203 av_log(avctx,
AV_LOG_DEBUG,
"%d slices\n", fbi.sLayerInfo[fbi.iLayerNum - 1].iNalCount);
210 for (layer = first_layer; layer < fbi.iLayerNum; layer++) {
211 memcpy(avpkt->
data + size, fbi.sLayerInfo[layer].pBsBuf, layer_size[layer]);
212 size += layer_size[layer];
215 if (fbi.eFrameType == videoFrameTypeIDR)
222 .
name =
"libopenh264",
233 .priv_class = &
class,