简介

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 ;
}
  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[], 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的实现的更多相关文章

  1. ffmpeg avpicture_fill的一些使用

    标签: ffmpegavpicture_fill 2013-05-17 10:03 4713人阅读 评论(1) 收藏 举报  分类: ffmpeg(3)  这个FFMPEG我没找到详细的中文教程,只有 ...

  2. 关于avpicture_fill 和 sws_scale的关系

    avpicture_fill((AVPicture *) pFrameRGB, buffer, PIX_FMT_RGB565, pCodecCtx->width, pCodecCtx->h ...

  3. 海康网络摄像机YV12转换为BGR,由opencv Mat显示 (转)

    我使用的是海康DS-2CD852MF-E, 200万,网络摄像机,已经比较老了,不过SDK在海康官网下载的,开发流程都差不多. 海康摄像机回调解码后的视频数据格式为YV12,顺便说一下YV12的数据格 ...

  4. FFmpeg学习5:多线程播放视音频

    在前面的学习中,视频和音频的播放是分开进行的.这主要是为了学习的方便,经过一段时间的学习,对FFmpeg的也有了一定的了解,本文就介绍了 如何使用多线程同时播放音频和视频(未实现同步),并对前面的学习 ...

  5. FFmpeg学习2:解码数据结构及函数总结

    在上一篇文章中,对FFmpeg的视频解码过程做了一个总结.由于才接触FFmpeg,还是挺陌生的,这里就解码过程再做一个总结. 本文的总结分为以下两个部分: 数据读取,主要关注在解码过程中所用到的FFm ...

  6. 【视频处理】YUV与RGB格式转换

    YUV格式具有亮度信息和色彩信息分离的特点,但大多数图像处理操作都是基于RGB格式. 因此当要对图像进行后期处理显示时,需要把YUV格式转换成RGB格式. RGB与YUV的变换公式如下: YUV(25 ...

  7. 简单播放器(增加sdl事件控制)

    #include <libavcodec/avcodec.h> #include <libavformat/avformat.h> #include <libswscal ...

  8. ffmpeg 和 SDL 的结合使用

    FFmpeg是一套可以用来记录.转换数字音频.视频,并能将其转化为流的开源计算机程序.采用LGPL或GPL许可证.它提供了录制.转换以及流化音视 频的完整解决方案.它包含了非常先进的音频/视频编解码库 ...

  9. 学习FFmpeg API

    ffmpeg是编解码的利器,用了很久,以前看过dranger 的教程,非常精彩,受益颇多,是学习ffmpeg api很好的材料.可惜的是其针对的ffmpeg版本已经比较老了,而ffmpeg的更新又很快 ...

随机推荐

  1. IntelliJ IDEA 高效率配置

    之前学习和开发的时候一直用Eclipse,现在转战IDEA,记录一下IDEA的个性化设置,有助于提高效率.(参考:http://www.cnblogs.com/huaxingtianxia/p/586 ...

  2. DAG也许是真正的区块链3.0

    从15年开始,区块链概念被单拎出来,这之前区块链还只是比特币技术里的一个数据结构,中本村白皮书里把block和chain连一起的时候也只是a chain of blocks .随着以太坊去中心化计算机 ...

  3. 解决在ubuntu上启动的django项目在windows进行访问无法访问的问题

    windows想要访问VMware中Ubuntu Server中Debug模式下的django服务,需要设置django允许非本机ip访问. 设置方法:1.查看虚拟机ip(建议VMware中设置Ubu ...

  4. .net core2 笔记

    资源: https://github.com/aspnet/home https://github.com/dotnet/cli https://www.cnblogs.com/billyang/p/ ...

  5. flask请求流程详解

    先看一个流程图: 1.当一个请求进入的时候,Flask框架首先会实例化一个Request Context,封装了请求信息,保存在Request中.生成请求上下文后,Flask框架会将请求上下文推入到_ ...

  6. 如果需要精确的答案,请避免使用float和double

    Java中的简单浮点数类型float和double不能够进行运算.不光是Java,在其它很多编程语言中也有这样的问题.在大多数情况下,计算的结果是准确的,但是多试几次(可以做一个循环)就可以试出类似上 ...

  7. org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manu

    这个是sql 语句 错误     仔细检查 SQL语句是否写错了 org.apache.ibatis.exceptions.PersistenceException: ### Error queryi ...

  8. 多线程系列之二:Single Thread Execution 模式

    一,什么是SingleThreadExecution模式?同一时间内只能让一个线程执行处理 二,例子 1.不安全的情况 用程序模拟 三个人频繁地通过一个只允许一个人经过的门.当人通过时,统计人数便会增 ...

  9. mysql备份(导出)数据库,并恢复数据

    导出某个数据库数据到文件中 假设要导出test这个数据库,那么可以在Linux命令行(不是在mysql中) [root@ubuntu /data]# mysqldump -uroot -p test ...

  10. 自签名证书 nginx tomcat

    给Nginx配置一个自签名的SSL证书 - 廖雪峰的官方网站 https://www.liaoxuefeng.com/article/0014189023237367e8d42829de24b6eaf ...