C++ 使用capture.get(CV\u CAP\u PROP\u FPS)时,OpenCV报告TBR而不是FPS

C++ 使用capture.get(CV\u CAP\u PROP\u FPS)时,OpenCV报告TBR而不是FPS,c++,qt,opencv,ffmpeg,osx-snow-leopard,C++,Qt,Opencv,Ffmpeg,Osx Snow Leopard,我有几个视频,我正试图在MacOS10.6.8(雪豹)上使用OpenCV和Qt4.7.4进行处理。如果我创建一个cv::VideoCapture对象,然后查询与此类视频相关的帧速率,我得到的是TBR而不是FPS 例如,如果使用ffprobe Video1.mp4我得到的是: >> ffprobe Video1.mp4 ffprobe version 0.7.8, Copyright (c) 2007-2011 the FFmpeg developers built on

我有几个视频,我正试图在MacOS10.6.8(雪豹)上使用OpenCV和Qt4.7.4进行处理。如果我创建一个
cv::VideoCapture
对象,然后查询与此类视频相关的帧速率,我得到的是TBR而不是FPS

例如,如果使用
ffprobe Video1.mp4
我得到的是:

>> ffprobe Video1.mp4      
ffprobe version 0.7.8, Copyright (c) 2007-2011 the FFmpeg developers
built on Nov 24 2011 14:31:00 with gcc 4.2.1 (Apple Inc. build 5666) (dot 3)
configuration: --prefix=/opt/local --enable-gpl --enable-postproc --enable-swscale --   
enable-avfilter --enable-libmp3lame --enable-libvorbis --enable-libtheora --enable-
libdirac --enable-libschroedinger --enable-libopenjpeg --enable-libxvid --enable-libx264 
--enable-libvpx --enable-libspeex --mandir=/opt/local/share/man --enable-shared --
enable-pthreads --cc=/usr/bin/gcc-4.2 --arch=x86_64 --enable-yasm
libavutil    50. 43. 0 / 50. 43. 0
libavcodec   52.123. 0 / 52.123. 0
libavformat  52.111. 0 / 52.111. 0
libavdevice  52.  5. 0 / 52.  5. 0
libavfilter   1. 80. 0 /  1. 80. 0
libswscale    0. 14. 1 /  0. 14. 1
libpostproc  51.  2. 0 / 51.  2. 0

Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'Video1.mp4':
Metadata:
major_brand     : isom
minor_version   : 0
compatible_brands: mp41avc1qt  
creation_time   : 2012-01-09 23:09:43
encoder         : vlc 1.1.3 stream output
encoder-eng     : vlc 1.1.3 stream output
Duration: 00:10:10.22, start: 0.000000, bitrate: 800 kb/s
Stream #0.0(eng): Video: h264 (Baseline), yuvj420p, 704x480 [PAR 10:11 DAR 4:3], 798 
kb/s, 27.71 fps, 1001 tbr, 1001 tbn, 2002 tbc
Metadata:
  creation_time   : 2012-01-09 23:09:43
Frame Rate: 1001 
Num of Frames: 610832 
OpenCV Version 2.3.1 
正确报告FPS=27.71和TBR=1001。但是,如果我使用以下OpenCV代码查询FPS:

QString filename = QFileDialog::getOpenFileName(this,
                                        "Open Video",
                                        "Video Files (*.mp4, *.mpg)");

capture.release();
capture.open(filename.toAscii().data());

if (!capture.isOpened()){
    qDebug() <<"Error when opening the video!";
    return;
}


qDebug() << "Frame Rate:" << capture.get(CV_CAP_PROP_FPS);
qDebug() << "Num of Frames:" << capture.get(CV_CAP_PROP_FRAME_COUNT);
qDebug() << "OpenCV Version" << CV_VERSION;
它报告TBR而不是FPS。当我尝试打开不同的视频时,这种行为是一致的


我检查了OpenCV,还发现堆栈溢出问题是一个类似但不完全相同的问题,所以我不知道下一步该怎么办。任何提示或想法都是最受欢迎的,因为我尝试了很多东西,但似乎一无所获。

我想他们之所以选择报告TBR,是因为这是关于实际帧率的。在许多容器上,fps字段(更具体地说是
AVStream.avg\u frame\u rate
)不可用,因此不能真正依赖它

以下是
ffmpeg
源代码对tbr、tbc和tbn字段的注释:

TBR(ffmpeg的最佳猜测):

struct AVStream {
...
/**
 * Real base framerate of the stream.
 * This is the lowest framerate with which all timestamps can be
 * represented accurately (it is the least common multiple of all
 * framerates in the stream). Note, this value is just a guess!
 * For example, if the time base is 1/90000 and all frames have either
 * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1.
 */
AVRational r_frame_rate;
struct AVCodecContext {
...
/**
 * This is the fundamental unit of time (in seconds) in terms
 * of which frame timestamps are represented. For fixed-fps content,
 * time base should be 1/framerate and timestamp increments should be 1.
 * decoding: set by libavformat
 * encoding: set by libavformat in av_write_header
 */
AVRational time_base;
struct AVStream {
...
/**
 * This is the fundamental unit of time (in seconds) in terms
 * of which frame timestamps are represented. For fixed-fps content,
 * timebase should be 1/framerate and timestamp increments should be
 * identically 1.
 * - encoding: MUST be set by user.
 * - decoding: Set by libavcodec.
 */
 AVRational time_base;
TBC(编解码器时基):

struct AVStream {
...
/**
 * Real base framerate of the stream.
 * This is the lowest framerate with which all timestamps can be
 * represented accurately (it is the least common multiple of all
 * framerates in the stream). Note, this value is just a guess!
 * For example, if the time base is 1/90000 and all frames have either
 * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1.
 */
AVRational r_frame_rate;
struct AVCodecContext {
...
/**
 * This is the fundamental unit of time (in seconds) in terms
 * of which frame timestamps are represented. For fixed-fps content,
 * time base should be 1/framerate and timestamp increments should be 1.
 * decoding: set by libavformat
 * encoding: set by libavformat in av_write_header
 */
AVRational time_base;
struct AVStream {
...
/**
 * This is the fundamental unit of time (in seconds) in terms
 * of which frame timestamps are represented. For fixed-fps content,
 * timebase should be 1/framerate and timestamp increments should be
 * identically 1.
 * - encoding: MUST be set by user.
 * - decoding: Set by libavcodec.
 */
 AVRational time_base;
TBN(流(容器)时基):

struct AVStream {
...
/**
 * Real base framerate of the stream.
 * This is the lowest framerate with which all timestamps can be
 * represented accurately (it is the least common multiple of all
 * framerates in the stream). Note, this value is just a guess!
 * For example, if the time base is 1/90000 and all frames have either
 * approximately 3600 or 1800 timer ticks, then r_frame_rate will be 50/1.
 */
AVRational r_frame_rate;
struct AVCodecContext {
...
/**
 * This is the fundamental unit of time (in seconds) in terms
 * of which frame timestamps are represented. For fixed-fps content,
 * time base should be 1/framerate and timestamp increments should be 1.
 * decoding: set by libavformat
 * encoding: set by libavformat in av_write_header
 */
AVRational time_base;
struct AVStream {
...
/**
 * This is the fundamental unit of time (in seconds) in terms
 * of which frame timestamps are represented. For fixed-fps content,
 * timebase should be 1/framerate and timestamp increments should be
 * identically 1.
 * - encoding: MUST be set by user.
 * - decoding: Set by libavcodec.
 */
 AVRational time_base;

希望这能解释为什么报告TBR而不是FPS。似乎
ffmpeg
很难确定视频流的时基,而容器(如AVI、MP4、DivX、XviD等)提供帧速率,因此
ffmpeg
即使无法通过分析确定,也会显示它。是否可以正确地重新编码视频?

重新编码视频虽然可行,但会很麻烦,因为视频太多,而且有点长。它们是由网络摄像机生成的。但你的回答清楚地解释了为什么我得到的是TBR而不是FPS。谢谢