我正在尝试使用以下代码录制h.264直播流:
AVOutputFormat* fmt = av_guess_format(NULL, "test.mpeg", NULL);
AVFormatContext* oc = avformat_alloc_context();
oc->oformat = fmt;
avio_open2(&oc->pb, "test.mpeg", AVIO_FLAG_WRITE, NULL, NULL);
AVStream* stream = NULL;
...
while(!done)
{
// Read a frame
if(av_read_frame(inputStreamFormatCtx, &packet)<0)
return false;
if(packet.stream_index==correct_index)
{
////////////////////////////////////////////////////////////////////////
// Is this a packet from the video stream -> decode video frame
if (stream == NULL){//create stream in file
stream = avformat_new_stream(oc, pFormatCtx->streams[videoStream]->codec->codec);
avcodec_copy_context(stream->codec, pFormatCtx->streams[videoStream]->codec);
stream->sample_aspect_ratio = pFormatCtx->streams[videoStream]->codec->sample_aspect_ratio;
stream->sample_aspect_ratio.num = pFormatCtx->streams[videoStream]->codec->sample_aspect_ratio.num;
stream->sample_aspect_ratio.den = pFormatCtx->streams[videoStream]->codec->sample_aspect_ratio.den;
// Assume r_frame_rate is accurate
stream->r_frame_rate = pFormatCtx->streams[videoStream]->r_frame_rate;
stream->avg_frame_rate = stream->r_frame_rate;
stream->time_base = av_inv_q(stream->r_frame_rate);
stream->codec->time_base = stream->time_base;
avformat_write_header(oc, NULL);
}
av_write_frame(oc, &packet);
...
}
}
然而,ffmpeg说
encoder did not produce proper pts making some up
当代码运行到av_write_frame()时;这有什么问题?
答案 0 :(得分:1)
首先确保inputStreamFormatCtx
已分配并填充正确的值(这是导致90%问题的解复用/重新转发问题) - 检查互联网上的一些示例以了解您应如何分配和设置其值。
错误告诉我们发生了什么,似乎只是一个警告。
PTS(演示时间戳)是基于stream->time_base
的数字,它告诉我们何时应该显示该数据包的解码帧。当你通过网络获得实时流时,服务器可能没有为数据包的PTS设置有效数字,当你收到数据时,它有一个无效的PTS(你可以通过阅读{{ 1}}并检查它是否为packet.pts
)。所以然后libav尝试根据流的帧速率和time_base生成正确的pts。这是一个有用的尝试,如果录制的文件可以在真实动作(fps-wise)上播放,你应该感到高兴。如果录制的文件将以快速或慢速运动(fps-wise)播放,则表示您遇到问题,并且您无法依靠libav来纠正fps。那么你应该通过解码数据包来计算正确的fps,然后根据AV_NOPTS_VALUE
计算出正确的pts并将其设置为stream->time_base
。