gpt4 book ai didi

c++ - FFMPEG H264 编码每个单图像

转载 作者:行者123 更新时间:2023-12-03 01:34:19 29 4
gpt4 key购买 nike

我目前将 QImage 从 RGB888 编码为 H264,但我想单独对每个图像进行编码(即使这不是完美的方式)。我能够对图像进行编码,但需要将同一张图像发送 46 次。我不知道我做错了什么(可能是编码的配置错误,但我找不到那里的问题)。

然后我解码该图像,然后将其转换回 QImage。我这样做只是为了测试其他一些代码。

avcodec_register_all();

AVCodec *nVidiaCodec = avcodec_find_encoder_by_name("h264_nvenc");
if (!nVidiaCodec)
{
return false;
}

AVCodecContext* av_codec_context_ = NULL;
av_codec_context_ = avcodec_alloc_context3(nVidiaCodec);
if (!av_codec_context_)
{
return false;
}

av_codec_context_->width = dst->width;
av_codec_context_->height = dst->height;
av_codec_context_->pix_fmt = AV_PIX_FMT_YUV420P;
av_codec_context_->gop_size = 1;
av_codec_context_->keyint_min = 0;
av_codec_context_->scenechange_threshold = 0;
av_codec_context_->bit_rate = 8000000;
av_codec_context_->time_base.den = 1;
av_codec_context_->time_base.num = 1;
av_codec_context_->refs = 0;
av_codec_context_->qmin = 1;
av_codec_context_->qmax = 1;
av_codec_context_->b_frame_strategy = 0;
av_codec_context_->max_b_frames = 0;
av_codec_context_->thread_count = 1;

av_opt_set(av_codec_context_, "preset", "slow", 0);
av_opt_set(av_codec_context_, "tune", "zerolatency", 0);

int ret = avcodec_open2(av_codec_context_, nVidiaCodec, NULL);
if (0 > ret)
{
return false;
}

AVFrame *picture = av_frame_alloc();
picture->format = AV_PIX_FMT_RGB24;
picture->width = dst->width;
picture->height = dst->height;

ret = avpicture_fill((AVPicture *)picture, imgSrc.bits(), AV_PIX_FMT_RGB24, dst->width, dst->height);
if (0 > ret)
{
return false;
}

AVFrame *tmp_picture = av_frame_alloc();
tmp_picture->format = AV_PIX_FMT_YUV420P;
tmp_picture->width = dst->width;
tmp_picture->height = dst->height;
ret = av_frame_get_buffer(tmp_picture, 32);

SwsContext *img_convert_ctx = sws_getContext(av_codec_context_->width, av_codec_context_->height, AV_PIX_FMT_RGB24, av_codec_context_->width, av_codec_context_->height, av_codec_context_->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL);
if (!img_convert_ctx)
{
return false;
}
ret = sws_scale(img_convert_ctx, picture->data, picture->linesize, 0, av_codec_context_->height, tmp_picture->data, tmp_picture->linesize);
if (0 > ret)
{
return false;
}

ret = avcodec_send_frame(av_codec_context_, tmp_picture);
if (0 > ret)
{
return false;
}

AVPacket pkt;
av_init_packet(&pkt);
pkt.data = NULL;
pkt.size = 0;
do
{
ret = avcodec_receive_packet(av_codec_context_, &pkt);
if (ret == 0)
{
break;
}
else if ((ret < 0) && (ret != AVERROR(EAGAIN)))
{
return false;
}
else if (ret == AVERROR(EAGAIN))
{
ret = avcodec_send_frame(av_codec_context_, tmp_picture);
if (0 > ret)
{
return false;
}
}
} while (ret == 0);

// the do while is called 46 times, then i get the packet, but i want to get the packet at the first call

如果您能帮助我,那就太好了。

谢谢大家。

最佳答案

我假设您只想对单个帧进行编码。在发送单个未压缩帧后,您需要通过发送 NULL 而不是有效缓冲区来刷新编码器。

int result = 0;

// encoder init


// send one uncompressed frame
result = avcodec_send_frame(av_codec_context_, tmp_picture);

if (result < 0) return false;

// send NULL to indicate flushing
result = avcodec_send_frame(av_codec_context_, NULL);


if (result < 0) return false;


while (result != AVERROR_EOF)
{
result = avcodec_receive_packet(av_codec_context_, &pkt);

if (!result)
{
// you should have your encoded frame; do something with it
}
}

关于c++ - FFMPEG H264 编码每个单图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49446335/

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