Hello, I'm trying to stream a video generated by a custom application. I'm using ffserver with the following config:
Port 8090 BindAddress 0.0.0.0 MaxClients 100 MaxBandwidth 10000 NoDaemon <Feed feed1.ffm> File /tmp/feed1.ffm FileMaxSize 1000M </Feed> <Stream test.avi> Feed feed1.ffm Format mpeg VideoCodec mpeg1video VideoFrameRate 25 VideoBufferSize 800000 VideoBitRate 800 VideoQMin 1 VideoQMax 5 VideoSize 1024x768 PreRoll 0 Noaudio </Stream> I access the server from another computer with: mplayer http://ipaddress:8090/test.avi I have a custom application that feeds the stream (it outputs mjpeg): c2mpg -o http://localhost:8090/feed1.ffm This application creates a ffmpeg stream and writes it to the output. If the output is a file, I can play the video without any problem. If the output is the feed, mplayer plays correctly **BUT ONLY ONCE** the custom application terminates. The sequence is the following: time t: ffserver -f config time t + 1s: mplayer http://ipaddress:8090/test.avi time t + 2s: c2mpg -o http://localhost:8090/feed1.ffm c2mpg feeds the video. In the mean time, mplayer seems to be blocked. It just fills the cache with a message saying that it's filled at 10%. time t + 30s: c2mpg terminates. t + 30s: mplayer starts playing the whole content provided by c2mpg. t + 58s: mplayer terminates. It seems that the stream is locked as long as c2mpg is alive. Obviously, it's not what I want to do, as I want to watch the video live. Any idea what I'm doing wrong? Many thanks in advance, Grégoire **** Some code of c2mpg **** void open_video(AVFormatContext *oc, AVStream *st) { AVCodec *codec; AVCodecContext *c; c = st->codec; /* find the video encoder */ codec = avcodec_find_encoder(c->codec_id); if (!codec) { fprintf(stderr, "codec not found\n"); exit(1); } /* open the codec */ if (avcodec_open(c, codec) < 0) { fprintf(stderr, "could not open codec\n"); exit(1); } video_outbuf = NULL; if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) { /* allocate output buffer */ /* XXX: API change will be done */ video_outbuf_size = 200000; video_outbuf = malloc(video_outbuf_size); } /* allocate the encoded raw picture */ picture = alloc_picture(c->pix_fmt, c->width, c->height); if (!picture) { fprintf(stderr, "Could not allocate picture\n"); exit(1); } /* if the output format is not RGB565, then a temporary RGB565 picture is needed too. It is then converted to the required output format */ tmp_picture = NULL; if (c->pix_fmt != PIX_FMT_RGB565) { tmp_picture = alloc_picture(PIX_FMT_RGB565, c->width, c->height); if (!tmp_picture) { fprintf(stderr, "Could not allocate temporary picture\n"); exit(1); } } } static int movie_open(int w, int h) { if (fmt->video_codec != CODEC_ID_NONE) { video_st = add_video_stream(oc, fmt->video_codec, w, h); } else return 1; /* set the output parameters (must be done even if no parameters). */ if (av_set_parameters(oc, NULL) < 0) { fprintf(stderr, "Invalid output format parameters\n"); return 2; } dump_format(oc, 0, filename, 1); /* 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_st); /* open the output file, if needed */ if (!(fmt->flags & AVFMT_NOFILE)) { if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) { fprintf(stderr, "Could not open '%s'\n", filename); return 3; } } /* write the stream header, if any */ av_write_header(oc); return 0; } _______________________________________________ libav-user mailing list [email protected] https://lists.mplayerhq.hu/mailman/listinfo/libav-user
