[Libav-user] code patch supporting I/O interrupts during av_read_frame()

Blake Senftner bsenftner at earthlink.net
Wed Feb 1 22:52:43 EET 2017


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. <---

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20170201/fffdd5d6/attachment.html>


More information about the Libav-user mailing list