基于Linux电视棒实现DLNA和airplay功能

http://blog.csdn.net/moruite/article/details/8496218

出发点:Android电视棒实现DLNA功能采用JAVA版本的cyberlink的话,缺点明显,SSDP协议设备发现有延时(有时还发现不了设备)体验差,基于Linux电视棒可以控制硬件成本在100元以下,而且c语言实现的cyberlink DLNA协议栈不存在设备发现不了的情况,本文记录记录linux下实现dlna碰到的一揽子问题

1. DLNA的DMR方案

方案1: MediaGateForCC (http://www.cybergarage.org/twiki/bin/view/Main/MediaGateForCC) 交叉编译,基于gstreamer实现播放器

Cyberlink协议栈需要依赖xml库, 可以选择xerces和libxml2, xerces是apatch提供的一个比较庞大的xml解析库,嵌入式设备不考虑。 

1) 编译libxml2

./configure --prefix=/home/work/mylib --host=mips-linux-gnu --build=i686 --target=mips-linux-gnu CC=mips-linux-gnu-gcc -EL CFLAGS=-I/home/work/mylib/include LDFLAGS=-L/home/work/mylib/lib

2)编译MediaGateForCC

 ./configure --prefix=/home/work/mylib --host=mips-linux-gnu --build=i686 --target=mips-linux-gnu CC=mips-linux-gnu-gcc -EL --enable-libxml2 CFLAGS=-I/home/work/mylib/include CPPFLAGS=-I/home/work/mylib/include LDFLAGS=-L/home/work/mylib/lib 

错误1:LibXml2Parser.cpp中Node *newChildNode = convertToCLinkFormat( doc, child, depth  1)改成Node *newChildNode = convertToCLinkFormat( doc, child, depth );

错误2:ControlPoint.cpp中Device **dev = new (Device(*[devCnt])); 改成 Device **dev = new Device* [devCnt];

编译成功

3) CyberLink中没有实现Media Renderer的AVTransport和RenderingControl服务,以下是补充的AVTransport..h和RenderingControl.h

[cpp]  view plain copy
  1. class AVT : public ActionListener, public QueryListener  
  2. {  
  3.   
  4.     CyberUtil::Mutex mutex;  
  5.     int maxConnectionID;  
  6.   
  7.       
  8.     ////////////////////////////////////////////////  
  9.     // Constants  
  10.     ////////////////////////////////////////////////  
  11.   
  12. public:  
  13.   
  14.     static const char *DESCRIPTION;  
  15.   
  16.     static const char *SERVICE_TYPE;  
  17.   
  18.     static const char * TRANSPORTSTATE ;  
  19.     static  const char *  TRANSPORTSTATUS ;  
  20.     static  const char *  PLAYBACKSTORAGEMEDIUM;  
  21.     static  const char *  RECORDSTORAGEMEDIUM;  
  22.     static  const char *  POSSIBLEPLAYBACKSTORAGEMEDIA;  
  23.     static  const char *  POSSIBLERECORDSTORAGEMEDIA;  
  24.     static  const char *  CURRENTPLAYMODE ;  
  25.     static  const char *  TRANSPORTPLAYSPEED;  
  26.     static  const char *  RECORDMEDIUMWRITESTATUS ;  
  27.     static  const char *  CURRENTRECORDQUALITYMODE ;  
  28.     static  const char *  POSSIBLERECORDQUALITYMODES;  
  29.     static  const char *  NUMBEROFTRACKS;  
  30.     static  const char *  CURRENTTRACK;  
  31.     static  const char *  CURRENTTRACKDURATION;  
  32.     static  const char *  CURRENTMEDIADURATION;  
  33.     static  const char *  CURRENTTRACKMETADATA;  
  34.     static  const char *  CURRENTTRACKURI;  
  35.     static  const char *  AVTRANSPORTURI;  
  36.     static  const char *  AVTRANSPORTURIMETADATA ;  
  37.     static  const char *  NEXTAVTRANSPORTURI;  
  38.     static  const char *  NEXTAVTRANSPORTURIMETADATA;  
  39.     static  const char *  RELATIVETIMEPOSITION;  
  40.     static  const char *  ABSOLUTETIMEPOSITION;  
  41.     static  const char *  RELATIVECOUNTERPOSITION ;  
  42.     static  const char *  ABSOLUTECOUNTERPOSITION ;  
  43.     static  const char *  CURRENTTRANSPORTACTIONS;  
  44.     static  const char *  LASTCHANGE;  
  45.     static  const char *  SETAVTRANSPORTURI;  
  46.     static  const char *  INSTANCEID;  
  47.     static  const char *  CURRENTURI;  
  48.     static  const char *  CURRENTURIMETADATA;  
  49.     static  const char *  SETNEXTAVTRANSPORTURI;  
  50.     static  const char *  NEXTURI;  
  51.     static  const char *  NEXTURIMETADATA ;  
  52.     static  const char *  GETMEDIAINFO;  
  53.     static  const char *  NRTRACKS;  
  54.     static  const char *  MEDIADURATION;  
  55.     static  const char *  PLAYMEDIUM ;  
  56.     static  const char *  RECORDMEDIUM ;  
  57.     static  const char *  WRITESTATUS ;  
  58.     static  const char *  GETTRANSPORTINFO ;  
  59.     static  const char *  CURRENTTRANSPORTSTATE;  
  60.     static  const char *  CURRENTTRANSPORTSTATUS ;  
  61.     static  const char *  CURRENTSPEED ;  
  62.     static  const char *  GETPOSITIONINFO;  
  63.     static  const char *  TRACK;  
  64.     static  const char *  TRACKDURATION;  
  65.     static  const char *  TRACKMETADATA ;  
  66.     static  const char *  TRACKURI ;  
  67.     static  const char *  RELTIME;  
  68.     static  const char *  ABSTIME;  
  69.     static  const char *  RELCOUNT;  
  70.     static  const char *  ABSCOUNT;  
  71.     static  const char *  GETDEVICECAPABILITIES;  
  72.     static  const char *  PLAYMEDIA ;  
  73.     static  const char *  RECMEDIA ;  
  74.     static  const char *  RECQUALITYMODES;  
  75.     static  const char *  GETTRANSPORTSETTINGS;  
  76.     static  const char *  PLAYMODE ;  
  77.     static  const char *  RECQUALITYMODE ;  
  78.     static  const char *  STOP;  
  79.     static  const char *  PLAY;  
  80.     static  const char *  SPEED ;  
  81.     static  const char *  PAUSE;  
  82.     static  const char *  RECORD ;  
  83.     static  const char *  SEEK ;  
  84.     static  const char *  UNIT;  
  85.     static  const char *  TARGET ;  
  86.     static  const char *  NEXT ;  
  87.     static  const char *  PREVIOUS ;  
  88.     static  const char *  SETPLAYMODE ;  
  89.     static  const char *  NEWPLAYMODE ;  
  90.     static  const char *  SETRECORDQUALITYMODE ;  
  91.     static  const char *  NEWRECORDQUALITYMODE ;  
  92.     static  const char *  GETCURRENTTRANSPORTACTIONS;  
  93.     static  const char *  ACTIONS;  
  94.       
  95.     static  const char *  STOPPED ;  
  96.     static  const char *  PLAYING ;  
  97.     static  const char *  OK;  
  98.     static  const char *  ERROR_OCCURRED ;  
  99.     static  const char *  NORMAL ;  
  100.     static  const char *  TRACK_NR ;  
  101.   
  102.   
  103.       
  104.       
  105.     ////////////////////////////////////////////////  
  106.     // Constructor   
  107.     ////////////////////////////////////////////////  
  108.       
  109. public:  
  110.   
  111.     AVT();  
  112.       
  113.     virtual ~AVT();  
  114.       
  115.   
  116.       
  117. public:  
  118.   
  119.     void lock()  
  120.     {  
  121.         mutex.lock();  
  122.     }  
  123.       
  124.     void unlock()  
  125.     {  
  126.         mutex.unlock();  
  127.     }  
  128.       
  129.     ////////////////////////////////////////////////  
  130.     // ConnectionID  
  131.     ////////////////////////////////////////////////  
  132.   
  133.   
  134.       
  135.     ////////////////////////////////////////////////  
  136.     // ActionListener  
  137.     ////////////////////////////////////////////////  
  138.   
  139. public:  
  140.   
  141.     bool actionControlReceived(Action *action);  
  142.   
  143.   
  144.   
  145. public:  
  146.   
  147.     bool queryControlReceived(StateVariable *stateVar);  
  148.   
  149. };  
[cpp]  view plain copy
  1.   
[cpp]  view plain copy
  1. RenderingControl服务类  
[cpp]  view plain copy
  1.   
[cpp]  view plain copy
  1. class RC : public ActionListener, public QueryListener  
  2. {  
  3.   
  4.     CyberUtil::Mutex mutex;  
  5.     int maxConnectionID;  
  6.   
  7.       
  8.     ////////////////////////////////////////////////  
  9.     // Constants  
  10.     ////////////////////////////////////////////////  
  11.   
  12. public:  
  13.   
  14.     static const char *DESCRIPTION;  
  15.   
  16.     static const char *SERVICE_TYPE;  
  17.       
  18.       
  19.     static const char *PRESETNAMELIST ;  
  20.         static const char *LASTCHANGE ;  
  21.         static const char *BRIGHTNESS;  
  22.         static const char *CONTRAST ;  
  23.         static const char *SHARPNESS ;  
  24.         static const char *REDVIDEOGAIN;  
  25.         static const char *GREENVIDEOGAIN ;  
  26.         static const char *BLUEVIDEOGAIN ;  
  27.         static const char *REDVIDEOBLACKLEVEL;  
  28.         static const char *GREENVIDEOBLACKLEVEL ;  
  29.         static const char *BLUEVIDEOBLACKLEVEL ;  
  30.         static const char *COLORTEMPERATURE ;  
  31.         static const char *HORIZONTALKEYSTONE ;  
  32.         static const char *VERTICALKEYSTONE ;  
  33.         static const char *MUTE ;  
  34.         static const char *VOLUME ;  
  35.         static const char *VOLUMEDB ;  
  36.         static const char *LOUDNESS ;  
  37.         static const char *LISTPRESETS;  
  38.         static const char *INSTANCEID ;  
  39.         static const char *CURRENTPRESETNAMELIST;  
  40.         static const char *SELECTPRESET;  
  41.         static const char *PRESETNAME;  
  42.         static const char *GETBRIGHTNESS;  
  43.         static const char *CURRENTBRIGHTNESS ;  
  44.         static const char *SETBRIGHTNESS;  
  45.         static const char *DESIREDBRIGHTNESS;  
  46.         static const char *GETCONTRAST;  
  47.         static const char *CURRENTCONTRAST;  
  48.         static const char *SETCONTRAST;  
  49.         static const char *DESIREDCONTRAST;  
  50.         static const char *GETSHARPNESS;  
  51.         static const char *CURRENTSHARPNESS;  
  52.         static const char *SETSHARPNESS;  
  53.         static const char *DESIREDSHARPNESS;  
  54.         static const char *GETREDVIDEOGAIN;  
  55.         static const char *CURRENTREDVIDEOGAIN;  
  56.         static const char *SETREDVIDEOGAIN;  
  57.         static const char *DESIREDREDVIDEOGAIN ;  
  58.         static const char *GETGREENVIDEOGAIN;  
  59.         static const char *CURRENTGREENVIDEOGAIN;  
  60.         static const char *SETGREENVIDEOGAIN ;  
  61.         static const char *DESIREDGREENVIDEOGAIN ;  
  62.         static const char *GETBLUEVIDEOGAIN ;  
  63.         static const char *CURRENTBLUEVIDEOGAIN ;  
  64.         static const char *SETBLUEVIDEOGAIN;  
  65.         static const char *DESIREDBLUEVIDEOGAIN ;  
  66.         static const char *GETREDVIDEOBLACKLEVEL ;  
  67.         static const char *CURRENTREDVIDEOBLACKLEVEL ;  
  68.         static const char *SETREDVIDEOBLACKLEVEL;  
  69.         static const char *DESIREDREDVIDEOBLACKLEVEL;  
  70.         static const char *GETGREENVIDEOBLACKLEVEL;  
  71.         static const char *CURRENTGREENVIDEOBLACKLEVEL;  
  72.         static const char *SETGREENVIDEOBLACKLEVEL;  
  73.         static const char *DESIREDGREENVIDEOBLACKLEVEL;  
  74.         static const char *GETBLUEVIDEOBLACKLEVEL;  
  75.         static const char *CURRENTBLUEVIDEOBLACKLEVEL;  
  76.         static const char *SETBLUEVIDEOBLACKLEVEL;  
  77.         static const char *DESIREDBLUEVIDEOBLACKLEVEL;  
  78.         static const char *GETCOLORTEMPERATURE ;  
  79.         static const char *CURRENTCOLORTEMPERATURE;  
  80.         static const char *SETCOLORTEMPERATURE;  
  81.         static const char *DESIREDCOLORTEMPERATURE;  
  82.         static const char *GETHORIZONTALKEYSTONE;  
  83.         static const char *CURRENTHORIZONTALKEYSTONE;  
  84.         static const char *SETHORIZONTALKEYSTONE;  
  85.         static const char *DESIREDHORIZONTALKEYSTONE;  
  86.         static const char *GETVERTICALKEYSTONE;  
  87.         static const char *CURRENTVERTICALKEYSTONE;  
  88.         static const char *SETVERTICALKEYSTONE;  
  89.         static const char *DESIREDVERTICALKEYSTONE;  
  90.         static const char *GETMUTE ;  
  91.         static const char *CHANNEL;  
  92.         static const char *CURRENTMUTE ;  
  93.         static const char *SETMUTE;  
  94.         static const char *DESIREDMUTE;  
  95.         static const char *GETVOLUME;  
  96.         static const char *CURRENTVOLUME ;  
  97.         static const char *SETVOLUME ;  
  98.         static const char *DESIREDVOLUME ;  
  99.         static const char *GETVOLUMEDB ;  
  100.         static const char *SETVOLUMEDB;  
  101.         static const char *GETVOLUMEDBRANGE ;  
  102.         static const char *MINVALUE;  
  103.         static const char *MAXVALUE;  
  104.         static const char *GETLOUDNESS ;  
  105.         static const char *CURRENTLOUDNESS;  
  106.         static const char *SETLOUDNESS ;  
  107.         static const char *DESIREDLOUDNESS;  
  108.           
  109.         static const char *MASTER ;  
  110.         static const char *FACTORYDEFAULTS ;  
  111.   
  112.       
  113.       
  114.       
  115. public:  
  116.   
  117.     RC();  
  118.       
  119.     virtual ~RC();  
  120.       
  121.   
  122.       
  123. public:  
  124.   
  125.     void lock()  
  126.     {  
  127.         mutex.lock();  
  128.     }  
  129.       
  130.     void unlock()  
  131.     {  
  132.         mutex.unlock();  
  133.     }  
  134.       
  135.     ////////////////////////////////////////////////  
  136.     // ConnectionID  
  137.     ////////////////////////////////////////////////  
  138.   
  139.   
  140.   
  141. public:  
  142.   
  143.     bool actionControlReceived(Action *action);  
  144.   
  145.   
  146.   
  147. public:  
  148.   
  149.     bool queryControlReceived(StateVariable *stateVar);  
  150.   
  151. };  

4)MediaRender的实现

MediaRender主要是实现ConnectionManager、AVTransport和RenderingControl服务

[cpp]  view plain copy
  1. class MP : public Device  
  2. {  
  3.   
  4.     CM *conMan;  
  5.     AVT *avTrans;  
  6.     RC *renderCon;  
  7.   
  8.     ////////////////////////////////////////////////  
  9.     // Constants  
  10.     ////////////////////////////////////////////////  
  11.       
  12. public:  
  13.   
  14.     static const char *DEVICE_TYPE;  
  15.   
  16.     static const int DEFAULT_HTTP_PORT;  
  17.       
  18.     static const char *DESCRIPTION;  
  19.   
  20.     ////////////////////////////////////////////////  
  21.     // Constructor  
  22.     ////////////////////////////////////////////////  
  23.       
  24. public:  
  25.       
  26.     MP();  
  27.   
  28.     ~MP();  
  29.       
  30.     ////////////////////////////////////////////////  
  31.     //  setName  
  32.     ////////////////////////////////////////////////  
  33.       
  34. public:  
  35.   
  36.     void setName(const char *name)  
  37.     {  
  38.         setFriendlyName(name);  
  39.     }  
  40.       
  41.     const char *getName()  
  42.     {  
  43.         getFriendlyName();  
  44.     }  
  45.   
  46.     ////////////////////////////////////////////////  
  47.     // Memeber  
  48.     ////////////////////////////////////////////////  
  49.       
  50. public:  
  51.   
  52.     CM *getConnectionManager()  
  53.     {  
  54.         return conMan;  
  55.     }  
  56.   
  57.     AVT *getAVTransport()  
  58.     {  
  59.         return avTrans;  
  60.     }  
  61.     RC *getRenderingControl()  
  62.     {  
  63.         return renderCon;  
  64.     }  
  65.     ////////////////////////////////////////////////  
  66.     //  ContentDirectory      
  67.     ////////////////////////////////////////////////  
  68.   
  69.   
  70.   
  71. public:  
  72.   
  73.     void setInterfaceAddress(const char *ifaddr)  
  74.     {  
  75.         CyberNet::SetHostInterface(ifaddr);  
  76.     }  
  77.   
  78.     const char *getInterfaceAddress()  
  79.     {  
  80.         return CyberNet::GetHostInterface();  
  81.     }             
  82.   
  83.     ////////////////////////////////////////////////  
  84.     // HttpRequestListner (Overridded)  
  85.     ////////////////////////////////////////////////  
  86.   
  87. public:  
  88.   
  89.     void httpRequestRecieved(CyberHTTP::HTTPRequest *httpReq);  
  90.   
  91.     ////////////////////////////////////////////////  
  92.     // start/stop (Overided)  
  93.     ////////////////////////////////////////////////  
  94.       
  95. public:  
  96.   
  97.     bool start()  
  98.     {  
  99.       
  100.         Device::start();  
  101.         return true;  
  102.     }  
  103.       
  104.     bool stop()  
  105.     {  
  106.           
  107.         Device::stop();  
  108.         return true;  
  109.     }  
  110.   
  111.   
  112. };  

[cpp]  view plain copy
  1. MP::MP() : Device()  
  2. {  
  3.     // Device Configuration  
  4.     loadDescription(MP::DESCRIPTION);  
  5.   
  6.     // Netwroking initialization          
  7.     UPnP::SetEnable(UPnP::USE_ONLY_IPV4_ADDR);  
  8.     string firstIf;  
  9.     GetHostAddress(0, firstIf);  
  10.     setInterfaceAddress(firstIf.c_str());  
  11.     setHTTPPort(DEFAULT_HTTP_PORT);  
  12.   
  13.     // Servce Configuration  
  14.     conMan = new CM();  
  15.   
  16.     Service *servConMan = getService(CM::SERVICE_TYPE);  
  17.     servConMan->loadSCPD(CM::DESCRIPTION);  
  18.     servConMan->setActionListener(getConnectionManager());  
  19.     servConMan->setQueryListener(getConnectionManager());  
  20.   
  21.   
  22.     avTrans= new AVT();  
  23.   
  24.     Service *servAvt = getService(AVT::SERVICE_TYPE);  
  25.     servAvt->loadSCPD(AVT::DESCRIPTION);  
  26.     servAvt->setActionListener(getAVTransport());  
  27.     servAvt->setQueryListener(getAVTransport());  
  28.   
  29.   
  30.       
  31.     renderCon= new RC();  
  32.   
  33.     Service *servRC = getService(RC::SERVICE_TYPE);  
  34.     servRC->loadSCPD(RC::DESCRIPTION);  
  35.     servRC->setActionListener(getRenderingControl());  
  36.     servRC->setQueryListener(getRenderingControl());  
  37.   
  38.       
  39. }  

5) 启动MeidaRender

[cpp]  view plain copy
  1. int main(int argc, char* argv[])  
  2. {  
  3. MP mplayer;  
  4.     Debug::on();  
  5.   
  6.     PrintMessage();  
  7.   
  8.     //MediaPlayer mplayer;  
  9.   
  10.     mplayer.start();  
  11. /* 
  12. #if !defined(WIN32) || defined(__CYGWIN__) 
  13.     kbinit(); 
  14. #endif 
  15. */  
  16.     int ch;  
  17.     do  
  18.     {  
  19. #if defined(WIN32) && !defined(__CYGWIN__)  
  20.         ch = getch();  
  21. #else  
  22.         ch = getchar();  
  23. #endif  
  24.         ch = toupper( ch );  
  25.         //if (ch == 'P')  
  26.             //PrintMediaServers(&mplayer);  
  27.     } while( ch != 'Q');  
  28.   
  29. /*#if !defined(WIN32) || defined(__CYGWIN__) 
  30.     kbexit(); 
  31. #endif 
  32. */  
  33.     mplayer.stop();  
  34.   
  35.     return 0;  
  36. }  

6)性能对比测试

在Mstar的mips处理器上运行后,设备发现速度比JAVA版本cyberlink要快,通过Intel的测试工具(Intel AV Media Controller)能快速发现到设备


你可能感兴趣的:(基于Linux电视棒实现DLNA和airplay功能)