gpt4 book ai didi

无法复制 FFMpeg Prores 质量设置

转载 作者:太空宇宙 更新时间:2023-11-04 04:25:31 29 4
gpt4 key购买 nike

使用 ffmpeg 作为库。我希望创建一个结果非常不一致的全局质量 slider 。 AvCodecContext::global_quality 似乎是一个不错的起点。并非所有有损编解码器都引用此成员,但它似乎确实适用于 ProRes。

c:\>ffmpeg.exe -i test.mov -c:v prores_ks -q:v 28 out.mov     # output 10mb file

c:\>ffmpeg.exe -i test.mov -c:v prores_ks -q:v 2 out.mov # output 28mb file

太棒了。现在让我们用代码来做。基于 Muxing.c。我对代码进行了大量提炼,只是为了提示我正在调用哪个 API。

AVStream* AddStream(AVFormatContext* formatContext, int quality)
{
AVCodec* codec = AVFindEncoder("prores_ks");

AVStream* newStream = avformat_new_stream(formatContext, codec);

newStream->id = formatContext->nb_streams - 1;

AVCodecContext c = avcodec_alloc_context3(codec);

c->codec_id = AV_CODEC_ID_PRORES;
c->codec_type = AVMEDIA_TYPE_VIDEO;
c->width = 1920;
c->height = 1080;

newStream->time_base = av_inv_q(frameRate);
c->time_base = av_inv_q(frameRate);

c->pix_fmt = AV_PIX_FMT_YUVA444P10;

c->global_quality = quality;

return newStream;
}
......
//excerpt from WriteFrame()

AVPacket pkt;
av_init_packet(&pkt);
pkt.data= pVideoBuffer;
pkt.size= iVideoBufferSize;
int gotpkt = 0;
int ret = avcodec_encode_video2(pCodecContext, &pkt, pPicture, &gotpkt);
if (ret == 0)
{
av_packet_rescale_ts(&pkt, pCodecContext->time_base, pVideoStream->time_base);

if (gotpkt) {
ret = av_interleaved_write_frame(pFormatContext, &pkt);
}
}

我无法获得影响输出大小的质量。有什么想法吗?

这是 proresenc_kostya.c 的摘录

ctx->force_quant = avctx->global_quality / FF_QP2LAMBDA;
if (!ctx->force_quant) {
if (!ctx->bits_per_mb) {
for (i = 0; i < NUM_MB_LIMITS - 1; i++)
if (prores_mb_limits[i] >= ctx->mb_width * ctx->mb_height *
ctx->pictures_per_frame)
break;
ctx->bits_per_mb = ctx->profile_info->br_tab[i];
} else if (ctx->bits_per_mb < 128) {
av_log(avctx, AV_LOG_ERROR, "too few bits per MB, please set at least 128\n");
return AVERROR_INVALIDDATA;
}

min_quant = ctx->profile_info->min_quant;
max_quant = ctx->profile_info->max_quant;
for (i = min_quant; i < MAX_STORED_Q; i++) {
for (j = 0; j < 64; j++)
ctx->quants[i][j] = ctx->quant_mat[j] * i;
}

ctx->slice_q = av_malloc(ctx->slices_per_picture * sizeof(*ctx->slice_q));
if (!ctx->slice_q) {
encode_close(avctx);
return AVERROR(ENOMEM);
}

ctx->tdata = av_mallocz(avctx->thread_count * sizeof(*ctx->tdata));
if (!ctx->tdata) {
encode_close(avctx);
return AVERROR(ENOMEM);
}

for (j = 0; j < avctx->thread_count; j++) {
ctx->tdata[j].nodes = av_malloc((ctx->slices_width + 1)
* TRELLIS_WIDTH
* sizeof(*ctx->tdata->nodes));
if (!ctx->tdata[j].nodes) {
encode_close(avctx);
return AVERROR(ENOMEM);
}
for (i = min_quant; i < max_quant + 2; i++) {
ctx->tdata[j].nodes[i].prev_node = -1;
ctx->tdata[j].nodes[i].bits = 0;
ctx->tdata[j].nodes[i].score = 0;
}
}
}

编辑:

ffmpeg.exe 的输出:

profile 4, 1020 slices, interlacing: no, 6576 bits per MB
frame size upper bound: 11429274

我的应用程序上 ffmpeg avlog 的输出:

profile 4, 1020 slices, interlacing: no, 1425 bits per MB
frame size upper bound: 6170103

最佳答案

有一些 hack 支持旧的编解码器。所以输入值在内部相乘。需要做与 ffmpeg.exe 相同的操作

#define FF_QP2LAMBDA 118

//from ffmpeg_opt.c

ost->enc_ctx->global_quality = FF_QP2LAMBDA * qscale;

关于无法复制 FFMpeg Prores 质量设置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42032065/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com