<项目日志 1004> 轻量便携流媒体播放器框架设计-2

来源:互联网 发布:怎样在淘宝上卖二手货 编辑:程序博客网 时间:2024/04/30 11:30
前面讨论最基础的设计思路,下面说明详细的设计实现。
  • Access 模块
     Access模块完成数据获得,设计两个接口:Open()/Close(),提供三个回调函数即onStreamBegin(bool), onStreamEnd(), onStreamData(void *,int);  看意思就清楚了,无需多余的说明,代码如下:
class Access {public:        virtual ~TeaAccess(){};    //interfaces    virtual bool Open() = 0;    virtual void Close() = 0;    //callbacks    sigslot::signal1<bool> signalBeginOfStream;    sigslot::signal0<> signalEndOfStream;    sigslot::signal2<const unsigned char*, size_t> signalData;};
    Access为独立线程,因此signalData回调需要进行数据复制之后进行线程切换。

  • Demux 模块
 Demux模块完成数据解析,提供的接口以及回调如下:
class Demux{public:            virtual ~TeaDemux(){};    //interfaces        virtual bool Open() = 0;    virtual void Close() = 0;    virtual bool PushNewData(const unsigned char *data, size_t length) = 0;                                    //callbacks    sigslot::signal1<bool> signalProbed;    sigslot::signal1<MediaPacket *> signalMediaPacket;        std::map<unsigned int, Decoder *> decoders;};

主要Open/Close如文字定义,负责Demuxer资源初始化和释放,其中PushNewData完成数据接收(即接收Access的数据)。
回调主要有两个,signalProbed(bool)回调主要完成是否正确解析多媒体文件,signalMediaPacket即解析出来的媒体包。
Demux为一独立线程,根据Access的数据不断产生MediaPacket数据,送给Decode模块解码。
此外,Demux在正确解析多媒体文件之后,维护Decoder对象,Decoder对象将MediaPacket解码为YUV和PCM数据。

  • DecodeTask 模块
该模块是整个播放器的核心之一,设计如下:
class DecodeTask {public:            DecodeTask(Demux *dm);    virtual ~DecodeTask(){};    //interfaces        void PushMediaPacket(MediaPacket *pkt);                                                                    void DecodeVideo(MediaTime target);    void DecodeAudio(MediaTime target);    MediaTime BufferedVideoLength();    unsigned int BufferedPictures();    MediaTime FirstPictureTime();    MediaTime LastPictureTime();    MediaTime BufferedAudioLength();    MediaTime FirstAudioTime();    MediaTime LastAudioTime();    //callbacks    sigslot::signal1<VideoPicture *> signalVideoPicture;    sigslot::signal1<AudioPCM *> signalVideoPCM;};

DecodeTask 模块独立线程,但是通过DecodeVideo/DecodeAudio驱动,生成的结果通过两个回调函数返回,并且提供内部音视频数据缓冲状况。Player对象通过定期查询DecodeTask的缓冲状况,驱动解码起进行解码,并将解码结果送交AudioOut模块以及VideoOut模块。