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 DEFINE_REF(eDVBAudio);
30 eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev): m_demux(demux)
33 #if HAVE_DVB_API_VERSION < 3
34 sprintf(filename, "/dev/dvb/card%d/audio%d", demux->adapter, dev);
36 sprintf(filename, "/dev/dvb/adapter%d/audio%d", demux->adapter, dev);
38 m_fd = ::open(filename, O_RDWR);
40 eWarning("%s: %m", filename);
41 #if HAVE_DVB_API_VERSION < 3
42 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
44 sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
46 m_fd_demux = ::open(filename, O_RDWR);
48 eWarning("%s: %m", filename);
51 int eDVBAudio::startPid(int pid, int type)
53 if ((m_fd < 0) || (m_fd_demux < 0))
55 dmx_pes_filter_params pes;
58 pes.input = DMX_IN_FRONTEND;
59 pes.output = DMX_OUT_DECODER;
60 pes.pes_type = DMX_PES_AUDIO; // DMX_PES_AUDIO0
62 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
64 eWarning("audio: DMX_SET_PES_FILTER: %m");
67 if (::ioctl(m_fd_demux, DMX_START) < 0)
69 eWarning("audio: DMX_START: %m");
90 if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
91 eWarning("audio: AUDIO_SET_BYPASS_MODE: %m");
93 if (::ioctl(m_fd, AUDIO_PLAY) < 0)
94 eWarning("audio: AUDIO_PLAY: %m");
98 void eDVBAudio::stop()
100 if (::ioctl(m_fd, AUDIO_STOP) < 0)
101 eWarning("audio: AUDIO_STOP: %m");
102 #if HAVE_DVB_API_VERSION > 2
103 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
104 eWarning("audio: DMX_STOP: %m");
108 #if HAVE_DVB_API_VERSION < 3
109 void eDVBAudio::stopPid()
111 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
112 eWarning("audio: DMX_STOP: %m");
116 void eDVBAudio::flush()
118 if (::ioctl(m_fd, AUDIO_CLEAR_BUFFER) < 0)
119 eDebug("audio: AUDIO_CLEAR_BUFFER: %m");
122 void eDVBAudio::freeze()
124 if (::ioctl(m_fd, AUDIO_PAUSE) < 0)
125 eDebug("video: AUDIO_PAUSE: %m");
128 void eDVBAudio::unfreeze()
130 if (::ioctl(m_fd, AUDIO_CONTINUE) < 0)
131 eDebug("video: AUDIO_CONTINUE: %m");
134 eDVBAudio::~eDVBAudio()
142 DEFINE_REF(eDVBVideo);
144 eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev): m_demux(demux)
147 #if HAVE_DVB_API_VERSION < 3
148 sprintf(filename, "/dev/dvb/card%d/video%d", demux->adapter, dev);
150 sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev);
152 m_fd = ::open(filename, O_RDWR);
154 eWarning("%s: %m", filename);
155 #if HAVE_DVB_API_VERSION < 3
156 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
158 sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
160 m_fd_demux = ::open(filename, O_RDWR);
162 eWarning("%s: %m", filename);
165 int eDVBVideo::startPid(int pid)
167 if ((m_fd < 0) || (m_fd_demux < 0))
169 dmx_pes_filter_params pes;
172 pes.input = DMX_IN_FRONTEND;
173 pes.output = DMX_OUT_DECODER;
174 pes.pes_type = DMX_PES_VIDEO;
176 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
178 eWarning("video: DMX_SET_PES_FILTER: %m");
181 if (::ioctl(m_fd_demux, DMX_START) < 0)
183 eWarning("video: DMX_START: %m");
186 if (::ioctl(m_fd, VIDEO_PLAY) < 0)
187 eWarning("video: VIDEO_PLAY: %m");
191 void eDVBVideo::stop()
193 #if HAVE_DVB_API_VERSION > 2
194 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
195 eWarning("video: DMX_STOP: %m");
197 eDebug("VIDEO_STOP");
198 if (::ioctl(m_fd, VIDEO_STOP, 1) < 0)
199 eWarning("video: VIDEO_STOP: %m");
202 #if HAVE_DVB_API_VERSION < 3
203 void eDVBVideo::stopPid()
205 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
206 eWarning("video: DMX_STOP: %m");
210 void eDVBVideo::flush()
212 if (::ioctl(m_fd, VIDEO_CLEAR_BUFFER) < 0)
213 eDebug("video: VIDEO_CLEAR_BUFFER: %m");
216 void eDVBVideo::freeze()
218 if (::ioctl(m_fd, VIDEO_FREEZE) < 0)
219 eDebug("video: VIDEO_FREEZE: %m");
222 void eDVBVideo::unfreeze()
224 if (::ioctl(m_fd, VIDEO_CONTINUE) < 0)
225 eDebug("video: VIDEO_CONTINUE: %m");
228 int eDVBVideo::setSlowMotion(int repeat)
230 m_is_slow_motion = repeat;
231 return ::ioctl(m_fd, VIDEO_SLOWMOTION, repeat);
234 int eDVBVideo::setFastForward(int skip)
236 m_is_fast_forward = skip;
237 return ::ioctl(m_fd, VIDEO_FAST_FORWARD, skip);
240 eDVBVideo::~eDVBVideo()
242 if (m_is_slow_motion)
244 if (m_is_fast_forward)
254 eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux)
257 #if HAVE_DVB_API_VERSION < 3
258 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
260 sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
262 m_fd_demux = ::open(filename, O_RDWR);
264 eWarning("%s: %m", filename);
267 int eDVBPCR::startPid(int pid)
271 dmx_pes_filter_params pes;
274 pes.input = DMX_IN_FRONTEND;
275 pes.output = DMX_OUT_DECODER;
276 pes.pes_type = DMX_PES_PCR;
278 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
280 eWarning("video: DMX_SET_PES_FILTER: %m");
283 if (::ioctl(m_fd_demux, DMX_START) < 0)
285 eWarning("video: DMX_START: %m");
293 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
294 eWarning("video: DMX_STOP: %m");
303 DEFINE_REF(eDVBTText);
305 eDVBTText::eDVBTText(eDVBDemux *demux): m_demux(demux)
308 #if HAVE_DVB_API_VERSION < 3
309 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
311 sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
313 m_fd_demux = ::open(filename, O_RDWR);
315 eWarning("%s: %m", filename);
318 int eDVBTText::startPid(int pid)
322 dmx_pes_filter_params pes;
325 pes.input = DMX_IN_FRONTEND;
326 pes.output = DMX_OUT_DECODER;
327 pes.pes_type = DMX_PES_TELETEXT;
329 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
331 eWarning("video: DMX_SET_PES_FILTER: %m");
334 if (::ioctl(m_fd_demux, DMX_START) < 0)
336 eWarning("video: DMX_START: %m");
342 void eDVBTText::stop()
344 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
345 eWarning("video: DMX_STOP: %m");
348 eDVBTText::~eDVBTText()
354 DEFINE_REF(eTSMPEGDecoder);
356 int eTSMPEGDecoder::setState()
360 int noaudio = m_is_sm || m_is_ff || m_is_trickmode;
361 int nott = noaudio; /* actually same conditions */
363 if ((noaudio && m_audio) || (!m_audio && !noaudio))
364 m_changed |= changeAudio;
366 if ((nott && m_text) || (!m_text && !nott))
367 m_changed |= changeText;
369 #if HAVE_DVB_API_VERSION < 3
370 if (m_changed & changeAudio && m_audio)
372 if (m_changed & changeVideo && m_video)
374 if (m_changed & changePCR && m_pcr)
379 if (m_changed & changeAudio && m_audio)
384 if (m_changed & changeVideo && m_video)
389 if (m_changed & changePCR)
391 m_pcr = new eDVBPCR(m_demux);
392 if (m_pcr->startPid(m_pcrpid))
394 eWarning("pcr: startpid failed!");
397 m_changed &= ~changePCR;
399 if (m_changed & changeVideo)
401 m_video = new eDVBVideo(m_demux, 0);
402 if (m_video->startPid(m_vpid))
404 eWarning("video: startpid failed!");
407 m_changed &= ~changeVideo;
409 if (m_changed & changeAudio)
411 m_audio = new eDVBAudio(m_demux, 0);
412 if (m_audio->startPid(m_apid, m_atype))
414 eWarning("audio: startpid failed!");
417 m_changed &= ~changeAudio;
420 if (m_changed & changePCR)
425 if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
427 m_pcr = new eDVBPCR(m_demux);
428 if (m_pcr->startPid(m_pcrpid))
430 eWarning("pcr: startpid failed!");
434 m_changed &= ~changePCR;
436 if (m_changed & changeVideo)
438 eDebug("VIDEO CHANGED (to %04x)", m_vpid);
445 if ((m_vpid >= 0) && (m_vpid < 0x1FFF))
448 m_video = new eDVBVideo(m_demux, 0);
449 if (m_video->startPid(m_vpid))
451 eWarning("video: startpid failed!");
455 m_changed &= ~changeVideo;
457 if (m_changed & changeAudio)
462 if ((m_apid >= 0) && (m_apid < 0x1FFF) && !noaudio)
464 m_audio = new eDVBAudio(m_demux, 0);
465 if (m_audio->startPid(m_apid, m_atype))
467 eWarning("audio: startpid failed!");
471 m_changed &= ~changeAudio;
473 if (m_changed & changeText)
478 if ((m_textpid >= 0) && (m_textpid < 0x1FFF) && !nott)
480 m_text = new eDVBTText(m_demux);
481 if (m_text->startPid(m_textpid))
483 eWarning("text: startpid failed!");
487 m_changed &= ~changeText;
493 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder): m_demux(demux), m_changed(0)
495 demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event);
496 m_is_ff = m_is_sm = m_is_trickmode = 0;
499 eTSMPEGDecoder::~eTSMPEGDecoder()
501 m_vpid = m_apid = m_pcrpid = pidNone;
506 RESULT eTSMPEGDecoder::setVideoPID(int vpid)
510 m_changed |= changeVideo;
516 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
518 if ((m_apid != apid) || (m_atype != type))
520 m_changed |= changeAudio;
527 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
529 if (m_pcrpid != pcrpid)
531 m_changed |= changePCR;
537 RESULT eTSMPEGDecoder::setTextPID(int textpid)
539 if (m_textpid != textpid)
541 m_changed |= changeText;
547 RESULT eTSMPEGDecoder::setSyncMaster(int who)
552 RESULT eTSMPEGDecoder::start()
557 RESULT eTSMPEGDecoder::freeze(int cont)
568 RESULT eTSMPEGDecoder::unfreeze()
579 RESULT eTSMPEGDecoder::setSinglePictureMode(int when)
584 RESULT eTSMPEGDecoder::setPictureSkipMode(int what)
589 RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip)
591 m_is_ff = frames_to_skip != 0;
596 return m_video->setFastForward(frames_to_skip);
601 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
603 m_is_sm = repeat != 0;
608 return m_video->setSlowMotion(repeat);
613 RESULT eTSMPEGDecoder::setZoom(int what)
618 RESULT eTSMPEGDecoder::flush()
627 void eTSMPEGDecoder::demux_event(int event)
631 case eDVBDemux::evtFlush:
639 RESULT eTSMPEGDecoder::setTrickmode(int what)
641 m_is_trickmode = what;