On 5/14/24 21:39, Marton Balint wrote:
>
>
> On Tue, 14 May 2024, Michael Riedl wrote:
>
>>>
>>>> Deprecate the option 'draw_bars' in favor of the new option 
>>>> 'signal_loss_action',
>>>> which controls the behavior when the input signal is not available
>>>> (including the behavior previously available through draw_bars).
>>>> The default behavior remains unchanged to be backwards compatible.
>>>> The new option is more flexible for extending now and in the future.
>>>>
>>>> The new value 'repeat' repeats the last video frame.
>>>> This is useful for very short dropouts and was not available before.
>>>
>>> As far as I see, you are overriding frameBytes for a repeated frame, that 
>>> seems wrong. pkt.data (frameBytes) must be associated with the videoFrame 
>>> which is passed to av_buffer_create() later on.
>>>
>>> Every AVFrame returned by the decklink device has an AVBuffer set up which
>>> keeps a reference to the original DeckLink frame. This allows the use of 
>>> the DeckLink frame's raw buffer directly. But you cannot use the raw buffer 
>>> of another DeckLink frame for which the AVBuffer of the AVFrame does not 
>>> keep a reference.
>>
>> Thank you for your feedback!
>>
>> I took another look at the code and revisited the DeckLink documentation to 
>> ensure my understanding was correct. It seems that frameBytes is a pointer 
>> to the buffer of an IDeckLinkVideoFrame, and it remains valid as long as the 
>> videoFrame is not released.
>
> That is just it. You are releasing the repeated frame as soon as a valid 
> frame comes in. The AVPacket data you previously returned will still point to 
> the now released frameBytes. As I wrote above, the decklink frame 
> corresponding to the returned frameBytes must be released in the destructor 
> of the AVPacket buffer.

Took me a while to understand the issue, thank you for pointing that out. If I 
understand it correctly, the issue is fixed when the AVBuffer references the 
corresponding video frame that manages frameBytes. Does the change below look 
good to you?


diff --git a/libavdevice/decklink_dec.cpp b/libavdevice/decklink_dec.cpp
index e10fd5d6569..a6f9c4e0b3c 100644
--- a/libavdevice/decklink_dec.cpp
+++ b/libavdevice/decklink_dec.cpp
@@ -734,6 +734,7 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
     BMDTimeValue frameDuration;
     int64_t wallclock = 0, abs_wallclock = 0;
     struct decklink_cctx *cctx = (struct decklink_cctx *) avctx->priv_data;
+    IDeckLinkVideoInputFrame *currentVideoFrame = videoFrame; // video frame 
that holds frameBytes
 
     if (ctx->autodetect) {
         if (videoFrame && !(videoFrame->GetFlags() & bmdFrameHasNoInputSource) 
&&
@@ -790,7 +791,8 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
                         *p++ = bars[(x * 8) / width];
                 }
             } else if (ctx->signal_loss_action == SIGNAL_LOSS_REPEAT) {
-                last_video_frame->GetBytes(&frameBytes);
+                currentVideoFrame = last_video_frame;
+                currentVideoFrame->GetBytes(&frameBytes);
             }
 
             if (!no_video) {
@@ -866,8 +868,8 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
         pkt.flags       |= AV_PKT_FLAG_KEY;
         pkt.stream_index = ctx->video_st->index;
         pkt.data         = (uint8_t *)frameBytes;
-        pkt.size         = videoFrame->GetRowBytes() *
-                           videoFrame->GetHeight();
+        pkt.size         = currentVideoFrame->GetRowBytes() *
+                           currentVideoFrame->GetHeight();
         //fprintf(stderr,"Video Frame size %d ts %d\n", pkt.size, pkt.pts);
 
         if (!no_video) {
@@ -943,9 +945,9 @@ HRESULT decklink_input_callback::VideoInputFrameArrived(
             }
         }
 
-        pkt.buf = av_buffer_create(pkt.data, pkt.size, decklink_object_free, 
videoFrame, 0);
+        pkt.buf = av_buffer_create(pkt.data, pkt.size, decklink_object_free, 
currentVideoFrame, 0);
         if (pkt.buf)
-            videoFrame->AddRef();
+            currentVideoFrame->AddRef();
 
         if (ff_decklink_packet_queue_put(&ctx->queue, &pkt) < 0) {
             ++ctx->dropped;

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
https://ffmpeg.org/mailman/listinfo/ffmpeg-devel

To unsubscribe, visit link above, or email
ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".

Reply via email to