sws_getContext用法实例

本文详细介绍了FFmpeg中sws_getContext和sws_scale函数的使用方法及参数设置,包括如何设置源和目标图像的尺寸、格式及缩放算法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

转载   sws_getContext用法实例 收藏

 

sws_getContext用法实例

视频编码  2009-06-30 10:16:57  阅读782  评论1   字号:   订阅

struct SwsContext*  sws_getContext (int srcW, int srcH, int srcFormat, int dstW, int dstH, int dstFormat, int flags, SwsFilter *srcFilter, SwsFilter *dstFilter, double *param)
Returns an SwsContext to be used in  sws_scale .

Params:
srcW, srcH, srcFormat : source width, height, and pix format
dstW, dstH, dstFormat : destination width, height, and pix format
flags : Method of scaling to use. Choices are SWS_FAST_BILINEAR, SWS_BILINEAR, SWS_BICUBIC, SWS_X, SWS_POINT, SWS_AREA, SWS_BICUBLIN, SWS_GAUSS, SWS_SINC, SWS_LANCZOS, SWS_SPLINE. Other flags include CPU capability flags: SWS_CPU_CAPS_MMX, SWS_CPU_CAPS_MMX2, SWS_CPU_CAPS_3DNOW, SWS_CPU_CAPS_ALTIVEC. Other flags include (currently not completely implemented) SWS_FULL_CHR_H_INT, SWS_FULL_CHR_H_INP, and SWS_DIRECT_BGR. Finally we have SWS_ACCURATE_RND and perhaps the most useful for beginners, SWS_PRINT_INFO. I have no idea what most of these do. Maybe email me?
srcFilter, dstFilter : SwsFilter for source and destination. SwsFilter involves chroma/luminsence filtering. A value of NULL sets these to the default.
param : should be a pointer to an int[2] buffer with coefficients. Not documented. Looks like it's used to alter the default scaling algorithms slightly. A value of NULL sets this to the default. Experts only!

使用方法如下:

#define W 96
#define H 96

struct SwsContext *sws;

sws= sws_getContext(W/12, H/12, PIX_FMT_RGB32, W, H, PIX_FMT_YUV420P, 2, NULL, NULL, NULL);

用途:

sws_scale(sws, rgb_src, rgb_stride, 0, H, src, stride);

### 如何使用FFmpeg保存OpenCV `cv::Mat` 对象表示的视频流 为了实现这一目标,通常需要创建一个管道来接收来自OpenCV捕获的数据帧并将其传递给FFmpeg进行编码和存储。下面展示了具体方法: #### 初始化FFmpeg环境与设置编解码器参数 首先初始化AVCodecContext结构体,并配置好相应的编解码选项以便后续操作。 ```cpp // 打开输出文件句柄 AVFormatContext *fmt_ctx = nullptr; if (avformat_alloc_output_context2(&fmt_ctx, NULL, "mp4", output_filename.c_str()) < 0) { throw std::runtime_error("Could not allocate format context"); } // 查找H.264编码器 const AVCodec* codec = avcodec_find_encoder(AV_CODEC_ID_H264); if (!codec){ throw std::runtime_error("Cannot find H.264 encoder."); } // 创建新的音频/视频流 AVStream* stream = avformat_new_stream(fmt_ctx, codec); if (!stream){ throw std::runtime_error("Failed to create new video stream."); } // 设置编解码上下文 AVCodecContext* cctx = avcodec_alloc_context3(codec); cctx->width = width; // 图像宽度 cctx->height = height; // 图像高度 cctx->time_base = {1, fps}; // 帧率倒数作为时间基底 cctx->framerate = {fps, 1}; cctx->gop_size = 10; // GOP大小 cctx->max_b_frames= 1; // B帧数量限制 cctx->pix_fmt = AV_PIX_FMT_YUV420P; // 开启编码器 if (avcodec_open2(cctx, codec, NULL) < 0){ throw std::runtime_error("Can't open the encoder!"); } ``` #### 将`cv::Mat` 转换为 `AVFrame` 当获取每一帧图像时(假设已经通过某种方式得到了`cv::Mat mat`),可以利用SWScale库完成色彩空间变换过程[^1]。 ```cpp // 准备输入数据缓冲区 uint8_t* data[4]; int linesize[4]; // 获取原始图像信息 data[0]=mat.data; linesize[0]=static_cast<int>(mat.step); // 构建临时AVFrame用于承载转换后的YUV数据 AVFrame* frame_yuv=new_frame(width,height,cctx->pix_fmt); // 使用sws_getContext()获得缩放上下文 struct SwsContext* sws_ctx = sws_getContext( static_cast<int>(mat.cols), static_cast<int>(mat.rows), AVPixelFormat{mat.type()}, cctx->width, cctx->height, cctx->pix_fmt, SWS_BILINEAR, NULL,NULL,NULL ); // 应用sws_scale()执行实际的颜色转换工作 sws_scale(sws_ctx,data,linesize,0,static_cast<int>(mat.rows),frame_yuv->data,frame_yuv->linesize); ``` #### 编写压缩包并将它们写入文件 一旦拥有了适当格式化的`AVFrame`实例,则可以通过调用`avcodec_send_frame()`发送至编码器;接着读取产生的比特流片段并通过`av_write_frame()`记录下来。 ```cpp for (;;){ int ret = avcodec_send_frame(cctx, frame ? frame : NULL); if(ret<0 && ret!=AVERROR(EAGAIN)){ break; } while(true){ AVPacket pkt={0}; ret=avcodec_receive_packet(cctx,&pkt); if(ret==AVERROR(EAGAIN)||ret==AVERROR_EOF){ break; }else if(ret>=0){ av_interleaved_write_frame(fmt_ctx,&pkt); av_packet_unref(&pkt); } } } ``` 最后不要忘记释放资源以及关闭所有打开的对象。 上述流程涵盖了从准备阶段直到最终写出媒体文件所需的关键步骤。值得注意的是这里仅提供了一个简化版本的实际应用场景可能更加复杂一些比如还需要考虑同步音轨等问题但是这应该足以帮助理解基本原理了[^1][^2].
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值