1 #include <lib/base/eerror.h>
2 #include <lib/dvb/decoder.h>
3 #if HAVE_DVB_API_VERSION < 3
4 #define audioStatus audio_status
5 #define videoStatus video_status
6 #define pesType pes_type
7 #define playState play_state
8 #define audioStreamSource_t audio_stream_source_t
9 #define videoStreamSource_t video_stream_source_t
10 #define streamSource stream_source
11 #define dmxPesFilterParams dmx_pes_filter_params
12 #define DMX_PES_VIDEO DMX_PES_VIDEO0
13 #define DMX_PES_AUDIO DMX_PES_AUDIO0
15 #include <ost/video.h>
16 #include <ost/audio.h>
18 #include <linux/dvb/audio.h>
19 #include <linux/dvb/video.h>
20 #include <linux/dvb/dmx.h>
25 #include <sys/ioctl.h>
28 /* these are quite new... */
30 #define AUDIO_GET_PTS _IOR('o', 19, __u64)
31 #define VIDEO_GET_PTS _IOR('o', 57, __u64)
34 DEFINE_REF(eDVBAudio);
36 eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev): m_demux(demux)
39 #if HAVE_DVB_API_VERSION < 3
40 sprintf(filename, "/dev/dvb/card%d/audio%d", demux->adapter, dev);
42 sprintf(filename, "/dev/dvb/adapter%d/audio%d", demux->adapter, dev);
44 m_fd = ::open(filename, O_RDWR);
46 eWarning("%s: %m", filename);
47 #if HAVE_DVB_API_VERSION < 3
48 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
50 sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
52 m_fd_demux = ::open(filename, O_RDWR);
54 eWarning("%s: %m", filename);
57 int eDVBAudio::startPid(int pid, int type)
59 if ((m_fd < 0) || (m_fd_demux < 0))
61 dmx_pes_filter_params pes;
64 pes.input = DMX_IN_FRONTEND;
65 pes.output = DMX_OUT_DECODER;
66 pes.pes_type = DMX_PES_AUDIO; // DMX_PES_AUDIO0
68 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
70 eWarning("audio: DMX_SET_PES_FILTER: %m");
73 if (::ioctl(m_fd_demux, DMX_START) < 0)
75 eWarning("audio: DMX_START: %m");
96 if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
97 eWarning("audio: AUDIO_SET_BYPASS_MODE: %m");
99 if (::ioctl(m_fd, AUDIO_PLAY) < 0)
100 eWarning("audio: AUDIO_PLAY: %m");
104 void eDVBAudio::stop()
106 if (::ioctl(m_fd, AUDIO_STOP) < 0)
107 eWarning("audio: AUDIO_STOP: %m");
108 #if HAVE_DVB_API_VERSION > 2
109 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
110 eWarning("audio: DMX_STOP: %m");
114 #if HAVE_DVB_API_VERSION < 3
115 void eDVBAudio::stopPid()
117 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
118 eWarning("audio: DMX_STOP: %m");
122 void eDVBAudio::flush()
124 if (::ioctl(m_fd, AUDIO_CLEAR_BUFFER) < 0)
125 eDebug("audio: AUDIO_CLEAR_BUFFER: %m");
128 void eDVBAudio::freeze()
130 if (::ioctl(m_fd, AUDIO_PAUSE) < 0)
131 eDebug("video: AUDIO_PAUSE: %m");
134 void eDVBAudio::unfreeze()
136 if (::ioctl(m_fd, AUDIO_CONTINUE) < 0)
137 eDebug("video: AUDIO_CONTINUE: %m");
140 int eDVBAudio::getPTS(pts_t &now)
142 return ::ioctl(m_fd, AUDIO_GET_PTS, &now);
145 eDVBAudio::~eDVBAudio()
153 DEFINE_REF(eDVBVideo);
155 eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev): m_demux(demux)
158 #if HAVE_DVB_API_VERSION < 3
159 sprintf(filename, "/dev/dvb/card%d/video%d", demux->adapter, dev);
161 sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev);
163 m_fd = ::open(filename, O_RDWR);
165 eWarning("%s: %m", filename);
166 #if HAVE_DVB_API_VERSION < 3
167 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
169 sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
171 m_fd_demux = ::open(filename, O_RDWR);
173 eWarning("%s: %m", filename);
176 int eDVBVideo::startPid(int pid)
178 if ((m_fd < 0) || (m_fd_demux < 0))
180 dmx_pes_filter_params pes;
183 pes.input = DMX_IN_FRONTEND;
184 pes.output = DMX_OUT_DECODER;
185 pes.pes_type = DMX_PES_VIDEO;
187 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
189 eWarning("video: DMX_SET_PES_FILTER: %m");
192 if (::ioctl(m_fd_demux, DMX_START) < 0)
194 eWarning("video: DMX_START: %m");
197 if (::ioctl(m_fd, VIDEO_PLAY) < 0)
198 eWarning("video: VIDEO_PLAY: %m");
202 void eDVBVideo::stop()
204 #if HAVE_DVB_API_VERSION > 2
205 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
206 eWarning("video: DMX_STOP: %m");
208 eDebug("VIDEO_STOP");
209 if (::ioctl(m_fd, VIDEO_STOP, 1) < 0)
210 eWarning("video: VIDEO_STOP: %m");
213 #if HAVE_DVB_API_VERSION < 3
214 void eDVBVideo::stopPid()
216 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
217 eWarning("video: DMX_STOP: %m");
221 void eDVBVideo::flush()
223 if (::ioctl(m_fd, VIDEO_CLEAR_BUFFER) < 0)
224 eDebug("video: VIDEO_CLEAR_BUFFER: %m");
227 void eDVBVideo::freeze()
229 if (::ioctl(m_fd, VIDEO_FREEZE) < 0)
230 eDebug("video: VIDEO_FREEZE: %m");
233 void eDVBVideo::unfreeze()
235 if (::ioctl(m_fd, VIDEO_CONTINUE) < 0)
236 eDebug("video: VIDEO_CONTINUE: %m");
239 int eDVBVideo::setSlowMotion(int repeat)
241 m_is_slow_motion = repeat;
242 return ::ioctl(m_fd, VIDEO_SLOWMOTION, repeat);
245 int eDVBVideo::setFastForward(int skip)
247 m_is_fast_forward = skip;
248 return ::ioctl(m_fd, VIDEO_FAST_FORWARD, skip);
251 int eDVBVideo::getPTS(pts_t &now)
253 return ::ioctl(m_fd, VIDEO_GET_PTS, &now);
256 eDVBVideo::~eDVBVideo()
258 if (m_is_slow_motion)
260 if (m_is_fast_forward)
270 eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux)
273 #if HAVE_DVB_API_VERSION < 3
274 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
276 sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
278 m_fd_demux = ::open(filename, O_RDWR);
280 eWarning("%s: %m", filename);
283 int eDVBPCR::startPid(int pid)
287 dmx_pes_filter_params pes;
290 pes.input = DMX_IN_FRONTEND;
291 pes.output = DMX_OUT_DECODER;
292 pes.pes_type = DMX_PES_PCR;
294 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
296 eWarning("video: DMX_SET_PES_FILTER: %m");
299 if (::ioctl(m_fd_demux, DMX_START) < 0)
301 eWarning("video: DMX_START: %m");
309 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
310 eWarning("video: DMX_STOP: %m");
319 DEFINE_REF(eDVBTText);
321 eDVBTText::eDVBTText(eDVBDemux *demux): m_demux(demux)
324 #if HAVE_DVB_API_VERSION < 3
325 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
327 sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
329 m_fd_demux = ::open(filename, O_RDWR);
331 eWarning("%s: %m", filename);
334 int eDVBTText::startPid(int pid)
338 dmx_pes_filter_params pes;
341 pes.input = DMX_IN_FRONTEND;
342 pes.output = DMX_OUT_DECODER;
343 pes.pes_type = DMX_PES_TELETEXT;
345 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
347 eWarning("video: DMX_SET_PES_FILTER: %m");
350 if (::ioctl(m_fd_demux, DMX_START) < 0)
352 eWarning("video: DMX_START: %m");
358 void eDVBTText::stop()
360 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
361 eWarning("video: DMX_STOP: %m");
364 eDVBTText::~eDVBTText()
370 DEFINE_REF(eTSMPEGDecoder);
372 int eTSMPEGDecoder::setState()
376 int noaudio = m_is_sm || m_is_ff || m_is_trickmode;
377 int nott = noaudio; /* actually same conditions */
379 if ((noaudio && m_audio) || (!m_audio && !noaudio))
380 m_changed |= changeAudio;
382 if ((nott && m_text) || (!m_text && !nott))
383 m_changed |= changeText;
385 #if HAVE_DVB_API_VERSION < 3
386 if (m_changed & changeAudio && m_audio)
388 if (m_changed & changeVideo && m_video)
390 if (m_changed & changePCR && m_pcr)
395 if (m_changed & changeAudio && m_audio)
400 if (m_changed & changeVideo && m_video)
405 if (m_changed & changePCR)
407 m_pcr = new eDVBPCR(m_demux);
408 if (m_pcr->startPid(m_pcrpid))
410 eWarning("pcr: startpid failed!");
413 m_changed &= ~changePCR;
415 if (m_changed & changeVideo)
417 m_video = new eDVBVideo(m_demux, 0);
418 if (m_video->startPid(m_vpid))
420 eWarning("video: startpid failed!");
423 m_changed &= ~changeVideo;
425 if (m_changed & changeAudio)
427 m_audio = new eDVBAudio(m_demux, 0);
428 if (m_audio->startPid(m_apid, m_atype))
430 eWarning("audio: startpid failed!");
433 m_changed &= ~changeAudio;
436 if (m_changed & changePCR)
441 if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
443 m_pcr = new eDVBPCR(m_demux);
444 if (m_pcr->startPid(m_pcrpid))
446 eWarning("pcr: startpid failed!");
450 m_changed &= ~changePCR;
452 if (m_changed & changeVideo)
454 eDebug("VIDEO CHANGED (to %04x)", m_vpid);
461 if ((m_vpid >= 0) && (m_vpid < 0x1FFF))
464 m_video = new eDVBVideo(m_demux, 0);
465 if (m_video->startPid(m_vpid))
467 eWarning("video: startpid failed!");
471 m_changed &= ~changeVideo;
473 if (m_changed & changeAudio)
478 if ((m_apid >= 0) && (m_apid < 0x1FFF) && !noaudio)
480 m_audio = new eDVBAudio(m_demux, 0);
481 if (m_audio->startPid(m_apid, m_atype))
483 eWarning("audio: startpid failed!");
487 m_changed &= ~changeAudio;
489 if (m_changed & changeText)
494 if ((m_textpid >= 0) && (m_textpid < 0x1FFF) && !nott)
496 m_text = new eDVBTText(m_demux);
497 if (m_text->startPid(m_textpid))
499 eWarning("text: startpid failed!");
503 m_changed &= ~changeText;
509 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder): m_demux(demux), m_changed(0)
511 demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event);
512 m_is_ff = m_is_sm = m_is_trickmode = 0;
515 eTSMPEGDecoder::~eTSMPEGDecoder()
517 m_vpid = m_apid = m_pcrpid = pidNone;
522 RESULT eTSMPEGDecoder::setVideoPID(int vpid)
526 m_changed |= changeVideo;
532 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
534 if ((m_apid != apid) || (m_atype != type))
536 m_changed |= changeAudio;
543 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
545 if (m_pcrpid != pcrpid)
547 m_changed |= changePCR;
553 RESULT eTSMPEGDecoder::setTextPID(int textpid)
555 if (m_textpid != textpid)
557 m_changed |= changeText;
563 RESULT eTSMPEGDecoder::setSyncMaster(int who)
568 RESULT eTSMPEGDecoder::start()
573 RESULT eTSMPEGDecoder::freeze(int cont)
584 RESULT eTSMPEGDecoder::unfreeze()
595 RESULT eTSMPEGDecoder::setSinglePictureMode(int when)
600 RESULT eTSMPEGDecoder::setPictureSkipMode(int what)
605 RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip)
607 m_is_ff = frames_to_skip != 0;
612 return m_video->setFastForward(frames_to_skip);
617 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
619 m_is_sm = repeat != 0;
624 return m_video->setSlowMotion(repeat);
629 RESULT eTSMPEGDecoder::setZoom(int what)
634 RESULT eTSMPEGDecoder::flush()
643 void eTSMPEGDecoder::demux_event(int event)
647 case eDVBDemux::evtFlush:
655 RESULT eTSMPEGDecoder::setTrickmode(int what)
657 m_is_trickmode = what;
662 RESULT eTSMPEGDecoder::getPTS(int what, pts_t &pts)
664 if (what == 0) /* auto */
665 what = m_video ? 1 : 2;
667 if (what == 1) /* video */
670 return m_video->getPTS(pts);
675 if (what == 2) /* audio */
678 return m_audio->getPTS(pts);