[Libav-user] Get EAGAIN error from av_read_frame

Константин Вуколов kasyanvukolov at gmail.com
Thu Aug 10 20:14:30 EEST 2017


Hi

I can’t obtain EAGAIN error from av_read_frame function when I open context from pipe.
I use boost::asio for managing connections to unix sockets and passing native socket descriptor to avformat_open_input
For correct managing i need to create kevent to get new data from socket and not to block thread until this event.

here is my example:

#include <iostream>
#include <boost/asio.hpp>
extern "C"{
#include <libavformat/avformat.h>
}

void on_accepted(std::shared_ptr<boost::asio::local::stream_protocol::socket> socket, const boost::system::error_code err){
   if(err){
       std::cout << "Error while accept " << err << std::endl;
       return;
   }
   socket->native_non_blocking(true);
   std::string path = "pipe:" + std::to_string(socket->native_handle());
   AVFormatContext* context = avformat_alloc_context();
   context->flags |= AVFMT_FLAG_NONBLOCK;
   auto open_result = avformat_open_input(&context, path.c_str(), nullptr, nullptr);
   AVPacket* packet = av_packet_alloc();
   int ret;
   while((ret = av_read_frame(context, packet)) >= 0){
       std::cout << "Packet received" << std::endl;
   }
   if(ret == EAGAIN || ret == AVERROR(EAGAIN)){
       std::cout << "EAGAIN got" << std::endl;
   }
   else{
       char buf[255];
       av_strerror( ret, buf, sizeof(buf));
       std::cout << "Error got " << buf << std::endl;
   }
   av_packet_free(&packet);
   avformat_free_context(context);
}

int main(){
   av_register_all();
   boost::asio::io_service io_service;
   ::unlink("/usr/local/sockets/test");
   boost::asio::local::stream_protocol::acceptor acceptor{io_service, "/usr/local/sockets/test"};
   acceptor.set_option(boost::asio::socket_base::reuse_address(true));
   auto socket = std::make_shared<boost::asio::local::stream_protocol::socket>( io_service);
   acceptor.async_accept(*socket,
           std::bind(on_accepted, socket, std::placeholders::_1)
           );
   std::cout << "Start accepting" << std::endl;
   io_service.run();
}

As i see in stack trace, ffmpeg get EAGAIN error and sends read call again.

read(0x7, "\0", 0x8000)		 = -1 Err#35
read(0x7, "\0", 0x8000)		 = -1 Err#35
read(0x7, "\0", 0x8000)		 = -1 Err#35
read(0x7, "\0", 0x8000)		 = -1 Err#35
read(0x7, "\0", 0x8000)		 = -1 Err#35
read(0x7, "\0", 0x8000)		 = -1 Err#35

How to get EAGAIN error in my application?


More information about the Libav-user mailing list