【Qt+FFmpeg】FFmpeg解码固定摄像头分辨率——推流 av_dict_set 参数设置

你是否出现过ffmpeg编解码摄像头在自己电脑上是正常的,但是在别的机子上却不能编码成功,或者即使成功,也只画面显示了一部分,和自己电脑上测试的不一样;

根据我的测试,这应该是摄像头分辨率不匹配造成的,比如说你电脑的摄像头分辨率是1080*720,在比你分辨率高的摄像头如1920*1080上运行时,画面像是被放大,只显示了一角;如果你在比你摄像头分辨率低的电脑上运行,如640*480,编码完就不能正常生成h264文件;

解决方法:

我们需要用到AVDictionary字典,并运用av_dict_set进行设置摄像头分辨率,每次打开只调用640*480档位的;

AVDictionary* options = nullptr;
av_dict_set(&options,"video_size","640*480",0);
int avformat_open_result = avformat_open_input(&avformat_context,filename.toStdString().c_str(),fmt,&options);

然后我们讲一讲什么是AVDictionary;

FFmpeg中的AVDictionary是一个结构体,简单的key/value存储 ;

av_dict_set()可以用来创建AVDictionary,通过给方法传入NULL指针,其内部会创建新的AVDictionary,并通过这个指针返回给用户新创建的AVDictionary对象;注意上面源码的示例,在key和value都已经分配好空间的时候,使用av_dict_set()时需要设置flags以便使得函数内部不再为key和value另分配空间了,直接利用外部已经分配好的

av_dict_set其他的一些参数设置:

一、关于影响时延的参数设置

1.preset :指定编码的配置

例:av_dict_set(&param, "preset", "ultrafast", 0);

2.muxdelay || max_delay:设置延迟约束,muxdelay以秒为单位设置延迟,而max_delay以微秒为单位设置延迟。最终结果是相同的。
例:av_dict_set(&param, "muxdelay", "1", 0);

3.zerolatency:转码延迟,以牺牲视频质量减少时延
例:av_dict_set(&param, "tune", "zerolatency", 0);

 

二、关于影响视频质量的参数设置

1.crf:用于指定输出视频的质量,取值范围是0-51,默认值为23,数字越小输出视频的质量越高。

例:av_dict_set(&param, "crf", "18", 0);

2.level:越高视频质量也就越高
例:av_dict_set(&param, "level", "4",0);

在这里插入图片描述 

三、其它

1.buffer_size:减少卡顿或者花屏现象,相当于增加或扩大了缓冲区,给予编码和发送足够的时间
例:av_dict_set(&param, "buffer_size", "1024000", 0);

2.rtsp_transport:修改优先连接发送方式,可以用udp、tcp、rtp
例:av_dict_set(&param, "rtsp_transport", "udp", 0);

3.stimeout:设置超时断开,在进行连接时是阻塞状态,若没有设置超时断开则会一直去阻塞获取数据,单位是微秒。
例:av_dict_set(&param, "stimeout", "5000000", 0);

4.movflags :加入mp4头。
例:av_dict_set(&param, "movflags", "empty_moov+default_base_moof+faststart", 0);

5.frag_duration:设定mp4容器大小
例:av_dict_set_int(&param,''frag_duration", 100 * 1000, 0);

av_dict_set其他设置详情参考

ffmpeg推流 av_dict_set 参数设置解析(降低延时、处理花屏、改善画面质量)(实时更新)_ZackZheng999的博客-CSDN博客_av_dict_set

 

感谢观看!!!!

以上就是全部内容,如果对您有帮助,欢迎点赞评论,或者发现有哪里写错的,欢迎指正!

 

以下是保存HDMI视频数据录像的Qt源代码示例: ```C++ #include <QCoreApplication> #include <QThread> #include <QDateTime> #include <QFile> #include <QDataStream> extern "C" { #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavdevice/avdevice.h> } int main(int argc, char *argv[]) { QCoreApplication a(argc, argv); // 初始化ffmpegav_register_all(); avdevice_register_all(); AVInputFormat *inputFormat = av_find_input_format("dshow"); AVDictionary *options = NULL; av_dict_set(&options, "video_size", "1920x1080", 0); av_dict_set(&options, "pixel_format", "uyvy422", 0); av_dict_set(&options, "framerate", "30", 0); av_dict_set(&options, "buffer_size", "1048576", 0); AVFormatContext *formatContext = NULL; int ret = avformat_open_input(&formatContext, "video=HD Webcam:audio=麦克风 (HD Webcam)", inputFormat, &options); if (ret != 0) { qDebug() << "avformat_open_input error" << av_err2str(ret); return 1; } // 查找视频 int videoStreamIndex = -1; for (int i = 0; i < formatContext->nb_streams; i++) { if (formatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { videoStreamIndex = i; break; } } if (videoStreamIndex == -1) { qDebug() << "can't find video stream"; return 1; } // 打开视频解码AVCodecParameters *videoCodecpar = formatContext->streams[videoStreamIndex]->codecpar; AVCodec *videoCodec = avcodec_find_decoder(videoCodecpar->codec_id); AVCodecContext *videoCodecContext = avcodec_alloc_context3(videoCodec); ret = avcodec_parameters_to_context(videoCodecContext, videoCodecpar); if (ret != 0) { qDebug() << "avcodec_parameters_to_context error" << av_err2str(ret); return 1; } ret = avcodec_open2(videoCodecContext, videoCodec, NULL); if (ret != 0) { qDebug() << "avcodec_open2 error" << av_err2str(ret); return 1; } // 准备视频帧 AVFrame *videoFrame = av_frame_alloc(); if (videoFrame == NULL) { qDebug() << "av_frame_alloc error"; return 1; } // 打开输出文件 QDateTime currentDateTime = QDateTime::currentDateTime(); QString fileName = currentDateTime.toString("yyyyMMdd_hhmmss") + ".avi"; QFile file(fileName); if (!file.open(QIODevice::WriteOnly)) { qDebug() << "open file error" << fileName; return 1; } // 写入文件头 AVOutputFormat *outputFormat = av_guess_format("avi", NULL, NULL); AVFormatContext *outFormatContext = NULL; ret = avformat_alloc_output_context2(&outFormatContext, outputFormat, NULL, fileName.toUtf8().data()); if (ret != 0) { qDebug() << "avformat_alloc_output_context2 error"
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

logani

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值