使用 capture.get(CV_CAP_PROP_FPS) 时 OpenCV 报告 TBR 而不是 FPS

发布于 2025-01-08 06:47:35 字数 2646 浏览 0 评论 0原文

我尝试在 Mac OS 10.6.8 (Snow Leopard) 上使用 OpenCV 和 Qt 4.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

正确报告 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;

我得到的输出是:

Frame Rate: 1001 
Num of Frames: 610832 
OpenCV Version 2.3.1 

报告 TBR 而不是 FPS。当我尝试打开不同的视频时,这种行为是一致的。

我检查了 OpenCV 的 bug 跟踪器,我还发现了 这个堆栈溢出问题是一个类似但不完全相同的问题,所以我不知道下一步该做什么。任何提示或想法都是最受欢迎的,因为我已经尝试了很多事情,但似乎一无所获。

I have several videos that I am trying to process using OpenCV and Qt 4.7.4 on Mac OS 10.6.8 (Snow Leopard). If I create a cv::VideoCapture object and then query for the frame rate related to such video, what I get back is the TBR and not FPS.

For instance if use ffprobe Video1.mp4 what I get is:

>> 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

Which correctly reports FPS = 27.71 and TBR = 1001. Nevertheless if I use the following OpenCV code to query for the 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;

The output I get is:

Frame Rate: 1001 
Num of Frames: 610832 
OpenCV Version 2.3.1 

Which reports the TBR instead of the FPS. This behavior is consistent when I try to open different videos.

I checked OpenCV's bug tracker and I also found this stack overflow question to be a similar but not quite the same problem, so I am at a loss to what to do next. Any hint or idea is most welcome since I've tried lots of things and seem to be getting nowhere.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

咿呀咿呀哟 2025-01-15 06:47:35

我想他们选择报告 TBR 是因为这是 ffmpeg 的最佳猜测实际的帧速率是多少。在许多容器上,fps 字段(更具体地说是 AVStream.avg_frame_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;

TBC(编解码器时基):< /strong>

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;

TBN(流(容器)时基):

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 显示它,即使它无法通过分析确定它。是否可以正确地重新编码视频?

I imagine they chose to report TBR because that is ffmpeg's best guess as to what the framerate actually is. On many containers, the fps field (more specifically AVStream.avg_frame_rate) is not available, so it can't really be relied upon.

Here are the comments from the ffmpeg source on the tbr, tbc, and tbn fields:

TBR (ffmpeg's best guess):

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;

TBC (the codec timebase):

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;

TBN (the stream (container) timebase):

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;

Hopefully, that explains why TBR is reported instead of FPS. It appears ffmpeg is having difficulty determining the time base for your video stream, and the container (e.g., AVI, MP4, DivX, XviD, etc...) supplies the framerate, so ffmpeg displays it even though it can't determine it through analysis. Is it possible to re-encode the video properly?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文