Ticket #49: analogscan.patch
File analogscan.patch, 14.5 KB (added by , 19 years ago) |
---|
-
analogscan.h
58 58 /** @brief Stops the scanning thread running */ 59 59 void stop(); 60 60 61 /** @brief Scans the given frequency list, implies start() 62 @see start() 63 */ 64 bool scan(unsigned nList); 65 /** @brief Scans the given frequency table, implies start() 66 @see start() 67 */ 68 bool scan(const QString& table); 61 /** @brief Scans the given frequency list, implies starting the thread() */ 62 bool scan(); 69 63 70 64 signals: 71 65 /** @brief Indicates how far through the scan we are as a percentage … … 86 80 unsigned sourceid; 87 81 unsigned cardid; 88 82 unsigned nTable; 89 int fd;90 QString device;91 QString vbidevice;92 struct vbi *vbi;93 83 94 /** @brief Is the current channel tuned95 @returns true if tuned96 */97 bool isTuned();98 84 /** @brief adds a found channel to the database 99 85 @param name name of the channel 100 86 @param frequency freqency/frequencyid of the channel 101 87 */ 102 void addChannel(const QString& name, int frequency); 103 /** @brief find the next available channel id 104 @param sourceID the source id of the video source to check 105 */ 106 int generateNewChanID(int sourceID); 107 /** @brief Starts the scanning thread running */ 108 bool start(); 109 110 /** @brief Controls access to the thread*/ 111 pthread_mutex_t lock; 88 void addChannel(int number, const QString& channum, 89 const QString& name, int frequency); 112 90 /** @brief Scanning thread*/ 113 91 pthread_t thread; 114 /** @brief vbi thread*/115 pthread_t threadVBI;116 92 117 93 /** @brief Actual scanning proc */ 118 94 void doScan(); 119 95 /** @brief Actual thread proc , calls doScan*/ 120 96 static void *spawn(void *param); 121 /** @brief Actual thread proc for vbi, calls doVBI*/122 static void *spawnVBI(void *param);123 /** @brief Actual vbi proc */124 void doVBI();125 /** @brief vbi callback proc */126 static void vbi_event(AnalogScan* data, struct vt_event *ev);127 97 }; 128 98 #endif //ANALOGSCAN_H -
videosource.h
67 67 static DISEQC_TYPES GetDISEqCType(uint cardid); 68 68 69 69 static CARD_TYPES GetDVBType(uint device, QString &name); 70 static QString GetDefaultInput(uint cardid); 70 71 }; 71 72 72 73 class VideoSource; -
videosource.cpp
297 297 return (DISEQC_TYPES)iRet; 298 298 } 299 299 300 /** \fn CardUtil::GetDefaultInput(uint) 301 * \brief Returns the default input for the card 302 * \param [in]nCardID card id to check 303 * \return the default input 304 */ 305 QString CardUtil::GetDefaultInput(uint nCardID) 306 { 307 QString str; 308 MSqlQuery query(MSqlQuery::InitCon()); 309 query.prepare("SELECT defaultinput " 310 "FROM capturecard " 311 "WHERE capturecard.cardid = :CARDID"); 312 query.bindValue(":CARDID", nCardID); 313 314 if (query.exec() && query.isActive() && query.size() > 0) 315 { 316 query.next(); 317 str = query.value(0).toString(); 318 } 319 return str; 320 } 321 300 322 QString VSSetting::whereClause(void) 301 323 { 302 324 return QString("sourceid = %1").arg(parent.getSourceID()); -
scanwizard.cpp
308 308 //Create an analog scan object 309 309 analogScan = new AnalogScan(nVideoSource, parent->captureCard()); 310 310 311 MSqlQuery query(MSqlQuery::InitCon());312 313 QString thequery = QString("SELECT freqtable "314 "FROM videosource WHERE "315 "sourceid = \"%1\";")316 .arg(nVideoSource);317 query.prepare(thequery);318 319 if (!query.exec() || !query.isActive())320 MythContext::DBError("fetchtuningparams", query);321 if (query.size() <= 0)322 return;323 query.next();324 325 QString freqtable = query.value(0).toString();326 // cerr << "frequency table = " << freqtable.ascii() << endl;327 328 311 popupProgress = new ScanProgressPopup(this,false); 329 312 connect(analogScan,SIGNAL(serviceScanComplete(void)), 330 313 this,SLOT(scanComplete(void))); … … 335 318 popupProgress->progress(0); 336 319 popupProgress->exec(this); 337 320 338 if (!analogScan->scan( freqtable))321 if (!analogScan->scan()) 339 322 { 340 323 MythPopupBox::showOkPopup(gContext->GetMainWindow(), 341 324 tr("ScanWizard"), -
channel.h
53 53 bool TuneMultiplex(uint mplexid); 54 54 bool Tune(uint frequency, QString inputname="", 55 55 QString modulation="analog"); 56 // V4L scanning stuff 57 bool IsTuned() const; 56 58 private: 57 59 // Helper Sets 58 60 void SetColourAttribute(int attrib, const char *name); -
analogscan.cpp
38 38 #include <unistd.h> 39 39 #include <fcntl.h> 40 40 41 #include <qmutex.h>42 41 #include "mythcontext.h" 43 42 #include "videosource.h" 44 43 #include "frequencies.h" 45 #include "videodev_myth.h" 44 #include "channel.h" 45 #include "channelutil.h" 46 46 47 extern "C" {48 #include "vbitext/vbi.h"49 };50 51 47 #include "analogscan.h" 52 48 53 49 AnalogScan::AnalogScan(unsigned _sourceid,unsigned _cardid) : … … 56 52 sourceid(_sourceid), 57 53 cardid(_cardid) 58 54 { 59 pthread_mutex_init(&lock, NULL);60 vbi=NULL;61 55 } 62 56 63 57 AnalogScan::~AnalogScan() 64 58 { 65 pthread_mutex_destroy(&lock);66 59 } 67 60 68 bool AnalogScan::start()69 {70 if (!CardUtil::GetVideoDevice(cardid, device, vbidevice))71 return false;72 73 fd = ::open(device.ascii(),O_RDWR);74 if (fd < 0)75 return false;76 77 pthread_mutex_lock(&lock);78 fRunning = true;79 fStop = false;80 pthread_mutex_unlock(&lock);81 82 pthread_create(&thread, NULL, spawn, this);83 #ifdef DOVBI84 pthread_create(&threadVBI, NULL, spawnVBI, this);85 #endif86 87 return true;88 }89 90 61 void AnalogScan::stop() 91 62 { 92 bool _stop = false; 93 pthread_mutex_lock(&lock); 94 if (fRunning && !fStop) 95 _stop = true; 96 fStop = true; 97 pthread_mutex_unlock(&lock); 98 99 if (_stop) 63 if (fRunning) 100 64 { 101 pthread_join(thread,NULL); 102 #ifdef DO_VBI 103 pthread_join(threadVBI,NULL); 104 #endif 105 if (fd >=0) 106 ::close(fd); 107 } 108 } 109 110 void AnalogScan::vbi_event(AnalogScan* _this, struct vt_event *ev) 111 { 112 (void)_this; 113 //cerr << "AnalogScan::vbi_event " << ev->type << "\n"; 114 switch (ev->type) 115 { 116 case EV_HEADER: 117 break; 118 case EV_XPACKET: 119 break; 120 // default: 121 // cerr << "AnalogScan unkown " << ev->type << "\n"; 65 fStop = true; 66 pthread_join(thread, NULL); 122 67 } 123 68 } 124 69 … … 129 74 return NULL; 130 75 } 131 76 132 void *AnalogScan::spawnVBI(void *param)133 {134 AnalogScan *_this = (AnalogScan*)param;135 _this->doVBI();136 return NULL;137 }138 139 void AnalogScan::doVBI()140 {141 vbi = ::vbi_open(vbidevice.ascii(), NULL, 99, -1);142 if (!vbi)143 return;144 VERBOSE(VB_IMPORTANT, QString("AnalogScan opened vbi device: %1").arg(vbidevice));145 vbi_add_handler(vbi, (void*)vbi_event,this);146 147 while(!fStop)148 {149 struct timeval tv;150 fd_set rdset;151 152 tv.tv_sec = 0;153 tv.tv_usec = 10000;154 FD_ZERO(&rdset);155 FD_SET(vbi->fd, &rdset);156 157 switch (::select(vbi->fd + 1, &rdset, 0, 0, &tv))158 {159 case -1:160 perror("vbi select");161 continue;162 case 0:163 //printf("vbi select timeout\n");164 continue;165 }166 vbi_handler(vbi, vbi->fd);167 }168 vbi_del_handler(vbi, (void*)vbi_event,this);169 ::vbi_close(vbi);170 }171 172 77 void AnalogScan::doScan() 173 78 { 174 struct CHANLIST *l = chanlists[nTable].list;175 int count = chanlists[nTable].count;176 for (int i = 0; i < count && !fStop; i++,l++)79 fRunning = true; 80 QString device; 81 if (CardUtil::GetVideoDevice(cardid, device)) 177 82 { 178 //cerr << i << " " << l->name << " " << l->freq << endl; 179 struct v4l2_frequency vf; 180 memset(&vf, 0, sizeof(vf)); 181 vf.frequency = l->freq * 16 / 1000; 182 vf.type = V4L2_TUNER_ANALOG_TV; 183 184 ::ioctl(fd, VIDIOC_S_FREQUENCY, &vf); 185 usleep(200000); /* 0.2 sec */ 186 if (isTuned()) 187 { 188 #ifdef DOVBI 189 usleep(2000000); /* 0.2 sec */ 190 #endif 191 addChannel(l->name,l->freq); 192 emit serviceScanUpdateText(QObject::tr("Channel %1").arg(l->name)); 83 Channel channel(NULL,device); 84 if (channel.Open()) 85 { 86 QString input = CardUtil::GetDefaultInput(cardid); 87 struct CHANLIST *l = chanlists[nTable].list; 88 int count = chanlists[nTable].count; 89 for (int i = 0; i < count && !fStop; i++,l++) 90 { 91 unsigned frequency = l->freq*1000; 92 channel.Tune(frequency,input); 93 usleep(200000); /* 0.2 sec */ 94 if (channel.IsTuned()) 95 { 96 //cerr << i << " " << l->name << " " << frequency << " Tuned " << endl; 97 QString name = QObject::tr("Channel %1").arg(l->name); 98 addChannel(i,l->name,name,l->freq); 99 emit serviceScanUpdateText(name); 100 } 101 emit serviceScanPCTComplete((i*100)/count); 102 } 103 channel.Close(); 193 104 } 194 emit serviceScanPCTComplete((i*100)/count);195 105 } 196 106 emit serviceScanComplete(); 197 pthread_mutex_lock(&lock);198 fRunning = false;199 pthread_mutex_unlock(&lock);200 107 } 201 108 202 bool AnalogScan::scan( const QString& freqtable)109 bool AnalogScan::scan() 203 110 { 204 111 int i = 0; 205 112 char *listname = (char *)chanlists[i].name; 206 113 QString table; 207 114 115 MSqlQuery query(MSqlQuery::InitCon()); 116 117 QString thequery = QString("SELECT freqtable FROM videosource WHERE " 118 "sourceid = \"%1\";").arg(sourceid); 119 query.prepare(thequery); 120 121 if (!query.exec() || !query.isActive()) 122 MythContext::DBError("analog scan freqtable", query); 123 if (query.size() <= 0) 124 return false; 125 query.next(); 126 127 QString freqtable = query.value(0).toString(); 128 // cerr << "frequency table = " << freqtable.ascii() << endl; 129 208 130 if (freqtable == "default" || freqtable.isNull() || freqtable.isEmpty()) 209 131 table = gContext->GetSetting("FreqTable"); 210 132 else 211 133 table = freqtable; 212 134 135 nTable = 0; 213 136 while (listname != NULL) 214 137 { 215 138 if (table == listname) 216 return scan(i); 139 { 140 nTable = i; 141 break; 142 } 217 143 i++; 218 144 listname = (char *)chanlists[i].name; 219 145 } 220 146 221 return scan(0); 147 if (!fRunning) 148 pthread_create(&thread, NULL, spawn, this); 149 while (!fRunning) 150 usleep(50); 151 return true; 222 152 } 223 153 224 bool AnalogScan::isTuned() 154 void AnalogScan::addChannel(int number,const QString& channumber, 155 const QString& name, int frequency) 225 156 { 226 struct v4l2_tuner tuner;227 228 memset(&tuner,0,sizeof(tuner));229 if (-1 == ::ioctl(fd,VIDIOC_G_TUNER,&tuner,0))230 return 0;231 return tuner.signal ? true : false;232 }233 234 bool AnalogScan::scan(unsigned table)235 {236 nTable = table;237 return start();238 }239 240 int AnalogScan::generateNewChanID(int sourceID)241 {242 157 MSqlQuery query(MSqlQuery::InitCon()); 243 244 QString theQuery =245 QString("SELECT max(chanid) as maxchan "246 "FROM channel WHERE sourceid=%1").arg(sourceID);247 query.prepare(theQuery);248 249 if(!query.exec())250 MythContext::DBError("Calculating new ChanID", query);251 252 if (!query.isActive())253 MythContext::DBError("Calculating new ChanID for Analog Channel",query);254 255 query.next();256 257 // If transport not present add it, and move on to the next258 if (query.size() <= 0)259 return sourceID * 1000;260 261 int MaxChanID = query.value(0).toInt();262 263 if (MaxChanID == 0)264 return sourceID * 1000;265 else266 return MaxChanID + 1;267 }268 269 void AnalogScan::addChannel(const QString& name, int frequency)270 {271 MSqlQuery query(MSqlQuery::InitCon());272 158 query.prepare("DELETE FROM channel WHERE channum=:CHANNUM AND " 273 159 "sourceid=:SOURCEID"); 274 query.bindValue(":CHANNUM", name);160 query.bindValue(":CHANNUM",channumber); 275 161 query.bindValue(":SOURCEID",sourceid); 276 162 query.exec(); 277 163 … … 280 166 "VALUES (:CHANID,:CHANNUM,:SOURCEID,:CALLSIGN," 281 167 ":NAME,:FREQID);"); 282 168 283 query.bindValue(":CHANID",generateNewChanID(sourceid)); 284 query.bindValue(":CHANNUM",name); 169 int chanid = ChannelUtil::CreateChanID(sourceid,QString::number(number)); 170 query.bindValue(":CHANID",chanid); 171 query.bindValue(":CHANNUM",channumber); 285 172 query.bindValue(":SOURCEID",sourceid); 286 173 query.bindValue(":CALLSIGN",name); 287 174 query.bindValue(":NAME",name); 288 175 query.bindValue(":FREQID",frequency); 289 176 290 177 if(!query.exec()) 291 MythContext::DBError("Adding new DVBChannel", query);178 MythContext::DBError("Adding new Channel", query); 292 179 293 180 if (!query.isActive()) 294 MythContext::DBError("Adding new DVBChannel", query);181 MythContext::DBError("Adding new Channel", query); 295 182 } -
channel.cpp
636 636 return true; 637 637 } 638 638 639 bool Channel::IsTuned() const 640 { 641 if (usingv4l2) 642 { 643 struct v4l2_tuner tuner; 644 645 memset(&tuner,0,sizeof(tuner)); 646 if (-1 == ::ioctl(videofd,VIDIOC_G_TUNER,&tuner,0)) 647 return false; 648 return tuner.signal ? true : false; 649 } 650 else 651 { 652 struct video_tuner tuner; 653 memset(&tuner,0,sizeof(tuner)); 654 if (-1 == ::ioctl(videofd,VIDIOCGTUNER,&tuner,0)) 655 return false; 656 return tuner.signal ? true : false; 657 } 658 } 659 639 660 int Channel::GetCardID() const 640 661 { 641 662 if (pParent)