<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      FFmpeg libswscale源碼分析1-API介紹

      本文為作者原創(chuàng),轉(zhuǎn)載請注明出處:http://www.rzrgm.cn/leisure_chn/p/14349382.html

      libswscale 是 FFmpeg 中完成圖像尺寸縮放和像素格式轉(zhuǎn)換的庫。用戶可以編寫程序,調(diào)用 libswscale 提供的 API 來進(jìn)行圖像尺寸縮放和像素格式轉(zhuǎn)換。也可以使用 scale 濾鏡完成這些功能,scale 濾鏡實(shí)現(xiàn)中調(diào)用了 libswscale 的 API。libswscale 的 API 非常簡單,就一個 sws_scale() 接口,但內(nèi)部的實(shí)現(xiàn)卻非常復(fù)雜。

      本文分析 libswscale 源碼,因篇幅較長,遂拆分成下面一系列文章:
      [1]. FFmpeg libswscale源碼分析1-API介紹
      [2]. FFmpeg libswscale源碼分析2-轉(zhuǎn)碼命令行與濾鏡圖
      [3]. FFmpeg libswscale源碼分析3-scale濾鏡源碼分析
      [4]. FFmpeg libswscale源碼分析4-libswscale源碼分析

      源碼分析基于 FFmpeg 4.1 版本。

      1. API 介紹

      1.1 相關(guān)基礎(chǔ)概念

      在解釋具體的函數(shù)前,必須理解與像素格式相關(guān)的幾個基礎(chǔ)概念:參色彩空間與像素格式一文第 4.1 節(jié)

      pixel_format:像素格式,圖像像素在內(nèi)存中的排列格式。一種像素格式包含有色彩空間、采樣方式、存儲模式、位深等信息,其中體現(xiàn)的最重要信息就是存儲模式,具體某一類的存儲模式參照本文第 2 節(jié)、第 3 節(jié)。

      bit_depth: 位深,指每個分量(Y、U、V、R、G、B 等)單個采樣點(diǎn)所占的位寬度。

      例如對于 yuv420p(位深是8)格式而言,每一個 Y 樣本、U 樣本和 V 樣本都是 8 位的寬度,只不過在水平方向和垂直方向,U 樣本數(shù)目和 V 樣本數(shù)目都只有 Y 樣本數(shù)目的一半。而 bpp (Bits Per Pixel)則是將圖像總比特數(shù)分?jǐn)偟矫總€像素上,計算出平均每個像素占多少個 bit,例如 yuv420p 的 bpp 是 12,表示平均每個像素占 12 bit(Y占8位、U占2位、V占2位),實(shí)際每個 U 樣本和 V 樣本都是 8 位寬度而不是 2 位寬度。

      plane: 存儲圖像中一個或多個分量的一片內(nèi)存區(qū)域。一個 plane 包含一個或多個分量。planar 存儲模式中,至少有一個分量占用單獨(dú)的一個 plane,具體到 yuv420p 格式有 Y、U、V 三個 plane,nv12 格式有 Y、UV 兩個 plane,gbrap 格式有 G、B、R、A 四個 plane。packed 存儲模式中,因?yàn)樗蟹至康南袼厥墙豢棿娣诺模?packed 存儲模式只有一個 plane。

      slice: slice 是 FFmpeg 中使用的一個內(nèi)部結(jié)構(gòu),在 codec、filter 中常有涉及,通常指圖像中一片連續(xù)的行,表示將一幀圖像分成多個片段。注意 slice 是針對圖像分片,而不是針對 plane 分片,一幀圖像有多個 plane,一個 slice 里同樣包含多個 plane。

      stride/pitch: 一行圖像中某個分量(如亮度分量或色度分量)所占的字節(jié)數(shù), 也就是一個 plane 中一行數(shù)據(jù)的寬度。有對齊要求,計算公式如下:

      stride 值 = 圖像寬度 * 分量數(shù) * 單樣本位寬度 / 水平子采樣因子 / 8
      

      其中,圖像寬度表示圖像寬度是多少個像素,分量數(shù)指當(dāng)前 plane 包含多少個分量(如 rgb24 格式一個 plane 有 R、G、B 三個分量),單位本位寬度指某分量的一個樣本在考慮對齊后在內(nèi)存中占用的實(shí)際位數(shù)(例如位深 8 占 8 位寬,位深 10 實(shí)際占 16 位寬,對齊值與平臺相關(guān)),水平子采樣因子指在水平方向上每多少個像素采樣出一個色度樣本(亮度樣本不進(jìn)行下采樣,所以采樣因子總是 1)。

      需要注意的是,stride 考慮的是 plane 中的一行。對 yuv420p 格式而言,Y 分量是完全采樣,因此一行 Y 樣本數(shù)等于圖像寬度,U 分量和 V 分量水平采樣因子是 2(每兩個像素采樣出一個U樣本和V樣本),因此一行 U 樣本數(shù)和一行 V 樣本數(shù)都等于圖像寬度的一半。U 分量和 V 分量垂直采樣因子也是 2,因此 U 分量和 V 分量的行數(shù)少了,只有圖像高度的一半,但垂直方向的采樣率并不影響一個 plane 的 stride 值,因?yàn)?stride 的定義決定了其值只取決于水平方向的采樣率。

      若源圖像像素格式是 yuv420p(有 Y、U、V 三個 plane),位深是 8(每一個Y樣本、U樣本、V樣本所占位寬度是 8 位),分辨率是 1280x720,則在 Y plane 的一行數(shù)據(jù)中,有 1280 個 Y 樣本,占用 1280 個字節(jié),stride 值是 1280;在 U plane 的一行數(shù)據(jù)中,有 640 個 U 樣本,占用 640 個字節(jié),stride 值是 640;在 V plane 的一行數(shù)據(jù)中,有 640 個樣本,占用 640 個字節(jié),stride 值是 640。

      若源圖像像素格式是 yuv420p10(有 Y、U、V 三個 plane),位深是 10 (內(nèi)存對齊后每個樣本占 16 位),分辨率仍然是 1280x720,則 Y plane 的 stride 值為 1280 x 16 / 8 = 2560,U plane stride 值為 640 x 16 / 8 = 1280,V plane stride 值為 640 x 16 / 8 = 1280。

      若源圖像像素格式是 yuv420p16le(有 Y、U、V 三個 plane),位深是 16,分辨率仍然是 1280x720,則 Y plane 的 stride 值為 1280 x 16 / 8 = 2560,U plane stride 值為 640 x 16 / 8 = 1280,V plane stride 值為 640 x 10 / 8 = 1280。

      若源圖像像素格式是 p010le(有 Y、UV 兩個 plane),位深是 10 (內(nèi)存對齊后,每個樣本占 16 位),分辨率仍然是 1280x720,則 Y plane 的 stride 值為 1280 x 16 / 8 = 2560,UV plane stride 值為 640 x 2 x 16 / 8 = 2560。

      若源圖像像素格式是 bgr24(有 BGR 一個 plane),位深是 8,分辨率仍然是 1280x720。因 bgr24 像素格式是 packed 存儲模式,每個像素 R、G、B 三個采樣點(diǎn)交織存放,內(nèi)存區(qū)的排列形式為 BGRBGR...,因此可以認(rèn)為它只有一個 plane,此 plane 中一行圖像有 1280 個 R 樣本,1280 個 G 樣本,1280 個 B 樣本,此 plane 的 stride 值為 1280 x 3 x 8 / 8 = 3840。

      1.2 初始化函數(shù) sws_getContext()

      sws_getContext()函數(shù)將創(chuàng)建一個 SwsContext,后續(xù)使用 sws_scale() 執(zhí)行縮放/格式轉(zhuǎn)換操作時需要用到此 SwsContext。

      /**
       * Allocate and return an SwsContext. You need it to perform
       * scaling/conversion operations using sws_scale().
       *
       * @param srcW the width of the source image
       * @param srcH the height of the source image
       * @param srcFormat the source image format
       * @param dstW the width of the destination image
       * @param dstH the height of the destination image
       * @param dstFormat the destination image format
       * @param flags specify which algorithm and options to use for rescaling
       * @param param extra parameters to tune the used scaler
       *              For SWS_BICUBIC param[0] and [1] tune the shape of the basis
       *              function, param[0] tunes f(1) and param[1] f′(1)
       *              For SWS_GAUSS param[0] tunes the exponent and thus cutoff
       *              frequency
       *              For SWS_LANCZOS param[0] tunes the width of the window function
       * @return a pointer to an allocated context, or NULL in case of error
       * @note this function is to be removed after a saner alternative is
       *       written
       */
      struct SwsContext *sws_getContext(int srcW, int srcH, enum AVPixelFormat srcFormat,
                                        int dstW, int dstH, enum AVPixelFormat dstFormat,
                                        int flags, SwsFilter *srcFilter,
                                        SwsFilter *dstFilter, const double *param);
      

      函數(shù)參數(shù)及返回值說明如下:

      @param srcW
      srcW 是源圖像的寬度。

      @param srcH
      srcH 是源圖像的高度。

      @param srcFormat
      srcFormat 是源圖像的像素格式。

      @param dstW
      dstW 是目標(biāo)圖像的寬度。

      @param dstH
      dstH 是目標(biāo)圖像的高度。

      @param dstFormat
      dstFormat 是目標(biāo)圖像的像素格式。

      @param flags
      flags 可以指定用于縮放/轉(zhuǎn)換操作的算法以及選項(xiàng)。

      @param param
      param 為縮放操作提供額外的參數(shù)。
      對于 BICUBIC 算法,param[0] 和 param[1] 調(diào)整基函數(shù)的形狀,param[0] 調(diào)整 f(1),param[1] 調(diào)整 f′(1)。
      對于 GAUSS 算法,param[0] 調(diào)整指數(shù),從而調(diào)整了截止頻率。
      對于 LANCZOS 算法,param[0] 調(diào)整窗口函數(shù)的寬度。

      @return
      返回值是一個指向已分配 context 的指針,出錯時為 NULL 。

      1.3 轉(zhuǎn)換函數(shù) sws_scale()

      圖像分辨率轉(zhuǎn)換、像素格式轉(zhuǎn)換都通過這一個函數(shù)完成。

      sws_scale() 函數(shù)接口定義如下:

      /**
       * Scale the image slice in srcSlice and put the resulting scaled
       * slice in the image in dst. A slice is a sequence of consecutive
       * rows in an image.
       *
       * Slices have to be provided in sequential order, either in
       * top-bottom or bottom-top order. If slices are provided in
       * non-sequential order the behavior of the function is undefined.
       *
       * @param c         the scaling context previously created with
       *                  sws_getContext()
       * @param srcSlice  the array containing the pointers to the planes of
       *                  the source slice
       * @param srcStride the array containing the strides for each plane of
       *                  the source image
       * @param srcSliceY the position in the source image of the slice to
       *                  process, that is the number (counted starting from
       *                  zero) in the image of the first row of the slice
       * @param srcSliceH the height of the source slice, that is the number
       *                  of rows in the slice
       * @param dst       the array containing the pointers to the planes of
       *                  the destination image
       * @param dstStride the array containing the strides for each plane of
       *                  the destination image
       * @return          the height of the output slice
       */
      int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[],
                    const int srcStride[], int srcSliceY, int srcSliceH,
                    uint8_t *const dst[], const int dstStride[]);
      

      sws_scale() 函數(shù)處理的對象是圖像中的一個 slice。源圖像中的一個 slice 經(jīng) sws_scale() 函數(shù)處理后,變成目標(biāo)圖像中的一個slice。一個 slice 指圖像中一片連接的行。每次向 sws_scale() 函數(shù)提供的源 slice 必須是連續(xù)的,可以按由圖像頂部到底部的順序,也可以使用從圖像底部到頂部的順序。如果不按順序提供 slice,sws_scale() 的執(zhí)行結(jié)果是不確定的。

      函數(shù)參數(shù)及返回值說明如下:

      @param c
      c 是由 sws_getContext() 函數(shù)創(chuàng)建的 SwsContext 上下文。

      @param srcSlice
      srcSlice 是一個指針數(shù)組(數(shù)組的每個元素是指針),每個指針指向源 slice 里的各個 plane。一幀圖像通常有多個 plane,若將一幀圖像劃分成多個 slice,則每個 slice 里同樣包含多個 plane。

      通常調(diào)用 sws_scale() 時不會將一幀圖像劃分多個 slice,一幀圖像就是一個 slice,所以通常為此函數(shù)提供的實(shí)參是 AVFrame.*data[]。

      在使用 scale 濾鏡時,可以將 nb_slices 選項(xiàng)參數(shù)設(shè)置為大于 1,以觀察將一幀圖像劃分為多個 slice 情況。scale 濾鏡中 nb_slices 選項(xiàng)的說明中有提到,此選項(xiàng)僅用于調(diào)試目的。

      @param srcStride
      srcStride 是一個數(shù)組,每個元素表示源圖像中一個 plane 的 stride。通常為此函數(shù)提供的實(shí)參是 AVFrame.linesize[]。如前所述,若源圖像是 yuv420p 8bit,分辨率是 1280x720,則 srcStride 數(shù)組有三個元素具有有效值,依次是 1280、640、640。

      @param srcSliceY
      srcSliceY 表示待處理的 slice 在源圖像中的起始位置(相對于第 1 行的行數(shù)),第 1 行位置為 0,第 2 行位置為 1,依此類推。

      @param srcSliceH
      srcSliceH 表示待處理的 slice 的高度(行數(shù))。

      @param dst
      dst 是一個指針數(shù)組,每個指針指向目標(biāo)圖像中的一個 plane。

      @param dstStride
      dstStride 是一個數(shù)組,每個元素表示目標(biāo)圖像中一個 plane 的 stride。

      @return
      函數(shù)返回值表示輸出 slice 的高度(行數(shù))。

      5 參考資料

      [1] 色彩空間與像素格式, http://www.rzrgm.cn/leisure_chn/p/10290575.html
      [2] FFmpeg源代碼簡單分析:libswscale的sws_getContext(), https://blog.csdn.net/leixiaohua1020/article/details/44305697
      [3] FFmpeg源代碼簡單分析:libswscale的sws_scale(), https://blog.csdn.net/leixiaohua1020/article/details/44346687

      6 修改記錄

      2021-01-30 V1.0 初稿

      posted @ 2021-02-01 08:49  葉余  閱讀(1832)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 日韩精品 在线 国产 丝袜| 巴青县| 亚洲国产精品一区二区第一页| 国产成人精品国内自产色| 亚洲一二区在线视频播放| 精品成人免费自拍视频| 日本精品不卡一二三区| 亚洲一精品一区二区三区| 亚洲综合高清一区二区三区| 18禁裸乳无遮挡啪啪无码免费| 亚洲日韩乱码中文无码蜜桃臀| 无码免费大香伊蕉在人线国产| 欧洲亚洲国内老熟女超碰| 国产综合欧美| 日韩一区在线中文字幕| 国内精品九九久久久精品| 制服丝袜美腿一区二区| 国产色视频一区二区三区qq号| 精品人妻二区中文字幕| 漂亮的保姆hd完整版免费韩国| 久久久午夜精品福利内容 | 亚洲天堂在线免费| 少妇又爽又刺激视频| 中文字幕av无码一区二区蜜芽三区| 国产成熟女人性满足视频| 爽爽精品dvd蜜桃成熟时电影院| 男女激情一区二区三区| 欧美人成精品网站播放| 威海市| 国产精品久久久久影院亚瑟| 内射干少妇亚洲69xxx| 久久中文骚妇内射| 国产精品美女www爽爽爽视频| 视频一区二区三区刚刚碰| 偷拍精品一区二区三区| 欧美亚洲h在线一区二区| 久久精品波多野结衣| 久久99国产一区二区三区| 暖暖 在线 日本 免费 中文| 国产真人无码作爱视频免费| 国产精品无码a∨麻豆|