最近找到的关于ffserver的资料

来源:互联网 发布:一个源码两个网站用 编辑:程序博客网 时间:2024/06/01 07:50
感觉资料真是少的可怜,也可能还没找到把,先贴过来

  
checkout了一个ffmpeg的包
编译了,也安装上了。
按照doc中的说明执行
ffserver -f doc/ffserver.conf
的时候显示
[hui@dh trunk]$ ./ffserver -f doc/ffserver.conf
Codecs do not match for stream 2
ffserver started.
这应该是有错误吧,后来看到有一个tests文件夹,cd,然后
[hui@dh trunk]$ ../ffserver -f test.conf
ffserver started.
然后就没“not”之类的提示了,估计是可以了,这个doc/ffserver.conf也是有问题的/????????????????就发布
了????????????????


2.3 How do I make it work?First, build the kit. It *really* helps to have installed LAME first. Then when you run the  
ffserver ./configure, make sure that you have the --enable-mp3lame flag turned on. LAME is important as it allows for
streaming audio to Windows Media Player. Don't ask why the other audio types do not work. As a simple test, just run the
following two command lines (assuming that you have a V4L video capture card): ./ffserver -f doc/ffserver.conf &./ffmpeg
http://localhost:8090/feed1.ffmAt this point you should be able to go to your Windows machine and fire up Windows Media
Player (WMP). Go to Open URL and enter http://<linuxbox>:8090/test.asfYou should (after a short delay) see video and
hear audio. WARNING: trying to stream test1.mpg doesn't work with WMP as it tries to


尤其是上面的文档,执行完./ffserver -f doc/ffserver.conf &后先是刚才的那个错误提示,由于多次未成功现在很是恼火(偶得气量不大),有问
题????????不可能吧!!可是提示有错误呀???!!!不管它,继续执行 ./ffmpeg http://localhost:8090/feed1.ffm又有了新的提示:
[hui@dh trunk]$ ./ffmpeg http://localhost:8090/feed1.ffm
FFmpeg version SVN-r9022, Copyright (c) 2000-2007 Fabrice Bellard, et al.
configuration: --prefix=../installdir
libavutil version: 49.4.0
libavcodec version: 51.40.4
libavformat version: 51.12.1
built on May 14 2007 16:38:55, gcc: 3.2.2 20030222 (Red Hat Linux 3.2.2-5)
Could not read stream parameters from 'http://localhost:8090/feed1.ffm'

相关讨论结果如下:

ffserver启动之后就会监听8090端口,这个端口号应该在conf文件中可配置。ffserver启动后会创建一临时文件feed1.ffm,文件大小大概是4096B,里面只
有头信息,是ffserver根据conf文件的配置生成的。
ffmpeg http://localhost:8090/feed1.ffm,它在做什么呢?大概是这样的,与ffserver建立http连接,然后从ffserver获取音频和视频的配置信息,然
后尝试用这些信息初始化设备和codec,所以看不到ffmpeg加一大堆参数启动。
ffmpeg启动工作后,会把编码后的数据通过udp发给ffserver,ffserver接收到数据后循环的写入feed1.ffm文件,应该是做缓冲。一边写,一边监听网络上的
动静。
ffmpeg 的main()入口是有参数的,就是argv数组地址和参数个数
而在ffserver中 有一个startchd()函数,其中有一个启动子进程的函数execvp(),正是通过这个函数,ffserver把ffserver.conf中的一些有关媒体的
配置信息通过argv数组传递给了ffmpeg,然后ffmpeg就进行数据采集或者格式转换的工作,转换之后的结果以feed1.ffm 文件存放在/tmp目录下,由
ffserver读取并监听网络,这就是ffserver多媒体服务器。
在解析参数的时候,调用opt_output_file,这里面要创建输出文件,对于filename为"http://localhost:8090/feed1.ffm"来说,调用url_fopen是建立
了和ffserver的连接。
再看视频输出的地方,do_video_out,需要把encodec后的数据写入文件(av_interleaved_write_frame),这个地方调用了s->oformat->write_packet
(),对于s->filename为"http://localhost:8090/feed1.ffm"来说,这里就是利用先前的连接把数据传给ffserver,以feed1.ffm文件的格式。

1.配置文件:

<Stream test1-sdp.mpg>
Format rtp
#Feed feed1.ffm
File "/home/teddy_linux/1.avi"
MulticastAddress 224.124.0.1
#MulticastAddress 192.168.205.51
MulticastPort 15000
MulticastTTL 16
#NoLoop
</Stream>

2.xvid压缩的视频和一个raw的音频

拆解一,
必须调用av_register_all();初始化所有的codec

拆解二,
配置文件要分清输入文件还有输出文件
test1-sdp.mpg 是输出文件名
/home/teddy_linux/1.avi 是输入文件名

所以放在两个不同的数据结构中。总的数据结构是HttpContext,输入文件放在fmt_in,然而输出文件放到了

stream中,见下图

HttpContext--->stream{FFStream}--->streams[] {AVStream} ---->codec {AVCodecContext}
             -                                          ---->time_base {AVRational}
             -
             -
             ->fmt_in{AVFormatContext}--->streams[] {AVStream}


拆解三,
打开输出文件前,要配置一下输出流的格式。
stream->fmt = guess_stream_format(NULL, stream->filename, NULL);

拆解四,
打开输入文件时,只要把文件名字传对,一切OK. 但要open_parser()

拆解五,
打开输出文件,其实就是把输入文件的音视频流拷贝到输出的两个流中.
rtp_new_av_stream()
memcpy(st,
               c->stream->feed->streams[c->stream->feed_streams[stream_index]],
               sizeof(AVStream));

拆解六,
输出流的层层剥离:url()--->rtp()---->url()---->udp()
协议栈剥离,要注意这里有一个bug,不能使用ipv6.然而,默认是用ipv6.所以,编译器选项应该是
../configure --disable-opts --disable-mmx --disable-ipv6
有调试信息很好用啊

拆解七,
使用poll_table 和poll_entry 的IP server模型,似乎必须要处于server模式,才能够正确发送流。其实,

其本质还是select模型。

            do {
         ret = poll(poll_table, poll_entry - poll_table, delay);
         if (ret < 0 && ff_neterrno() != FF_NETERROR(EAGAIN) &&
             ff_neterrno() != FF_NETERROR(EINTR))
             return -1;
     } while (ret < 0);

服务器主循环,任何事件都放到poll_table中。关心的状态也放到其中

  case HTTPSTATE_SEND_DATA:
         case HTTPSTATE_SEND_DATA_TRAILER:
             if (!c->is_packetized) {
                 /* for TCP, we output as much as we can (may need to put a limit) */
                 c->poll_entry = poll_entry;
                 poll_entry->fd = fd;
                 poll_entry->events = POLLOUT;
                 poll_entry++;
             } else {
                 /* when ffserver is doing the timing, we work by
                    looking at which packet need to be sent every
                    10 ms */
                 delay1 = 10; /* one tick wait XXX: 10 ms assumed */
                 if (delay1 < delay)
                     delay = delay1;
             }
             break;
os_support.c中重新改写了poll函数,但是似乎link不上,总是调用的sys/poll.h函数。

拆解八,
handle_connection()
真正的开始搬运数据,从输入到输出 



http://cekirdek.pardus.org.tr/~ismail/ffmpeg-docs/index.html

http://yjaps26.blog.163.com/blog/static/24483312200861091059866/
原创粉丝点击