gpt4 book ai didi

encoding - 视频编码和关键帧

转载 作者:行者123 更新时间:2023-12-01 03:59:10 25 4
gpt4 key购买 nike

我正在逐帧转码视频并使用 x264+ffmpeg 进行编码。原始视频播放良好,但我转码视频的前几帧显示灰色伪影。我知道这是因为时间压缩,这些伪影在几帧后消失了。

请看这两张图片,它们是第一帧和第二帧。第三帧是正常的(即没有灰色伪影,也不像第二帧那样模糊)
First frame
Second frame

如何强制第一帧成为关键帧(即在我的输出视频中完全编码),以使这些伪影不显示?

编辑 - 更多细节

这是我正在做的更多细节。我使用 bit form differents 教程逐帧读取视频并将每一帧重新编码为新视频。我的编码参数如下:

avcodec_get_context_defaults3(c, *codec);
c->codec_id = codec_id;
c->bit_rate = output_bitrate;
/* Resolution must be a multiple of two. */
c->width = output_width;
c->height = output_height;
/* timebase: This is the fundamental unit of time (in seconds) in terms
* of which frame timestamps are represented. For fixed-fps content,
* timebase should be 1/framerate and timestamp increments should be
* identical to 1. */
st->r_frame_rate.num = output_framerate_num;
st->r_frame_rate.den = output_framerate_den;
c->time_base.den = output_timebase_den;
c->time_base.num = output_timebase_num;
c->gop_size = 3; /* emit one intra frame every twelve frames at most */
c->pix_fmt = STREAM_PIX_FMT;
if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
/* just for testing, we also add B frames */
c->max_b_frames = 2;
}
if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
/* Needed to avoid using macroblocks in which some coeffs overflow.
* This does not happen with normal video, it just happens here as
* the motion of the chroma plane does not match the luma plane. */
c->mb_decision = 2;
}
c->max_b_frames = 2;
c->scenechange_threshold = 0;
c->rc_buffer_size = 0;
c->me_method = ME_ZERO;

然后我处理每一帧,可能在那里做错了什么。解码位:
while(av_read_frame(gFormatCtx, &packet)>=0) {
// Is this a packet from the video stream?
if(packet.stream_index==gVideoStreamIndex) {
// Decode video frame
avcodec_decode_video2(gVideoCodecCtx, pCurrentFrame, &frameFinished, &packet);
// Did we get a video frame?
if(frameFinished) {
[...]
if(firstPts == -999) /*Initial value*/
firstPts = packet.pts;
deltaPts = packet.pts - firstPts;
double seconds = deltaPts*av_q2d(gFormatCtx->streams[gVideoStreamIndex]->time_base);
[...]
muxing_writeVideoFrame(pCurrentFrame, packet.pts);
}
}
}

实际写法:
int muxing_writeVideoFrame(AVFrame *frame, int64_t pts)
{
frameCount = frameCount +1;
if(frameCount > 0)
{
if (video_st)
video_pts = (double)video_st->pts.val * video_st->time_base.num /
video_st->time_base.den;
else
video_pts = 0.0;

if (video_st && !(video_st && audio_st && audio_pts < video_pts))
{
frame->pts = pts;//av_rescale_q(frame_count, video_st->codec->time_base, video_st->time_base);
write_video_frame(oc, video_st, frame);
}
}

return 0;
}

static int write_video_frame(AVFormatContext *oc, AVStream *st, AVFrame *frame)
{
int ret;
static struct SwsContext *sws_ctx;
//LOGI(10, frame_count);
AVCodecContext *c = st->codec;

/* encode the image */
AVPacket pkt;
int got_output;
av_init_packet(&pkt);
pkt.data = NULL; // packet data will be allocated by the encoder
pkt.size = 0;
ret = avcodec_encode_video2(c, &pkt, frame, &got_output);
if (ret < 0) {
fprintf(stderr, "Error encoding video frame: %s\n", av_err2str(ret));
exit(1);
}
/* If size is zero, it means the image was buffered. */
if (got_output) {
if (c->coded_frame->key_frame)
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.stream_index = st->index;
/* Write the compressed frame to the media file. */
ret = av_interleaved_write_frame(oc, &pkt);
} else {
ret = 0;
}

if (ret != 0) {
LOGI(10, av_err2str(ret));
exit(1);
}
frame_count++;
return got_output;
}

最佳答案

您的问题很可能出在解码部分而不是编码中(x264 无法产生此类伪影)。如上所述,您似乎不是从关键帧开始解码(或者可能是您的流是开放式的,并且您没有丢弃第一个 B 帧)。

关于encoding - 视频编码和关键帧,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14676234/

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