<div dir="ltr"><div><div><div><div><div><div><div>Hi all,<br><br></div>I took the muxing.c example and modified it in order to send a stream through a network socket. I only made few modifications:<br><br></div>main function now looks like:<br>
<br>int main()<br>{ <br> AVOutputFormat *fmt;<br> AVFormatContext *oc;<br> AVStream *audio_st, *video_st;<br> AVCodec *audio_codec, *video_codec;<br> double audio_time, video_time;<br> int flush, ret;<br>
<br> /* Initialize libavcodec, and register all codecs and formats. */<br> av_register_all();<br> avformat_network_init();<br><br> /* allocate the output media context */<br> avformat_alloc_output_context2(&oc, NULL, "mpegts", NULL);<br>
if (!oc) {<br> printf("Could not deduce output format from file extension: using MPEG.\n");<br> avformat_alloc_output_context2(&oc, NULL, "mpegts", NULL);<br> }<br> if (!oc)<br>
return 1;<br><br> fmt = oc->oformat;<br> //fmt->video_codec = AV_CODEC_ID_MPEG2VIDEO;<br> //fmt->audio_codec = AV_CODEC_ID_MP3;<br><br> /* Add the audio and video streams using the default format codecs<br>
* and initialize the codecs. */<br> video_st = NULL;<br> audio_st = NULL;<br><br> if (fmt->video_codec != AV_CODEC_ID_NONE)<br> video_st = add_stream(oc, &video_codec, fmt->video_codec);<br>
if (fmt->audio_codec != AV_CODEC_ID_NONE)<br> audio_st = add_stream(oc, &audio_codec, fmt->audio_codec);<br><br> /* Now that all the parameters are set, we can open the audio and<br> * video codecs and allocate the necessary encode buffers. */<br>
if (video_st)<br> open_video(oc, video_codec, video_st);<br> if (audio_st)<br> open_audio(oc, audio_codec, audio_st);<br><br> av_dump_format(oc, 0, "<a href="http://localhost:8090/feed1.ffm">http://localhost:8090/feed1.ffm</a>", 1);<br>
<br> /* open the output file, if needed */<br> if (!(fmt->flags & AVFMT_NOFILE)) {<br> ret = avio_open(&oc->pb, "<a href="http://localhost:8090/feed1.ffm">http://localhost:8090/feed1.ffm</a>", AVIO_FLAG_WRITE);<br>
if (ret < 0) {<br> fprintf(stderr, "Could not open '%s': %s\n", "<a href="http://localhost:8090/feed1.ffm">http://localhost:8090/feed1.ffm</a>",<br> av_err2str(ret));<br>
return 1;<br> }<br> }<br><br> /* Write the stream header, if any. */<br> ret = avformat_write_header(oc, NULL);<br> if (ret < 0) {<br> fprintf(stderr, "Error occurred when opening output file: %s\n",<br>
av_err2str(ret));<br> return 1;<br> }<br><br> flush = 0;<br> while ((video_st && !video_is_eof) || (audio_st && !audio_is_eof)) {<br> /* Compute current audio and video time. */<br>
audio_time = (audio_st && !audio_is_eof) ? audio_st->pts.val * av_q2d(audio_st->time_base) : INFINITY;<br> video_time = (video_st && !video_is_eof) ? video_st->pts.val * av_q2d(video_st->time_base) : INFINITY;<br>
<br> if (!flush &&<br> (!audio_st || audio_time >= STREAM_DURATION) &&<br> (!video_st || video_time >= STREAM_DURATION)) {<br> flush = 1;<br> }<br><br> /* write interleaved audio and video frames */<br>
if (audio_st && !audio_is_eof && audio_time <= video_time) {<br> write_audio_frame(oc, audio_st, flush);<br> } else if (video_st && !video_is_eof && video_time < audio_time) {<br>
write_video_frame(oc, video_st, flush);<br> }<br> }<br><br> /* Write the trailer, if any. The trailer must be written before you<br> * close the CodecContexts open when you wrote the header; otherwise<br>
* av_write_trailer() may try to use memory that was freed on<br> * av_codec_close(). */<br> av_write_trailer(oc);<br><br> /* Close each codec. */<br> if (video_st)<br> close_video(oc, video_st);<br>
if (audio_st)<br> close_audio(oc, audio_st);<br><br> if (!(fmt->flags & AVFMT_NOFILE))<br> /* Close the output file. */<br> avio_close(oc->pb);<br><br> /* free the stream */<br> avformat_free_context(oc);<br>
<br> return 0;<br>}<br><br></div>and, in order to avoid a warning about channel layout not specified, I added:<br><br>c->channel_layout = av_get_default_channel_layout(c->channels);<br><br></div>in function AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,<br>
enum AVCodecID codec_id)<br></div>just under the row c->channels = 2;<br><br><br></div>I also raised a ffserver with the following configuration (showing only feed lines):<br><br><Feed feed1.ffm><br>
File /tmp/feed1.ffm<br> FileMaxSize 1GB<br> ACL allow 127.0.0.1<br> ACL allow 192.168.0.0 192.168.255.255<br></Feed><br><br></div>ffserver is working fine if I feed it with a ffmpeg commandline, e.g:<br>
ffmpeg -r 25 -i movie.mp4 -acodec libfdk_aac -ab 128k -vcodec libx264 -fpre libx264-fast.ffpreset <a href="http://localhost:8090/feed1.ffm">http://localhost:8090/feed1.ffm</a><br><div><div><br><br>But with my example, I can write only few frames and after that may muxing modified program ends with:<br>
<br>Error while writing audio frame: Connection reset by peer<br><br></div><div>I tried also different codecs (h264) and format (flv), turning out in a different number of frames written, but eventually I got the same error above.<br>
</div><div><br>ffserver do not reports errors at all, only write:<br>Tue Mar 4 12:55:10 2014 127.0.0.1 - - [POST] "/feed1.ffm HTTP/1.1" 200 4096<br></div><div>confirming that the communication socket was open<br>
<br></div><div>What I am missing??<br><br></div><div>Thanks<br></div></div></div>