ffempg硬件缩放C++使用scale_cuda过滤器缩放视频

时间: 2023-09-16 15:14:06 浏览: 55
ffmpeg是一个非常强大的开源多媒体处理库,它支持各种格式的视频和音频的编解码、转换、过滤等操作。在ffmpeg中,scale_cuda过滤器可以使用GPU加速进行视频缩放。 下面是使用scale_cuda过滤器进行视频缩放的C++代码示例: ```c++ #include <iostream> #include <string> #include <opencv2/opencv.hpp> #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libavutil/opt.h> #include <libavutil/imgutils.h> #include <libavfilter/avfilter.h> #include <libavfilter/buffersink.h> #include <libavfilter/buffersrc.h> using namespace std; using namespace cv; int main(int argc, char* argv[]) { if (argc != 4) { cout << "Usage: ./scale_cuda <input_file> <width> <height>" << endl; return -1; } string input_file = argv[1]; int dst_width = stoi(argv[2]); int dst_height = stoi(argv[3]); // 初始化ffmpeg av_register_all(); avfilter_register_all(); // 打开输入文件 AVFormatContext* input_ctx = nullptr; if (avformat_open_input(&input_ctx, input_file.c_str(), nullptr, nullptr) < 0) { cout << "Failed to open input file" << endl; return -1; } // 获取视频流信息 if (avformat_find_stream_info(input_ctx, nullptr) < 0) { cout << "Failed to find stream information" << endl; avformat_close_input(&input_ctx); return -1; } // 获取视频流索引 int video_stream_index = -1; for (unsigned int i = 0; i < input_ctx->nb_streams; i++) { if (input_ctx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { video_stream_index = i; break; } } if (video_stream_index == -1) { cout << "Failed to find video stream" << endl; avformat_close_input(&input_ctx); return -1; } // 创建输入流上下文 AVCodecParameters* codecpar = input_ctx->streams[video_stream_index]->codecpar; AVStream* input_stream = input_ctx->streams[video_stream_index]; AVCodec* codec = avcodec_find_decoder(codecpar->codec_id); AVCodecContext* codec_ctx = avcodec_alloc_context3(codec); avcodec_parameters_to_context(codec_ctx, codecpar); avcodec_open2(codec_ctx, codec, nullptr); AVFrame* raw_frame = av_frame_alloc(); AVPacket* packet = av_packet_alloc(); // 创建输出流上下文 AVFilterContext* buffersrc_ctx = nullptr; AVFilterContext* buffersink_ctx = nullptr; AVFilterGraph* filter_graph = avfilter_graph_alloc(); // 创建buffersrc过滤器 AVFilter* buffersrc = avfilter_get_by_name("buffer"); AVDictionary* options = nullptr; av_dict_set(&options, "video_size", "1920x1080", 0); av_dict_set(&options, "pix_fmt", "0", 0); av_dict_set(&options, "time_base", "1/25", 0); av_dict_set(&options, "pixel_aspect", "0/1", 0); char args[512]; snprintf(args, sizeof(args), "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d", codec_ctx->width, codec_ctx->height, codec_ctx->pix_fmt, input_stream->time_base.num, input_stream->time_base.den, codecpar->sample_aspect_ratio.num, codecpar->sample_aspect_ratio.den); avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in", args, options, filter_graph); // 创建scale_cuda过滤器 AVFilter* scale_cuda = avfilter_get_by_name("scale_cuda"); snprintf(args, sizeof(args), "%d:%d", dst_width, dst_height); avfilter_graph_create_filter(&buffersink_ctx, scale_cuda, "out", args, nullptr, filter_graph); // 连接过滤器 avfilter_link(buffersrc_ctx, 0, buffersink_ctx, 0); avfilter_graph_config(filter_graph, nullptr); // 读取视频帧并进行缩放 Mat frame; AVFrame* scaled_frame = av_frame_alloc(); while (av_read_frame(input_ctx, packet) >= 0) { if (packet->stream_index == video_stream_index) { avcodec_send_packet(codec_ctx, packet); while (avcodec_receive_frame(codec_ctx, raw_frame) == 0) { av_buffersrc_add_frame_flags(buffersrc_ctx, raw_frame, AV_BUFFERSRC_FLAG_KEEP_REF); while (av_buffersink_get_frame(buffersink_ctx, scaled_frame) == 0) { av_image_fill_arrays(scaled_frame->data, scaled_frame->linesize, frame.data, AV_PIX_FMT_BGR24, dst_width, dst_height, 1); frame = Mat(dst_height, dst_width, CV_8UC3, scaled_frame->data[0], scaled_frame->linesize[0]); imshow("Scaled Video", frame); waitKey(1); av_frame_unref(scaled_frame); } } } av_packet_unref(packet); } // 释放资源 avfilter_graph_free(&filter_graph); avcodec_free_context(&codec_ctx); av_packet_free(&packet); av_frame_free(&raw_frame); av_frame_free(&scaled_frame); avformat_close_input(&input_ctx); return 0; } ``` 在这个示例中,我们首先使用ffmpeg打开输入视频文件,并获取视频流的信息和索引。然后创建输入流和输出流的上下文,以及buffersrc和scale_cuda过滤器。最后,我们使用av_read_frame()函数读取视频帧,并使用av_buffersrc_add_frame_flags()函数将原始帧发送到buffersrc过滤器,然后使用av_buffersink_get_frame()函数从buffersink过滤器中获取缩放后的帧。最后,我们将缩放后的帧转换为OpenCV的Mat格式,并使用imshow()函数显示到窗口中。

相关推荐

最新推荐

recommend-type

基于多相位插值的视频缩放系统FPGA实现

其中硬件电路控制部分使用Xilinx公司的Spartan6系列FPGA芯片,系统可以实现将四路摄像头采集的视频信号从任意通道放大到1 920x1 080@60 Hz的分辨率显示,结果表明输出视频图像的实时性和细节保持良好。
recommend-type

JS实现禁止用户使用Ctrl+鼠标滚轮缩放网页的方法

主要介绍了JS实现禁止用户使用Ctrl+鼠标滚轮缩放网页的方法,涉及javascript页面元素与事件相关操作技巧,需要的朋友可以参考下
recommend-type

用JAVA获取视频文件中的帧图片并等比缩放

用JAVA获取视频文件中的帧图片并等比缩放,java 获取视频中图片 缩放比例 javacv
recommend-type

Unity3D使用鼠标旋转缩放平移视角

主要为大家详细介绍了Unity3D使用鼠标旋转缩放平移视角,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
recommend-type

Android使用Photoview实现图片左右滑动及缩放功能

主要为大家详细介绍了Android使用Photoview实现图片左右滑动及缩放功能,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
recommend-type

zigbee-cluster-library-specification

最新的zigbee-cluster-library-specification说明文档。
recommend-type

管理建模和仿真的文件

管理Boualem Benatallah引用此版本:布阿利姆·贝纳塔拉。管理建模和仿真。约瑟夫-傅立叶大学-格勒诺布尔第一大学,1996年。法语。NNT:电话:00345357HAL ID:电话:00345357https://theses.hal.science/tel-003453572008年12月9日提交HAL是一个多学科的开放存取档案馆,用于存放和传播科学研究论文,无论它们是否被公开。论文可以来自法国或国外的教学和研究机构,也可以来自公共或私人研究中心。L’archive ouverte pluridisciplinaire
recommend-type

实现实时数据湖架构:Kafka与Hive集成

![实现实时数据湖架构:Kafka与Hive集成](https://img-blog.csdnimg.cn/img_convert/10eb2e6972b3b6086286fc64c0b3ee41.jpeg) # 1. 实时数据湖架构概述** 实时数据湖是一种现代数据管理架构,它允许企业以低延迟的方式收集、存储和处理大量数据。与传统数据仓库不同,实时数据湖不依赖于预先定义的模式,而是采用灵活的架构,可以处理各种数据类型和格式。这种架构为企业提供了以下优势: - **实时洞察:**实时数据湖允许企业访问最新的数据,从而做出更明智的决策。 - **数据民主化:**实时数据湖使各种利益相关者都可
recommend-type

list根据id查询pid 然后依次获取到所有的子节点数据

可以使用递归的方式来实现根据id查询pid并获取所有子节点数据。具体实现可以参考以下代码: ``` def get_children_nodes(nodes, parent_id): children = [] for node in nodes: if node['pid'] == parent_id: node['children'] = get_children_nodes(nodes, node['id']) children.append(node) return children # 测试数
recommend-type

JSBSim Reference Manual

JSBSim参考手册,其中包含JSBSim简介,JSBSim配置文件xml的编写语法,编程手册以及一些应用实例等。其中有部分内容还没有写完,估计有生之年很难看到完整版了,但是内容还是很有参考价值的。