Skip to content

Commit bc55810

Browse files
committed
Refactor EOF packet logic
1 parent f8f0402 commit bc55810

File tree

4 files changed

+33
-33
lines changed

4 files changed

+33
-33
lines changed

src/torchcodec/_core/BetaCudaDeviceInterface.cpp

Lines changed: 22 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -331,28 +331,33 @@ int BetaCudaDeviceInterface::streamPropertyChange(CUVIDEOFORMAT* videoFormat) {
331331
// Moral equivalent of avcodec_send_packet(). Here, we pass the AVPacket down to
332332
// the NVCUVID parser.
333333
int BetaCudaDeviceInterface::sendPacket(ReferenceAVPacket& packet) {
334+
TORCH_CHECK(
335+
packet.get() && packet->data && packet->size > 0,
336+
"sendPacket received an empty packet, this is unexpected, please report.");
337+
338+
applyBSF(packet);
339+
334340
CUVIDSOURCEDATAPACKET cuvidPacket = {};
341+
cuvidPacket.payload = packet->data;
342+
cuvidPacket.payload_size = packet->size;
343+
cuvidPacket.flags = CUVID_PKT_TIMESTAMP;
344+
cuvidPacket.timestamp = packet->pts;
335345

336-
if (packet.get() && packet->data && packet->size > 0) {
337-
applyBSF(packet);
346+
return sendCuvidPacket(cuvidPacket);
347+
}
338348

339-
// Regular packet with data
340-
cuvidPacket.payload = packet->data;
341-
cuvidPacket.payload_size = packet->size;
342-
cuvidPacket.flags = CUVID_PKT_TIMESTAMP;
343-
cuvidPacket.timestamp = packet->pts;
349+
int BetaCudaDeviceInterface::sendEOFPacket() {
350+
CUVIDSOURCEDATAPACKET cuvidPacket = {};
351+
cuvidPacket.flags = CUVID_PKT_ENDOFSTREAM;
352+
eofSent_ = true;
344353

345-
} else {
346-
// End of stream packet
347-
cuvidPacket.flags = CUVID_PKT_ENDOFSTREAM;
348-
eofSent_ = true;
349-
}
354+
return sendCuvidPacket(cuvidPacket);
355+
}
350356

357+
int BetaCudaDeviceInterface::sendCuvidPacket(
358+
CUVIDSOURCEDATAPACKET& cuvidPacket) {
351359
CUresult result = cuvidParseVideoData(videoParser_, &cuvidPacket);
352-
if (result != CUDA_SUCCESS) {
353-
return AVERROR_EXTERNAL;
354-
}
355-
return AVSUCCESS;
360+
return result == CUDA_SUCCESS ? AVSUCCESS : AVERROR_EXTERNAL;
356361
}
357362

358363
void BetaCudaDeviceInterface::applyBSF(ReferenceAVPacket& packet) {
@@ -541,17 +546,7 @@ UniqueAVFrame BetaCudaDeviceInterface::convertCudaFrameToAVFrame(
541546
void BetaCudaDeviceInterface::flush() {
542547
isFlushing_ = true;
543548

544-
// TODONVDEC P0: simplify flushing and "eofSent_" logic. We should just have a
545-
// "sendEofPacket()" function that does the right thing, instead of setting
546-
// CUVID_PKT_ENDOFSTREAM in different places.
547-
if (!eofSent_) {
548-
CUVIDSOURCEDATAPACKET cuvidPacket = {};
549-
cuvidPacket.flags = CUVID_PKT_ENDOFSTREAM;
550-
CUresult result = cuvidParseVideoData(videoParser_, &cuvidPacket);
551-
if (result == CUDA_SUCCESS) {
552-
eofSent_ = true;
553-
}
554-
}
549+
sendEOFPacket();
555550

556551
isFlushing_ = false;
557552

src/torchcodec/_core/BetaCudaDeviceInterface.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ class BetaCudaDeviceInterface : public DeviceInterface {
5454
}
5555

5656
int sendPacket(ReferenceAVPacket& packet) override;
57+
int sendEOFPacket() override;
5758
int receiveFrame(UniqueAVFrame& avFrame) override;
5859
void flush() override;
5960

@@ -63,6 +64,7 @@ class BetaCudaDeviceInterface : public DeviceInterface {
6364
int frameReadyInDisplayOrder(CUVIDPARSERDISPINFO* dispInfo);
6465

6566
private:
67+
int sendCuvidPacket(CUVIDSOURCEDATAPACKET& cuvidPacket);
6668
// Apply bitstream filter, modifies packet in-place
6769
void applyBSF(ReferenceAVPacket& packet);
6870
void initializeBSF(

src/torchcodec/_core/DeviceInterface.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ class DeviceInterface {
8686
return AVERROR(ENOSYS);
8787
}
8888

89+
// Send an EOF packet to flush the decoder
90+
// Returns AVSUCCESS on success, or other AVERROR on failure
91+
virtual int sendEOFPacket() {
92+
TORCH_CHECK(
93+
false, "Send EOF packet not implemented for this device interface");
94+
return AVERROR(ENOSYS);
95+
}
96+
8997
// Moral equivalent of avcodec_receive_frame()
9098
// Returns AVSUCCESS on success, AVERROR(EAGAIN) if no frame ready,
9199
// AVERROR_EOF if end of stream, or other AVERROR on failure

src/torchcodec/_core/SingleStreamDecoder.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1202,12 +1202,7 @@ UniqueAVFrame SingleStreamDecoder::decodeAVFrame(
12021202
if (status == AVERROR_EOF) {
12031203
// End of file reached. We must drain the decoder
12041204
if (useCustomInterface) {
1205-
// TODONVDEC P0: Re-think this. This should be simpler.
1206-
AutoAVPacket eofAutoPacket;
1207-
ReferenceAVPacket eofPacket(eofAutoPacket);
1208-
eofPacket->data = nullptr;
1209-
eofPacket->size = 0;
1210-
status = deviceInterface_->sendPacket(eofPacket);
1205+
status = deviceInterface_->sendEOFPacket();
12111206
} else {
12121207
status = avcodec_send_packet(
12131208
streamInfo.codecContext.get(),

0 commit comments

Comments
 (0)