avpicture_fill的实现
简介
avpicture_fill函数将ptr指向的数据填充到picture内,但并没有拷贝,只是将picture结构内的data指针指向了ptr的数据。其实现如下:
avpiture_fill
avpiture_fill直接调用av_image_fill_arrays函数。
// libavcodec/avpicture.c
int avpicture_fill(AVPicture *picture, const uint8_t *ptr,
enum AVPixelFormat pix_fmt, int width, int height)
{
return av_image_fill_arrays(picture->data, picture->linesize,
ptr, pix_fmt, width, height, );
}
av_image_fill_arrays
// libavutil/imgutils.c
int av_image_fill_arrays(uint8_t *dst_data[], int dst_linesize[],
const uint8_t *src, enum AVPixelFormat pix_fmt,
int width, int height, int align)
{
int ret, i; ret = av_image_check_size(width, height, , NULL);
if (ret < )
return ret; ret = av_image_fill_linesizes(dst_linesize, pix_fmt, width);
if (ret < )
return ret; for (i = ; i < ; i++)
dst_linesize[i] = FFALIGN(dst_linesize[i], align); return av_image_fill_pointers(dst_data, pix_fmt, height, (uint8_t *)src, dst_linesize);
}
其中av_image_check_size用来检测输入的widht和height是否可用,判断条件如下:
if ((int)w>0 && (int)h>0 && (w+128)*(uint64_t)(h+128) < INT_MAX/8)
return 0;
av_image_fill_linesizes
int av_image_fill_linesizes(int linesizes[], enum AVPixelFormat pix_fmt, int width)
{
int i, ret;
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
int max_step []; /* max pixel step for each plane */
int max_step_comp[]; /* the component for each plane which has the max pixel step */ memset(linesizes, , *sizeof(linesizes[])); if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
return AVERROR(EINVAL); av_image_fill_max_pixsteps(max_step, max_step_comp, desc);
for (i = ; i < ; i++) {
if ((ret = image_get_linesize(width, i, max_step[i], max_step_comp[i], desc)) < ) return ret;
linesizes[i] = ret;
} return ;
}
- 将linsizes数组的内容置为0;
- 利用av_pix_fmt_desc_get函数得到输入格式的AVPixFmtDescriptor指针;
最后利用image_get_linesize函数获得linesizes数组中每个元素的值;
FFALIGN
由于在afpicture_fill中填充的align为1, 故该宏返回的值还是linesizes[i];
// libavutil/common.h #define FFALIGN(x, a) (((x)+(a)-1)&~((a)-1))
av_image_fill_pointers
int av_image_fill_pointers(uint8_t *data[], enum AVPixelFormat pix_fmt, int height,
uint8_t *ptr, const int linesizes[])
{
int i, total_size, size[] = { }, has_plane[] = { }; const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
memset(data , , sizeof(data[])*); if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL)
return AVERROR(EINVAL); data[] = ptr;
if (linesizes[] > (INT_MAX - ) / height)
return AVERROR(EINVAL);
size[] = linesizes[] * height; if (desc->flags & AV_PIX_FMT_FLAG_PAL ||
desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {
size[] = (size[] + ) & ~;
data[] = ptr + size[]; /* palette is stored here as 256 32 bits words */
return size[] + * ;
} for (i = ; i < ; i++)
has_plane[desc->comp[i].plane] = ; total_size = size[];
for (i = ; i < && has_plane[i]; i++) {
int h, s = (i == || i == ) ? desc->log2_chroma_h : ;
data[i] = data[i-] + size[i-];
h = (height + ( << s) - ) >> s;
if (linesizes[i] > INT_MAX / h)
return AVERROR(EINVAL);
size[i] = h * linesizes[i];
if (total_size > INT_MAX - size[i])
return AVERROR(EINVAL);
total_size += size[i];
} return total_size;
}将data数组内的指针分别指向ptr内的数据。
转自 http://www.voidcn.com/article/p-aquvaett-zg.html
avpicture_fill的实现的更多相关文章
- ffmpeg avpicture_fill的一些使用
标签: ffmpegavpicture_fill 2013-05-17 10:03 4713人阅读 评论(1) 收藏 举报 分类: ffmpeg(3) 这个FFMPEG我没找到详细的中文教程,只有 ...
- 关于avpicture_fill 和 sws_scale的关系
avpicture_fill((AVPicture *) pFrameRGB, buffer, PIX_FMT_RGB565, pCodecCtx->width, pCodecCtx->h ...
- 海康网络摄像机YV12转换为BGR,由opencv Mat显示 (转)
我使用的是海康DS-2CD852MF-E, 200万,网络摄像机,已经比较老了,不过SDK在海康官网下载的,开发流程都差不多. 海康摄像机回调解码后的视频数据格式为YV12,顺便说一下YV12的数据格 ...
- FFmpeg学习5:多线程播放视音频
在前面的学习中,视频和音频的播放是分开进行的.这主要是为了学习的方便,经过一段时间的学习,对FFmpeg的也有了一定的了解,本文就介绍了 如何使用多线程同时播放音频和视频(未实现同步),并对前面的学习 ...
- FFmpeg学习2:解码数据结构及函数总结
在上一篇文章中,对FFmpeg的视频解码过程做了一个总结.由于才接触FFmpeg,还是挺陌生的,这里就解码过程再做一个总结. 本文的总结分为以下两个部分: 数据读取,主要关注在解码过程中所用到的FFm ...
- 【视频处理】YUV与RGB格式转换
YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式. 因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式. RGB与YUV的变换公式如下: YUV(25 ...
- 简单播放器(增加sdl事件控制)
#include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libswscal ...
- ffmpeg 和 SDL 的结合使用
FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.采用LGPL或GPL许可证.它提供了录制.转换以及流化音视 频的完整解决方案.它包含了非常先进的音频/视频编解码库 ...
- 学习FFmpeg API
ffmpeg是编解码的利器,用了很久,以前看过dranger 的教程,非常精彩,受益颇多,是学习ffmpeg api很好的材料.可惜的是其针对的ffmpeg版本已经比较老了,而ffmpeg的更新又很快 ...
随机推荐
- 深入理解JAVA虚拟机(内存模型+GC算法+JVM调优)
目录 1.Java虚拟机内存模型 1.1 程序计数器 1.2 Java虚拟机栈 局部变量 1.3 本地方法栈 1.4 Java堆 1.5 方法区(永久区.元空间) 附图 2.JVM内存分配参数 2.1 ...
- 我们都被GitHub出卖了!逃跑吧兄弟!
周一突然间爆出微软以75亿收购GitHub可真是一颗重磅炸弹,一下轰动整个软件业.如果你不是搞开发的这篇文章几本不会引起你的共鸣:如果你没有用源代码管理这个消息也只不过是个新闻:如果你是微软系的朋友那 ...
- 微软Ignite2018——微软宣布新的学习平台:Microsoft Learn
Ignite 2018 首日感受 头一次参加美国的微软 Ignite 大会,确实规模比国内的大不少.23日是 MVP & RD 的 Pre Day(MVP即Most Valuable Prof ...
- SQL Server 使用 Merge 关键字进行表数据同步
简介 Merge关键字是一个神奇的DML关键字.它在SQL Server 2008被引入,它能将Insert,Update,Delete简单的并为一句.MSDN对于Merge的解释非常的短小精悍:”根 ...
- CentOS 6 升级 curl
zabbix 发邮件报 Support for SMTP authentication was not compiled in 其实出现这种问题的原因是我们机器上的 libcurl 版本太低所致.在z ...
- php微信公众号开发入门小教程
1.配置相关服务器 (1) 如下,把自己的服务器ip白名单配置上: (2) 开始配置令牌,配置令牌时先需要把现成的代码放到自己的服务器上面,代码里面包含自己的设置的令牌号码,这样才可以配置成功. 注意 ...
- 线程锁(互斥锁Mutex)及递归锁
一.线程锁(互斥锁) 在一个程序内,主进程可以启动很多个线程,这些线程都可以访问主进程的内存空间,在Python中虽然有了GIL,同一时间只有一个线程在运行,可是这些线程的调度都归系统,操作系统有自身 ...
- semantic-ui 分割线
分割线即原生html中的<hr>标签.不过semantic-ui中将<hr>美化了一下下. 1.基础分割线 需要注意的是分割线只能使用div标签和p标签,不能使用span标签. ...
- Eclipse支持文件UTF-8编码
Eclipse修改编码格式_百度经验https://jingyan.baidu.com/article/2009576193ee38cb0721b416.html 这篇最棒 如何为eclipse中的文 ...
- vue-router的简单实现原理
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...