@@ -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
0 commit comments