Hello libav-users,
With some investigation, i was able to confirm libavformat’s I/O Interrupt
Callback is not being called by av_read_frame(). Currently, when
av_read_frame() is called while consuming either USB or IP media streams, if
the connection is terminated from actions such as the ethernet/usb cable being
disconnected, av_read_frame() will hang.
I was able to modify the av_read_frame() routine from libavformat such that the
same I/O interrupt callback used for other libavformat I/O routines is called
when reading packets from a stream. It appears to be a minimal change, with no
API changes.
The only behavioral change is the I/O Interrupt Callback is called, and it
respects a positive return value to indicate termination of I/O by
av_read_frame().
It seems like I am correcting a design oversight: there is a facility for
library clients to check on pending I/O, that’s the I/O interrupt callback. It
is being called during other libavformat routines that perform I/O. Yet, for
the critical step of reading packets from a media stream, it was not being
called. Finding wrapper logic enabling the hooking in of the interrupt callback
a mere 3 lines of code, I tried it, built windows x64 and win32 dlls and tested
with my employer's computer vision system. It does exactly what is needed: when
reading USB video or IP cameras or Internet streams, "if the cable gets pulled”
the media library does not hang. Through the interrupt callback, my libavformat
client code easily implements a timeout, signaling back to libavformat when to
stop waiting for I/O.
Seeing multiple developers requesting this functionality online, I looked into
making a patch for submission this back to the ffmpeg developers. It looks like
the patch submission process is a bit more time consuming than my schedule
allows. Pretty much because it would require my using git in a manner I am
unfamiliar. (I barely use git myself, rarely directly.)
I did a git diff to create this, it is the entire change enabling this critical
functionality:
————————
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 0711310..5971e31 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -1718,6 +1718,12 @@ int av_read_frame(AVFormatContext *s, AVPacket *pkt)
}
for (;;) {
+ if (ff_check_interrupt(&s->interrupt_callback)) {
+ ret = AVERROR_EXIT;
+ av_log(s, AV_LOG_DEBUG, "interrupted\n");
+ return ret;
+ }
+
AVPacketList *pktl = s->internal->packet_buffer;
if (pktl) {
————————
I’ll continue looking into creating a formal submission to the ffmpeg
developers - BUT if someone more familiar with the process wants to step in, by
all means. I’ll be fumbling with those steps, under a constrained schedule…
Sincerely,
-Blake Senftner
---> Blake loves the Planet Earth and is proud to display this email with
Recycled Electrons. <---
_______________________________________________
Libav-user mailing list
[email protected]
http://ffmpeg.org/mailman/listinfo/libav-user