使用ffmpeg将网络流保存到本地视频文件时的码率异常

y0724 2017-11-28 11:46:51
接收并解码网络视频流,使用的是ffmpeg3.4,解码显示正常,但是在保存到本地文件时,标清流保存的文件码率正常,高清流保存是,码率总是不能正常设置。不知道为什么,大神们帮忙看看。

代码如下,保存本地文件的时候,直接保存的packet,解码的部分就不放上来了。

这段代码是在解码处理线程里面,标记为开始保存时,使用 avformat_write_header 写入文件头,在每收到一个packet时,使用av_interleaved_write_frame 写入一个包,标记为结束保存时,使用av_write_trailer写入文件尾,并且关闭输出流。

文件保存正常,也能正常播放,标清流一切正常,播放速度正常,查看文件时帧速率基本都是25左右;高清流时,帧速率就是一个很大的数据,导致播放时速度异常。

标清文件帧速率信息

高清文件帧速率信息




ret = av_read_frame(pFormatCtx, packet);
if( ret>=0){
if(packet->stream_index==videoindex){

CLogDebug( LogModuleName, "[FfmpegPlay.play hwnd:%d] av_read_frame get packet. packet.size:%d", playhwnd, packet->size);

//修改为3.x模式 解码函数
//将接收到的包发送给解码器进行解码处理
got_picture = avcodec_send_packet(pCodecCtx,packet);

//修改前代码
//ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);

if (got_picture >=0)
{
// 录像相关处理(基于 packet 数据进行)
if (FlagstartVideo && !FlagstopVideo)
{
if (flag)
{
//const char *outfilename = "1.mp4";
const char *outfilename = m_RecordfilePath.c_str();

//o_fmt_ctx = avformat_alloc_context();
avformat_alloc_output_context2(&o_fmt_ctx, NULL, NULL, outfilename);
o_video_stream = avformat_new_stream(o_fmt_ctx, NULL);
{
// 修改为 3.4模式 解码器上下文获取方式
avcodec_parameters_copy( o_video_stream->codecpar, i_video_stream->codecpar );

o_video_stream->time_base = i_video_stream->time_base;
o_video_stream->avg_frame_rate = i_video_stream->avg_frame_rate;
o_video_stream->r_frame_rate = i_video_stream->r_frame_rate;
o_video_stream->display_aspect_ratio = i_video_stream->display_aspect_ratio;
}


avio_open(&o_fmt_ctx->pb, outfilename, AVIO_FLAG_WRITE);

//AVDictionary* opt = NULL;
//av_dict_set_int(&opt, "video_track_timescale", 25, 0);
avformat_write_header(o_fmt_ctx, &opt);
flag = false;
}

packet->flags |= AV_PKT_FLAG_KEY;
pts = packet->pts;
packet->pts += last_pts;
dts = packet->dts;
packet->dts += last_dts;
packet->stream_index = 0;
av_interleaved_write_frame(o_fmt_ctx, packet);
}

if (FlagstopVideo && FlagstartVideo)
{
FlagstartVideo = false;
FlagstopVideo = false;
av_write_trailer(o_fmt_ctx);
flag = true;

av_freep(&o_fmt_ctx->streams[0]);

avio_close(o_fmt_ctx->pb);
//av_free(o_fmt_ctx);
avformat_free_context(o_fmt_ctx);
}
}



...全文
1148 3 打赏 收藏 转发到动态 举报
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
百灵工作室 2018-01-04
  • 打赏
  • 举报
回复
检查时间戳的间隔,时间戳间隔异常时,考虑变换时间基,time_base进行打时间戳
fighttosky 2017-12-12
  • 打赏
  • 举报
回复
同问,ffmpeg3.4下,输出流的时候在哪里设置帧率? 尝试着设置了下面代码里面的那些属性,貌似都不行。 也是标清的还行,一到高清就不行。

							const char *outfilename = m_RecordfilePath.c_str();

							avformat_alloc_output_context2(&o_fmt_ctx, NULL, NULL, outfilename);
							
							o_video_stream = avformat_new_stream(o_fmt_ctx, NULL);
							
							octx = avcodec_alloc_context3(NULL);
							avcodec_parameters_to_context(octx,i_video_stream->codecpar);
							octx->time_base.num = i_video_stream->time_base.num;
							octx->time_base.den = i_video_stream->time_base.den;
							octx->pix_fmt = pCodecCtx->pix_fmt;
							octx->flags = pCodecCtx->flags;
							octx->flags |= CODEC_FLAG_GLOBAL_HEADER;
							octx->codec_type = pCodecCtx->codec_type;
							octx->bit_rate = pCodecCtx->bit_rate;
							octx->me_range = pCodecCtx->me_range;
							octx->max_qdiff = pCodecCtx->max_qdiff;
							octx->qmin = pCodecCtx->qmin;
							octx->qmax = pCodecCtx->qmax;
							octx->qcompress = pCodecCtx->qcompress;
							
							oc = avcodec_find_encoder( octx->codec_id );

							int iret = avcodec_open2( octx, oc, NULL );
							TRACE("======%d========\r\n",iret);

							avcodec_parameters_from_context(o_video_stream->codecpar, octx);

							av_stream_set_r_frame_rate(o_video_stream, i_video_stream->r_frame_rate);

							avio_open(&o_fmt_ctx->pb, outfilename, AVIO_FLAG_WRITE);
							
							AVDictionary* opt = NULL;
							//av_dict_set_int(&opt, "video_track_timescale", 25, 0);
							avformat_write_header(o_fmt_ctx, &opt);

rightorwrong 2017-11-30
  • 打赏
  • 举报
回复
帧率是可以设置的啊

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧