简介

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, 1);
}

av_image_fill_arrays

// libavutil/imgutils.cint av_image_fill_arrays(uint8_t *dst_data[4], int dst_linesize[4],const uint8_t *src, enum AVPixelFormat pix_fmt,int width, int height, int align){int ret, i;ret = av_image_check_size(width, height, 0, NULL);if (ret < 0)return ret;ret = av_image_fill_linesizes(dst_linesize, pix_fmt, width);if (ret < 0)return ret;for (i = 0; i < 4; 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[4], enum AVPixelFormat pix_fmt, int width){int i, ret;const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);int max_step     [4];       /* max pixel step for each plane */int max_step_comp[4];       /* the component for each plane which has the max pixel step */memset(linesizes, 0, 4*sizeof(linesizes[0]));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 = 0; i < 4; i++) {if ((ret = image_get_linesize(width, i, max_step[i], max_step_comp[i], desc)) < 0)             return ret;linesizes[i] = ret;}return 0;}

  1. 将linsizes数组的内容置为0;
  2. 利用av_pix_fmt_desc_get函数得到输入格式的AVPixFmtDescriptor指针;
  3. 最后利用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[4], enum AVPixelFormat pix_fmt, int height,uint8_t *ptr, const int linesizes[4])
    {
    int i, total_size, size[4] = { 0 }, has_plane[4] = { 0 };const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pix_fmt);
    memset(data     , 0, sizeof(data[0])*4);if (!desc || desc->flags & AV_PIX_FMT_FLAG_HWACCEL)return AVERROR(EINVAL);data[0] = ptr;
    if (linesizes[0] > (INT_MAX - 1024) / height)return AVERROR(EINVAL);
    size[0] = linesizes[0] * height;if (desc->flags & AV_PIX_FMT_FLAG_PAL ||desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) {size[0] = (size[0] + 3) & ~3;data[1] = ptr + size[0]; /* palette is stored here as 256 32 bits words */return size[0] + 256 * 4;
    }for (i = 0; i < 4; i++)has_plane[desc->comp[i].plane] = 1;total_size = size[0];
    for (i = 1; i < 4 && has_plane[i]; i++) {int h, s = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;data[i] = data[i-1] + size[i-1];h = (height + (1 << s) - 1) >> 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

转载于:https://www.cnblogs.com/nanqiang/p/10439011.html

avpicture_fill的实现相关推荐

  1. 'avpicture_fill': 被声明为已否决

    'avpicture_fill': 被声明为已否决 尝试这个 1.Project Properties > Configuration Properties > C/C++ > Ge ...

  2. ffmpeg解码视频存为BMP文件

    ffmpeg解码视频存为BMP文件 分类: ffmpeg2011-07-28 12:13 8人阅读 评论(0) 收藏 举报 view plain #include <windows.h> ...

  3. android ffmpeg 编码h264,Mac系统下ffmpeg+h264+flv编码的android录制屏幕实现2

    接上一篇. activity_flv.xml xmlns:tools="http://schemas.android.com/tools" android:layout_width ...

  4. Android NDK开发之旅29 云服务器Ubuntu下搭建NDK环境,并编译FFmpeg

    ###前言 因为在Linux环境下编译FFmpeg生成库和头文件下比较方便,所以接下来主要操作在Linux环境下进行.但是对于Android NDK 开发新手来说,自己电脑配置Ubuntu Linux ...

  5. 在visual studio 2010中调用ffmpeg

    转自:http://blog.sina.com.cn/s/blog_4178f4bf01018wqh.html 最近几天一直在折腾ffmpeg,在网上也查了许多资料,费了不少劲,现在在这里和大家分享一 ...

  6. ffmpeg综合应用示例(一)——摄像头直播

    本文的示例将实现:读取PC摄像头视频数据并以RTMP协议发送为直播流.示例包含了 1.ffmpeg的libavdevice的使用 2.视频解码.编码.推流的基本流程 具有较强的综合性. 要使用liba ...

  7. (转译)用FFmpeg和SDL写播放器--01视频帧提取

    指导1:制作视频帧提取 概要 电影文件有很多基本的组成部分.首先,文件本身被称为容器Container,容器的类型决定了信息 被存放在文件中的位置.AVI和Quicktime就是容器的例子.接着,你有 ...

  8. ffmpeg 找不到bin_FFmpeg开发笔记(九):ffmpeg解码rtsp流并使用SDL同步播放

    若该文为原创文章,转载请注明原文出处 本文章博客地址:https://blog.csdn.net/qq21497936/article/details/109603499 各位读者,知识无穷而人力有穷 ...

  9. FFmpeg编写一个简单播放器 -1

    2019独角兽企业重金招聘Python工程师标准>>> 指导1:制作屏幕录像 概要   电影文件有很多基本的组成部分.首先,文件本身被称为容器Container,容器的类型决定了信息 ...

最新文章

  1. 如何在centos安装python-mysql
  2. tensorflow tf.keras.utils.plot_model 画深度学习神经网络拓扑图
  3. python 参数类型的多态_【Python】面向对象:类与对象\封装\继承\多态
  4. Android NFC开发实战详解
  5. 三类医械计算机系统要求,三类医疗器械计算机管理系统要求
  6. windows环境安装haproxy及初步配置负载均衡使用示例
  7. 解决jquery的scrollTop()置顶的浏览器兼容
  8. WeirdSort CodeForces - 1311B(暴力)
  9. 在Linux系统上部署java web项目
  10. codeforces 379F-New Year Tree
  11. AxonFramework,存储库
  12. 如何实现Activiti的分支条件的自定义配置(转)
  13. 水很深的深度学习(四)——卷积神经网络CNN
  14. C#中启动外部应用程序
  15. sql统计表中各类型金额_各类型模具设计中“脱料结构”种类、使用范围揭秘,值得学习...
  16. 台式计算机usb口不能用,电脑usb接口不能用怎么办【图文教程】
  17. c语言 double **x,C语言题目 若已定义x和y为double类型,则表达式“x=1,y=x+3/2的值是:...
  18. 苹果Airplay协议以及AirTunes流程总结
  19. java实现beamsearch_Beam Search(集束搜索/束搜索)
  20. flowchart.fun 语法

热门文章

  1. 在kotlin companion object中读取spring boot配置文件,静态类使用@Value注解配置
  2. 2022-2028年中国钢材市场投资分析及前景预测报告(全卷)
  3. 2022-2028年中国无滴消雾大棚膜行业市场研究及前瞻分析报告
  4. C/C++ 编程规范(02)— 标识符命名
  5. 分析两小段c++代码 关于unsigned运算的坑
  6. LeetCode简单题之作为子字符串出现在单词中的字符串数目
  7. 2021年大数据Spark(五十):Structured Streaming 案例一实时数据ETL架构
  8. [JAVA EE]Spring Boot 控制层:参数传递方法
  9. 零起点学算法07——复杂一点的表达式计算
  10. Android Studio 引入aar文件