音视频入门底子:H.264专题(13)——FFmpeg源码中通过SPS属性获取视频色彩 ...

打印 上一主题 下一主题

主题 532|帖子 532|积分 1596

一、弁言

通过FFmpeg命令可以获取到H.264裸流文件的色彩格式(又译作色度采样结构、像素格式):



在vlc中也可以获取到色彩格式(vlc底层也使用了FFmpeg举行解码):


这个色彩格式就是之前的文章《音视频入门底子:像素格式专题(4)——YUV简介》中形貌的像素格式。以是FFmpeg和vlc是怎样获取到H.264编码的视频的色彩格式呢?它们其实是通过SPS中的属性chroma_format_idc获取的。



二、H.264官方文档对chroma_format_idc的形貌

chroma_format_idc属性在H.264官方文档《T-REC-H.264-202108-I!!PDF-E.pdf》第44页中定义:



根据H.264官方文档《T-REC-H.264-202108-I!!PDF-E.pdf》第22页,当chroma_format_idc = 0时,色彩格式为单色;chroma_format_idc = 1时,色彩格式为YUV 4:2:0;chroma_format_idc = 2时,色彩格式为YUV 4:2:2;chroma_format_idc = 3时,色彩格式为YUV 4:4:4:



根据H.264官方文档第74页,chroma_format_idc的值应该在0到3的范围内(包罗0和3)。当chroma_format_idc不存在时,应推断其值为1(4:2:0的色度格式)。


也就是说,只有当profile_idc等于下面红框里的这些值时,chroma_format_idc才会存在。如果profile_idc不是这些值,chroma_format_idc的值就是1,表现色彩格式为YUV 4:2:0:




三、计算色彩格式的例子

下面以某个视频文件为例,陈诉怎么计算它的色彩格式。用Elecard Stream Analyzer工具打开一个用H.264编码的视频文件,看到其profile_idc值为77。由于profile_idc不是上图红框里的那些值,以是chroma_format_idc值为1,以是该视频的色彩格式为YUV 4:2:0:



用Elecard StreamEye工具可以看到该视频的色彩格式确实为YUV 4:2:0,证明我们的计算是正确的:




四、FFmpeg源码中获取色彩格式的实现

从文章《音视频入门底子:H.264专题(10)——FFmpeg源码中,存放SPS属性的结构体息争码SPS的函数分析》中,我们可以知道,FFmpeg源码中通过ff_h264_decode_seq_parameter_set函数解码SPS,从而拿到SPS中的属性。

在ff_h264_decode_seq_parameter_set函数中有如下代码,通过下面的这部分代码拿到SPS中的chroma_format_idc:
  1. int ff_h264_decode_seq_parameter_set(GetBitContext *gb, AVCodecContext *avctx,
  2.                                      H264ParamSets *ps, int ignore_truncation)
  3. {
  4.     //...
  5.     if (sps->profile_idc == 100 ||  // High profile
  6.         sps->profile_idc == 110 ||  // High10 profile
  7.         sps->profile_idc == 122 ||  // High422 profile
  8.         sps->profile_idc == 244 ||  // High444 Predictive profile
  9.         sps->profile_idc ==  44 ||  // Cavlc444 profile
  10.         sps->profile_idc ==  83 ||  // Scalable Constrained High profile (SVC)
  11.         sps->profile_idc ==  86 ||  // Scalable High Intra profile (SVC)
  12.         sps->profile_idc == 118 ||  // Stereo High profile (MVC)
  13.         sps->profile_idc == 128 ||  // Multiview High profile (MVC)
  14.         sps->profile_idc == 138 ||  // Multiview Depth High profile (MVCD)
  15.         sps->profile_idc == 144) {  // old High444 profile
  16.         sps->chroma_format_idc = get_ue_golomb_31(gb);
  17.     //...
  18.     }else {
  19.         sps->chroma_format_idc = 1;
  20.         //...
  21.     }
  22.     //...
  23. }
复制代码


然后在FFmpeg源码的源文件libavcodec/h264_parser.c的parse_nal_units函数中,通过如下代码,得到色彩格式:
  1. static inline int parse_nal_units(AVCodecParserContext *s,
  2.                                   AVCodecContext *avctx,
  3.                                   const uint8_t * const buf, int buf_size)
  4. {
  5.     //...
  6.    
  7.     for (;;) {
  8.         switch (nal.type) {
  9.         case H264_NAL_SPS:
  10.             ff_h264_decode_seq_parameter_set(&nal.gb, avctx, &p->ps, 0);
  11.             break;
  12.          
  13.         //...
  14.         case H264_NAL_IDR_SLICE:
  15.         
  16.         //...
  17.             switch (sps->bit_depth_luma) {
  18.             case 9:
  19.                 if (sps->chroma_format_idc == 3)      s->format = AV_PIX_FMT_YUV444P9;
  20.                 else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P9;
  21.                 else                                  s->format = AV_PIX_FMT_YUV420P9;
  22.                 break;
  23.             case 10:
  24.                 if (sps->chroma_format_idc == 3)      s->format = AV_PIX_FMT_YUV444P10;
  25.                 else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P10;
  26.                 else                                  s->format = AV_PIX_FMT_YUV420P10;
  27.                 break;
  28.             case 8:
  29.                 if (sps->chroma_format_idc == 3)      s->format = AV_PIX_FMT_YUV444P;
  30.                 else if (sps->chroma_format_idc == 2) s->format = AV_PIX_FMT_YUV422P;
  31.                 else                                  s->format = AV_PIX_FMT_YUV420P;
  32.                 break;
  33.             default:
  34.                 s->format = AV_PIX_FMT_NONE;
  35.             }
  36.         //...
  37.         }
  38.         //...
  39.     }
  40. }
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

河曲智叟

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表