关闭

ffserver 拆解

3443人阅读 评论(0) 收藏 举报

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()
真正的开始搬运数据,从输入到输出 

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:115033次
    • 积分:1768
    • 等级:
    • 排名:千里之外
    • 原创:63篇
    • 转载:1篇
    • 译文:0篇
    • 评论:8条
    最新评论
    linux下c++编程