mirror of
https://github.com/opencv/opencv.git
synced 2025-06-07 17:44:04 +08:00
videoio: fix incorrect timestamps returned by VideoCapture when using raw video parsing mode
This commit is contained in:
parent
a8ec658611
commit
81865b3d52
@ -1587,8 +1587,11 @@ bool CvCapture_FFMPEG::grabFrame()
|
|||||||
if (picture_pts == AV_NOPTS_VALUE_) {
|
if (picture_pts == AV_NOPTS_VALUE_) {
|
||||||
if (!rawMode)
|
if (!rawMode)
|
||||||
picture_pts = picture->CV_FFMPEG_PTS_FIELD != AV_NOPTS_VALUE_ && picture->CV_FFMPEG_PTS_FIELD != 0 ? picture->CV_FFMPEG_PTS_FIELD : picture->pkt_dts;
|
picture_pts = picture->CV_FFMPEG_PTS_FIELD != AV_NOPTS_VALUE_ && picture->CV_FFMPEG_PTS_FIELD != 0 ? picture->CV_FFMPEG_PTS_FIELD : picture->pkt_dts;
|
||||||
else
|
else {
|
||||||
picture_pts = packet.pts != AV_NOPTS_VALUE_ && packet.pts != 0 ? packet.pts : packet.dts;
|
const AVPacket& packet_raw = packet.data != 0 ? packet : packet_filtered;
|
||||||
|
picture_pts = packet_raw.pts != AV_NOPTS_VALUE_ && packet_raw.pts != 0 ? packet_raw.pts : packet_raw.dts;
|
||||||
|
if (picture_pts < 0) picture_pts = 0;
|
||||||
|
}
|
||||||
frame_number++;
|
frame_number++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,6 +235,66 @@ const videoio_container_params_t videoio_container_params[] =
|
|||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(/**/, videoio_container, testing::ValuesIn(videoio_container_params));
|
INSTANTIATE_TEST_CASE_P(/**/, videoio_container, testing::ValuesIn(videoio_container_params));
|
||||||
|
|
||||||
|
typedef tuple<VideoCaptureAPIs, string, int, int, int, int, int> videoio_container_get_params_t;
|
||||||
|
typedef testing::TestWithParam<videoio_container_get_params_t > videoio_container_get;
|
||||||
|
|
||||||
|
TEST_P(videoio_container_get, read)
|
||||||
|
{
|
||||||
|
const VideoCaptureAPIs api = get<0>(GetParam());
|
||||||
|
|
||||||
|
if (!videoio_registry::hasBackend(api))
|
||||||
|
throw SkipTestException("Backend was not found");
|
||||||
|
|
||||||
|
const string fileName = get<1>(GetParam());
|
||||||
|
const int height = get<2>(GetParam());
|
||||||
|
const int width = get<3>(GetParam());
|
||||||
|
const int nFrames = get<4>(GetParam());
|
||||||
|
const int bitrate = get<5>(GetParam());
|
||||||
|
const int fps = get<6>(GetParam());
|
||||||
|
|
||||||
|
VideoCapture container(findDataFile(fileName), api, { CAP_PROP_FORMAT, -1 });
|
||||||
|
if (!container.isOpened())
|
||||||
|
throw SkipTestException("Video stream is not supported");
|
||||||
|
|
||||||
|
const int heightProp = static_cast<int>(container.get(CAP_PROP_FRAME_HEIGHT));
|
||||||
|
ASSERT_EQ(height, heightProp);
|
||||||
|
const int widthProp = static_cast<int>(container.get(CAP_PROP_FRAME_WIDTH));
|
||||||
|
ASSERT_EQ(width, widthProp);
|
||||||
|
const int nFramesProp = static_cast<int>(container.get(CAP_PROP_FRAME_COUNT));
|
||||||
|
ASSERT_EQ(nFrames, nFramesProp);
|
||||||
|
const int bitrateProp = static_cast<int>(container.get(CAP_PROP_BITRATE));
|
||||||
|
ASSERT_EQ(bitrate, bitrateProp);
|
||||||
|
const double fpsProp = container.get(CAP_PROP_FPS);
|
||||||
|
ASSERT_EQ(fps, fpsProp);
|
||||||
|
// remove when PR fixing raw video CAP_PROP_POS_MSEC return value is merged and windows dll is updated
|
||||||
|
#ifndef _WIN32
|
||||||
|
vector<int> displayTimeMs;
|
||||||
|
int iFrame = 1;
|
||||||
|
while (container.grab()) {
|
||||||
|
displayTimeMs.push_back(static_cast<int>(container.get(CAP_PROP_POS_MSEC)));
|
||||||
|
const int iFrameProp = static_cast<int>(container.get(CAP_PROP_POS_FRAMES));
|
||||||
|
ASSERT_EQ(iFrame++, iFrameProp);
|
||||||
|
}
|
||||||
|
sort(displayTimeMs.begin(), displayTimeMs.end());
|
||||||
|
vector<int> displayTimeDiffMs(displayTimeMs.size());
|
||||||
|
std::adjacent_difference(displayTimeMs.begin(), displayTimeMs.end(), displayTimeDiffMs.begin());
|
||||||
|
auto minTimeMsIt = min_element(displayTimeDiffMs.begin() + 1, displayTimeDiffMs.end());
|
||||||
|
auto maxTimeMsIt = max_element(displayTimeDiffMs.begin() + 1, displayTimeDiffMs.end());
|
||||||
|
const int frameTimeMs = static_cast<int>(1000.0 / fps);
|
||||||
|
ASSERT_NEAR(frameTimeMs, *minTimeMsIt, 1);
|
||||||
|
ASSERT_NEAR(frameTimeMs, *maxTimeMsIt, 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
const videoio_container_get_params_t videoio_container_get_params[] =
|
||||||
|
{
|
||||||
|
videoio_container_get_params_t(CAP_FFMPEG, "video/big_buck_bunny.mp4", 384, 672, 125, 483, 24),
|
||||||
|
videoio_container_get_params_t(CAP_FFMPEG, "video/big_buck_bunny.mjpg.avi", 384, 672, 125, 2713, 24),
|
||||||
|
videoio_container_get_params_t(CAP_FFMPEG, "video/sample_322x242_15frames.yuv420p.libx264.mp4", 242, 322, 15, 542, 25)
|
||||||
|
};
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(/**/, videoio_container_get, testing::ValuesIn(videoio_container_get_params));
|
||||||
|
|
||||||
typedef tuple<string, string, int, int> videoio_encapsulate_params_t;
|
typedef tuple<string, string, int, int> videoio_encapsulate_params_t;
|
||||||
typedef testing::TestWithParam< videoio_encapsulate_params_t > videoio_encapsulate;
|
typedef testing::TestWithParam< videoio_encapsulate_params_t > videoio_encapsulate;
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <numeric>
|
||||||
|
|
||||||
#include "opencv2/ts.hpp"
|
#include "opencv2/ts.hpp"
|
||||||
#include "opencv2/ts/ocl_test.hpp"
|
#include "opencv2/ts/ocl_test.hpp"
|
||||||
|
Loading…
Reference in New Issue
Block a user