[Libav-user] problems sending stream through network

Marco Lorrai lorrai.m at gmail.com
Tue Mar 4 13:11:53 CET 2014


Hi all,

I took the muxing.c example and modified it in order to send a stream
through a network socket. I only made few modifications:

main function now looks like:

int main()
{
    AVOutputFormat *fmt;
    AVFormatContext *oc;
    AVStream *audio_st, *video_st;
    AVCodec *audio_codec, *video_codec;
    double audio_time, video_time;
    int flush, ret;

    /* Initialize libavcodec, and register all codecs and formats. */
    av_register_all();
    avformat_network_init();

    /* allocate the output media context */
    avformat_alloc_output_context2(&oc, NULL, "mpegts", NULL);
    if (!oc) {
        printf("Could not deduce output format from file extension: using
MPEG.\n");
        avformat_alloc_output_context2(&oc, NULL, "mpegts", NULL);
    }
    if (!oc)
        return 1;

    fmt = oc->oformat;
    //fmt->video_codec = AV_CODEC_ID_MPEG2VIDEO;
    //fmt->audio_codec = AV_CODEC_ID_MP3;

    /* Add the audio and video streams using the default format codecs
     * and initialize the codecs. */
    video_st = NULL;
    audio_st = NULL;

    if (fmt->video_codec != AV_CODEC_ID_NONE)
        video_st = add_stream(oc, &video_codec, fmt->video_codec);
    if (fmt->audio_codec != AV_CODEC_ID_NONE)
        audio_st = add_stream(oc, &audio_codec, fmt->audio_codec);

    /* Now that all the parameters are set, we can open the audio and
     * video codecs and allocate the necessary encode buffers. */
    if (video_st)
        open_video(oc, video_codec, video_st);
    if (audio_st)
        open_audio(oc, audio_codec, audio_st);

   av_dump_format(oc, 0, "http://localhost:8090/feed1.ffm", 1);

    /* open the output file, if needed */
    if (!(fmt->flags & AVFMT_NOFILE)) {
        ret = avio_open(&oc->pb, "http://localhost:8090/feed1.ffm",
AVIO_FLAG_WRITE);
        if (ret < 0) {
            fprintf(stderr, "Could not open '%s': %s\n", "
http://localhost:8090/feed1.ffm",
                    av_err2str(ret));
            return 1;
        }
    }

    /* Write the stream header, if any. */
    ret = avformat_write_header(oc, NULL);
    if (ret < 0) {
        fprintf(stderr, "Error occurred when opening output file: %s\n",
                av_err2str(ret));
        return 1;
    }

    flush = 0;
    while ((video_st && !video_is_eof) || (audio_st && !audio_is_eof)) {
        /* Compute current audio and video time. */
        audio_time = (audio_st && !audio_is_eof) ? audio_st->pts.val *
av_q2d(audio_st->time_base) : INFINITY;
        video_time = (video_st && !video_is_eof) ? video_st->pts.val *
av_q2d(video_st->time_base) : INFINITY;

        if (!flush &&
            (!audio_st || audio_time >= STREAM_DURATION) &&
            (!video_st || video_time >= STREAM_DURATION)) {
            flush = 1;
        }

        /* write interleaved audio and video frames */
        if (audio_st && !audio_is_eof && audio_time <= video_time) {
            write_audio_frame(oc, audio_st, flush);
        } else if (video_st && !video_is_eof && video_time < audio_time) {
            write_video_frame(oc, video_st, flush);
        }
    }

    /* Write the trailer, if any. The trailer must be written before you
     * close the CodecContexts open when you wrote the header; otherwise
     * av_write_trailer() may try to use memory that was freed on
     * av_codec_close(). */
    av_write_trailer(oc);

    /* Close each codec. */
    if (video_st)
        close_video(oc, video_st);
    if (audio_st)
        close_audio(oc, audio_st);

    if (!(fmt->flags & AVFMT_NOFILE))
        /* Close the output file. */
        avio_close(oc->pb);

    /* free the stream */
    avformat_free_context(oc);

    return 0;
}

and, in order to avoid a warning about channel layout not specified, I
added:

c->channel_layout      = av_get_default_channel_layout(c->channels);

in function AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,
                            enum AVCodecID codec_id)
just under the row c->channels    = 2;


I also raised a ffserver with the following configuration (showing only
feed lines):

<Feed feed1.ffm>
        File /tmp/feed1.ffm
        FileMaxSize 1GB
        ACL allow 127.0.0.1
        ACL allow 192.168.0.0 192.168.255.255
</Feed>

ffserver is working fine if I feed it with a ffmpeg commandline, e.g:
ffmpeg -r 25 -i movie.mp4 -acodec libfdk_aac  -ab 128k -vcodec libx264
-fpre libx264-fast.ffpreset http://localhost:8090/feed1.ffm


But with my example, I can write only few frames and after that may muxing
modified program ends with:

Error while writing audio frame: Connection reset by peer

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.

ffserver do not reports errors at all, only write:
Tue Mar  4 12:55:10 2014 127.0.0.1 - - [POST] "/feed1.ffm HTTP/1.1" 200 4096
confirming that the communication socket was open

What I am missing??

Thanks
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20140304/8b93d14b/attachment.html>


More information about the Libav-user mailing list