Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3534752
  • 博文数量: 864
  • 博客积分: 14125
  • 博客等级: 上将
  • 技术积分: 10634
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-27 16:53
个人简介

https://github.com/zytc2009/BigTeam_learning

文章分类

全部博文(864)

文章存档

2023年(1)

2021年(1)

2019年(3)

2018年(1)

2017年(10)

2015年(3)

2014年(8)

2013年(3)

2012年(69)

2011年(103)

2010年(357)

2009年(283)

2008年(22)

分类: C/C++

2010-12-01 12:42:48

主要是流层图,一共三 份:包括数据流向、内存分配以及结构框架.先发数据流向图,其他两份我需要整理后在发送,另外数据流向图中关于layerbuff部分并不完全,具体的会 在内存分配(也就是front buffer,back buffer两层递换分配原理)中解释.建议几位朋友还是自己多看代码,代码就是资料!最近一直忙于工作,少了时间看Android,一切的一切还是以赚 钱为主.
    Ok! 最近在为公司的wifi tablet 添加mms协议流媒体的播放功能,商业协议缺少资料让我苦不堪言,另外mplayer等对mms协议的支持也是非常不理想,使得我没有可参考的代码,连蒙 带猜的终于实现了pause与seek.当然wifi tablet本身的局限性使得困难也增加不少,不管怎么样,至少我现在除了能播放mms流媒体,还能正常的seek与pause.再次抱怨一下国内技术的 落后,微软很早就宣布淘汰mms了,可是国内运营商们清一色的mms协议流媒体真是让人心寒啊!
    下面是代码时间,首先我的修改基于libmms.我在此基础上的修改并不多,加了状态基,加了0x09 command.不过这点修改仍然耗费了我两个星期的时间去探索,这里现贴代码,关于ffmpeg流媒体代码的架构问题,我下次在贴出:
    int mms_read_pause(mms_io_t *io, mms_t *this, int pause)
  {
      mms_packet_header_t header;
      if(pause)
      {
          if (!send_command (io, this, 0x09, 1, 0xffff0100, 0))
                         
return 0;
          this->eos =
MMS_PAUSE_ACKNOWLEDGE;
          while (this->eos !=
STREAM_PAUSED)
              {
                      get_media_packet(io, this);
              }
          this->eos =
STREAMING;
         
return 0;
      }
      else
      {
          this->eos =
STREAMING;
         
return 1;
      }
  }   

这个是0x09命令,关于mms中这个命令的描述:
 

09 To Server

Prefix 1 01 00 00 00 - CommandLevel

Prefix 2 ff ff 01 00

This is sent by Media Player when the Stop button is activated. If Media Player needs to stop the stream for any reason, it sends this command. The socket connection is kept open.


void mms_close (mms_io_t *io, mms_t *this) {

   int ret;
   if(this->eos == STREAMING || this->eos == STREAM_PAUSED)
   {
     ret = send_command (io, this, 0x0D, 1, 1, 0);
   }    
   while(this->eos != STREAM_DONE)
   {
     if(ret == 0)
                 break;
     get_media_packet(io, this);
   }        
   if (this->s != -1)
     //close (this->s);
     io_close(io, this->s);
   if (this->url)

     free(this->url);

   if (this->proto)
     free(this->proto);
   if (this->host)
     free(this->host);
   if (this->user)
     free(this->user);
   if (this->password)
     free(this->password);
   if (this->uri)
     free(this->uri);

  
   free (this);
 }

这个是0x0D命令,关于mms中这个命令的描述:

0D To Server

Prefix 1 01 00 00 00 - CommandLevel

Prefix 2 01 00 00 00


Cancel protocol. This can be sent if the player cancels viewing before the protocol has been fully established, or after a timeout occurs. It is also sent when media player closes the socket connection.


int mms_request_time_seek (mms_io_t *io, mms_t *this, double time_sec) {
        int ret;
        if (++this->packet_id_type <= ASF_MEDIA_PACKET_ID_TYPE)
        this->packet_id_type = ASF_MEDIA_PACKET_ID_TYPE+1;
        //return mms_request_data_packet (io, this, time_sec, 0xFFFFFFFF, 0x00FFFFFF);
        // also adjust time by preroll

        if(mms_request_data_packet (io, this,
                                  time_sec+(double)(this->preroll)/1000,
                                  0xFFFFFFFF, 0x00FFFFFF))
                return -1;
        this->eos = MMS_SEEK_ACKNOWLEDGE;
        ret = peek_and_set_pos (io, this);
        this->eos = STREAMING;
        return ret;
}


static int mms_request_data_packet (mms_io_t *io, mms_t *this,
  double time_sec, unsigned long first_packet, unsigned long time_msec_limit) {
  /* command 0x07 */
  {
    mms_buffer_t command_buffer;
    //mms_buffer_init(&command_buffer, this->scmd_body);
    //mms_buffer_put_32 (&command_buffer, 0x00000000);                  /* 64 byte float timestamp */
    //mms_buffer_put_32 (&command_buffer, 0x00000000);                 

    memcpy(this->scmd_body, &time_sec, 8);
    mms_buffer_init(&command_buffer, this->scmd_body+8);
    mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF);                  /* ?? */
    //mms_buffer_put_32 (&command_buffer, 0xFFFFFFFF);                  /* first packet sequence */
    mms_buffer_put_32 (&command_buffer, first_packet);                  /* first packet sequence */
    //mms_buffer_put_8  (&command_buffer, 0xFF);                        /* max stream time limit (3 bytes) */
    //mms_buffer_put_8  (&command_buffer, 0xFF);
    //mms_buffer_put_8  (&command_buffer, 0xFF);
    //mms_buffer_put_8  (&command_buffer, 0x00);       
                 /* stream time limit flag */
    mms_buffer_put_32 (&command_buffer, time_msec_limit & 0x00FFFFFF);/* max stream time limit (3 bytes) */
    mms_buffer_put_32 (&command_buffer, this->packet_id_type);    /* asf media packet id type */
    if (!send_command (io, this, 0x07, 1, 0x0001FFFF, 8+command_buffer.pos)) {
  /* FIXME: de-xine-ification */
      return 0;
    }
  }
  /* TODO: adjust current_pos, considering asf_header_read */
  return 1;
}


这个是0x07命令,关于mms中这个命令的描述:

07 To Server

Prefix 1 01 00 00 00 - CommandLevel

Prefix 2 ff ff 01 00 - or shows 76 04 00 00 with optional data #

Then structure data below

Start sending file from packet xx. This command is also used for resume downloads or requesting a lost packet. Also used for seeking by sending a play point value which seeks to the media time point. Includes media ‘PacketIDType’ value in pre header and the maximum media stream time.

This command sets the start point within the media using the packet sequence number and/or the play time point. It can be used to continue a download session after a previous uncompleted session. Or, it can be used to re-access a specific lost packet and for seeking during a fast forward or re-wind operation. Its main use is simply to start the file playing from the beginning.

    当然如果认为发送这么几个命令就万事大吉,那就错了,我们还需要一个状态基来随时监控流媒体状态的变换,这也是我的主要修改工作,关于这部分代码由于比较 多,我还是分几次贴吧.而作为我们wifi tablet部分的代码呢,我们还有不少接口需要变动,我们同样放到下一次贴代码.

阅读(5515) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~