00001 #include "channel.h"
00002 #include "condition.h"
00003 #include "devicedvbinput.h"
00004 #include "devicedvbinput.inc"
00005 #include "edl.h"
00006 #include "edlsession.h"
00007 #include "mutex.h"
00008 #include "mwindow.h"
00009 #include "recordconfig.h"
00010 #include "renderfarm.h"
00011
00012
00013
00014 #include <errno.h>
00015 #include <netdb.h>
00016 #include <netinet/in.h>
00017 #include <string.h>
00018 #include <sys/socket.h>
00019 #include <unistd.h>
00020
00021
00022
00023
00024 DeviceDVBInput::DeviceDVBInput(MWindow *mwindow, VideoInConfig *config)
00025 : GarbageObject("DeviceDVBInput")
00026 {
00027 reset();
00028 this->config = config;
00029 this->mwindow = mwindow;
00030 signal_lock = new Condition(0, "DeviceDVBInput::signal_lock", 0);
00031 channel = new Channel;
00032 }
00033
00034 DeviceDVBInput::~DeviceDVBInput()
00035 {
00036 close();
00037 delete signal_lock;
00038
00039
00040
00041 mwindow->dvb_input = 0;
00042 delete channel;
00043 }
00044
00045
00046 void DeviceDVBInput::reset()
00047 {
00048 tuner_fd = -1;
00049 want_signal = 0;
00050 signal_lock = 0;
00051 lock_result = 0;
00052 signal_result = 0;
00053 channel_changed = 0;
00054 }
00055
00056 DeviceDVBInput* DeviceDVBInput::get_input_thread(MWindow *mwindow)
00057 {
00058 DeviceDVBInput *input_thread = 0;
00059 mwindow->dvb_input_lock->lock("DeviceDVBInput::get_input_thread");
00060
00061 if(mwindow->dvb_input)
00062 {
00063 input_thread = mwindow->dvb_input;
00064 input_thread->add_user();
00065 }
00066 else
00067
00068 {
00069 input_thread = mwindow->dvb_input =
00070 new DeviceDVBInput(mwindow, mwindow->edl->session->vconfig_in);
00071 input_thread->GarbageObject::add_user();
00072
00073
00074 }
00075 mwindow->dvb_input_lock->unlock();
00076 return input_thread;
00077 }
00078
00079 void DeviceDVBInput::put_input_thread(MWindow *mwindow)
00080 {
00081 mwindow->dvb_input_lock->lock("DeviceDVBInput::put_input_thread");
00082 mwindow->dvb_input->GarbageObject::remove_user();
00083 Garbage::delete_object(mwindow->dvb_input);
00084 mwindow->dvb_input_lock->unlock();
00085 }
00086
00087 int DeviceDVBInput::close()
00088 {
00089 if(tuner_fd >= 0)
00090 {
00091
00092 ::close(tuner_fd);
00093 tuner_fd = -1;
00094 }
00095 return 0;
00096 }
00097
00098 int DeviceDVBInput::try_tuner()
00099 {
00100 int error = 0;
00101 printf("DeviceDVBInput::try_tuner 1\n");
00102 tuner_fd = RenderFarmServerThread::open_client(config->dvb_in_host,
00103 config->dvb_in_port);
00104
00105 printf("DeviceDVBInput::try_tuner 10\n");
00106 if(tuner_fd < 0) return 1;
00107
00108
00109
00110 error = write_int64(RENDERFARM_TUNER);
00111 if(error)
00112 {
00113 ::close(tuner_fd);
00114 tuner_fd = -1;
00115 return 1;
00116 }
00117
00118 printf("DeviceDVBInput::try_tuner 20\n");
00119
00120
00121 int available = !read_int64(&error);
00122
00123 if(!available || error)
00124 {
00125 printf("DeviceDVBInput::try_tuner available=%d error=%d\n", available, error);
00126 ::close(tuner_fd);
00127 tuner_fd = -1;
00128 return 1;
00129 }
00130
00131 return 0;
00132 }
00133
00134
00135
00136 int DeviceDVBInput::reopen_tuner()
00137 {
00138
00139
00140 if(tuner_fd >= 0)
00141 {
00142 ::close(tuner_fd);
00143 tuner_fd = -1;
00144 }
00145
00146
00147
00148
00149
00150 for(int attempts = 0; attempts < 3; attempts++)
00151 {
00152 if(!try_tuner()) break;
00153
00154 if(tuner_fd >= 0)
00155 {
00156 break;
00157 }
00158
00159 sleep(1);
00160 }
00161
00162
00163 if(tuner_fd < 0)
00164 {
00165 printf("DeviceDVBInput::reopen_tuner: tuner '%s' not available\n",
00166 config->dvb_in_host);
00167 return 1;
00168 }
00169
00170
00171
00172
00173
00174 if(write_int64(NETTUNE_SET_CHANNEL)) return 1;
00175 if(write_int64(channel->entry)) return 1;
00176
00177 if(write_int64(NETTUNE_SET_TABLE)) return 1;
00178 if(write_int64(channel->freqtable)) return 1;
00179
00180 if(write_int64(NETTUNE_SET_AUDIO_PID)) return 1;
00181 if(write_int64(channel->audio_pid)) return 1;
00182
00183 if(write_int64(NETTUNE_SET_VIDEO_PID)) return 1;
00184 if(write_int64(channel->video_pid)) return 1;
00185
00186
00187
00188 if(write_int64(NETTUNE_OPEN)) return 1;
00189
00190 if(read_int64(0))
00191 {
00192 printf("DeviceDVBInput::reopen_tuner: open failed\n");
00193 return 1;
00194 }
00195
00196
00197
00198 return 0;
00199 }
00200
00201 int DeviceDVBInput::get_signal_strength(int channel, int tuner_id)
00202 {
00203 sleep(5);
00204
00205 want_signal = 1;
00206 signal_lock->lock("NetTune::get_signal_strength");
00207
00208
00209
00210
00211
00212 if(lock_result)
00213 {
00214 if(!signal_result)
00215 {
00216 signal_result = 1;
00217 }
00218 }
00219 else
00220 {
00221 signal_result = 0;
00222 }
00223
00224 return signal_result;
00225 }
00226
00227
00228
00229
00230 int64_t DeviceDVBInput::read_int64(int *error)
00231 {
00232 int temp = 0;
00233 if(!error) error = &temp;
00234
00235 unsigned char data[sizeof(int64_t)];
00236 *error = (read_tuner(data, sizeof(int64_t)) != sizeof(int64_t));
00237
00238
00239
00240 int64_t result = 1;
00241 if(!*error)
00242 {
00243 result = (((int64_t)data[0]) << 56) |
00244 (((uint64_t)data[1]) << 48) |
00245 (((uint64_t)data[2]) << 40) |
00246 (((uint64_t)data[3]) << 32) |
00247 (((uint64_t)data[4]) << 24) |
00248 (((uint64_t)data[5]) << 16) |
00249 (((uint64_t)data[6]) << 8) |
00250 data[7];
00251 }
00252 return result;
00253 }
00254
00255 int DeviceDVBInput::write_int64(int64_t value)
00256 {
00257 unsigned char data[sizeof(int64_t)];
00258 data[0] = (value >> 56) & 0xff;
00259 data[1] = (value >> 48) & 0xff;
00260 data[2] = (value >> 40) & 0xff;
00261 data[3] = (value >> 32) & 0xff;
00262 data[4] = (value >> 24) & 0xff;
00263 data[5] = (value >> 16) & 0xff;
00264 data[6] = (value >> 8) & 0xff;
00265 data[7] = value & 0xff;
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275 return (write_tuner(data, sizeof(int64_t)) != sizeof(int64_t));
00276 }
00277
00278 int DeviceDVBInput::write_tuner(unsigned char *data, int size)
00279 {
00280 return write(tuner_fd, data, size);
00281 }
00282
00283 int DeviceDVBInput::read_stream(unsigned char *data, int size)
00284 {
00285 int result = 0;
00286 if(tuner_fd < 0 || channel_changed)
00287 {
00288 int result2 = reopen_tuner();
00289
00290 if(result2)
00291 {
00292 close();
00293 return 0;
00294 }
00295
00296 channel_changed = 0;
00297 }
00298
00299
00300
00301
00302 return result;
00303 }
00304
00305 int DeviceDVBInput::read_tuner(unsigned char *data, int size)
00306 {
00307 int bytes_read = 0;
00308 int offset = 0;
00309 while(size > 0)
00310 {
00311 bytes_read = ::read(tuner_fd, data + offset, size);
00312 if(bytes_read > 0)
00313 {
00314 offset += bytes_read;
00315 size -= bytes_read;
00316 }
00317 else
00318 if(bytes_read <= 0)
00319 {
00320 printf("NetTune::read_tuner connection closed\n");
00321 ::close(tuner_fd);
00322 tuner_fd = -1;
00323 break;
00324 }
00325 }
00326 return offset;
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341