zoukankan      html  css  js  c++  java
  • 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, 1);
    }

    av_image_fill_arrays

    // libavutil/imgutils.c
     int 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

  • 相关阅读:
    PHP的函数应用
    MyEclipse 使用Junit
    JAVASE知识点总结
    常见排序算法
    数据结构的java实现
    JDK1.5新特性总结
    Oracle练习题
    Oracle面试题2
    Oracle面试题1
    分别使用Statement和PreparedStatement对数据库进行操作
  • 原文地址:https://www.cnblogs.com/nanqiang/p/10439011.html
Copyright © 2011-2022 走看看