ADDON_STATUS ADDON_Create(void* hdl, void* props) { XVDR::MutexLock lock(&addonMutex); if (!hdl || !props) return ADDON_STATUS_UNKNOWN; XBMC = new CHelper_libXBMC_addon; if (!XBMC->RegisterMe(hdl)) { ADDON_Cleanup(); return ADDON_STATUS_UNKNOWN; } GUI = new CHelper_libXBMC_gui; if (!GUI->RegisterMe(hdl)) return ADDON_STATUS_UNKNOWN; PVR = new CHelper_libXBMC_pvr; if (!PVR->RegisterMe(hdl)) { ADDON_Cleanup(); return ADDON_STATUS_UNKNOWN; } CODEC = new CHelper_libXBMC_codec; if (!CODEC->RegisterMe(hdl)) { ADDON_Cleanup(); return ADDON_STATUS_UNKNOWN; } XBMC->Log(LOG_DEBUG, "Creating VDR XVDR PVR-Client"); cXBMCSettings& s = cXBMCSettings::GetInstance(); s.load(); mClient = new cXBMCClient; mClient->SetTimeout(s.ConnectTimeout() * 1000); mClient->SetCompressionLevel(s.Compression() * 3); mClient->SetAudioType(s.AudioType()); TimeMs RetryTimeout; bool bConnected = false; while (!(bConnected = mClient->Open(s.Hostname())) && RetryTimeout.Elapsed() < (uint32_t)s.ConnectTimeout() * 1000) XVDR::CondWait::SleepMs(100); if (!bConnected){ ADDON_Cleanup(); return ADDON_STATUS_LOST_CONNECTION; } if (!mClient->EnableStatusInterface(s.HandleMessages())) { return ADDON_STATUS_LOST_CONNECTION; } mClient->ChannelFilter(s.FTAChannels(), s.NativeLangOnly(), s.vcaids); mClient->SetUpdateChannels(s.UpdateChannels()); PVR_MENUHOOK hook; // add menuhook if scanning is supported if(mClient->SupportChannelScan()) { hook.category = PVR_MENUHOOK_SETTING; hook.iHookId = XVDR_HOOK_SETTINGS_CHANNELSCAN; hook.iLocalizedStringId = 30008; PVR->AddMenuHook(&hook); } return ADDON_STATUS_OK; }
int main(int argc, char* argv[]) { std::string hostname = "192.168.16.10"; int channel_number = 1; if(argc >= 2) { hostname = argv[1]; } if(argc >= 3) { channel_number = atoi(argv[2]); } ConsoleClient client; if(!client.Open(hostname, "Demux test client")) { client.Log(FAILURE,"Unable to open connection !"); return 1; } if(!client.EnableStatusInterface(true)) { client.Log(FAILURE,"Unable to enable status interface !"); return 1; } client.Log(INFO, "Fetching channels .."); client.GetChannelsList(); client.Log(INFO, "Got %i channels.", client.m_channels.size()); Channel c = client.m_channels[channel_number]; Demux demux(&client); TimeMs t; client.Log(INFO, "Opening channel #%i (%s)", channel_number, c.Name.c_str()); if(demux.OpenChannel(hostname, c.UID) != Demux::SC_OK) { client.Log(FAILURE, "Unable to open channel !"); return 1; } ConsoleClient::Packet* p = NULL; int firstVideoPacket = 0; int firstPacket = 0; int switchTime = t.Elapsed(); client.Log(INFO, "Switched to channel after %i ms", switchTime); for(int i = 0; i < 100; i++) { p = demux.Read<ConsoleClient::Packet>(); if(p == NULL) { break; } if(p->data != NULL) { if(firstPacket == 0) { firstPacket = t.Elapsed(); client.Log(INFO, "Received first packet after %i ms", firstPacket); } if(firstVideoPacket == 0 && p->index == 0) { firstVideoPacket = t.Elapsed(); client.Log(INFO, "Received first video packet after %i ms", firstVideoPacket); } uint32_t header = p->data[0] << 24 | p->data[1] << 16 | p->data[2] << 8 | p->data[3]; client.Log(INFO, "Demux (index: %i length: %i bytes) Header: %08X PTS: %lli", p->index, p->length, header, p->pts); } client.FreePacket(p); } client.Log(INFO, "Stopping ..."); t.Set(0); // wait for pending notifications if(p == NULL) { CondWait::SleepMs(5000); } demux.CloseChannel(); client.Close(); int stopTime = t.Elapsed(); client.Log(INFO, ""); client.Log(INFO, "Stream summary:"); client.Log(INFO, "Channel: %i - %s", channel_number, c.Name.c_str()); client.Log(INFO, "Switch time: %i ms", switchTime); client.Log(INFO, "First packet after: %i ms", firstPacket); client.Log(INFO, "First video after: %i ms", firstVideoPacket); return 0; }