ffserver 拆解

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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值