Skip to content

Commit be8a481

Browse files
committed
Address BSF uglyness - kinda
1 parent d072832 commit be8a481

File tree

4 files changed

+21
-27
lines changed

4 files changed

+21
-27
lines changed

src/torchcodec/_core/BetaCudaDeviceInterface.cpp

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -350,13 +350,20 @@ int BetaCudaDeviceInterface::sendPacket(ReferenceAVPacket& packet) {
350350
packet.get() && packet->data && packet->size > 0,
351351
"sendPacket received an empty packet, this is unexpected, please report.");
352352

353-
applyBSF(packet);
353+
// Apply BSF if needed. We want applyBSF to return a *new* filtered packet, or
354+
// the original one if no BSF is needed. This new filtered packet must be
355+
// allocated outside of applyBSF: if it were allocated inside applyBSF, it
356+
// would be destroyed at the end of the function, leaving us with a dangling
357+
// reference.
358+
AutoAVPacket filteredAutoPacket;
359+
ReferenceAVPacket filteredPacket(filteredAutoPacket);
360+
ReferenceAVPacket& packetToSend = applyBSF(packet, filteredPacket);
354361

355362
CUVIDSOURCEDATAPACKET cuvidPacket = {};
356-
cuvidPacket.payload = packet->data;
357-
cuvidPacket.payload_size = packet->size;
363+
cuvidPacket.payload = packetToSend->data;
364+
cuvidPacket.payload_size = packetToSend->size;
358365
cuvidPacket.flags = CUVID_PKT_TIMESTAMP;
359-
cuvidPacket.timestamp = packet->pts;
366+
cuvidPacket.timestamp = packetToSend->pts;
360367

361368
return sendCuvidPacket(cuvidPacket);
362369
}
@@ -375,9 +382,11 @@ int BetaCudaDeviceInterface::sendCuvidPacket(
375382
return result == CUDA_SUCCESS ? AVSUCCESS : AVERROR_EXTERNAL;
376383
}
377384

378-
void BetaCudaDeviceInterface::applyBSF(ReferenceAVPacket& packet) {
385+
ReferenceAVPacket& BetaCudaDeviceInterface::applyBSF(
386+
ReferenceAVPacket& packet,
387+
ReferenceAVPacket& filteredPacket) {
379388
if (!bitstreamFilter_) {
380-
return;
389+
return packet;
381390
}
382391

383392
int retVal = av_bsf_send_packet(bitstreamFilter_.get(), packet.get());
@@ -386,27 +395,17 @@ void BetaCudaDeviceInterface::applyBSF(ReferenceAVPacket& packet) {
386395
"Failed to send packet to bitstream filter: ",
387396
getFFMPEGErrorStringFromErrorCode(retVal));
388397

389-
// Create a temporary packet to receive the filtered data
390398
// TODO P1: the docs mention there can theoretically be multiple output
391399
// packets for a single input, i.e. we may need to call av_bsf_receive_packet
392400
// more than once. We should figure out whether that applies to the BSF we're
393401
// using.
394-
AutoAVPacket filteredAutoPacket;
395-
ReferenceAVPacket filteredPacket(filteredAutoPacket);
396402
retVal = av_bsf_receive_packet(bitstreamFilter_.get(), filteredPacket.get());
397403
TORCH_CHECK(
398404
retVal >= AVSUCCESS,
399405
"Failed to receive packet from bitstream filter: ",
400406
getFFMPEGErrorStringFromErrorCode(retVal));
401407

402-
// Free the original packet's data which isn't needed anymore, and move the
403-
// fields of the filtered packet into the original packet. The filtered packet
404-
// fields are re-set by av_packet_move_ref, so when it goes out of scope and
405-
// gets destructed, it's not going to affect the original packet.
406-
packet.reset(filteredPacket);
407-
// TODONVDEC P0: consider cleaner ways to do this. Maybe we should let
408-
// applyBSF return a new packet, and maybe that new packet needs to be a field
409-
// on the interface to avoid complex lifetime issues.
408+
return filteredPacket;
410409
}
411410

412411
// Parser triggers this callback within cuvidParseVideoData when a frame is

src/torchcodec/_core/BetaCudaDeviceInterface.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,11 @@ class BetaCudaDeviceInterface : public DeviceInterface {
6464
private:
6565
int sendCuvidPacket(CUVIDSOURCEDATAPACKET& cuvidPacket);
6666

67-
// Apply bitstream filter, modifies packet in-place
68-
void applyBSF(ReferenceAVPacket& packet);
67+
// Apply bitstream filter, returns filtered packet or original if no filter
68+
// needed.
69+
ReferenceAVPacket& applyBSF(
70+
ReferenceAVPacket& packet,
71+
ReferenceAVPacket& filteredPacket);
6972
void initializeBSF(
7073
const AVCodecParameters* codecPar,
7174
const UniqueDecodingAVFormatContext& avFormatCtx);

src/torchcodec/_core/FFMPEGCommon.cpp

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,6 @@ AVPacket* ReferenceAVPacket::operator->() {
3333
return avPacket_;
3434
}
3535

36-
void ReferenceAVPacket::reset(ReferenceAVPacket& other) {
37-
if (this != &other) {
38-
av_packet_unref(avPacket_);
39-
av_packet_move_ref(avPacket_, other.avPacket_);
40-
}
41-
}
42-
4336
AVCodecOnlyUseForCallingAVFindBestStream
4437
makeAVCodecOnlyUseForCallingAVFindBestStream(const AVCodec* codec) {
4538
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 18, 100)

src/torchcodec/_core/FFMPEGCommon.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ class ReferenceAVPacket {
135135
~ReferenceAVPacket();
136136
AVPacket* get();
137137
AVPacket* operator->();
138-
void reset(ReferenceAVPacket& other);
139138
};
140139

141140
// av_find_best_stream is not const-correct before commit:

0 commit comments

Comments
 (0)