FFmpeg C Api - 降低 fps 但保持视频持续时间
FFmpeg C Api - Reduce fps but maintain video duration
使用 FFmpeg C API 我正在尝试将输入视频转换为看起来像动画 gif 的视频 - 这意味着没有音频流和 4/fps 的视频流。
我有 decode/encode 部分工作。我可以从输出文件中删除音频流,但我无法降低 fps。我可以将输出视频流的 time_base 更改为 4/fps,但它会增加视频的持续时间 - 基本上以慢动作播放。
我想我需要在将它们写入输出容器之前删除额外的帧。
下面是我读取输入帧的循环,然后将它们写入输出容器。
这是我要删除额外帧的地方吗?如何确定要丢弃的帧(I、P、B 帧)?
while(av_read_frame(input_container, &decoded_packet)>=0) {
if (decoded_packet.stream_index == video_stream_index) {
len = avcodec_decode_video2(input_stream->codec, decoded_frame, &got_frame, &decoded_packet);
if(len < 0) {
exit(1);
}
if(got_frame) {
av_init_packet(&encoded_packet);
encoded_packet.data = NULL;
encoded_packet.size = 0;
if(avcodec_encode_video2(output_stream->codec, &encoded_packet, decoded_frame, &got_frame) < 0) {
exit(1);
}
if(got_frame) {
if (output_stream->codec->coded_frame->key_frame) {
encoded_packet.flags |= AV_PKT_FLAG_KEY;
}
encoded_packet.stream_index = output_stream->index;
encoded_packet.pts = av_rescale_q(current_frame_num, output_stream->codec->time_base, output_stream->time_base);
encoded_packet.dts = av_rescale_q(current_frame_num, output_stream->codec->time_base, output_stream->time_base);
if(av_interleaved_write_frame(output_container, &encoded_packet) < 0) {
exit(1);
}
else {
current_frame_num +=1;
}
}
frame_count+=1;
av_free_packet(&encoded_packet);
}
}
}
您似乎正在对视频进行解码然后重新编码。在解码状态下,没有 I/B/P 这样的东西。它们都是 I 帧。这也是您应该丢帧的地方。您必须解码每一帧,但一旦解码,只需不将它们发送到编码器即可丢弃不再需要的帧。最后,根本不要碰时基。
使用 FFmpeg C API 我正在尝试将输入视频转换为看起来像动画 gif 的视频 - 这意味着没有音频流和 4/fps 的视频流。
我有 decode/encode 部分工作。我可以从输出文件中删除音频流,但我无法降低 fps。我可以将输出视频流的 time_base 更改为 4/fps,但它会增加视频的持续时间 - 基本上以慢动作播放。
我想我需要在将它们写入输出容器之前删除额外的帧。
下面是我读取输入帧的循环,然后将它们写入输出容器。
这是我要删除额外帧的地方吗?如何确定要丢弃的帧(I、P、B 帧)?
while(av_read_frame(input_container, &decoded_packet)>=0) {
if (decoded_packet.stream_index == video_stream_index) {
len = avcodec_decode_video2(input_stream->codec, decoded_frame, &got_frame, &decoded_packet);
if(len < 0) {
exit(1);
}
if(got_frame) {
av_init_packet(&encoded_packet);
encoded_packet.data = NULL;
encoded_packet.size = 0;
if(avcodec_encode_video2(output_stream->codec, &encoded_packet, decoded_frame, &got_frame) < 0) {
exit(1);
}
if(got_frame) {
if (output_stream->codec->coded_frame->key_frame) {
encoded_packet.flags |= AV_PKT_FLAG_KEY;
}
encoded_packet.stream_index = output_stream->index;
encoded_packet.pts = av_rescale_q(current_frame_num, output_stream->codec->time_base, output_stream->time_base);
encoded_packet.dts = av_rescale_q(current_frame_num, output_stream->codec->time_base, output_stream->time_base);
if(av_interleaved_write_frame(output_container, &encoded_packet) < 0) {
exit(1);
}
else {
current_frame_num +=1;
}
}
frame_count+=1;
av_free_packet(&encoded_packet);
}
}
}
您似乎正在对视频进行解码然后重新编码。在解码状态下,没有 I/B/P 这样的东西。它们都是 I 帧。这也是您应该丢帧的地方。您必须解码每一帧,但一旦解码,只需不将它们发送到编码器即可丢弃不再需要的帧。最后,根本不要碰时基。