FFMPEG一些color屬性處理

FFMPEG一些color屬性

ffmpeg color有四個(gè)屬性color space擎淤、transfer function宣鄙、primaries、range岸啡,四個(gè)屬性,定義主要見(jiàn)libavutils/pixfmt.h中,以AVCOL_前綴的幾個(gè)enum類型渊额。

1, color space: YUV是基于RGB的顏色空間,color space屬性是決定了YUV2RGB/RGB2YUV的轉(zhuǎn)換計(jì)算matrix
2, color primaries:基于的RGB空間對(duì)應(yīng)的絕對(duì)顏色XYZ的變換,決定了最終三原色RGB分別是什么顏色
3, color transfer:定義了transfer funciton的gamma值旬迹,從RGB到最終顯示的值需要進(jìn)行g(shù)amma壓暗火惊,比如bt709的平均gamma為1.96
4,color range:pc range和tv range(又叫video range和full range)奔垦,full range中YUV的取值[0-255]屹耐,video range中Y[16-235],UV [16-240]

這4個(gè)值默認(rèn)都是UnSpecified椿猎,這種情況下對(duì)于不同的播放器解釋行為不太一致惶岭,要注意一下,可能會(huì)造成不同播放器下的顏色不一致犯眠,建議是已知的color屬性在播放按灶、轉(zhuǎn)碼的時(shí)候切記都要考慮!

shaders相關(guān)

移動(dòng)端中在播放視頻的時(shí)候需要YUV轉(zhuǎn)RGB筐咧,直接拿SwsContext轉(zhuǎn)太慢了鸯旁,可以使用shader來(lái)完成,需要注意轉(zhuǎn)換矩陣問(wèn)題:

1量蕊,YUV2RGB
// Reference http://www.equasys.de/colorconversion.html
static const GLfloat kBt709VideoRangeYUV2RGBMatrix[] = {
  1.164,  1.164,  1.164,
  0.0,   -0.213,  2.112,
  1.793, -0.533,  0.0,
};

// not found bt709 full range matrix, identical with video range
static const GLfloat kBt709FullRangeYUV2RGBMatrix[] = {
  1.164,  1.164,  1.164,
  0.0,   -0.213,  2.112,
  1.793, -0.533,  0.0,
};

static const GLfloat kBt601VideoRangeYUV2RGBMatrix[] = {
  1.164,  1.164, 1.164,
  0.0,   -0.392, 2.017,
  1.596, -0.813, 0.0,
};

static const GLfloat kBt601FullRangeYUV2RGBMatrix[] = {
  1.0, 1.0, 1.0,
  0.0, -0.343, 1.765,
  1.4, -0.711, 0.0,
};

static const char* kGlvsYuv420pToRgb =
    "    // Vertex Shader                                                                \n"
    "    precision highp float;                                                           \n"
    "    attribute highp vec4 a_position;                                                      \n"
    "    attribute highp vec2 a_texCoord0;                                                     \n"
    "    varying highp vec2 v_texCoord0;                                                       \n"
    "    void main(void)                                                                 \n"
    "    {                                                                               \n"
    "        gl_Position = a_position;                                                   \n"
    "        v_texCoord0 = vec2(a_texCoord0.x,1.0-a_texCoord0.y);                        \n"
    "    }                                                                               \n";


static const char* kGlfsYuv420pToRgb =
    "    // Pixel Shader                                                                 \n"
    "    precision highp float;                                                           \n"
    "    uniform lowp sampler2D  ImageInput0    ;                                             \n"
    "    uniform lowp sampler2D  ImageInput1    ;                                             \n"
    "    uniform lowp sampler2D  ImageInput2    ;                                             \n"
    "    varying highp vec2 v_texCoord0;                                                       \n"
    "    uniform float y_offset;                                                         \n"
    "    uniform mat3 um3_ColorConversion;                            \n"
    "                                                                                    \n"
    "    void main(void)                                                                 \n"
    "    {                                                                               \n"
    "        mediump vec3 yuv;                                                           \n"
    "        lowp vec3 rgb;                                                              \n"
    "        yuv.x = texture2D(ImageInput0, v_texCoord0.xy).r - (y_offset / 255.0);      \n"
    "        yuv.y = texture2D(ImageInput1, v_texCoord0.xy).r - 0.5;                     \n"
    "        yuv.z = texture2D(ImageInput2, v_texCoord0.xy).r - 0.5;                     \n"
    "        rgb = um3_ColorConversion * yuv;                      \n"
    "                                                          \n"
    "        gl_FragColor = vec4(rgb, 1.0);                                             \n"
    "    }                                                                               \n";
}  // namespace

2羡亩,RGB2YUV
static const GLfloat kBt709VideoRangeRGB2YUVMatrix[] = {
  0.183,  -0.101, 0.439,
  0.614, -0.339, -0.399,
  0.062, 0.439, -0.040,
};

// Not found bt709 full range, identical as video range for now
static const GLfloat kBt709FullRangeRGB2YUVMatrix[] = {
  0.183,  -0.101, 0.439,
  0.614, -0.339, -0.399,
  0.062, 0.439, -0.040,
};

static const GLfloat kBt601VideoRangeRGB2YUVMatrix[] = {
  0.257, -0.148, 0.439,
  0.504, -0.291, -0.368,
  0.098, 0.439, -0.071,
};

static const GLfloat kBt601FullRangeRGB2YUVMatrix[] = {
  0.299, -0.169, 0.500,
  0.587, -0.331, -0.419,
  0.114, 0.500, -0.081,
};

// Reference:   http://www.equasys.de/colorconversion.html
static const char* kGlfsRgbToYuv420p =
    "    // Pixel Shader                                                                 \n"
    "    precision highp float;                                                           \n"                                               
    "    uniform sampler2D  ImageSampler;                                             \n"
    "    varying vec2 v_texCoord0;                                                       \n"
    "    uniform   mat3 um3_ColorConversion;                                             \n"
    "    uniform   float y_offset;                                                        \n"
    "                                                                                    \n"
    "    void main(void)                                                                 \n"
    "    {                                                                               \n"
    "        lowp vec3 yuv;                                                               \n"
    "                                                                                   \n"
    "        vec4 rgba = texture2D(ImageSampler, v_texCoord0.xy);                         \n"
    "        yuv = um3_ColorConversion * rgba.rgb;                                              \n"
    "        yuv.r = yuv.r + (y_offset / 255.0);                                                  \n"
    "        yuv.g = yuv.g + 0.5;            \n"
    "        yuv.b = yuv.b + 0.5;             \n "
    "        gl_FragColor = vec4(yuv, 1.0);                                          \n"
    "    }                                                                               \n";

VideoToolBox相關(guān)

使用VT來(lái)硬解視頻的時(shí)候支持直接輸出RGB(kCVPixelFormatType_32BGRA等RGB空間的輸出),也能夠使用硬件加速危融,不過(guò)要注意color相關(guān)問(wèn)題畏铆,否則會(huì)偏色。ffmpeg中和VT中對(duì)于color一些屬性的name方式不一樣吉殃。

 if (avctx->color_primaries == AVCOL_PRI_BT709) {
        av_log(avctx, AV_LOG_INFO, "Setting VideoToolbox Color Primaries to BT709\n");
        CFDictionarySetValue(config_info,
                             kCMFormatDescriptionExtension_ColorPrimaries,
                             kCMFormatDescriptionColorPrimaries_ITU_R_709_2);
    } else if (avctx->color_primaries == AVCOL_PRI_SMPTE170M
               || avctx->color_primaries == AVCOL_PRI_SMPTE240M) {
        av_log(avctx, AV_LOG_INFO, "Setting VideoToolbox Color Primaries to SMPTE_C\n");
        CFDictionarySetValue(config_info,
                             kCMFormatDescriptionExtension_ColorPrimaries,
                             kCMFormatDescriptionColorPrimaries_SMPTE_C);
    } else if (avctx->color_primaries == AVCOL_SPC_BT470BG) {
        av_log(avctx, AV_LOG_INFO, "Setting VideoToolbox Color Primaries to EBU_3213\n");
        CFDictionarySetValue(config_info,
                             kCMFormatDescriptionExtension_ColorPrimaries,
                             kCMFormatDescriptionColorPrimaries_EBU_3213);
    } else {
        av_log(avctx, AV_LOG_INFO, "Did not set VideoToolbox Color Primaries for %d\n", avctx->color_primaries);
    }

    if (avctx->color_trc == AVCOL_TRC_BT709
        || avctx->color_trc == AVCOL_TRC_BT2020_10
        || avctx->color_trc == AVCOL_TRC_BT2020_12)
    {
        av_log(avctx, AV_LOG_INFO, "Setting VideoToolbox Color Transfer Function to BT709\n");
        CFDictionarySetValue(config_info,
                             kCMFormatDescriptionExtension_TransferFunction,
                             kCMFormatDescriptionTransferFunction_ITU_R_709_2);
    } else if (avctx->color_trc == AVCOL_TRC_SMPTE170M || avctx->color_trc == AVCOL_TRC_SMPTE240M) {
        av_log(avctx, AV_LOG_INFO, "Setting VideoToolbox Color Transfer Function to SMPTE_240M_1995\n");
        CFDictionarySetValue(config_info,
                             kCMFormatDescriptionExtension_TransferFunction,
                             kCMFormatDescriptionTransferFunction_SMPTE_240M_1995);
    } else {
        av_log(avctx, AV_LOG_INFO, "Did not set VideoToolbox Color Transfer Function for %d\n", avctx->color_trc);
    }


    if (avctx->colorspace == AVCOL_SPC_BT709) {
        av_log(avctx, AV_LOG_INFO, "Setting VideoToolbox Color Space to BT709\n");
        CFDictionarySetValue(config_info,
                             kCMFormatDescriptionExtension_YCbCrMatrix,
                             kCMFormatDescriptionYCbCrMatrix_ITU_R_709_2);
    } else if (avctx->colorspace == AVCOL_SPC_SMPTE170M || avctx->colorspace == AVCOL_SPC_BT470BG) {  
        // TODO: not sure for now whether AVCOL_SPC_BT470BG use 601_4
        av_log(avctx, AV_LOG_INFO, "Setting VideoToolbox Color Space to ITU_R_601_4\n");
        CFDictionarySetValue(config_info,
                             kCMFormatDescriptionExtension_YCbCrMatrix,
                             kCMFormatDescriptionYCbCrMatrix_ITU_R_601_4);
    } else if (avctx->colorspace == AVCOL_SPC_SMPTE240M) {
        av_log(avctx, AV_LOG_INFO, "Setting VideoToolbox Color Space to 240M_1995\n");
        CFDictionarySetValue(config_info,
                             kCMFormatDescriptionExtension_YCbCrMatrix,
                             kCMFormatDescriptionYCbCrMatrix_SMPTE_240M_1995);
    } else {
        av_log(avctx, AV_LOG_INFO, "Did not set VideoToolbox Color Space for %d\n", avctx->colorspace);
    }

    if (avctx->color_range == AVCOL_RANGE_JPEG) {
        av_log(avctx, AV_LOG_INFO, "Setting VideoToolbox Color Range to full range\n");
        CFDictionarySetValue(config_info,
                             kCMFormatDescriptionExtension_FullRangeVideo,
                             kCFBooleanTrue);
    } else {
        av_log(avctx, AV_LOG_INFO, "Did not set VideoToolbox Color Range, will use video-range by default\n");
    }
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末辞居,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子蛋勺,更是在濱河造成了極大的恐慌瓦灶,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件抱完,死亡現(xiàn)場(chǎng)離奇詭異贼陶,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)巧娱,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門(mén)碉怔,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人禁添,你說(shuō)我怎么就攤上這事撮胧。” “怎么了老翘?”我有些...
    開(kāi)封第一講書(shū)人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵芹啥,是天一觀的道長(zhǎng)锻离。 經(jīng)常有香客問(wèn)我,道長(zhǎng)墓怀,這世上最難降的妖魔是什么汽纠? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮傀履,結(jié)果婚禮上疏虫,老公的妹妹穿的比我還像新娘。我一直安慰自己啤呼,他們只是感情好卧秘,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著官扣,像睡著了一般翅敌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上惕蹄,一...
    開(kāi)封第一講書(shū)人閱讀 51,631評(píng)論 1 305
  • 那天蚯涮,我揣著相機(jī)與錄音,去河邊找鬼卖陵。 笑死遭顶,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的泪蔫。 我是一名探鬼主播棒旗,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼撩荣!你這毒婦竟也來(lái)了铣揉?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤餐曹,失蹤者是張志新(化名)和其女友劉穎逛拱,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體台猴,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡朽合,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了饱狂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片曹步。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖嗡官,靈堂內(nèi)的尸體忽然破棺而出箭窜,到底是詐尸還是另有隱情,我是刑警寧澤衍腥,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布磺樱,位于F島的核電站,受9級(jí)特大地震影響婆咸,放射性物質(zhì)發(fā)生泄漏竹捉。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一尚骄、第九天 我趴在偏房一處隱蔽的房頂上張望块差。 院中可真熱鬧,春花似錦倔丈、人聲如沸憨闰。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)鹉动。三九已至,卻和暖如春宏邮,著一層夾襖步出監(jiān)牢的瞬間泽示,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來(lái)泰國(guó)打工蜜氨, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留械筛,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓飒炎,卻偏偏與公主長(zhǎng)得像埋哟,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子郎汪,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • 教程一:視頻截圖(Tutorial 01: Making Screencaps) 首先我們需要了解視頻文件的一些基...
    90后的思維閱讀 4,700評(píng)論 0 3
  • 發(fā)現(xiàn) 關(guān)注 消息 iOS 第三方庫(kù)定欧、插件、知名博客總結(jié) 作者大灰狼的小綿羊哥哥關(guān)注 2017.06.26 09:4...
    肇東周閱讀 12,105評(píng)論 4 62
  • 常量定義THINKPHP->Library->Behavior>ContentReplaceBehavior.cl...
    hello大象閱讀 1,998評(píng)論 0 0
  • 社群是一種新的人際關(guān)系爷辱,是建立在互聯(lián)網(wǎng)基礎(chǔ)上,社群是依據(jù)人們的興趣愛(ài)好朦肘,身份地位饭弓,審美觀和人生價(jià)值觀建立起來(lái)的圈子...
    崇立鑫閱讀 10,542評(píng)論 0 49
  • 嶄新的一年拉開(kāi)了序幕∶娇伲縱使外面霧霾重重弟断,依然阻擋不了我們熱愛(ài)生活的步伐。有句話說(shuō)的好趴生,真正的熱愛(ài)阀趴,是你看透生活后依...
    故道浮云閱讀 277評(píng)論 6 5