我们在FFmpeg简单总结对FFmpeg 组成模块,编码进行了简单介绍。
FFmpeg组成部分:
libavcodec: 提供了音视频编解码器的库。
libavformat: 处理多媒体容器格式的库,包括封装和解封装。
libavutil: 包含一些公共的实用工具函数。
libswscale: 提供图像缩放和颜色转换功能的库。
libavfilter: 实现音视频过滤器的库,用于进行各种音视频处理操作。
ffmpeg: 命令行工具,用于进行音视频处理和转码。
ffprobe: 用于检测多媒体文件信息的命令行工具。
ffplay: 简单的播放器,支持音视频播放。
libswscale
libswscale(Software Scaling and Conversion Library)是FFmpeg中的一个库,用于执行图像缩放、颜色空间转换以及图像格式转换等操作。它主要提供了一些函数和工具,使得在视频处理过程中可以方便地进行图像大小和颜色空间的调整。
常用的API介绍
sws_getContext: 创建并返回一个SwsContext对象,用于设置缩放和颜色空间转换的参数。
struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat, int dstW, int dstH, enum AVPixelFormat dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, const double *param);
sws_scale: 将输入图像进行缩放和颜色空间转换,并将结果输出到目标图像。
int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[], const int srcStride[], int srcSliceY, int srcSliceH, uint8_t *const dst[], const int dstStride[]);
sws_freeContext: 释放SwsContext对象占用的资源。
void sws_freeContext(struct SwsContext *swsContext);
灰度化
下面给出一个例子,使用FFmpeg对图像进行处理,该程序解码视频流,选取视频流中的输入图片,进行灰度化处理,然后保存为新的图片
#include#include #include #include #include #include void process_image(const char *input_filename, const char *output_filename) { AVFormatContext *input_format_context = NULL; AVCodecContext *codec_context = NULL; AVCodec *codec = NULL; AVFrame *frame = NULL; AVFrame *gray_frame = NULL; AVPacket packet; struct SwsContext *sws_context = NULL; // Register FFmpeg components av_register_all(); // Open input file if (avformat_open_input(&input_format_context, input_filename, NULL, NULL) != 0) { fprintf(stderr, "Error opening input file\n"); exit(EXIT_FAILURE); } // Retrieve stream information if (avformat_find_stream_info(input_format_context, NULL) < 0) { fprintf(stderr, "Error finding stream information\n"); exit(EXIT_FAILURE); } // Find the first video stream int video_stream_index = -1; for (int i = 0; i < input_format_context->nb_streams; i++) { if (input_format_context->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) { video_stream_index = i; break; } } if (video_stream_index == -1) { fprintf(stderr, "Error: No video stream found\n"); exit(EXIT_FAILURE); } // Find the decoder for the video stream codec = avcodec_find_decoder(input_format_context->streams[video_stream_index]->codecpar->codec_id); if (!codec) { fprintf(stderr, "Error: No decoder found\n"); exit(EXIT_FAILURE); } // Allocate a codec context for the decoder codec_context = avcodec_alloc_context3(codec); if (!codec_context) { fprintf(stderr, "Error allocating codec context\n"); exit(EXIT_FAILURE); } // Copy codec parameters from input stream to codec context if (avcodec_parameters_to_context(codec_context, input_format_context->streams[video_stream_index]->codecpar) < 0) { fprintf(stderr, "Error setting codec parameters\n"); exit(EXIT_FAILURE); } // Open codec if (avcodec_open2(codec_context, codec, NULL) < 0) { fprintf(stderr, "Error opening codec\n"); exit(EXIT_FAILURE); } // Allocate video frames frame = av_frame_alloc(); gray_frame = av_frame_alloc(); if (!frame || !gray_frame) { fprintf(stderr, "Error allocating frames\n"); exit(EXIT_FAILURE); } // Determine required buffer size and allocate buffer int num_bytes = av_image_get_buffer_size(AV_PIX_FMT_GRAY8, codec_context->width, codec_context->height, 1); uint8_t *buffer = (uint8_t *)av_malloc(num_bytes * sizeof(uint8_t)); // Assign appropriate parts of buffer to image planes in gray_frame av_image_fill_arrays(gray_frame->data, gray_frame->linesize, buffer, AV_PIX_FMT_GRAY8, codec_context->width, codec_context->height, 1); // Initialize SwsContext for converting between color spaces sws_context = sws_getContext( codec_context->width, codec_context->height, codec_context->pix_fmt, codec_context->width, codec_context->height, AV_PIX_FMT_GRAY8, SWS_BILINEAR, NULL, NULL, NULL); // Open output file FILE *output_file = fopen(output_filename, "wb"); if (!output_file) { fprintf(stderr, "Error opening output file\n"); exit(EXIT_FAILURE); } // Read frames from the input file, convert to grayscale, and write to the output file while (av_read_frame(input_format_context, &packet) == 0) { if (packet.stream_index == video_stream_index) { // Decode video frame if (avcodec_receive_frame(codec_context, frame) == 0) { // Convert frame to grayscale sws_scale(sws_context, frame->data, frame->linesize, 0, frame->height, gray_frame->data, gray_frame->linesize); // Write grayscale frame to output file fwrite(gray_frame->data[0], 1, num_bytes, output_file); } } av_packet_unref(&packet); } // Cleanup fclose(output_file); av_frame_free(&frame); av_frame_free(&gray_frame); av_free(buffer); sws_freeContext(sws_context); avcodec_close(codec_context); avformat_close_input(&input_format_context); } int main() { const char *input_filename = "input.jpg"; const char *output_filename = "output.gray"; process_image(input_filename, output_filename); return 0; }
放大缩小
也可以直接用接口函数,对image操作
#include#include #include #include int main() { // Input image parameters int src_width = 1920; int src_height = 1080; enum AVPixelFormat src_format = AV_PIX_FMT_RGB24; // Output image parameters int dst_width = 640; int dst_height = 360; enum AVPixelFormat dst_format = AV_PIX_FMT_YUV420P; // Allocate source and destination buffers uint8_t *src_data[4]; int src_linesize[4]; uint8_t *dst_data[4]; int dst_linesize[4]; // Initialize SwsContext struct SwsContext *sws_context = sws_getContext(src_width, src_height, src_format, dst_width, dst_height, dst_format, SWS_BILINEAR, NULL, NULL, NULL); // Perform scaling and color space conversion sws_scale(sws_context, src_data, src_linesize, 0, src_height, dst_data, dst_linesize); // Free resources sws_freeContext(sws_context); return 0; }
猜你喜欢
- 11天前(鄂尔多斯航空公司客服电话)架起“北方之路” ,中国联合航空带您飞向鄂尔多斯重回1倍速
- 11天前(上海文旅产业发展高峰论坛)《上海打造文旅元宇宙新赛道行动方案》发布
- 11天前(中旅酒店 维景)中旅酒店首次AI数字人直播亮相南京维景
- 11天前(安徽民航君澜大饭店装饰设计招标)集东方文化气息,品徽派隽美风韵----安徽民航君澜大饭店静待绽放
- 11天前(天气预报 华为)2025HDC华为天气上新系统级天气智能体,引领更智能的气象服务
- 11天前(曼谷丽思卡尔顿公寓价格)在曼谷丽思卡尔顿酒店CALEŌ 邂逅鸡尾酒的浪漫艺术
- 11天前(当科学邂逅喜剧:科技馆喜剧嘉年华背后的"文旅破壁者")当科学邂逅喜剧:科技馆喜剧嘉年华背后的"文旅破壁者"
- 11天前(希尔顿集团2021年筹建的酒店)希尔顿集团两大重点项目亮相第四届上海旅游投资促进大会
- 11天前(芜宣机场国际航班)新华丝路:芜宣机场开通至越南首都河内的国际货运航线
- 11天前(我在港航“呵护”飞机 每一次安全着陆就是最好的荣誉)我在港航“呵护”飞机 每一次安全着陆就是最好的荣誉
网友评论
- 搜索
- 最新文章
- (2020广州车展哈弗)你的猛龙 独一无二 哈弗猛龙广州车展闪耀登场
- (哈弗新能源suv2019款)智能科技颠覆出行体验 哈弗重塑新能源越野SUV价值认知
- (2021款全新哈弗h5自动四驱报价)新哈弗H5再赴保障之旅,无惧冰雪护航哈弗全民电四驱挑战赛
- (海南航空现况怎样)用一场直播找到市场扩张新渠道,海南航空做对了什么?
- (visa jcb 日本)优惠面面俱到 JCB信用卡邀您畅玩日本冰雪季
- (第三届“堡里有年味·回村过大年”民俗花灯会活动)第三届“堡里有年味·回村过大年”民俗花灯会活动
- (展示非遗魅力 长安启源助力铜梁龙舞出征)展示非遗魅力 长安启源助力铜梁龙舞出征
- (阿斯塔纳航空公司)阿斯塔纳航空机队飞机数量增至50架
- (北京香港航班动态查询)香港快运航空北京大兴新航线今日首航
- (我在港航“呵护”飞机 每一次安全着陆就是最好的荣誉)我在港航“呵护”飞机 每一次安全着陆就是最好的荣誉
- 热门文章