[关闭]
@ltlovezh 2019-08-21T10:10:52.000000Z 字数 11988 阅读 4105

FFmpeg之ffprobe

ffmpeg


ffprobeffmpeg提供的三大工具之一,用来查看音视频文件的各种信息,比如:封装格式、音频/视频流信息、数据包信息等。

ffprobe的源码是ffprobe.c,开发过程中如果想获取ffprobe查看的信息,可以通过分析源码,获得对应字段。 本文主要介绍formatstreamPacketFrame信息,包含每个字段的说明以及对应的ffmpeg字段。

查看音视频文件的封装格式

  1. ffprobe -show_format inputFile

输出如下信息:

  1. [FORMAT]
  2. // 文件名
  3. filename=VID_20190811_113717.mp4
  4. // 容器中流的个数,即AVFormatContext->nb_streams
  5. nb_streams=2
  6. // 即AVFormatContext->nb_programs
  7. nb_programs=0
  8. // 封装格式,即AVFormatContext->iformat->name
  9. format_name=mov,mp4,m4a,3gp,3g2,mj2
  10. // 即AVFormatContext->iformat->long_name
  11. format_long_name=QuickTime / MOV
  12. // 即AVFormatContext->start_time,基于AV_TIME_BASE_Q,换算为秒
  13. start_time=0.000000
  14. // 即AVFormatContext->duration,基于AV_TIME_BASE_Q,换算为秒
  15. duration=10.508000
  16. // 单位字节,即avio_size(AVFormatContext->pb)
  17. size=27263322
  18. // 码率,即AVFormatContext->bit_rate
  19. bit_rate=20756240
  20. // 即AVFormatContext->probe_score
  21. probe_score=100
  22. [/FORMAT]

查看音视频文件的流信息

  1. ffprobe -show_streams inputFile

输出如下信息:

  1. [STREAM]
  2. // 当前流的索引信息,对应于AVStream->index
  3. index=0
  4. // AVCodecDescriptor * cd = avcodec_descriptor_get(AVStream->codecpar->codec_id)
  5. // 编码名称,即cd->name
  6. codec_name=h264
  7. // 编码全称,即cd->long_name
  8. codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10
  9. // 一个编码参数,可以为Baseline、Main、High等,Baseline无B帧,Main及以后可以包含B帧
  10. // 通过avcodec_profile_name(AVStream->codecpar->codec_id, AVStream->codecpar->profile)获得
  11. profile=High
  12. // 流类型,即av_get_media_type_string(AVStream->codecpar->codec_type)
  13. codec_type=video
  14. // 即AVStream->codec->time_base
  15. codec_time_base=14777/877500
  16. // 通过宏av_fourcc2str(AVStream->codecpar->codec_tag)获得
  17. codec_tag_string=avc1
  18. // 对应AVStream->codecpar->codec_tag
  19. codec_tag=0x31637661
  20. // 有效区域的宽度,即AVStream->codecpar->width
  21. width=1920
  22. // 有效区域的高度,即AVStream->codecpar->height
  23. height=1080
  24. // 视频帧宽度,可能与上面的宽度不同,即AVStream->codec->coded_width,例如:当解码帧在输出前裁剪或启用低分辨率时
  25. coded_width=1920
  26. // 视频帧高度,可能与上面的高度不同,即AVStream->codec->coded_height,例如:当解码帧在输出前裁剪或启用低分辨率时
  27. coded_height=1088
  28. // 视频的延迟帧数,即AVStream->codecpar->video_delay
  29. has_b_frames=0
  30. // sar,图像采集时,横向采集点数与纵向采集点数的比例
  31. // FFmpeg提供了多个sar:AVStream->sample_aspect_ratio、AVStream->codecpar->sample_aspect_ratio、AVFrame->sample_aspect_ratio
  32. // 通过av_guess_sample_aspect_ratio获取最终的sar
  33. sample_aspect_ratio=1:1
  34. // dar,真正展示的图像宽高比,在渲染视频时,必须根据这个比例进行缩放
  35. // 通过av_reduce计算得到,par * sar = dar
  36. display_aspect_ratio=16:9
  37. // 像素格式,即av_get_pix_fmt_name(AVStream->codecpar->format)
  38. pix_fmt=yuvj420p
  39. // 编码参数,即AVStream->codecpar->level
  40. level=40
  41. // 额外的色彩空间特征,即av_color_range_name(AVStream->codecpar->color_range),AVCOL_RANGE_MPEG对应tv,AVCOL_RANGE_JPEG对应pc
  42. color_range=pc
  43. // YUV彩色空间类型,即av_color_space_name(AVStream->codecpar->color_space)
  44. color_space=bt470bg
  45. // 颜色传输特性,即av_color_transfer_name(AVStream->codecpar->color_trc)
  46. color_transfer=smpte170m
  47. // 即av_color_primaries_name(AVStream->codecpar->color_primaries)
  48. color_primaries=bt470bg
  49. // 色度样品的位置,即av_chroma_location_name(AVStream->codecpar->chroma_location)
  50. chroma_location=left
  51. // 交错视频中字段的顺序,即AVStream->codecpar->field_order
  52. field_order=unknown
  53. // av_timecode_make_mpeg_tc_string处理AVStream->codec->timecode_frame_start获得
  54. timecode=N/A
  55. // 参考帧数量,即AVStream->codec->refs
  56. refs=1
  57. is_avc=true
  58. // 表示用几个字节表示NALU的长度
  59. nal_length_size=4
  60. id=N/A
  61. // 当前流的基本帧率,这个值仅是一个猜测,对应于AVStream->r_frame_rate
  62. r_frame_rate=30/1
  63. // 平均帧率,对应于AVStream->avg_frame_rate
  64. avg_frame_rate=438750/14777
  65. // AVStream的时间基准,即AVStream->time_base
  66. time_base=1/90000
  67. // 流开始时间,基于time_base,即AVStream->start_time
  68. start_pts=0
  69. // 转换(start_pts * time_base)之后的开始时间,单位秒
  70. start_time=0.000000
  71. // 流时长,基于time_base,即AVStream->duration
  72. duration_ts=945728
  73. // 转换(duration_ts * time_base)之后的时长,单位秒
  74. duration=10.508089
  75. // 码率,即AVStream->codecpar->bit_rate
  76. bit_rate=19983544
  77. // 最大码率,即AVStream->codec->rc_max_rate
  78. max_bit_rate=N/A
  79. // Bits per sample/pixel,即AVStream->codec->bits_per_raw_sample
  80. bits_per_raw_sample=8
  81. // 视频流中的帧数,即AVStream->nb_frames
  82. nb_frames=312
  83. nb_read_frames=N/A
  84. nb_read_packets=N/A
  85. // 下面TAG为AVStream->metadata中的信息
  86. // 逆时针的旋转角度(相当于正常视频的逆时针旋转角度)
  87. TAG:rotate=90
  88. // 创建时间
  89. TAG:creation_time=2019-08-11T03:37:28.000000Z
  90. // 语言
  91. TAG:language=eng
  92. TAG:handler_name=VideoHandle
  93. // SIDE_DATA为AVStream->side_data数据
  94. [SIDE_DATA]
  95. // side_data数据类型,Display Matrix表示一个3*3的矩阵,这个矩阵需要应用到解码后的视频帧上,才能正确展示
  96. side_data_type=Display Matrix
  97. displaymatrix=
  98. 00000000: 0 65536 0
  99. 00000001: -65536 0 0
  100. 00000002: 0 0 1073741824
  101. // 顺时针旋转90度还原视频
  102. rotation=-90
  103. [/SIDE_DATA]
  104. [/STREAM]
  105. [STREAM]
  106. // 当前流的索引信息,对应于AVStream->index
  107. index=1
  108. // AVCodecDescriptor * cd = avcodec_descriptor_get(AVStream->codecpar->codec_id)
  109. // 编码名称,即cd->name
  110. codec_name=aac
  111. // 编码全称,即cd->long_name
  112. codec_long_name=AAC (Advanced Audio Coding)
  113. // 通过avcodec_profile_name(AVStream->codecpar->codec_id, AVStream->codecpar->profile)获得
  114. profile=LC
  115. // 流类型,即av_get_media_type_string(AVStream->codecpar->codec_type)
  116. codec_type=audio
  117. // 即AVStream->codec->time_base
  118. codec_time_base=1/48000
  119. // 通过宏av_fourcc2str(AVStream->codecpar->codec_tag)获得
  120. codec_tag_string=mp4a
  121. // 对应AVStream->codecpar->codec_tag
  122. codec_tag=0x6134706d
  123. // 采样点格式,通过av_get_sample_fmt_name(AVStream->codecpar->format)获取
  124. sample_fmt=fltp
  125. // 采样率,即AVStream->codecpar->sample_rate
  126. sample_rate=48000
  127. // 通道数,即AVStream->codecpar->channels
  128. channels=2
  129. // 通道布局,与channels是相对应,通过av_bprint_channel_layout获取,stereo表示立体声
  130. channel_layout=stereo
  131. // 每个采样点占用多少bit,即av_get_bits_per_sample(par->codec_id)
  132. bits_per_sample=0
  133. id=N/A
  134. r_frame_rate=0/0
  135. avg_frame_rate=0/0
  136. // AVStream的时间基准,即AVStream->time_base
  137. time_base=1/48000
  138. // 流开始时间,基于time_base,即AVStream->start_time
  139. start_pts=0
  140. // 转换(start_pts * time_base)之后的开始时间,单位秒
  141. start_time=0.000000
  142. // 流时长,基于time_base,即AVStream->duration
  143. duration_ts=502776
  144. // 转换(duration_ts * time_base)之后的时长,单位秒
  145. duration=10.474500
  146. // 码率,即AVStream->codecpar->bit_rate
  147. bit_rate=156002
  148. // 最大码率,即AVStream->codec->rc_max_rate
  149. max_bit_rate=156000
  150. // Bits per sample/pixel,即AVStream->codec->bits_per_raw_sample
  151. bits_per_raw_sample=N/A
  152. // 音频流中的帧数,即AVStream->nb_frames
  153. nb_frames=491
  154. nb_read_frames=N/A
  155. nb_read_packets=N/A
  156. TAG:creation_time=2019-08-11T03:37:28.000000Z
  157. TAG:language=eng
  158. TAG:handler_name=SoundHandle
  159. [/STREAM]

SAR(Sample Aspect Ratio): 采样数宽高比,图像的横向采集点数与纵向采集点数的比值,即像素个数的比值。
PAR(Pixel Aspect Ratio): 像素宽高比,即每个像素的宽度与高度的比值,所以可以认为像素不是正方形的。
DAR(Display Aspect Ratio): 显示宽高比,图像最终展示的宽高比,播放器在渲染视频帧时,需要保持DAR的比例。
它们之间的关系:PAR * SAR = DAR
dar示例
如上图所示:每个方格代表一个像素,宽度为5像素,高度为4像素,即SAR=5 : 4
假设图像的显示宽度为160,高度为120,即DAR=4 : 3
那么可以计算出PAR = DAR / SAR = 16 : 15,表示像素方格是一个长方形。

FFmpeg提供了多个SAR:
AVStream->sample_aspect_ratio
AVStream->codecpar->sample_aspect_ratio
AVFrame->sample_aspect_ratio
最终的SAR是通过av_guess_sample_aspect_ratio获取的。

对于DAR,AVStream->display_aspect_ratio的值始终为0:0,参考ffprobe代码,可知DAR是通过av_reduce计算得到的,如下所示:

  1. AVRational sar, dar;
  2. // par
  3. AVCodecParameters *par = AVStream->codecpar;
  4. // 计算出sar
  5. sar = av_guess_sample_aspect_ratio(AVFormatContext, AVStream, NULL);
  6. // 根据par和sar计算出dar
  7. av_reduce(&dar.num, &dar.den,
  8. par->width * sar.num,
  9. par->height * sar.den,
  10. 1024*1024);

查看音视频文件的数据包信息

  1. // -select_streams表示选择音频或者视频
  2. ffprobe -show_format [-select_streams audio | video] inputFile

首先看下视频流的第一个Packet和第二个Packet:

  1. [PACKET]
  2. //Packet类型,即av_get_media_type_string(AVStream->codecpar->codec_type)
  3. codec_type=video
  4. // 当前帧所属流的索引信息,对应于AVStream->index
  5. stream_index=0
  6. // 帧展示时间,即AVPacket->pts,基于AVStream->time_base时间基准
  7. pts=0
  8. // 换算为秒
  9. pts_time=0.000000
  10. // 帧解码时间,即AVPacket->dts,基于AVStream->time_base时间基准
  11. dts=0
  12. // 换算为秒
  13. dts_time=0.000000
  14. // 当前帧的时长,等于下一帧的pts - 当前帧pts,即AVPacket->duration,基于AVStream->time_base时间基准
  15. duration=12972
  16. // 换算为秒
  17. duration_time=0.144133
  18. // AVPacket->convergence_duration,也是基于AVStream->time_base时间基准
  19. convergence_duration=N/A
  20. // 换算为秒
  21. convergence_duration_time=N/A
  22. // 当前帧的Size,字节,即AVPacket->size
  23. size=187872
  24. // 当前帧地址偏移量,即AVPacket->pos
  25. pos=830842
  26. flags=K_
  27. [/PACKET]
  28. [PACKET]
  29. codec_type=video
  30. stream_index=0
  31. pts=12972
  32. // 即 12972 / 90000
  33. pts_time=0.144133
  34. dts=12972
  35. dts_time=0.144133
  36. duration=2999
  37. duration_time=0.033322
  38. convergence_duration=N/A
  39. convergence_duration_time=N/A
  40. size=31200
  41. // 上一帧的pos + size
  42. pos=1018714
  43. flags=__
  44. [/PACKET]

然后看下音频流的第一个Packet和第二个Packet:

  1. [PACKET]
  2. // 音频帧
  3. codec_type=audio
  4. // 当前帧所属流的索引信息,对应于AVStream->index
  5. stream_index=1
  6. // 帧展示时间,即AVPacket->pts,基于AVStream->time_base时间基准
  7. pts=0
  8. pts_time=0.000000
  9. // 帧解码时间,即AVPacket->dts,基于AVStream->time_base时间基准
  10. dts=0
  11. dts_time=0.000000
  12. // 当前帧的时长,等于下一帧的pts - 当前帧pts,即AVPacket->duration,基于AVStream->time_base时间基准
  13. duration=1024
  14. // 1024 / 48000
  15. duration_time=0.021333
  16. convergence_duration=N/A
  17. convergence_duration_time=N/A
  18. size=416
  19. pos=810458
  20. flags=K_
  21. [/PACKET]
  22. [PACKET]
  23. // 音频帧
  24. codec_type=audio
  25. stream_index=1
  26. pts=1024
  27. // 1024 / 48000
  28. pts_time=0.021333
  29. dts=1024
  30. dts_time=0.021333
  31. duration=1024
  32. duration_time=0.021333
  33. convergence_duration=N/A
  34. convergence_duration_time=N/A
  35. size=416
  36. // 上一帧的pos + size
  37. pos=810874
  38. flags=K_
  39. [/PACKET]

查看音视频文件解码后的帧信息

  1. // -select_streams表示选择音频或者视频
  2. ffprobe -show_frames [-select_streams audio | video] inputFile

首先看下视频流的第一帧和第二帧:

  1. [FRAME]
  2. // 帧类型,即av_get_media_type_string(AVStream->codecpar->codec_type)
  3. media_type=video
  4. // 当前帧所属流的索引信息, 对应于AVStream->index
  5. stream_index=0
  6. // 是否关键帧,1:关键帧,0:非关键帧,即AVFrame->key_frame
  7. key_frame=1
  8. // 帧展示时间, 即AVFrame->pts, 基于AVStream->time_base时间基准
  9. pkt_pts=0
  10. // 换算为秒
  11. pkt_pts_time=0.000000
  12. // 帧解码时间,从对应的AVPacket copy而来,即AVFrame->pkt_dts,基于AVStream->time_base时间基准
  13. pkt_dts=0
  14. // 换算为秒
  15. pkt_dts_time=0.000000
  16. // 帧时间戳,基本与pts相同,即AVFrame->best_effort_timestamp,基于AVStream->time_base时间基准
  17. best_effort_timestamp=0
  18. // 换算为秒
  19. best_effort_timestamp_time=0.000000
  20. // 对应的AVPacket的帧时长,即AVFrame->pkt_duration,基于AVStream->time_base时间基准
  21. pkt_duration=12972
  22. // 换算为秒
  23. pkt_duration_time=0.144133
  24. // 从最后一个已输入解码器的AVPacket重新排序的pos,即AVFrame->pkt_pos
  25. pkt_pos=830842
  26. // 对应的AVPacket的帧size,即AVFrame->pkt_size
  27. pkt_size=187872
  28. // 旋转之前的帧宽度,即AVFrame->width
  29. width=1920
  30. // 旋转之前的帧高度,即AVFrame->height
  31. height=1080
  32. // 视频帧的像素格式,即av_get_pix_fmt_name(AVFrame->format)
  33. pix_fmt=yuvj420p
  34. // sar,图像采集时,横向采集点数与纵向采集点数的比例
  35. // FFmpeg提供了多个sar:AVStream->sample_aspect_ratio、AVStream->codecpar->sample_aspect_ratio、AVFrame->sample_aspect_ratio
  36. // 通过av_guess_sample_aspect_ratio获取最终的sar
  37. sample_aspect_ratio=1:1
  38. // 视频帧的图片类型,此处为I帧,即av_get_picture_type_char(frame->pict_type)
  39. pict_type=I
  40. // picture number in bitstream order, 即AVFrame->coded_picture_number
  41. coded_picture_number=0
  42. // picture number in display order, 即AVFrame->display_picture_number
  43. display_picture_number=0
  44. // 视频帧内容是否是交错的, 即AVFrame->interlaced_frame
  45. interlaced_frame=0
  46. // 若视频帧内容是交错的,表示首先展示的顶部字段,即AVFrame->top_field_first
  47. top_field_first=0
  48. // 当解码时,这个信号表明视频帧必须延迟多少。extra_delay = repeat_pict / (2*fps), 即AVFrame->repeat_pict
  49. repeat_pict=0
  50. // 额外的色彩空间特征,即av_color_range_name(AVFrame->color_range),AVCOL_RANGE_MPEG对应tv,AVCOL_RANGE_JPEG对应pc
  51. color_range=pc
  52. // YUV彩色空间类型,即av_color_space_name(AVFrame->colorspace)
  53. color_space=bt470bg
  54. // 即av_color_primaries_name(AVFrame->color_primaries)
  55. color_primaries=bt470bg
  56. // 颜色传输特性,即av_color_transfer_name(AVFrame->color_trc)
  57. color_transfer=smpte170m
  58. // 色度样品的位置,即av_chroma_location_name(AVFrame->chroma_location)
  59. chroma_location=left
  60. [/FRAME]
  61. [FRAME]
  62. media_type=video
  63. stream_index=0
  64. // 非关键帧
  65. key_frame=0
  66. pkt_pts=12972
  67. // 12972 / 90000
  68. pkt_pts_time=0.144133
  69. pkt_dts=12972
  70. pkt_dts_time=0.144133
  71. best_effort_timestamp=12972
  72. best_effort_timestamp_time=0.144133
  73. pkt_duration=2999
  74. pkt_duration_time=0.033322
  75. pkt_pos=1018714
  76. pkt_size=31200
  77. width=1920
  78. height=1080
  79. pix_fmt=yuvj420p
  80. sample_aspect_ratio=1:1
  81. // 视频帧的图片类型,此处为P帧,即av_get_picture_type_char(frame->pict_type)
  82. pict_type=P
  83. coded_picture_number=1
  84. display_picture_number=0
  85. interlaced_frame=0
  86. top_field_first=0
  87. repeat_pict=0
  88. color_range=pc
  89. color_space=bt470bg
  90. color_primaries=bt470bg
  91. color_transfer=smpte170m
  92. chroma_location=left
  93. [/FRAME]

然后看下音频流的第一帧和第二帧:

  1. [FRAME]
  2. // 帧类型,即av_get_media_type_string(AVStream->codecpar->codec_type)
  3. media_type=audio
  4. // 当前帧所属流的索引信息, 对应于AVStream->index
  5. stream_index=1
  6. // 是否关键帧
  7. key_frame=1
  8. // 帧展示时间, 即AVFrame->pts, 基于AVStream->time_base时间基准
  9. pkt_pts=0
  10. // 换算为秒
  11. pkt_pts_time=0.000000
  12. // 帧解码时间,从对应的AVPacket copy而来,即AVFrame->pkt_dts,基于AVStream->time_base时间基准
  13. pkt_dts=0
  14. // 换算为秒
  15. pkt_dts_time=0.000000
  16. // 帧时间戳,基本与pts相同,即AVFrame->best_effort_timestamp,基于AVStream->time_base时间基准
  17. best_effort_timestamp=0
  18. // 换算为秒
  19. best_effort_timestamp_time=0.000000
  20. // 对应的AVPacket的帧时长,即AVFrame->pkt_duration,基于AVStream->time_base时间基准
  21. pkt_duration=1024
  22. // 换算为秒
  23. pkt_duration_time=0.021333
  24. // 从最后一个已输入解码器的AVPacket重新排序的pos,即AVFrame->pkt_pos
  25. pkt_pos=810458
  26. // 对应的AVPacket的帧size,即AVFrame->pkt_size
  27. pkt_size=416
  28. // 音频采样点格式,即av_get_sample_fmt_name(AVFrame->format)
  29. sample_fmt=fltp
  30. // 当前音频帧的采样点数,即AVFrame->nb_samples
  31. nb_samples=1024
  32. // 通道数,即AVFrame->channels
  33. channels=2
  34. // 通道布局,通过av_bprint_channel_layout得到,与channels对应
  35. channel_layout=stereo
  36. [/FRAME]
  37. [FRAME]
  38. media_type=audio
  39. stream_index=1
  40. key_frame=1
  41. pkt_pts=1024
  42. pkt_pts_time=0.021333
  43. pkt_dts=1024
  44. pkt_dts_time=0.021333
  45. best_effort_timestamp=1024
  46. best_effort_timestamp_time=0.021333
  47. pkt_duration=1024
  48. pkt_duration_time=0.021333
  49. pkt_pos=810874
  50. pkt_size=416
  51. sample_fmt=fltp
  52. nb_samples=1024
  53. channels=2
  54. channel_layout=stereo
  55. [/FRAME]

后续继续补充更多音视频信息。

参考文章

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注