日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

avpicture_fill的实现

發布時間:2023/11/27 生活经验 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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.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的实现的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。