From 43d4d88e40827ea9b03c0761a7d06c4bfa1d672e Mon Sep 17 00:00:00 2001 From: focus Date: Sun, 30 Jan 2011 14:00:26 +0000 Subject: [PATCH] Testing pmt update while recording fix git-svn-id: file:///home/bas/coolstream_public_svn/THIRDPARTY/applications/neutrino-experimental@1095 e54a6e83-5905-42d5-8d5c-058d10e6a962 --- src/daemonc/remotecontrol.cpp | 5 + src/driver/rcinput.cpp | 4 + src/driver/stream2file.cpp | 21 ++ src/driver/stream2file.h | 4 + src/driver/vcrcontrol.cpp | 298 ++++++++++--------- src/driver/vcrcontrol.h | 43 ++- src/driver/vfd.cpp | 2 +- src/gui/infoviewer.cpp | 6 +- src/neutrino.cpp | 40 ++- src/neutrinoMessages.h | 5 +- src/zapit/include/zapit/client/zapitclient.h | 1 + src/zapit/src/zapit.cpp | 26 +- 12 files changed, 279 insertions(+), 176 deletions(-) diff --git a/src/daemonc/remotecontrol.cpp b/src/daemonc/remotecontrol.cpp index 7b6ba997e..35e52189b 100644 --- a/src/daemonc/remotecontrol.cpp +++ b/src/daemonc/remotecontrol.cpp @@ -296,6 +296,11 @@ int CRemoteControl::handleMsg(const neutrino_msg_t msg, neutrino_msg_data_t data } return messages_return::handled; } + else if (msg == NeutrinoMessages::EVT_PMT_CHANGED) { + g_Zapit->getPIDS(current_PIDs); + processAPIDnames(); + return messages_return::unhandled; + } else if (msg == NeutrinoMessages::EVT_ZAP_ISNVOD) { if ((*(t_channel_id *)data) == current_channel_id) diff --git a/src/driver/rcinput.cpp b/src/driver/rcinput.cpp index 68f755010..b53b43244 100644 --- a/src/driver/rcinput.cpp +++ b/src/driver/rcinput.cpp @@ -1015,6 +1015,10 @@ printf("[neutrino] CSectionsdClient::EVT_GOT_CN_EPG\n"); *msg = NeutrinoMessages::EVT_SERVICES_UPD; *data = 0; break; + case CZapitClient::EVT_PMT_CHANGED: + *msg = NeutrinoMessages::EVT_PMT_CHANGED; + *data = 0; + break; default: printf("[neutrino] event INITID_ZAPIT - unknown eventID 0x%x\n", emsg.eventID ); } diff --git a/src/driver/stream2file.cpp b/src/driver/stream2file.cpp index 7dfab8807..ef87e873c 100644 --- a/src/driver/stream2file.cpp +++ b/src/driver/stream2file.cpp @@ -195,3 +195,24 @@ stream2file_error_msg_t stop_recording(const char * const info) return ret; } +stream2file_error_msg_t update_recording(const char * const info, const unsigned short vpid, + const unsigned short * const pids, const unsigned int numpids) +{ + stream2file_error_msg_t ret; + char buf[FILENAMEBUFFERSIZE]; + int fd; + + sprintf(buf, "%s.xml", rec_filename); + if ((fd = open(buf, O_SYNC | O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) >= 0) { + write(fd, info, strlen(info)); + fdatasync(fd); + close(fd); + } + if(record) + record->ChangePids((unsigned short) vpid, (unsigned short *) pids, numpids); + + if(g_current_channel) + cam0->setCaPmt(g_current_channel->getCaPmt(), DEMUX_SOURCE_0, cam0->getCaMask() | DEMUX_DECODE_0 | DEMUX_DECODE_2, true); + + return ret; +} diff --git a/src/driver/stream2file.h b/src/driver/stream2file.h index 909fa8600..059bca9d4 100644 --- a/src/driver/stream2file.h +++ b/src/driver/stream2file.h @@ -55,5 +55,9 @@ stream2file_error_msg_t start_recording(const char * const filename, const unsigned short * const apids, const unsigned int numpids); stream2file_error_msg_t stop_recording(const char * const info); +stream2file_error_msg_t update_recording(const char * const info, + const unsigned short vpid, + const unsigned short * const apids, + const unsigned int numpids); #endif diff --git a/src/driver/vcrcontrol.cpp b/src/driver/vcrcontrol.cpp index eedd9002d..5b212ab99 100644 --- a/src/driver/vcrcontrol.cpp +++ b/src/driver/vcrcontrol.cpp @@ -55,7 +55,6 @@ #include #include -//#include #include #include @@ -73,7 +72,7 @@ extern "C" { #include } -t_channel_id rec_channel_id; +extern t_channel_id rec_channel_id; static CVCRControl vcrControl; @@ -132,14 +131,22 @@ MI_MOVIE_INFO * CVCRControl::GetMovieInfo(void) bool CVCRControl::GetPids(unsigned short *vpid, unsigned short *vtype, unsigned short *apid, unsigned short *atype, unsigned short * apidnum, unsigned short * apids, unsigned short * atypes) { if(Device) { - *vpid = Device->rec_vpid; - *vtype = Device->rec_vtype; - *apid = Device->rec_currentapid; - *atype = Device->rec_currentac3; - *apidnum = Device->rec_numpida; - for(int i = 0; i < Device->rec_numpida; i++) { - apids[i] = Device->rec_apids[i]; - atypes[i] = Device->rec_ac3flags[i]; + if(vpid) + *vpid = Device->rec_vpid; + if(vtype) + *vtype = Device->rec_vtype; + if(apid) + *apid = Device->rec_currentapid; + if(atype) + *atype = Device->rec_currentac3; + if(apidnum) { + *apidnum = Device->rec_numpida; + for(int i = 0; i < Device->rec_numpida; i++) { + if(apids) + apids[i] = Device->rec_apids[i]; + if(atypes) + atypes[i] = Device->rec_ac3flags[i]; + } } return true; } @@ -147,102 +154,84 @@ bool CVCRControl::GetPids(unsigned short *vpid, unsigned short *vtype, unsigned } //------------------------------------------------------------------------- -void CVCRControl::CDevice::getAPIDs(const unsigned char ap, APIDList & apid_list) +void CVCRControl::CDevice::getAPIDs(const unsigned char _apidmode, APIDList & apid_list) { -// (strstr(g_RemoteControl->current_PIDs.APIDs[i].desc, "(AC3)") == NULL)) - unsigned char apids=ap; - if (apids == TIMERD_APIDS_CONF) - apids = g_settings.recording_audio_pids_default; + unsigned char apidmode = _apidmode; + + if (apidmode == TIMERD_APIDS_CONF) + apidmode = g_settings.recording_audio_pids_default; + apid_list.clear(); - CZapitClient::responseGetPIDs allpids; + //CZapitClient::responseGetPIDs allpids; g_Zapit->getPIDS(allpids); + // assume smallest apid ist std apid - if (apids & TIMERD_APIDS_STD) - { + if (apidmode & TIMERD_APIDS_STD) { uint32_t apid_min=UINT_MAX; uint32_t apid_min_idx=0; - for(unsigned int i = 0; i < allpids.APIDs.size(); i++) - { - if (allpids.APIDs[i].pid < apid_min && !allpids.APIDs[i].is_ac3) - { + for(unsigned int i = 0; i < allpids.APIDs.size(); i++) { + if (allpids.APIDs[i].pid < apid_min && !allpids.APIDs[i].is_ac3) { apid_min = allpids.APIDs[i].pid; apid_min_idx = i; } } - if (apid_min != UINT_MAX) - { + if (apid_min != UINT_MAX) { APIDDesc a = {apid_min, apid_min_idx, false}; apid_list.push_back(a); } } - if (apids & TIMERD_APIDS_ALT) - { + if (apidmode & TIMERD_APIDS_ALT) { uint32_t apid_min=UINT_MAX; uint32_t apid_min_idx=0; - for(unsigned int i = 0; i < allpids.APIDs.size(); i++) - { - if (allpids.APIDs[i].pid < apid_min && !allpids.APIDs[i].is_ac3) - { + for(unsigned int i = 0; i < allpids.APIDs.size(); i++) { + if (allpids.APIDs[i].pid < apid_min && !allpids.APIDs[i].is_ac3) { apid_min = allpids.APIDs[i].pid; apid_min_idx = i; } } - for(unsigned int i = 0; i < allpids.APIDs.size(); i++) - { - if (allpids.APIDs[i].pid != apid_min && !allpids.APIDs[i].is_ac3) - { + for(unsigned int i = 0; i < allpids.APIDs.size(); i++) { + if (allpids.APIDs[i].pid != apid_min && !allpids.APIDs[i].is_ac3) { APIDDesc a = {allpids.APIDs[i].pid, i, false}; apid_list.push_back(a); } } } - if (apids & TIMERD_APIDS_AC3) - { + if (apidmode & TIMERD_APIDS_AC3) { bool ac3_found=false; - for(unsigned int i = 0; i < allpids.APIDs.size(); i++) - { - if (allpids.APIDs[i].is_ac3) - { + for(unsigned int i = 0; i < allpids.APIDs.size(); i++) { + if (allpids.APIDs[i].is_ac3) { APIDDesc a = {allpids.APIDs[i].pid, i, true}; apid_list.push_back(a); ac3_found=true; } } // add non ac3 apid if ac3 not found - if (!(apids & TIMERD_APIDS_STD) && !ac3_found) - { + if (!(apidmode & TIMERD_APIDS_STD) && !ac3_found) { uint32_t apid_min=UINT_MAX; uint32_t apid_min_idx=0; - for(unsigned int i = 0; i < allpids.APIDs.size(); i++) - { - if (allpids.APIDs[i].pid < apid_min && !allpids.APIDs[i].is_ac3) - { + for(unsigned int i = 0; i < allpids.APIDs.size(); i++) { + if (allpids.APIDs[i].pid < apid_min && !allpids.APIDs[i].is_ac3) { apid_min = allpids.APIDs[i].pid; apid_min_idx = i; } } - if (apid_min != UINT_MAX) - { + if (apid_min != UINT_MAX) { APIDDesc a = {apid_min, apid_min_idx, false}; apid_list.push_back(a); } } } // no apid selected use standard - if (apid_list.empty() && !allpids.APIDs.empty()) - { + if (apid_list.empty() && !allpids.APIDs.empty()) { uint32_t apid_min=UINT_MAX; uint32_t apid_min_idx=0; - for(unsigned int i = 0; i < allpids.APIDs.size(); i++) - { - if (allpids.APIDs[i].pid < apid_min && !allpids.APIDs[i].is_ac3) - { + for(unsigned int i = 0; i < allpids.APIDs.size(); i++) { + if (allpids.APIDs[i].pid < apid_min && !allpids.APIDs[i].is_ac3) { apid_min = allpids.APIDs[i].pid; apid_min_idx = i; } } - if (apid_min != UINT_MAX) - { + if (apid_min != UINT_MAX) { APIDDesc a = {apid_min, apid_min_idx, false}; apid_list.push_back(a); } @@ -266,44 +255,38 @@ bool CVCRControl::CVCRDevice::Stop() } //------------------------------------------------------------------------- -bool CVCRControl::CVCRDevice::Record(const t_channel_id channel_id, int mode, const event_id_t epgid, const std::string& /*epgTitle*/, unsigned char apids, const time_t /*epg_time*/) +bool CVCRControl::CVCRDevice::Record(const t_channel_id channel_id, int mode, const event_id_t epgid, const std::string& /*epgTitle*/, unsigned char apidmode, const time_t /*epg_time*/) { - printf("Record channel_id: " PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS " epg: %llx, apids 0x%X mode \n", - channel_id, epgid, apids); + printf("Record channel_id: " PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS " epg: %llx, apidmode 0x%X mode \n", + channel_id, epgid, apidmode); + // leave menu (if in any) g_RCInput->postMsg( CRCInput::RC_timeout, 0 ); last_mode = CNeutrinoApp::getInstance()->getMode(); - if(mode != last_mode) { + if(mode != last_mode) CNeutrinoApp::getInstance()->handleMsg( NeutrinoMessages::CHANGEMODE , mode | NeutrinoMessages::norezap ); - } - if(channel_id != 0) // wenn ein channel angegeben ist - { - if(g_Zapit->getCurrentServiceID() != channel_id) // und momentan noch nicht getuned ist - { - g_Zapit->zapTo_serviceID(channel_id); // dann umschalten - } + if(channel_id != 0) { + if(g_Zapit->getCurrentServiceID() != channel_id) + g_Zapit->zapTo_serviceID(channel_id); } - if(! (apids & TIMERD_APIDS_STD)) // nicht std apid - { + if(! (apidmode & TIMERD_APIDS_STD)) { APIDList apid_list; - getAPIDs(apids,apid_list); - if(!apid_list.empty()) - { + getAPIDs(apidmode,apid_list); + if(!apid_list.empty()) { if(!apid_list.begin()->ac3) g_Zapit->setAudioChannel(apid_list.begin()->index); else - g_Zapit->setAudioChannel(0); //sonst apid 0, also auf jeden fall ac3 aus ! + g_Zapit->setAudioChannel(0); } else - g_Zapit->setAudioChannel(0); //sonst apid 0, also auf jeden fall ac3 aus ! + g_Zapit->setAudioChannel(0); } else - g_Zapit->setAudioChannel(0); //sonst apid 0, also auf jeden fall ac3 aus ! + g_Zapit->setAudioChannel(0); - if(SwitchToScart) - { + if(SwitchToScart) { // Auf Scart schalten CNeutrinoApp::getInstance()->handleMsg( NeutrinoMessages::VCR_ON, 0 ); // Das ganze nochmal in die queue, da obiges RC_timeout erst in der naechsten ev. loop ausgeführt wird @@ -312,19 +295,7 @@ bool CVCRControl::CVCRDevice::Record(const t_channel_id channel_id, int mode, co } deviceState = CMD_VCR_RECORD; - // Send IR - return true; -} -//------------------------------------------------------------------------- -bool CVCRControl::CVCRDevice::Pause() -{ - return true; -} - -//------------------------------------------------------------------------- -bool CVCRControl::CVCRDevice::Resume() -{ return true; } @@ -385,7 +356,7 @@ void CVCRControl::CFileAndServerDevice::CutBackNeutrino(const t_channel_id chann bool sectionsd_getEPGidShort(event_id_t epgID, CShortEPGData * epgdata); bool sectionsd_getEPGid(const event_id_t epgID, const time_t startzeit, CEPGData * epgdata); -std::string CVCRControl::CFileAndServerDevice::getCommandString(const CVCRCommand command, const t_channel_id channel_id, const event_id_t epgid, const std::string& epgTitle, unsigned char apids) +std::string CVCRControl::CFileAndServerDevice::getCommandString(const CVCRCommand command, const t_channel_id channel_id, const event_id_t epgid, const std::string& epgTitle, unsigned char apidmode) { char tmp[40]; std::string apids_selected; @@ -426,7 +397,7 @@ std::string CVCRControl::CFileAndServerDevice::getCommandString(const CVCRComman CZapitClient::CCurrentServiceInfo si = g_Zapit->getCurrentServiceInfo (); APIDList apid_list; - getAPIDs(apids,apid_list); + getAPIDs(apidmode,apid_list); apids_selected=""; for(APIDList::iterator it = apid_list.begin(); it != apid_list.end(); it++) { @@ -517,12 +488,9 @@ bool CVCRControl::CFileDevice::Stop() if(recMovieInfo && cMovieInfo) { // recMovieInfo->length = (end_time - start_time) / 60; recMovieInfo->length = (int) round((double) (end_time - start_time) / (double) 60); -//printf("[direct] stop recording 1\n"); fflush(stdout); cMovieInfo->encodeMovieInfoXml(&extMessage, recMovieInfo); -//printf("[direct] stop recording 2\n"); fflush(stdout); } bool return_value = (::stop_recording(extMessage.c_str()) == STREAM2FILE_OK); -//printf("[direct] stop recording 3\n"); fflush(stdout); RestoreNeutrino(); @@ -541,45 +509,48 @@ bool CVCRControl::CFileDevice::Stop() return return_value; } -std::string ext_channel_name; -bool CVCRControl::CFileDevice::Record(const t_channel_id channel_id, int mode, const event_id_t epgid, const std::string& epgTitle, unsigned char apids, const time_t epg_time) +bool CVCRControl::CFileDevice::Record(const t_channel_id channel_id, int mode, const event_id_t epgid, const std::string& epgTitle, unsigned char apidmode, const time_t epg_time) { -printf("Record channel_id: " PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS " epg: %llx, apids 0x%X mode %d\n", - channel_id, epgid, apids, mode); + std::string ext_channel_name; + unsigned short apids[REC_MAX_PIDS]; + unsigned int numpids = 0; + unsigned int pos; + char filename[512]; // UTF-8 + + printf("Record channel_id: " PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS " epg: %llx, apidmode 0x%X mode %d\n", + channel_id, epgid, apidmode, mode); CutBackNeutrino(channel_id, mode); -#define MAXPIDS 64 - unsigned short pids[MAXPIDS]; - unsigned int numpids; - unsigned int pos; + apids_mode = apidmode; CZapitClient::CCurrentServiceInfo si = g_Zapit->getCurrentServiceInfo(); - numpids = 0; if (si.vpid != 0) transfer_pids(si.vpid, si.vtype ? EN_TYPE_AVC : EN_TYPE_VIDEO, 0); APIDList apid_list; - getAPIDs(apids,apid_list); + getAPIDs(apids_mode, apid_list); + for(APIDList::iterator it = apid_list.begin(); it != apid_list.end(); it++) { - pids[numpids++] = it->apid; + apids[numpids++] = it->apid; transfer_pids(it->apid, EN_TYPE_AUDIO, it->ac3 ? 1 : 0); } #if 0 // FIXME : why this needed ? if(!apid_list.empty()) g_Zapit->setAudioChannel(apid_list.begin()->index); #endif +#if 0 CZapitClient::responseGetPIDs allpids; g_Zapit->getPIDS(allpids); +#endif if ((StreamVTxtPid) && (si.vtxtpid != 0)) { - pids[numpids++] = si.vtxtpid; + apids[numpids++] = si.vtxtpid; } if ((StreamPmtPid) && (si.pmtpid != 0)) { - pids[numpids++] = si.pmtpid; + apids[numpids++] = si.pmtpid; } - char filename[512]; // UTF-8 // Create filename for recording pos = Directory.size(); @@ -608,7 +579,6 @@ printf("Record channel_id: " PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS " epg: %llx int res = stat(filename,&statInfo); if (res == -1) { if (errno == ENOENT) { - //res = mkdir(filename,0755); res = safe_mkdir(filename); if (res == 0) { strcat(filename,"/"); @@ -656,7 +626,7 @@ printf("Record channel_id: " PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS " epg: %llx start_time = time(0); stream2file_error_msg_t error_msg = ::start_recording(filename, getMovieInfoString(CMD_VCR_RECORD, channel_id, epgid, epgTitle, apid_list, epg_time).c_str(), - si.vpid, pids, numpids); + si.vpid, apids, numpids); if (error_msg == STREAM2FILE_OK) { deviceState = CMD_VCR_RECORD; @@ -677,6 +647,70 @@ printf("Record channel_id: " PRINTF_CHANNEL_ID_TYPE_NO_LEADING_ZEROS " epg: %llx } } +bool CVCRControl::CFileDevice::Update(void) +{ + EPG_AUDIO_PIDS audio_pids; + std::string extMessage; + //unsigned short apids[REC_MAX_PIDS]; + //unsigned int numpids = 0; + APIDList apid_list; + APIDList::iterator it; + bool update = false; + + if(!recMovieInfo || !cMovieInfo) + return false; + + getAPIDs(apids_mode, apid_list); + CZapitClient::CCurrentServiceInfo si = g_Zapit->getCurrentServiceInfo (); + + g_RemoteControl->current_PIDs = allpids; + g_RemoteControl->processAPIDnames(); + + for(it = apid_list.begin(); it != apid_list.end(); it++) { + bool found = false; + for(unsigned int i = 0; i < rec_numpida; i++) { + if(rec_apids[i] == it->apid) { + found = true; + break; + } + } + if(!found) { + update = true; + printf("CVCRControl::CFileDevice::Update: apid %x not found in recording pids\n", it->apid); + for(unsigned int i = 0; i < allpids.APIDs.size(); i++) { + if(allpids.APIDs[i].pid == it->apid) { + audio_pids.epgAudioPid = allpids.APIDs[i].pid; + audio_pids.epgAudioPidName = ZapitTools::UTF8_to_UTF8XML(g_RemoteControl->current_PIDs.APIDs[i].desc); + audio_pids.atype = allpids.APIDs[i].is_ac3 ? 1 : allpids.APIDs[i].is_aac ? 5 : 0; + audio_pids.selected = (audio_pids.epgAudioPid == (int) rec_currentapid) ? 1 : 0; + recMovieInfo->audioPids.push_back(audio_pids); + + if(allpids.APIDs[i].is_ac3) + rec_ac3flags[rec_numpida] = 1; + if(allpids.APIDs[i].is_aac) + rec_ac3flags[rec_numpida] = 5; + + rec_apids[rec_numpida] = allpids.APIDs[i].pid; + if(rec_apids[rec_numpida] == rec_currentapid) + rec_currentac3 = allpids.APIDs[i].is_ac3 ? 1 : allpids.APIDs[i].is_aac ? 5 : 0; + rec_numpida++; + } + + } + } + } + if(!update) { + printf("CVCRControl::CFileDevice::Update: no update needed\n"); + return false; + } + + cMovieInfo->encodeMovieInfoXml(&extMessage, recMovieInfo); + /* neutrino check if vpid changed, so using 0 to disable vpid restart */ + ::update_recording(extMessage.c_str(), 0 /*si.vpid*/, rec_apids, rec_numpida); + + return true; +} + bool sectionsd_getActualEPGServiceKey(const t_channel_id uniqueServiceKey, CEPGData * epgdata); void CVCRControl::Screenshot(const t_channel_id channel_id, char * fname) @@ -765,7 +799,7 @@ bool CVCRControl::CServerDevice::Record(const t_channel_id channel_id, int mode, return false; } else { - ext_channel_name = g_Zapit->getChannelName(channel_id); + //ext_channel_name = g_Zapit->getChannelName(channel_id); return true; } } @@ -830,17 +864,18 @@ bool CVCRControl::CServerDevice::serverConnect() std::string CVCRControl::CFileAndServerDevice::getMovieInfoString(const CVCRCommand /*command*/, const t_channel_id channel_id, const event_id_t epgid, const std::string& epgTitle, APIDList apid_list, const time_t epg_time) { std::string extMessage; - std::string apids10; std::string info1, info2; + if(!cMovieInfo) cMovieInfo = new CMovieInfo(); if(!recMovieInfo) recMovieInfo = new MI_MOVIE_INFO(); cMovieInfo->clearMovieInfo(recMovieInfo); - +#if 0 CZapitClient::responseGetPIDs pids; g_Zapit->getPIDS (pids); +#endif CZapitClient::CCurrentServiceInfo si = g_Zapit->getCurrentServiceInfo (); std::string tmpstring = g_Zapit->getChannelName(channel_id); @@ -852,7 +887,6 @@ std::string CVCRControl::CFileAndServerDevice::getMovieInfoString(const CVCRComm tmpstring = "not available"; if (epgid != 0) { CEPGData epgdata; - //if (g_Sectionsd->getEPGid(epgid, epg_time, &epgdata)) { if (sectionsd_getEPGid(epgid, epg_time, &epgdata)) { tmpstring = epgdata.title; info1 = epgdata.info1; @@ -886,38 +920,38 @@ std::string CVCRControl::CFileAndServerDevice::getMovieInfoString(const CVCRComm rec_numpida = 0; EPG_AUDIO_PIDS audio_pids; - // super hack :-), der einfachste weg an die apid descriptions ranzukommen - g_RemoteControl->current_PIDs = pids; + /* super hack :-), der einfachste weg an die apid descriptions ranzukommen */ + g_RemoteControl->current_PIDs = allpids; g_RemoteControl->processAPIDnames(); APIDList::iterator it; - for(unsigned int i= 0; i< pids.APIDs.size(); i++) { + for(unsigned int i= 0; i< allpids.APIDs.size(); i++) { for(it = apid_list.begin(); it != apid_list.end(); it++) { - if(pids.APIDs[i].pid == it->apid) { - audio_pids.epgAudioPid = pids.APIDs[i].pid; + if(allpids.APIDs[i].pid == it->apid) { + audio_pids.epgAudioPid = allpids.APIDs[i].pid; audio_pids.epgAudioPidName = ZapitTools::UTF8_to_UTF8XML(g_RemoteControl->current_PIDs.APIDs[i].desc); - audio_pids.atype = pids.APIDs[i].is_ac3 ? 1 : pids.APIDs[i].is_aac ? 5 : 0; + audio_pids.atype = allpids.APIDs[i].is_ac3 ? 1 : allpids.APIDs[i].is_aac ? 5 : 0; audio_pids.selected = (audio_pids.epgAudioPid == (int) rec_currentapid) ? 1 : 0; recMovieInfo->audioPids.push_back(audio_pids); - if(pids.APIDs[i].is_ac3) - rec_ac3flags[i] = 1; - if(pids.APIDs[i].is_aac) - rec_ac3flags[i] = 5; + if(allpids.APIDs[i].is_ac3) + rec_ac3flags[rec_numpida] = 1; + if(allpids.APIDs[i].is_aac) + rec_ac3flags[rec_numpida] = 5; - rec_apids[i] = pids.APIDs[i].pid; - if(rec_apids[i] == rec_currentapid) - rec_currentac3 = pids.APIDs[i].is_ac3 ? 1 : pids.APIDs[i].is_aac ? 5 : 0; + rec_apids[rec_numpida] = allpids.APIDs[i].pid; + if(rec_apids[rec_numpida] == rec_currentapid) + rec_currentac3 = allpids.APIDs[i].is_ac3 ? 1 : allpids.APIDs[i].is_aac ? 5 : 0; rec_numpida++; } } } - //FIXME sometimes no apid in xml ?? - if(recMovieInfo->audioPids.empty() && pids.APIDs.size()) { + /* FIXME sometimes no apid in xml ?? */ + if(recMovieInfo->audioPids.empty() && allpids.APIDs.size()) { int i = 0; - audio_pids.epgAudioPid = pids.APIDs[i].pid; + audio_pids.epgAudioPid = allpids.APIDs[i].pid; audio_pids.epgAudioPidName = ZapitTools::UTF8_to_UTF8XML(g_RemoteControl->current_PIDs.APIDs[i].desc); - audio_pids.atype = pids.APIDs[i].is_ac3 ? 1 : pids.APIDs[i].is_aac ? 5 : 0; + audio_pids.atype = allpids.APIDs[i].is_ac3 ? 1 : allpids.APIDs[i].is_aac ? 5 : 0; audio_pids.selected = 1; recMovieInfo->audioPids.push_back(audio_pids); } @@ -925,7 +959,5 @@ std::string CVCRControl::CFileAndServerDevice::getMovieInfoString(const CVCRComm cMovieInfo->encodeMovieInfoXml(&extMessage, recMovieInfo); - //recMovieInfo->audioPids.clear(); - return extMessage; } diff --git a/src/driver/vcrcontrol.h b/src/driver/vcrcontrol.h index e6b003835..088d5ee58 100644 --- a/src/driver/vcrcontrol.h +++ b/src/driver/vcrcontrol.h @@ -42,6 +42,7 @@ #include #define REC_MAX_APIDS 10 +#define REC_MAX_PIDS 13 class CVCRControl { @@ -72,9 +73,10 @@ class CVCRControl virtual CVCRDevices getDeviceType(void) const = 0; CVCRStates deviceState; virtual bool Stop() = 0; - virtual bool Record(const t_channel_id channel_id = 0, int mode=1, const event_id_t epgid = 0, const std::string& epgTitle = "", unsigned char apids = 0, const time_t epg_time=0) = 0; // epg_time added for .xml (MovieBrowser) + virtual bool Record(const t_channel_id channel_id = 0, int mode=1, const event_id_t epgid = 0, const std::string& epgTitle = "", unsigned char apidmode = 0, const time_t epg_time=0) = 0; // epg_time added for .xml (MovieBrowser) virtual bool Pause() = 0; virtual bool Resume() = 0; + virtual bool Update() = 0; virtual bool IsAvailable() = 0; CDevice() { deviceState = CMD_VCR_STOP; cMovieInfo = NULL; recMovieInfo = NULL; rec_numpida = 0; rec_vpid = 0;}; virtual ~CDevice(){}; @@ -84,7 +86,7 @@ class CVCRControl bool ac3; } APIDDesc; typedef std::list APIDList; - virtual void getAPIDs(const unsigned char apids, APIDList & apid_list); + virtual void getAPIDs(const unsigned char apidmode, APIDList & apid_list); CMovieInfo * cMovieInfo; MI_MOVIE_INFO * recMovieInfo; unsigned short rec_vpid; @@ -93,6 +95,8 @@ class CVCRControl unsigned short rec_ac3flags[REC_MAX_APIDS]; unsigned short rec_numpida; unsigned short rec_currentapid, rec_currentac3; + unsigned char apids_mode; + CZapitClient::responseGetPIDs allpids; }; class CVCRDevice : public CDevice // VCR per IR @@ -105,9 +109,10 @@ class CVCRControl return DEVICE_VCR; }; virtual bool Stop(); - virtual bool Record(const t_channel_id channel_id = 0, int mode=1, const event_id_t epgid = 0, const std::string& epgTitle = "", unsigned char apids = 0, const time_t epg_time=0); // epg_time added for .xml (MovieBrowser) - virtual bool Pause(); - virtual bool Resume(); + virtual bool Record(const t_channel_id channel_id = 0, int mode=1, const event_id_t epgid = 0, const std::string& epgTitle = "", unsigned char apidmode = 0, const time_t epg_time=0); // epg_time added for .xml (MovieBrowser) + virtual bool Pause() { return false; }; + virtual bool Resume() { return false; }; + virtual bool Update() { return false; }; virtual bool IsAvailable() { return true; }; CVCRDevice(bool switchtoscart) { SwitchToScart = switchtoscart; }; virtual ~CVCRDevice(){}; @@ -118,27 +123,17 @@ class CVCRControl protected: void RestoreNeutrino(void); void CutBackNeutrino(const t_channel_id channel_id, const int mode); - std::string getCommandString(const CVCRCommand command, const t_channel_id channel_id, const event_id_t epgid, const std::string& epgTitle, unsigned char apids); + std::string getCommandString(const CVCRCommand command, const t_channel_id channel_id, const event_id_t epgid, const std::string& epgTitle, unsigned char apidmode); std::string getMovieInfoString(const CVCRCommand command, const t_channel_id channel_id,const event_id_t epgid, const std::string& epgTitle, APIDList apid_list, const time_t epg_time); public: bool StopPlayBack; bool StopSectionsd; - virtual bool Pause() - { - return false; - }; - - virtual bool Resume() - { - return false; - }; - - virtual bool IsAvailable() - { - return true; - }; + virtual bool Pause() { return false; }; + virtual bool Resume() { return false; }; + virtual bool Update() { return false; }; + virtual bool IsAvailable() { return true; }; }; class CFileDevice : public CFileAndServerDevice @@ -158,7 +153,8 @@ class CVCRControl }; virtual bool Stop(); - virtual bool Record(const t_channel_id channel_id = 0, int mode=1, const event_id_t epgid = 0, const std::string& epgTitle = "", unsigned char apids = 0, const time_t epg_time=0); // epg_time added for .xml (MovieBrowser) + virtual bool Record(const t_channel_id channel_id = 0, int mode=1, const event_id_t epgid = 0, const std::string& epgTitle = "", unsigned char apidmode = 0, const time_t epg_time=0); // epg_time added for .xml (MovieBrowser) + virtual bool Update(void); CFileDevice(const bool stopplayback, const bool stopsectionsd, const char * const directory, const unsigned int splitsize, const bool use_o_sync, const bool use_fdatasync, const bool stream_vtxt_pid, const bool stream_pmt_pid, const unsigned int ringbuffers) { @@ -183,7 +179,7 @@ class CVCRControl bool serverConnect(); void serverDisconnect(); - bool sendCommand(CVCRCommand command, const t_channel_id channel_id = 0, const event_id_t epgid = 0, const std::string& epgTitle = "", unsigned char apids = 0); + bool sendCommand(CVCRCommand command, const t_channel_id channel_id = 0, const event_id_t epgid = 0, const std::string& epgTitle = "", unsigned char apidmode = 0); public: std::string ServerAddress; @@ -195,7 +191,7 @@ class CVCRControl }; virtual bool Stop(); - virtual bool Record(const t_channel_id channel_id = 0, int mode=1, const event_id_t epgid = 0, const std::string& epgTitle = "", unsigned char apids = 0, const time_t epg_time=0); // epg_time added for .xml (MovieBrowser) + virtual bool Record(const t_channel_id channel_id = 0, int mode=1, const event_id_t epgid = 0, const std::string& epgTitle = "", unsigned char apidmode = 0, const time_t epg_time=0); // epg_time added for .xml (MovieBrowser) CServerDevice(const bool stopplayback, const bool stopsectionsd, const char * const serveraddress, const unsigned int serverport) { @@ -224,6 +220,7 @@ class CVCRControl bool Record(const CTimerd::RecordingInfo * const eventinfo); bool Pause(){return Device->Pause();}; bool Resume(){return Device->Resume();}; + bool Update() {return Device->Update();}; void Screenshot(const t_channel_id channel_id, char * fname = NULL); MI_MOVIE_INFO * GetMovieInfo(void); bool GetPids(unsigned short *vpid, unsigned short *vtype, unsigned short *apid, unsigned short *atype, unsigned short * apidnum, unsigned short * apids, unsigned short * atypes); diff --git a/src/driver/vfd.cpp b/src/driver/vfd.cpp index 9cb2103f7..f2c816771 100644 --- a/src/driver/vfd.cpp +++ b/src/driver/vfd.cpp @@ -262,7 +262,7 @@ void CVFD::showTime(bool force) ShowIcon(VFD_ICON_CAM1, true); setled(VFD_LED_1_ON, VFD_LED_2_ON); } - } else if(recstatus != CNeutrinoApp::getInstance ()->recordingstatus) { // in case icon ON after record stopped + } else if(clearClock || (recstatus != CNeutrinoApp::getInstance ()->recordingstatus)) { // in case icon ON after record stopped clearClock = 0; if(has_lcd) ShowIcon(VFD_ICON_CAM1, false); diff --git a/src/gui/infoviewer.cpp b/src/gui/infoviewer.cpp index df4c34928..c26d8acde 100644 --- a/src/gui/infoviewer.cpp +++ b/src/gui/infoviewer.cpp @@ -71,6 +71,7 @@ extern CPictureViewer * g_PicViewer; extern CFrontend * frontend; extern cVideo * videoDecoder; extern t_channel_id live_channel_id; //zapit +extern t_channel_id rec_channel_id; //zapit #define COL_INFOBAR_BUTTONS (COL_INFOBAR_SHADOW + 1) #define COL_INFOBAR_BUTTONS_BACKGROUND (COL_INFOBAR_SHADOW_PLUS_1) @@ -89,7 +90,7 @@ static bool sortByDateTime (const CChannelEvent& a, const CChannelEvent& b) extern bool autoshift; extern uint32_t shift_timer; -extern std::string ext_channel_name; +//extern std::string ext_channel_name; extern bool timeset; CInfoViewer::CInfoViewer () @@ -299,7 +300,8 @@ void CInfoViewer::showRecordIcon (const bool show) if (!autoshift && !shift_timer) { frameBuffer->paintBoxRel (ChanName_X + SHADOW_OFFSET, BoxStartY + box_pos + SHADOW_OFFSET, box_len, chanH, COL_INFOBAR_SHADOW_PLUS_0); frameBuffer->paintBoxRel (ChanName_X , BoxStartY + box_pos , box_len, chanH, COL_INFOBAR_PLUS_0); - g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->RenderString (ChanName_X +icon_w + (icon_space*2), BoxStartY + box_pos + chanH, box_len, ext_channel_name.c_str (), COL_INFOBAR, 0, true); + g_Font[SNeutrinoSettings::FONT_TYPE_INFOBAR_SMALL]->RenderString (ChanName_X +icon_w + (icon_space*2), BoxStartY + box_pos + chanH, box_len, + g_Zapit->getChannelName(rec_channel_id)/*ext_channel_name.c_str()*/, COL_INFOBAR, 0, true); } else { frameBuffer->paintBackgroundBoxRel (ChanName_X , BoxStartY + box_pos, box_len + SHADOW_OFFSET, chanH + SHADOW_OFFSET); } diff --git a/src/neutrino.cpp b/src/neutrino.cpp index 237dd89ea..4aa471b86 100644 --- a/src/neutrino.cpp +++ b/src/neutrino.cpp @@ -184,6 +184,7 @@ extern int zapit_ready; static pthread_t zapit_thread ; void * zapit_main_thread(void *data); extern t_channel_id live_channel_id; //zapit +extern t_channel_id rec_channel_id; //zapit extern CZapitChannel *g_current_channel; void setZapitConfig(Zapit_config * Cfg); void getZapitConfig(Zapit_config *Cfg); @@ -2192,7 +2193,7 @@ int CNeutrinoApp::run(int argc, char **argv) g_Sectionsd->registerEvent(CSectionsdClient::EVT_BOUQUETS_UPDATE, 222, NEUTRINO_UDS_NAME); g_Sectionsd->registerEvent(CSectionsdClient::EVT_WRITE_SI_FINISHED, 222, NEUTRINO_UDS_NAME); -#define ZAPIT_EVENT_COUNT 29 +#define ZAPIT_EVENT_COUNT 30 const CZapitClient::events zapit_event[ZAPIT_EVENT_COUNT] = { CZapitClient::EVT_ZAP_COMPLETE, @@ -2223,7 +2224,8 @@ int CNeutrinoApp::run(int argc, char **argv) CZapitClient::EVT_SCAN_FOUND_TV_CHAN, CZapitClient::EVT_SCAN_FOUND_RADIO_CHAN, CZapitClient::EVT_SCAN_FOUND_DATA_CHAN, - CZapitClient::EVT_SDT_CHANGED + CZapitClient::EVT_SDT_CHANGED, + CZapitClient::EVT_PMT_CHANGED }; for (int i = 0; i < ZAPIT_EVENT_COUNT; i++) @@ -3075,6 +3077,37 @@ printf("NeutrinoMessages::EVT_BOUQUETSCHANGED\n");fflush(stdout); delete[] (unsigned char*) data; return messages_return::handled; } + else if( msg == NeutrinoMessages::EVT_PMT_CHANGED) { + res = messages_return::handled; +#if 1 // debug + printf("NeutrinoMessages::EVT_PMT_CHANGED: vpid %x apids(%d): ", g_RemoteControl->current_PIDs.PIDs.vpid, g_RemoteControl->current_PIDs.APIDs.size()); + for(unsigned int i = 0; i < g_RemoteControl->current_PIDs.APIDs.size(); i++) + printf("%x ", g_RemoteControl->current_PIDs.APIDs[i].pid); + printf("\n"); +#endif + + if(!autoshift && recordingstatus && (rec_channel_id == live_channel_id)) { +#if 1 // debug + unsigned short vpid, apid, apidnum; + unsigned short apids[REC_MAX_APIDS]; + CVCRControl::getInstance()->GetPids(&vpid, NULL, &apid, NULL, &apidnum, apids, NULL); + printf("NeutrinoMessages::EVT_PMT_CHANGED: old vpid %x apids(%d): ", vpid, apidnum); + for(unsigned int i = 0; i < apidnum; i++) + printf("%x ", apids[i]); + printf("\n"); +#endif + + if((g_RemoteControl->current_PIDs.PIDs.vpid != vpid)) { + CVCRControl::getInstance()->Stop(); + /* FIXME CVCRControl::getInstance()->Directory ? */ + doGuiRecord(g_settings.network_nfs_recordingdir, false); + if(CMoviePlayerGui::getInstance().timeshift) + res |= messages_return::cancel_all; + } else + CVCRControl::getInstance()->Update(); + } + return res; + } else if( msg == NeutrinoMessages::ZAPTO) { CTimerd::EventInfo * eventinfo; eventinfo = (CTimerd::EventInfo *) data; @@ -4011,8 +4044,7 @@ printf("CNeutrinoApp::startNextRecording: start to dir %s\n", recordingDir); /* Note: CTimerd::RecordingInfo is a class! * What a brilliant idea to send classes via the eventserver! - * => typecast to avoid destructor call - */ + * => typecast to avoid destructor call */ delete [](unsigned char *)nextRecordingInfo; nextRecordingInfo = NULL; diff --git a/src/neutrinoMessages.h b/src/neutrinoMessages.h index be29ec36a..f1b0d73d2 100644 --- a/src/neutrinoMessages.h +++ b/src/neutrinoMessages.h @@ -80,15 +80,17 @@ struct NeutrinoMessages { EVT_MODECHANGED = CRCInput::RC_Events + 4, EVT_BOUQUETSCHANGED = CRCInput::RC_Events + 6, EVT_SERVICESCHANGED = CRCInput::RC_Events + 7, + EVT_SCAN_COMPLETE = CRCInput::RC_Events + 16, EVT_SCAN_NUM_TRANSPONDERS = CRCInput::RC_Events + 17, EVT_SCAN_NUM_CHANNELS = CRCInput::RC_Events + 18, EVT_SHUTDOWN = CRCInput::RC_Events + 19, EVT_TIMER = CRCInput::RC_Events + 20, + EVT_PROGRAMLOCKSTATUS = CRCInput::RC_Events + 22, EVT_RECORDMODE = CRCInput::RC_Events + 24, #ifndef SKIP_CA_STATUS - EVT_ZAP_CA_ID = CRCInput::RC_Events + 50, + EVT_ZAP_CA_ID = CRCInput::RC_Events + 25, EVT_ZAP_CA_CLEAR = CRCInput::RC_Events + 26, EVT_ZAP_CA_LOCK = CRCInput::RC_Events + 27, EVT_ZAP_CA_FTA = CRCInput::RC_Events + 28, @@ -105,6 +107,7 @@ struct NeutrinoMessages { EVT_SERVICES_UPD = CRCInput::RC_Events + 38, EVT_SI_FINISHED = CRCInput::RC_Events + 39, + EVT_PMT_CHANGED = CRCInput::RC_Events + 40, /* NEVER CHANGE THIS */ EVT_CA_MESSAGE = CRCInput::RC_Events + 60, /* data = CA_MESSAGE pointer */ /* END */ diff --git a/src/zapit/include/zapit/client/zapitclient.h b/src/zapit/include/zapit/client/zapitclient.h index 3c90b4904..5857f07ed 100644 --- a/src/zapit/include/zapit/client/zapitclient.h +++ b/src/zapit/include/zapit/client/zapitclient.h @@ -70,6 +70,7 @@ class CZapitClient:public CBasicClient EVT_ZAP_CA_ID, EVT_SDT_CHANGED, EVT_SERVICES_CHANGED, + EVT_PMT_CHANGED, LAST_EVENT_MARKER // <- no actual event, needed by pzapit }; diff --git a/src/zapit/src/zapit.cpp b/src/zapit/src/zapit.cpp index 75449b7b0..51443b6a9 100644 --- a/src/zapit/src/zapit.cpp +++ b/src/zapit/src/zapit.cpp @@ -92,7 +92,7 @@ int aspectratio=0; int mode43=0; int def_audio_mode = 0; t_channel_id live_channel_id; -static t_channel_id rec_channel_id; +t_channel_id rec_channel_id; int rezapTimeout; int feTimeout = 40; bool fastZap; @@ -356,7 +356,7 @@ CZapitClient::responseGetLastChannel load_settings(void) * if we zap from, we start cam1 for new live and update cam0 with camask for rec. * if to recording channel, we must stop cam1 and update cam0 with live+rec camask. */ -static int camask = 1; // demux 0 + void start_camd(bool forupdate = false) { if(!g_current_channel) @@ -365,22 +365,19 @@ void start_camd(bool forupdate = false) if(currentMode & RECORD_MODE) { if(rec_channel_id != live_channel_id) { /* zap from rec. channel */ - camask = 1; cam1->setCaPmt(g_current_channel->getCaPmt(), DEMUX_SOURCE_0, DEMUX_DECODE_0 /*1*/); // demux 0 } else if(forupdate) { //FIXME broken! - /* forupdate means pmt update for live channel, using old camask. - * TODO what if forupdate comes while live == rec ? - */ - cam0->setCaPmt(g_current_channel->getCaPmt(), DEMUX_SOURCE_0, cam0->getCaMask(), true);// update +#if 0 // moved to stream2file.cpp + /* forupdate means pmt update for live channel, using old camask. */ + cam0->setCaPmt(g_current_channel->getCaPmt(), DEMUX_SOURCE_0, cam0->getCaMask() | DEMUX_DECODE_0 | DEMUX_DECODE_2, true);// update +#endif } else { /* zap back to rec. channel */ - camask = 5; // demux 0 + 2 - cam0->setCaPmt(g_current_channel->getCaPmt(), DEMUX_SOURCE_0, cam0->getCaMask() | DEMUX_DECODE_0 | DEMUX_DECODE_2 /*camask*/, true); // update + cam0->setCaPmt(g_current_channel->getCaPmt(), DEMUX_SOURCE_0, cam0->getCaMask() | DEMUX_DECODE_0 | DEMUX_DECODE_2 /*5*/, true); // update cam1->sendMessage(0,0); // stop/close } } else { - camask = 1; - cam0->setCaPmt(g_current_channel->getCaPmt(), DEMUX_SOURCE_0, DEMUX_DECODE_0 /*camask*/); + cam0->setCaPmt(g_current_channel->getCaPmt(), DEMUX_SOURCE_0, cam0->getCaMask() | DEMUX_DECODE_0 /*1*/, forupdate); } int len; unsigned char * pmt = g_current_channel->getRawPmt(len); @@ -444,7 +441,8 @@ printf("[zapit] saving channel, apid %x sub pid %x mode %d volume %d\n", g_curre } pmt_stop_update_filter(&pmt_update_fd); - stopPlayBack(true); + + stopPlayBack(!forupdate); if(!forupdate && g_current_channel && g_current_channel->getCaPmt()) { g_current_channel->resetPids(); @@ -597,6 +595,10 @@ printf("[zapit] saving channel, apid %x sub pid %x mode %d volume %d\n", g_curre printf("[zapit] sending capmt....\n"); + if(forupdate) { + if(event_mode) + eventServer->sendEvent(CZapitClient::EVT_PMT_CHANGED, CEventServer::INITID_ZAPIT, &channel_id, sizeof(channel_id)); + } start_camd(forupdate); //play: send_ca_id(1);