目录一、前言二、效果图三、体验地址四、相关代码五、功能特点5.1 基础功能5.2 特色功能5.3 视频控件一、前言 用手机或者平板拍摄的视频文件,很可能是旋转的,比如分辨率是1280
用手机或者平板拍摄的视频文件,很可能是旋转的,比如分辨率是1280x720,确是垂直的,相当于分辨率变成了720x1280,如果不做旋转处理的话,那脑袋必须歪着看才行,这样看起来太难受,所以一定要想办法解析到视频的旋转角度,然后根据这个角度重新绘制。在窗体那边也需要调整对应的分辨率,一般都是宽度高度互换。其实早期的很多播放器比如vlc2版本的播放器也是不支持旋转的,从vlc3开始内置会自动给旋转,估计这种场景越来越多,毕竟现在智能手机大行其道,用手机拍摄的视频很多都是竖屏的。
在FFmpeg中旋转frame帧数据,有多种方式,方式一是直接通过运算逐行取出数据,重新组织旋转后的视频帧数据;方式二通过滤镜来实现。最开始还没学会用ffmpeg的滤镜的时候,用的就是方式一,通俗易懂,但是很傻,尤其是运算很占CPU,毕竟for循环来个很多次挨个取数据又重新组织数据。自从学会用ffmpeg滤镜以后,从滤镜大全中找到了居然也支持旋转,而且任意角度旋转都可以,甚至镜像操作,这就非常强大了,马上将这个架构的旋转部分全部换成了滤镜旋转,连之前用于旋转的中间过渡帧数据变量都不需要,代码更精简,功能更强大,拓展性更好,这其实就是一个不断精进迭代的过程,第一步解决从无到有的过程,后面才是持续不断的完善。
国内站点:https://gitee.com/feiyangqingyun
国际站点:Https://GitHub.com/feiyangqingyun
体验地址:https://pan.baidu.com/s/1YOVD8nkoOSYwX9KgSauLeQ 提取码:kcgz 文件名:bin_video_demo/bin_linux_video。
int FFmpegFilter::initFilter(AbstractVideoThread *thread, AVStream *stream, AVCodecContext *avctx, FilterData &filterData)
{
int result = -1;
if (!filterData.enable) {
return result;
}
//貌似硬解码不支持滤镜
if (filterData.fORMatIn == AV_PIX_FMT_NV12) {
return result;
}
//先释放相关资源
freeFilter(filterData);
//获取滤镜字符串
QString filters = getFilter(filterData);
if (filters.isEmpty()) {
return result;
}
//输入帧序列的参数信息
QStringList listArg;
listArg << QString("video_size=%1x%2").arg(avctx->width).arg(avctx->height);
listArg << QString("pix_fmt=%1").arg(avctx->pix_fmt);
listArg << QString("time_base=%1/%2").arg(stream->time_base.num).arg(stream->time_base.den);
listArg << QString("pixel_aspect=%1/%2").arg(avctx->sample_aspect_ratio.num).arg(avctx->sample_aspect_ratio.den);
QString args = listArg.join(":");
//输入帧格式
enum AVPixelFormat pix_fmts[] = {filterData.formatIn, AV_PIX_FMT_NONE};
//获取要使用的滤镜
const AVFilter *filterSrc = avfilter_get_by_name("buffer");
const AVFilter *filterSink = avfilter_get_by_name("buffersink");
//创建输入输出滤镜参数
AVFilterInOut *inputs = avfilter_inout_alloc();
AVFilterInOut *outputs = avfilter_inout_alloc();
//创建滤镜容器
filterData.filterGraph = avfilter_graph_alloc();
if (!inputs || !outputs || !filterData.filterGraph) {
result = AVERROR(ENOMEM);
Goto end;
}
//创建输入滤镜
result = avfilter_graph_create_filter(&filterData.filterSrcCtx, filterSrc, "in", args.toUtf8().constData(), NULL, filterData.filterGraph);
if (result < 0) {
thread->debug("滤镜处理", QString("创建输入滤镜失败: %1").arg(FFmpegHelper::getError(result)), "");
goto end;
}
//创建输出滤镜
result = avfilter_graph_create_filter(&filterData.filterSinkCtx, filterSink, "out", NULL, NULL, filterData.filterGraph);
if (result < 0) {
thread->debug("滤镜处理", QString("创建输出滤镜失败: %1").arg(FFmpegHelper::getError(result)), "");
goto end;
}
//设置输出滤镜格式
result = av_opt_set_int_list(filterData.filterSinkCtx, "pix_fmts", pix_fmts, filterData.formatOut, AV_OPT_SEARCH_CHILDREN);
if (result < 0) {
thread->debug("滤镜处理", QString("设置输出滤镜格式: %1").arg(FFmpegHelper::getError(result)), "");
goto end;
}
//设置滤镜的参数
outputs->name = av_strdup("in");
outputs->filter_ctx = filterData.filterSrcCtx;
outputs->pad_idx = 0;
outputs->next = NULL;
inputs->name = av_strdup("out");
inputs->filter_ctx = filterData.filterSinkCtx;
inputs->pad_idx = 0;
inputs->next = NULL;
//初始化滤镜
result = avfilter_graph_parse_ptr(filterData.filterGraph, filters.toUtf8().constData(), &inputs, &outputs, NULL);
if (result < 0) {
thread->debug("滤镜处理", QString("初始化滤镜失败: %1").arg(FFmpegHelper::getError(result)), "");
goto end;
}
//应用滤镜配置
result = avfilter_graph_config(filterData.filterGraph, NULL);
if (result < 0) {
thread->debug("滤镜处理", QString("应用滤镜配置失败: %1").arg(FFmpegHelper::getError(result)), "");
goto end;
}
end:
//释放对应的输入输出
avfilter_inout_free(&inputs);
avfilter_inout_free(&outputs);
filterData.isOk = (result >= 0);
return result;
}
void FFmpegFilter::freeFilter(FilterData &filterData)
{
if (filterData.isOk) {
filterData.enable = true;
filterData.init = true;
filterData.isOk = false;
avfilter_free(filterData.filterSrcCtx);
avfilter_free(filterData.filterSinkCtx);
avfilter_graph_free(&filterData.filterGraph);
filterData.filterSrcCtx = NULL;
filterData.filterSinkCtx = NULL;
filterData.filterGraph = NULL;
}
}
以上就是Qt音视频开发之实现ffmpeg视频旋转显示的详细内容,更多关于Qt ffmpeg视频旋转显示的资料请关注编程网其它相关文章!
--结束END--
本文标题: Qt音视频开发之实现ffmpeg视频旋转显示
本文链接: https://www.lsjlt.com/news/200872.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
下载Word文档到电脑,方便收藏和打印~
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0