如何在FFmpeg C API编码之前计算帧的正确PTS值?
对于编码我正在使用函数avcodec_encode_video2,然后通过编写它av_interleaved_write_frame.
我发现了一些公式,但其中没有一个不起作用.
在doxygen示例中,他们正在使用
frame->pts = 0;
for (;;) {
// encode & write frame
// ...
frame->pts += av_rescale_q(1, video_st->codec->time_base, video_st->time_base);
}
Run Code Online (Sandbox Code Playgroud)
这篇博客说公式必须是这样的:
(1/FPS)*采样率*帧数
有人只使用帧号来设置pts:
frame->pts = videoCodecCtx->frame_number;
Run Code Online (Sandbox Code Playgroud)
或者替代方式:
int64_t now = av_gettime();
frame->pts = av_rescale_q(now, (AVRational){1, 1000000}, videoCodecCtx->time_base);
Run Code Online (Sandbox Code Playgroud)
最后一个:
// 40 * 90 means 40 ms and 90 because of the 90kHz by the standard for PTS-values.
frame->pts = encodedFrames * 40 * 90;
Run Code Online (Sandbox Code Playgroud)
哪一个是正确的?我认为这个问题的答案不仅对我有帮助.
如何使用FFmpeg C API剪切视频?例如从00:10:00到00:20:00.我需要使用哪些功能?
我使用此功能转换视频:
int convert(char *file) {
AVFrame *frame;
AVPacket inPacket, outPacket;
if(avio_open(&outFormatContext->pb, file, AVIO_FLAG_WRITE) < 0) {
fprintf(stderr, "convert(): cannot open out file\n");
return 0;
}
avformat_write_header(outFormatContext, NULL);
frame = avcodec_alloc_frame();
av_init_packet(&inPacket);
while(av_read_frame(inFormatContext, &inPacket) >= 0) {
if(inPacket.stream_index == inVideoStreamIndex) {
avcodec_decode_video2(inCodecContext, frame, &frameFinished, &inPacket);
if(frameFinished) {
av_init_packet(&outPacket);
avcodec_encode_video2(outCodecContext, &outPacket, frame, &outputed);
if(outputed) {
if (av_write_frame(outFormatContext, &outPacket) != 0) {
fprintf(stderr, "convert(): error while writing video frame\n");
return 0;
}
}
av_free_packet(&outPacket);
}
}
}
av_write_trailer(outFormatContext);
av_free_packet(&inPacket);
return …Run Code Online (Sandbox Code Playgroud)