Starting point:If Android TV sticks use the Java cyberlink to implement the dlna function, the disadvantages are obvious. SSDP Protocol devices may experience poor experience (sometimes unable to detect devices, the Linux TV stick can control the hardware cost less than 100 RMB, and the cyberlink dlna protocol stack implemented by C language does not exist and cannot be found by devices. This article records a package of problems encountered in implementing dlna in Linux.
1. DMR solution of dlna
Solution 1: mediagateforcc (http://www.cybergarage.org/twiki/bin/view/Main/MediaGateForCC) Cross-compilation, Player Based on gstreamer
The cyberlink protocol stack depends on the XML library. You can select xerces and libxml2. xerces is a large XML parsing library provided by apatch, which is not considered by embedded devices.
1) Compile 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) Compile 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
Error 1: In libxml2parser. cpp, change node * newchildnode = converttoclinkformat (Doc, child, depth 1) to node * newchildnode = converttoclinkformat (Doc, child, depth );
Error 2: Device ** Dev = new (device (* [devcnt]) in controlpoint. cpp; change to device ** Dev = new device * [devcnt];
Compiled successfully
3) The avtransport and renderingcontrol services of media Renderer are not implemented in cyberlink. Below are the supplemental avtransport .. h and renderingcontrol. h
class AVT : public ActionListener, public QueryListener{CyberUtil::Mutex mutex;int maxConnectionID;////////////////////////////////////////////////// Constants////////////////////////////////////////////////public:static const char *DESCRIPTION;static const char *SERVICE_TYPE;static const char * TRANSPORTSTATE ;staticconst char * TRANSPORTSTATUS ;staticconst char * PLAYBACKSTORAGEMEDIUM;staticconst char * RECORDSTORAGEMEDIUM;staticconst char * POSSIBLEPLAYBACKSTORAGEMEDIA;staticconst char * POSSIBLERECORDSTORAGEMEDIA;staticconst char * CURRENTPLAYMODE ;staticconst char * TRANSPORTPLAYSPEED;staticconst char * RECORDMEDIUMWRITESTATUS ;staticconst char * CURRENTRECORDQUALITYMODE ;staticconst char * POSSIBLERECORDQUALITYMODES;staticconst char * NUMBEROFTRACKS;staticconst char * CURRENTTRACK;staticconst char * CURRENTTRACKDURATION;staticconst char * CURRENTMEDIADURATION;staticconst char * CURRENTTRACKMETADATA;staticconst char * CURRENTTRACKURI;staticconst char * AVTRANSPORTURI;staticconst char * AVTRANSPORTURIMETADATA ;staticconst char * NEXTAVTRANSPORTURI;staticconst char * NEXTAVTRANSPORTURIMETADATA;staticconst char * RELATIVETIMEPOSITION;staticconst char * ABSOLUTETIMEPOSITION;staticconst char * RELATIVECOUNTERPOSITION ;staticconst char * ABSOLUTECOUNTERPOSITION ;staticconst char * CURRENTTRANSPORTACTIONS;staticconst char * LASTCHANGE;staticconst char * SETAVTRANSPORTURI;staticconst char * INSTANCEID;staticconst char * CURRENTURI;staticconst char * CURRENTURIMETADATA;staticconst char * SETNEXTAVTRANSPORTURI;staticconst char * NEXTURI;staticconst char * NEXTURIMETADATA ;staticconst char * GETMEDIAINFO;staticconst char * NRTRACKS;staticconst char * MEDIADURATION;staticconst char * PLAYMEDIUM ;staticconst char * RECORDMEDIUM ;staticconst char * WRITESTATUS ;staticconst char * GETTRANSPORTINFO ;staticconst char * CURRENTTRANSPORTSTATE;staticconst char * CURRENTTRANSPORTSTATUS ;staticconst char * CURRENTSPEED ;staticconst char * GETPOSITIONINFO;staticconst char * TRACK;staticconst char * TRACKDURATION;staticconst char * TRACKMETADATA ;staticconst char * TRACKURI ;staticconst char * RELTIME;staticconst char * ABSTIME;staticconst char * RELCOUNT;staticconst char * ABSCOUNT;staticconst char * GETDEVICECAPABILITIES;staticconst char * PLAYMEDIA ;staticconst char * RECMEDIA ;staticconst char * RECQUALITYMODES;staticconst char * GETTRANSPORTSETTINGS;staticconst char * PLAYMODE ;staticconst char * RECQUALITYMODE ;staticconst char * STOP;staticconst char * PLAY;staticconst char * SPEED ;staticconst char * PAUSE;staticconst char * RECORD ;staticconst char * SEEK ;staticconst char * UNIT;staticconst char * TARGET ;staticconst char * NEXT ;staticconst char * PREVIOUS ;staticconst char * SETPLAYMODE ;staticconst char * NEWPLAYMODE ;staticconst char * SETRECORDQUALITYMODE ;staticconst char * NEWRECORDQUALITYMODE ;staticconst char * GETCURRENTTRANSPORTACTIONS;staticconst char * ACTIONS;staticconst char * STOPPED ;staticconst char * PLAYING ;staticconst char * OK;staticconst char * ERROR_OCCURRED ;staticconst char * NORMAL ;staticconst char * TRACK_NR ;////////////////////////////////////////////////// Constructor ////////////////////////////////////////////////public:AVT();virtual ~AVT();public:void lock(){mutex.lock();}void unlock(){mutex.unlock();}////////////////////////////////////////////////// ConnectionID////////////////////////////////////////////////////////////////////////////////////////////////// ActionListener////////////////////////////////////////////////public:bool actionControlReceived(Action *action);public:bool queryControlReceived(StateVariable *stateVar);};
Renderingcontrol service class
class RC : public ActionListener, public QueryListener{CyberUtil::Mutex mutex;int maxConnectionID;////////////////////////////////////////////////// Constants////////////////////////////////////////////////public:static const char *DESCRIPTION;static const char *SERVICE_TYPE;static const char *PRESETNAMELIST ;static const char *LASTCHANGE ;static const char *BRIGHTNESS;static const char *CONTRAST ;static const char *SHARPNESS ;static const char *REDVIDEOGAIN;static const char *GREENVIDEOGAIN ;static const char *BLUEVIDEOGAIN ;static const char *REDVIDEOBLACKLEVEL;static const char *GREENVIDEOBLACKLEVEL ;static const char *BLUEVIDEOBLACKLEVEL ;static const char *COLORTEMPERATURE ;static const char *HORIZONTALKEYSTONE ;static const char *VERTICALKEYSTONE ;static const char *MUTE ;static const char *VOLUME ;static const char *VOLUMEDB ;static const char *LOUDNESS ;static const char *LISTPRESETS;static const char *INSTANCEID ;static const char *CURRENTPRESETNAMELIST;static const char *SELECTPRESET;static const char *PRESETNAME;static const char *GETBRIGHTNESS;static const char *CURRENTBRIGHTNESS ;static const char *SETBRIGHTNESS;static const char *DESIREDBRIGHTNESS;static const char *GETCONTRAST;static const char *CURRENTCONTRAST;static const char *SETCONTRAST;static const char *DESIREDCONTRAST;static const char *GETSHARPNESS;static const char *CURRENTSHARPNESS;static const char *SETSHARPNESS;static const char *DESIREDSHARPNESS;static const char *GETREDVIDEOGAIN;static const char *CURRENTREDVIDEOGAIN;static const char *SETREDVIDEOGAIN;static const char *DESIREDREDVIDEOGAIN ;static const char *GETGREENVIDEOGAIN;static const char *CURRENTGREENVIDEOGAIN;static const char *SETGREENVIDEOGAIN ;static const char *DESIREDGREENVIDEOGAIN ;static const char *GETBLUEVIDEOGAIN ;static const char *CURRENTBLUEVIDEOGAIN ;static const char *SETBLUEVIDEOGAIN;static const char *DESIREDBLUEVIDEOGAIN ;static const char *GETREDVIDEOBLACKLEVEL ;static const char *CURRENTREDVIDEOBLACKLEVEL ;static const char *SETREDVIDEOBLACKLEVEL;static const char *DESIREDREDVIDEOBLACKLEVEL;static const char *GETGREENVIDEOBLACKLEVEL;static const char *CURRENTGREENVIDEOBLACKLEVEL;static const char *SETGREENVIDEOBLACKLEVEL;static const char *DESIREDGREENVIDEOBLACKLEVEL;static const char *GETBLUEVIDEOBLACKLEVEL;static const char *CURRENTBLUEVIDEOBLACKLEVEL;static const char *SETBLUEVIDEOBLACKLEVEL;static const char *DESIREDBLUEVIDEOBLACKLEVEL;static const char *GETCOLORTEMPERATURE ;static const char *CURRENTCOLORTEMPERATURE;static const char *SETCOLORTEMPERATURE;static const char *DESIREDCOLORTEMPERATURE;static const char *GETHORIZONTALKEYSTONE;static const char *CURRENTHORIZONTALKEYSTONE;static const char *SETHORIZONTALKEYSTONE;static const char *DESIREDHORIZONTALKEYSTONE;static const char *GETVERTICALKEYSTONE;static const char *CURRENTVERTICALKEYSTONE;static const char *SETVERTICALKEYSTONE;static const char *DESIREDVERTICALKEYSTONE;static const char *GETMUTE ;static const char *CHANNEL;static const char *CURRENTMUTE ;static const char *SETMUTE;static const char *DESIREDMUTE;static const char *GETVOLUME;static const char *CURRENTVOLUME ;static const char *SETVOLUME ;static const char *DESIREDVOLUME ;static const char *GETVOLUMEDB ;static const char *SETVOLUMEDB;static const char *GETVOLUMEDBRANGE ;static const char *MINVALUE;static const char *MAXVALUE;static const char *GETLOUDNESS ;static const char *CURRENTLOUDNESS;static const char *SETLOUDNESS ;static const char *DESIREDLOUDNESS;static const char *MASTER ;static const char *FACTORYDEFAULTS ;public:RC();virtual ~RC();public:void lock(){mutex.lock();}void unlock(){mutex.unlock();}////////////////////////////////////////////////// ConnectionID////////////////////////////////////////////////public:bool actionControlReceived(Action *action);public:bool queryControlReceived(StateVariable *stateVar);};
4) Implementation of mediarender
Mediarender is mainly used to implement the connectionmanager, avtransport, and renderingcontrol services.
class MP : public Device{CM *conMan;AVT *avTrans;RC *renderCon;////////////////////////////////////////////////// Constants////////////////////////////////////////////////public:static const char *DEVICE_TYPE;static const int DEFAULT_HTTP_PORT;static const char *DESCRIPTION;////////////////////////////////////////////////// Constructor////////////////////////////////////////////////public:MP();~MP();//////////////////////////////////////////////////setName////////////////////////////////////////////////public:void setName(const char *name){setFriendlyName(name);}const char *getName(){getFriendlyName();}////////////////////////////////////////////////// Memeber////////////////////////////////////////////////public:CM *getConnectionManager(){return conMan;}AVT *getAVTransport(){return avTrans;}RC *getRenderingControl(){return renderCon;}//////////////////////////////////////////////////ContentDirectory////////////////////////////////////////////////public:void setInterfaceAddress(const char *ifaddr){CyberNet::SetHostInterface(ifaddr);}const char *getInterfaceAddress(){return CyberNet::GetHostInterface();}////////////////////////////////////////////////// HttpRequestListner (Overridded)////////////////////////////////////////////////public:void httpRequestRecieved(CyberHTTP::HTTPRequest *httpReq);////////////////////////////////////////////////// start/stop (Overided)////////////////////////////////////////////////public:bool start(){Device::start();return true;}bool stop(){Device::stop();return true;}};
MP::MP() : Device(){// Device ConfigurationloadDescription(MP::DESCRIPTION);// Netwroking initializationUPnP::SetEnable(UPnP::USE_ONLY_IPV4_ADDR);string firstIf;GetHostAddress(0, firstIf);setInterfaceAddress(firstIf.c_str());setHTTPPort(DEFAULT_HTTP_PORT);// Servce ConfigurationconMan = new CM();Service *servConMan = getService(CM::SERVICE_TYPE);servConMan->loadSCPD(CM::DESCRIPTION);servConMan->setActionListener(getConnectionManager());servConMan->setQueryListener(getConnectionManager());avTrans= new AVT();Service *servAvt = getService(AVT::SERVICE_TYPE);servAvt->loadSCPD(AVT::DESCRIPTION);servAvt->setActionListener(getAVTransport());servAvt->setQueryListener(getAVTransport());renderCon= new RC();Service *servRC = getService(RC::SERVICE_TYPE);servRC->loadSCPD(RC::DESCRIPTION);servRC->setActionListener(getRenderingControl());servRC->setQueryListener(getRenderingControl());}
5) Start meidarender
int main(int argc, char* argv[]){MP mplayer;Debug::on();PrintMessage();//MediaPlayer mplayer;mplayer.start();/*#if !defined(WIN32) || defined(__CYGWIN__)kbinit();#endif*/int ch;do{#if defined(WIN32) && !defined(__CYGWIN__)ch = getch();#elsech = getchar();#endifch = toupper( ch );//if (ch == 'P')//PrintMediaServers(&mplayer);} while( ch != 'Q');/*#if !defined(WIN32) || defined(__CYGWIN__)kbexit();#endif*/mplayer.stop();return 0;}
6) Performance Comparison Test
After running on the mstar MIPS processor, the device discovery speed is faster than that of the Java version cyberlink. The device can be quickly discovered through Intel's test tool (Intel AV Media Controller ).