Skip to content

Commit eb3cc16

Browse files
Dan-FloresDaniel Flores
andauthored
Consistently use ptsToSeconds (#784)
Co-authored-by: Daniel Flores <[email protected]>
1 parent fe0dd01 commit eb3cc16

File tree

3 files changed

+21
-22
lines changed

3 files changed

+21
-22
lines changed

src/torchcodec/_core/SingleStreamDecoder.cpp

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ namespace facebook::torchcodec {
1818
namespace {
1919

2020
double ptsToSeconds(int64_t pts, const AVRational& timeBase) {
21-
return static_cast<double>(pts) * timeBase.num / timeBase.den;
21+
return static_cast<double>(pts) * av_q2d(timeBase);
2222
}
2323

2424
int64_t secondsToClosestPts(double seconds, const AVRational& timeBase) {
@@ -129,11 +129,11 @@ void SingleStreamDecoder::initializeDecoder() {
129129

130130
if (avStream->duration > 0 && avStream->time_base.den > 0) {
131131
streamMetadata.durationSecondsFromHeader =
132-
av_q2d(avStream->time_base) * avStream->duration;
132+
ptsToSeconds(avStream->duration, avStream->time_base);
133133
}
134134
if (avStream->start_time != AV_NOPTS_VALUE) {
135135
streamMetadata.beginStreamSecondsFromHeader =
136-
av_q2d(avStream->time_base) * avStream->start_time;
136+
ptsToSeconds(avStream->start_time, avStream->time_base);
137137
}
138138

139139
if (avStream->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
@@ -304,13 +304,12 @@ void SingleStreamDecoder::scanFileAndUpdateMetadataAndIndex() {
304304
streamInfos_[streamIndex].allFrames.size();
305305

306306
if (streamMetadata.beginStreamPtsFromContent.has_value()) {
307-
streamMetadata.beginStreamPtsSecondsFromContent =
308-
*streamMetadata.beginStreamPtsFromContent *
309-
av_q2d(avStream->time_base);
307+
streamMetadata.beginStreamPtsSecondsFromContent = ptsToSeconds(
308+
*streamMetadata.beginStreamPtsFromContent, avStream->time_base);
310309
}
311310
if (streamMetadata.endStreamPtsFromContent.has_value()) {
312-
streamMetadata.endStreamPtsSecondsFromContent =
313-
*streamMetadata.endStreamPtsFromContent * av_q2d(avStream->time_base);
311+
streamMetadata.endStreamPtsSecondsFromContent = ptsToSeconds(
312+
*streamMetadata.endStreamPtsFromContent, avStream->time_base);
314313
}
315314
}
316315

@@ -344,11 +343,11 @@ void SingleStreamDecoder::readCustomFrameMappingsUpdateMetadataAndIndex(
344343
all_frames[-1].item<int64_t>() + duration[-1].item<int64_t>();
345344

346345
auto avStream = formatContext_->streams[streamIndex];
347-
streamMetadata.beginStreamPtsSecondsFromContent =
348-
*streamMetadata.beginStreamPtsFromContent * av_q2d(avStream->time_base);
346+
streamMetadata.beginStreamPtsSecondsFromContent = ptsToSeconds(
347+
*streamMetadata.beginStreamPtsFromContent, avStream->time_base);
349348

350-
streamMetadata.endStreamPtsSecondsFromContent =
351-
*streamMetadata.endStreamPtsFromContent * av_q2d(avStream->time_base);
349+
streamMetadata.endStreamPtsSecondsFromContent = ptsToSeconds(
350+
*streamMetadata.endStreamPtsFromContent, avStream->time_base);
352351

353352
streamMetadata.numFramesFromContent = all_frames.size(0);
354353
for (int64_t i = 0; i < all_frames.size(0); ++i) {

test/VideoDecoderTest.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -267,9 +267,9 @@ TEST_P(SingleStreamDecoderTest, SeeksCloseToEof) {
267267
ourDecoder->addVideoStream(-1);
268268
ourDecoder->setCursorPtsInSeconds(388388. / 30'000);
269269
auto output = ourDecoder->getNextFrame();
270-
EXPECT_EQ(output.ptsSeconds, 388'388. / 30'000);
270+
EXPECT_DOUBLE_EQ(output.ptsSeconds, 388'388. / 30'000);
271271
output = ourDecoder->getNextFrame();
272-
EXPECT_EQ(output.ptsSeconds, 389'389. / 30'000);
272+
EXPECT_DOUBLE_EQ(output.ptsSeconds, 389'389. / 30'000);
273273
EXPECT_THROW(ourDecoder->getNextFrame(), std::exception);
274274
}
275275

@@ -300,7 +300,7 @@ TEST_P(SingleStreamDecoderTest, GetsFramePlayedAtTimestamp) {
300300
// Sanity check: make sure duration is strictly positive.
301301
EXPECT_GT(kPtsPlusDurationOfLastFrame, kPtsOfLastFrameInVideoStream);
302302
output = ourDecoder->getFramePlayedAt(kPtsPlusDurationOfLastFrame - 1e-6);
303-
EXPECT_EQ(output.ptsSeconds, kPtsOfLastFrameInVideoStream);
303+
EXPECT_DOUBLE_EQ(output.ptsSeconds, kPtsOfLastFrameInVideoStream);
304304
}
305305

306306
TEST_P(SingleStreamDecoderTest, SeeksToFrameWithSpecificPts) {
@@ -311,7 +311,7 @@ TEST_P(SingleStreamDecoderTest, SeeksToFrameWithSpecificPts) {
311311
ourDecoder->setCursorPtsInSeconds(6.0);
312312
auto output = ourDecoder->getNextFrame();
313313
torch::Tensor tensor6FromOurDecoder = output.data;
314-
EXPECT_EQ(output.ptsSeconds, 180'180. / 30'000);
314+
EXPECT_DOUBLE_EQ(output.ptsSeconds, 180'180. / 30'000);
315315
torch::Tensor tensor6FromFFMPEG =
316316
readTensorFromDisk("nasa_13013.mp4.time6.000000.pt");
317317
EXPECT_TRUE(torch::equal(tensor6FromOurDecoder, tensor6FromFFMPEG));
@@ -327,7 +327,7 @@ TEST_P(SingleStreamDecoderTest, SeeksToFrameWithSpecificPts) {
327327
ourDecoder->setCursorPtsInSeconds(6.1);
328328
output = ourDecoder->getNextFrame();
329329
torch::Tensor tensor61FromOurDecoder = output.data;
330-
EXPECT_EQ(output.ptsSeconds, 183'183. / 30'000);
330+
EXPECT_DOUBLE_EQ(output.ptsSeconds, 183'183. / 30'000);
331331
torch::Tensor tensor61FromFFMPEG =
332332
readTensorFromDisk("nasa_13013.mp4.time6.100000.pt");
333333
EXPECT_TRUE(torch::equal(tensor61FromOurDecoder, tensor61FromFFMPEG));
@@ -347,7 +347,7 @@ TEST_P(SingleStreamDecoderTest, SeeksToFrameWithSpecificPts) {
347347
ourDecoder->setCursorPtsInSeconds(10.0);
348348
output = ourDecoder->getNextFrame();
349349
torch::Tensor tensor10FromOurDecoder = output.data;
350-
EXPECT_EQ(output.ptsSeconds, 300'300. / 30'000);
350+
EXPECT_DOUBLE_EQ(output.ptsSeconds, 300'300. / 30'000);
351351
torch::Tensor tensor10FromFFMPEG =
352352
readTensorFromDisk("nasa_13013.mp4.time10.000000.pt");
353353
EXPECT_TRUE(torch::equal(tensor10FromOurDecoder, tensor10FromFFMPEG));
@@ -364,7 +364,7 @@ TEST_P(SingleStreamDecoderTest, SeeksToFrameWithSpecificPts) {
364364
ourDecoder->setCursorPtsInSeconds(6.0);
365365
output = ourDecoder->getNextFrame();
366366
tensor6FromOurDecoder = output.data;
367-
EXPECT_EQ(output.ptsSeconds, 180'180. / 30'000);
367+
EXPECT_DOUBLE_EQ(output.ptsSeconds, 180'180. / 30'000);
368368
EXPECT_TRUE(torch::equal(tensor6FromOurDecoder, tensor6FromFFMPEG));
369369
EXPECT_EQ(ourDecoder->getDecodeStats().numSeeksAttempted, 1);
370370
// We cannot skip a seek here because timestamp=6 has a different keyframe
@@ -379,7 +379,7 @@ TEST_P(SingleStreamDecoderTest, SeeksToFrameWithSpecificPts) {
379379
ourDecoder->setCursorPtsInSeconds(kPtsOfLastFrameInVideoStream);
380380
output = ourDecoder->getNextFrame();
381381
torch::Tensor tensor7FromOurDecoder = output.data;
382-
EXPECT_EQ(output.ptsSeconds, 389'389. / 30'000);
382+
EXPECT_DOUBLE_EQ(output.ptsSeconds, 389'389. / 30'000);
383383
torch::Tensor tensor7FromFFMPEG =
384384
readTensorFromDisk("nasa_13013.mp4.time12.979633.pt");
385385
EXPECT_TRUE(torch::equal(tensor7FromOurDecoder, tensor7FromFFMPEG));

test/test_ops.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -751,7 +751,7 @@ def test_next(self, asset):
751751
frame, asset.get_frame_data_by_index(frame_index)
752752
)
753753
frame_info = asset.get_frame_info(frame_index)
754-
assert pts_seconds == frame_info.pts_seconds
754+
assert pts_seconds == pytest.approx(frame_info.pts_seconds)
755755
assert duration_seconds == frame_info.duration_seconds
756756
frame_index += 1
757757

@@ -955,7 +955,7 @@ def test_pts(self, asset):
955955
frames, asset.get_frame_data_by_index(frame_index)
956956
)
957957

958-
assert pts_seconds == start_seconds
958+
assert pts_seconds == pytest.approx(start_seconds)
959959

960960
def test_sample_rate_conversion(self):
961961
def get_all_frames(asset, sample_rate=None, stop_seconds=None):

0 commit comments

Comments
 (0)