libopenh264enc: Added max_nal_size option

Also added dynamic slice_mode option, needed for the max_nal_size.

Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
This commit is contained in:
Mario Gasparoni 2015-10-08 14:28:55 -03:00 committed by Luca Barbato
parent 00cc10aee3
commit c3e5c47bda
1 changed files with 28 additions and 0 deletions

View File

@ -37,6 +37,7 @@ typedef struct SVCContext {
int slice_mode; int slice_mode;
int loopfilter; int loopfilter;
char *profile; char *profile;
int max_nal_size;
} SVCContext; } SVCContext;
#define OPENH264_VER_AT_LEAST(maj, min) \ #define OPENH264_VER_AT_LEAST(maj, min) \
@ -50,8 +51,10 @@ static const AVOption options[] = {
{ "fixed", "A fixed number of slices", 0, AV_OPT_TYPE_CONST, { .i64 = SM_FIXEDSLCNUM_SLICE }, 0, 0, VE, "slice_mode" }, { "fixed", "A fixed number of slices", 0, AV_OPT_TYPE_CONST, { .i64 = SM_FIXEDSLCNUM_SLICE }, 0, 0, VE, "slice_mode" },
{ "rowmb", "One slice per row of macroblocks", 0, AV_OPT_TYPE_CONST, { .i64 = SM_ROWMB_SLICE }, 0, 0, VE, "slice_mode" }, { "rowmb", "One slice per row of macroblocks", 0, AV_OPT_TYPE_CONST, { .i64 = SM_ROWMB_SLICE }, 0, 0, VE, "slice_mode" },
{ "auto", "Automatic number of slices according to number of threads", 0, AV_OPT_TYPE_CONST, { .i64 = SM_AUTO_SLICE }, 0, 0, VE, "slice_mode" }, { "auto", "Automatic number of slices according to number of threads", 0, AV_OPT_TYPE_CONST, { .i64 = SM_AUTO_SLICE }, 0, 0, VE, "slice_mode" },
{ "dyn", "Dynamic slicing", 0, AV_OPT_TYPE_CONST, { .i64 = SM_DYN_SLICE }, 0, 0, VE, "slice_mode" },
{ "loopfilter", "Enable loop filter", OFFSET(loopfilter), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE }, { "loopfilter", "Enable loop filter", OFFSET(loopfilter), AV_OPT_TYPE_INT, { .i64 = 1 }, 0, 1, VE },
{ "profile", "Set profile restrictions", OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE }, { "profile", "Set profile restrictions", OFFSET(profile), AV_OPT_TYPE_STRING, { 0 }, 0, 0, VE },
{ "max_nal_size", "Set maximum NAL size in bytes", OFFSET(max_nal_size), AV_OPT_TYPE_INT, { 0 }, 0, INT_MAX, VE },
{ NULL } { NULL }
}; };
@ -165,11 +168,36 @@ static av_cold int svc_encode_init(AVCodecContext *avctx)
param.sSpatialLayers[0].iSpatialBitrate = param.iTargetBitrate; param.sSpatialLayers[0].iSpatialBitrate = param.iTargetBitrate;
param.sSpatialLayers[0].iMaxSpatialBitrate = param.iMaxBitrate; param.sSpatialLayers[0].iMaxSpatialBitrate = param.iMaxBitrate;
if ((avctx->slices > 1) && (s->max_nal_size)){
av_log(avctx,AV_LOG_ERROR,"Invalid combination -slices %d and -max_nal_size %d.\n",avctx->slices,s->max_nal_size);
goto fail;
}
if (avctx->slices > 1) if (avctx->slices > 1)
s->slice_mode = SM_FIXEDSLCNUM_SLICE; s->slice_mode = SM_FIXEDSLCNUM_SLICE;
if (s->max_nal_size)
s->slice_mode = SM_DYN_SLICE;
param.sSpatialLayers[0].sSliceCfg.uiSliceMode = s->slice_mode; param.sSpatialLayers[0].sSliceCfg.uiSliceMode = s->slice_mode;
param.sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceNum = avctx->slices; param.sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceNum = avctx->slices;
if (s->slice_mode == SM_DYN_SLICE) {
if (s->max_nal_size){
param.uiMaxNalSize = s->max_nal_size;
param.sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = s->max_nal_size;
} else {
if (avctx->rtp_payload_size) {
av_log(avctx,AV_LOG_DEBUG,"Using RTP Payload size for uiMaxNalSize");
param.uiMaxNalSize = avctx->rtp_payload_size;
param.sSpatialLayers[0].sSliceCfg.sSliceArgument.uiSliceSizeConstraint = avctx->rtp_payload_size;
} else {
av_log(avctx,AV_LOG_ERROR,"Invalid -max_nal_size, specify a valid max_nal_size to use -slice_mode dyn\n");
goto fail;
}
}
}
if ((*s->encoder)->InitializeExt(s->encoder, &param) != cmResultSuccess) { if ((*s->encoder)->InitializeExt(s->encoder, &param) != cmResultSuccess) {
av_log(avctx, AV_LOG_ERROR, "Initialize failed\n"); av_log(avctx, AV_LOG_ERROR, "Initialize failed\n");
goto fail; goto fail;