00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <fstream>
00034 #include <cstdlib>
00035 #include <cerrno>
00036 #include "mmsmedia/mmscda.h"
00037 extern "C" {
00038 #include <linux/cdrom.h>
00039 #include <sys/ioctl.h>
00040 #include <sys/types.h>
00041 #include <sys/stat.h>
00042 #include <fcntl.h>
00043 }
00044
00045 MMS_CREATEERROR(MMSCDAError);
00046
00047 #ifdef __HAVE_GSTREAMER__
00048 #endif
00049 #ifdef __HAVE_XINE__
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061 static void queue_cb(void *userData, const xine_event_t *event) {
00062 MMSCDA *mmscda = (MMSCDA*)userData;
00063
00064 switch(event->type) {
00065 case XINE_EVENT_UI_PLAYBACK_FINISHED:
00066 mmscda->onStatusChange->emit(103,0);
00067 break;
00068 }
00069 }
00070 #endif
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083 void MMSCDA::checkDevice(const string device) {
00084 if (this->backend == MMSMEDIA_BE_GST) {
00085 #ifdef __HAVE_GSTREAMER__
00086 #endif
00087 }
00088 else {
00089 #ifdef __HAVE_XINE__
00090 string d = device;
00091 xine_health_check_t hc, *result;
00092
00093 if(d.length() == 0)
00094 d = "/dev/cdrom";
00095
00096 hc.cdrom_dev = xine_config_register_string(xine, "input.cdrom_dev", d.c_str(), "device used as cdrom drive", NULL, 0, NULL, NULL);
00097 result = xine_health_check(&hc, CHECK_CDROM);
00098 if(result->status != XINE_HEALTH_CHECK_OK) {
00099 throw MMSCDAError(0, "No DVD Device found at " + d);
00100 }
00101
00102 this->device = d;
00103 DEBUGMSG("MMSMedia", "Using " + this->device + " as CDROM device");
00104 #endif
00105 }
00106 }
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 MMSCDA::MMSCDA(MMSWindow *window, const string device, const bool verbose) {
00120 MMSAV::initialize(verbose, window);
00121
00122
00123 checkDevice(device);
00124
00125
00126 if(window) {
00127 MMSFBRectangle rect = window->getGeometry();
00128 this->windowWidth = rect.w;
00129 this->windowHeight = rect.h;
00130 }
00131 }
00132
00133
00134
00135
00136 MMSCDA::~MMSCDA() {
00137 }
00138
00139 #if defined __HAVE_GSTREAMER__
00140 #elif defined __HAVE_XINE__
00141
00142
00143
00144 void MMSCDA::xineOpen() {
00145 MMSAV::xineOpen(queue_cb, (void*)this);
00146 }
00147 #endif
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157 void MMSCDA::startPlaying(int tracknum) {
00158 string mrl = "cdda://" + this->device;
00159 if(tracknum <= titlecount && tracknum >= 1)
00160 mrl += "/" + iToStr(tracknum);
00161
00162 this->currtitle = (tracknum >= 1 ? tracknum : 1);
00163
00164 #ifdef __HAVE_XINE__
00165 if(!this->stream) MMSAV::xineOpen(queue_cb, (void*)this);
00166 #endif
00167
00168 MMSAV::startPlaying(mrl, false);
00169 }
00170
00171
00172
00173
00174
00175
00176
00177 void MMSCDA::rewind() {
00178 DEBUGMSG("MMSMedia", "MMSCDA::rewind() not yet implemented");
00179 #if 0
00180 if(this->status != this->STATUS_NONE) {
00181 this->setStatus(this->STATUS_REWIND);
00182 xine_trick_mode (this->stream, XINE_TRICK_MODE_FAST_REWIND, 1);
00183 }
00184 #endif
00185 }
00186
00187
00188
00189
00190
00191
00192 void MMSCDA::previous() {
00193 if (this->backend == MMSMEDIA_BE_GST) {
00194 #ifdef __HAVE_GSTREAMER__
00195 #endif
00196 }
00197 else {
00198 #ifdef __HAVE_XINE__
00199 if(currtitle>1)
00200 currtitle--;
00201 else
00202 currtitle=titlecount;
00203 this->stop(false);
00204 this->startPlaying(currtitle);
00205 #endif
00206 }
00207
00208 }
00209
00210
00211
00212
00213
00214
00215 void MMSCDA::next() {
00216 if (this->backend == MMSMEDIA_BE_GST) {
00217 #ifdef __HAVE_GSTREAMER__
00218 #endif
00219 }
00220 else {
00221 #ifdef __HAVE_XINE__
00222 if(currtitle<titlecount)
00223 currtitle++;
00224 else
00225 currtitle=1;
00226 this->stop(false);
00227 this->startPlaying(currtitle);
00228 #endif
00229 }
00230
00231 }
00232
00233
00234
00235
00236
00237
00238
00239 void MMSCDA::eject() {
00240
00241 this->setStatus(this->STATUS_NONE);
00242
00243 if (this->backend == MMSMEDIA_BE_GST) {
00244 #ifdef __HAVE_GSTREAMER__
00245 #endif
00246 }
00247 else {
00248 #ifdef __HAVE_XINE__
00249 if(this->stream)
00250 xine_dispose(this->stream);
00251 this->stream = 0;
00252
00253 #endif
00254 }
00255
00256 int status = -1;
00257 int fd = open(device.c_str(), O_RDONLY|O_NONBLOCK);
00258
00259 if(fd < 0) {
00260 DEBUGMSG("MMSCDA", "Eject failed (can't open device: %s.)", strerror(errno));
00261 return;
00262 }
00263
00264 #if defined(CDROMEJECT)
00265 status = ioctl(fd, CDROMEJECT);
00266 #elif defined(CDIOCEJECT)
00267 status = ioctl(fd, CDIOCEJECT);
00268 #endif
00269
00270 close(fd);
00271 if(status != 0) {
00272 DEBUGMSG("MMSCDA", "Eject failed: %s.", strerror(errno));
00273 }
00274 }
00275
00276
00277
00278
00279
00280
00281
00282 int MMSCDA::getTitleNumber() {
00283 if (this->backend == MMSMEDIA_BE_GST) {
00284 #ifdef __HAVE_GSTREAMER__
00285
00286 return 0;
00287 #endif
00288 }
00289 else {
00290 #ifdef __HAVE_XINE__
00291 return this->currtitle;
00292 #endif
00293 }
00294
00295 throw MMSCDAError(0, "MMSCDA::getTitleNumber() called but media backend does not match supported backends");
00296 }
00297
00298
00299
00300
00301
00302
00303 int MMSCDA::getTitleCount() {
00304 if (this->backend == MMSMEDIA_BE_GST) {
00305 #ifdef __HAVE_GSTREAMER__
00306
00307 return 0;
00308 #endif
00309 }
00310 else {
00311 #ifdef __HAVE_XINE__
00312 return this->titlecount;
00313 #endif
00314 }
00315
00316 throw MMSCDAError(0, "MMSCDA::getTitleCount() called but media backend does not match supported backends");
00317 }
00318
00319
00320 void MMSCDA::checktoc() {
00321 int fd_cd = open(device.c_str(), O_RDONLY | O_NONBLOCK);
00322 if(fd_cd<0) {
00323 this->titlecount=-1;
00324 return;
00325 }
00326 struct cdrom_tochdr hdr;
00327 if(ioctl(fd_cd, CDROMREADTOCHDR, &hdr) == -1) {
00328 this->titlecount=-1;
00329 } else {
00330 DEBUGMSG("MMSMedia", "tochdr cdth_trk0: " + iToStr(hdr.cdth_trk0) + " cdth_trk1: " + iToStr(hdr.cdth_trk1));
00331 this->titlecount = hdr.cdth_trk1;
00332 }
00333
00334 close(fd_cd);
00335 }