Skip to content

Commit fbd16f6

Browse files
authored
BETA CUDA interface: Cleanup EOF packet sending logic (#922)
1 parent 1177bb4 commit fbd16f6

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
@@ -337,28 +337,33 @@ int BetaCudaDeviceInterface::streamPropertyChange(CUVIDEOFORMAT* videoFormat) {
337337
// Moral equivalent of avcodec_send_packet(). Here, we pass the AVPacket down to
338338
// the NVCUVID parser.
339339
int BetaCudaDeviceInterface::sendPacket(ReferenceAVPacket& packet) {
340+
TORCH_CHECK(
341+
packet.get() && packet->data && packet->size > 0,
342+
"sendPacket received an empty packet, this is unexpected, please report.");
343+
344+
applyBSF(packet);
345+
340346
CUVIDSOURCEDATAPACKET cuvidPacket = {};
347+
cuvidPacket.payload = packet->data;
348+
cuvidPacket.payload_size = packet->size;
349+
cuvidPacket.flags = CUVID_PKT_TIMESTAMP;
350+
cuvidPacket.timestamp = packet->pts;
341351

342-
if (packet.get() && packet->data && packet->size > 0) {
343-
applyBSF(packet);
352+
return sendCuvidPacket(cuvidPacket);
353+
}
344354

345-
// Regular packet with data
346-
cuvidPacket.payload = packet->data;
347-
cuvidPacket.payload_size = packet->size;
348-
cuvidPacket.flags = CUVID_PKT_TIMESTAMP;
349-
cuvidPacket.timestamp = packet->pts;
355+
int BetaCudaDeviceInterface::sendEOFPacket() {
356+
CUVIDSOURCEDATAPACKET cuvidPacket = {};
357+
cuvidPacket.flags = CUVID_PKT_ENDOFSTREAM;
358+
eofSent_ = true;
350359

351-
} else {
352-
// End of stream packet
353-
cuvidPacket.flags = CUVID_PKT_ENDOFSTREAM;
354-
eofSent_ = true;
355-
}
360+
return sendCuvidPacket(cuvidPacket);
361+
}
356362

363+
int BetaCudaDeviceInterface::sendCuvidPacket(
364+
CUVIDSOURCEDATAPACKET& cuvidPacket) {
357365
CUresult result = cuvidParseVideoData(videoParser_, &cuvidPacket);
358-
if (result != CUDA_SUCCESS) {
359-
return AVERROR_EXTERNAL;
360-
}
361-
return AVSUCCESS;
366+
return result == CUDA_SUCCESS ? AVSUCCESS : AVERROR_EXTERNAL;
362367
}
363368

364369
void BetaCudaDeviceInterface::applyBSF(ReferenceAVPacket& packet) {
@@ -551,17 +556,7 @@ UniqueAVFrame BetaCudaDeviceInterface::convertCudaFrameToAVFrame(
551556
void BetaCudaDeviceInterface::flush() {
552557
isFlushing_ = true;
553558

554-
// TODONVDEC P0: simplify flushing and "eofSent_" logic. We should just have a
555-
// "sendEofPacket()" function that does the right thing, instead of setting
556-
// CUVID_PKT_ENDOFSTREAM in different places.
557-
if (!eofSent_) {
558-
CUVIDSOURCEDATAPACKET cuvidPacket = {};
559-
cuvidPacket.flags = CUVID_PKT_ENDOFSTREAM;
560-
CUresult result = cuvidParseVideoData(videoParser_, &cuvidPacket);
561-
if (result == CUDA_SUCCESS) {
562-
eofSent_ = true;
563-
}
564-
}
559+
sendEOFPacket();
565560

566561
isFlushing_ = false;
567562

src/torchcodec/_core/BetaCudaDeviceInterface.h

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

5454
int sendPacket(ReferenceAVPacket& packet) override;
55+
int sendEOFPacket() override;
5556
int receiveFrame(UniqueAVFrame& avFrame) override;
5657
void flush() override;
5758

@@ -61,6 +62,7 @@ class BetaCudaDeviceInterface : public DeviceInterface {
6162
int frameReadyInDisplayOrder(CUVIDPARSERDISPINFO* dispInfo);
6263

6364
private:
65+
int sendCuvidPacket(CUVIDSOURCEDATAPACKET& cuvidPacket);
6466
// Apply bitstream filter, modifies packet in-place
6567
void applyBSF(ReferenceAVPacket& packet);
6668
void initializeBSF(

src/torchcodec/_core/DeviceInterface.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,14 @@ class DeviceInterface {
100100
return AVERROR(ENOSYS);
101101
}
102102

103+
// Send an EOF packet to flush the decoder
104+
// Returns AVSUCCESS on success, or other AVERROR on failure
105+
virtual int sendEOFPacket() {
106+
TORCH_CHECK(
107+
false, "Send EOF packet not implemented for this device interface");
108+
return AVERROR(ENOSYS);
109+
}
110+
103111
// Moral equivalent of avcodec_receive_frame()
104112
// Returns AVSUCCESS on success, AVERROR(EAGAIN) if no frame ready,
105113
// 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
@@ -1220,12 +1220,7 @@ UniqueAVFrame SingleStreamDecoder::decodeAVFrame(
12201220
if (status == AVERROR_EOF) {
12211221
// End of file reached. We must drain the decoder
12221222
if (deviceInterface_->canDecodePacketDirectly()) {
1223-
// TODONVDEC P0: Re-think this. This should be simpler.
1224-
AutoAVPacket eofAutoPacket;
1225-
ReferenceAVPacket eofPacket(eofAutoPacket);
1226-
eofPacket->data = nullptr;
1227-
eofPacket->size = 0;
1228-
status = deviceInterface_->sendPacket(eofPacket);
1223+
status = deviceInterface_->sendEOFPacket();
12291224
} else {
12301225
status = avcodec_send_packet(
12311226
streamInfo.codecContext.get(),

0 commit comments

Comments
 (0)