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_VIDEO0 DMX_PES_VIDEO
13 #define DMX_PES_AUDIO0 DMX_PES_AUDIO
14 #define DMX_PES_VIDEO1 DMX_PES_VIDEO
15 #define DMX_PES_AUDIO1 DMX_PES_AUDIO
17 #include <ost/video.h>
18 #include <ost/audio.h>
20 #include <linux/dvb/audio.h>
21 #include <linux/dvb/video.h>
22 #include <linux/dvb/dmx.h>
27 #include <sys/ioctl.h>
30 /* these are quite new... */
32 #define AUDIO_GET_PTS _IOR('o', 19, __u64)
33 #define VIDEO_GET_PTS _IOR('o', 57, __u64)
36 DEFINE_REF(eDVBAudio);
38 eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev): m_demux(demux), m_dev(dev)
41 #if HAVE_DVB_API_VERSION < 3
42 sprintf(filename, "/dev/dvb/card%d/audio%d", demux->adapter, dev);
44 sprintf(filename, "/dev/dvb/adapter%d/audio%d", demux->adapter, dev);
46 m_fd = ::open(filename, O_RDWR);
48 eWarning("%s: %m", filename);
49 #if HAVE_DVB_API_VERSION < 3
50 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
52 sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
54 m_fd_demux = ::open(filename, O_RDWR);
56 eWarning("%s: %m", filename);
59 int eDVBAudio::startPid(int pid, int type)
61 if ((m_fd < 0) || (m_fd_demux < 0))
63 dmx_pes_filter_params pes;
66 pes.input = DMX_IN_FRONTEND;
67 pes.output = DMX_OUT_DECODER;
68 pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */
70 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
72 eWarning("audio: DMX_SET_PES_FILTER: %m");
75 if (::ioctl(m_fd_demux, DMX_START) < 0)
77 eWarning("audio: DMX_START: %m");
98 if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
99 eWarning("audio: AUDIO_SET_BYPASS_MODE: %m");
101 if (::ioctl(m_fd, AUDIO_PLAY) < 0)
102 eWarning("audio: AUDIO_PLAY: %m");
106 void eDVBAudio::stop()
108 if (::ioctl(m_fd, AUDIO_STOP) < 0)
109 eWarning("audio: AUDIO_STOP: %m");
110 #if HAVE_DVB_API_VERSION > 2
111 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
112 eWarning("audio: DMX_STOP: %m");
116 #if HAVE_DVB_API_VERSION < 3
117 void eDVBAudio::stopPid()
119 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
120 eWarning("audio: DMX_STOP: %m");
124 void eDVBAudio::flush()
126 if (::ioctl(m_fd, AUDIO_CLEAR_BUFFER) < 0)
127 eDebug("audio: AUDIO_CLEAR_BUFFER: %m");
130 void eDVBAudio::freeze()
132 if (::ioctl(m_fd, AUDIO_PAUSE) < 0)
133 eDebug("video: AUDIO_PAUSE: %m");
136 void eDVBAudio::unfreeze()
138 if (::ioctl(m_fd, AUDIO_CONTINUE) < 0)
139 eDebug("video: AUDIO_CONTINUE: %m");
142 void eDVBAudio::setChannel(int channel)
144 int val = AUDIO_STEREO;
147 case aMonoLeft: val = AUDIO_MONO_LEFT; break;
148 case aMonoRight: val = AUDIO_MONO_RIGHT; break;
151 if (::ioctl(m_fd, AUDIO_CHANNEL_SELECT, val) < 0)
152 eDebug("video: AUDIO_CHANNEL_SELECT: %m");
155 int eDVBAudio::getPTS(pts_t &now)
157 return ::ioctl(m_fd, AUDIO_GET_PTS, &now);
160 eDVBAudio::~eDVBAudio()
168 DEFINE_REF(eDVBVideo);
170 eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev): m_demux(demux), m_dev(dev)
173 #if HAVE_DVB_API_VERSION < 3
174 sprintf(filename, "/dev/dvb/card%d/video%d", demux->adapter, dev);
176 sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev);
178 m_fd = ::open(filename, O_RDWR);
180 eWarning("%s: %m", filename);
182 eDebug("Video Device: %s", filename);
183 #if HAVE_DVB_API_VERSION < 3
184 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
186 sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
188 m_fd_demux = ::open(filename, O_RDWR);
190 eWarning("%s: %m", filename);
191 eDebug("demux device: %s", filename);
194 // not finally values i think.. !!
195 #define VIDEO_STREAMTYPE_MPEG2 0
196 #define VIDEO_STREAMTYPE_MPEG4_H264 1
198 int eDVBVideo::startPid(int pid, int type)
200 if ((m_fd < 0) || (m_fd_demux < 0))
202 dmx_pes_filter_params pes;
204 if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE,
205 type == MPEG4_H264 ? VIDEO_STREAMTYPE_MPEG4_H264 : VIDEO_STREAMTYPE_MPEG2) < 0)
206 eWarning("video: VIDEO_SET_STREAMTYPE: %m");
209 pes.input = DMX_IN_FRONTEND;
210 pes.output = DMX_OUT_DECODER;
211 pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */
213 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
215 eWarning("video: DMX_SET_PES_FILTER: %m");
218 if (::ioctl(m_fd_demux, DMX_START) < 0)
220 eWarning("video: DMX_START: %m");
223 if (::ioctl(m_fd, VIDEO_PLAY) < 0)
224 eWarning("video: VIDEO_PLAY: %m");
228 void eDVBVideo::stop()
230 #if HAVE_DVB_API_VERSION > 2
231 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
232 eWarning("video: DMX_STOP: %m");
234 eDebug("VIDEO_STOP");
235 if (::ioctl(m_fd, VIDEO_STOP, 1) < 0)
236 eWarning("video: VIDEO_STOP: %m");
239 #if HAVE_DVB_API_VERSION < 3
240 void eDVBVideo::stopPid()
242 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
243 eWarning("video: DMX_STOP: %m");
247 void eDVBVideo::flush()
249 if (::ioctl(m_fd, VIDEO_CLEAR_BUFFER) < 0)
250 eDebug("video: VIDEO_CLEAR_BUFFER: %m");
253 void eDVBVideo::freeze()
255 if (::ioctl(m_fd, VIDEO_FREEZE) < 0)
256 eDebug("video: VIDEO_FREEZE: %m");
259 void eDVBVideo::unfreeze()
261 if (::ioctl(m_fd, VIDEO_CONTINUE) < 0)
262 eDebug("video: VIDEO_CONTINUE: %m");
265 int eDVBVideo::setSlowMotion(int repeat)
267 m_is_slow_motion = repeat;
268 return ::ioctl(m_fd, VIDEO_SLOWMOTION, repeat);
271 int eDVBVideo::setFastForward(int skip)
273 m_is_fast_forward = skip;
274 return ::ioctl(m_fd, VIDEO_FAST_FORWARD, skip);
277 int eDVBVideo::getPTS(pts_t &now)
279 return ::ioctl(m_fd, VIDEO_GET_PTS, &now);
282 eDVBVideo::~eDVBVideo()
284 if (m_is_slow_motion)
286 if (m_is_fast_forward)
296 eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux)
299 #if HAVE_DVB_API_VERSION < 3
300 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
302 sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
304 m_fd_demux = ::open(filename, O_RDWR);
306 eWarning("%s: %m", filename);
309 int eDVBPCR::startPid(int pid)
313 dmx_pes_filter_params pes;
316 pes.input = DMX_IN_FRONTEND;
317 pes.output = DMX_OUT_DECODER;
318 pes.pes_type = DMX_PES_PCR;
320 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
322 eWarning("video: DMX_SET_PES_FILTER: %m");
325 if (::ioctl(m_fd_demux, DMX_START) < 0)
327 eWarning("video: DMX_START: %m");
335 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
336 eWarning("video: DMX_STOP: %m");
345 DEFINE_REF(eDVBTText);
347 eDVBTText::eDVBTText(eDVBDemux *demux): m_demux(demux)
350 #if HAVE_DVB_API_VERSION < 3
351 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
353 sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
355 m_fd_demux = ::open(filename, O_RDWR);
357 eWarning("%s: %m", filename);
360 int eDVBTText::startPid(int pid)
364 dmx_pes_filter_params pes;
367 pes.input = DMX_IN_FRONTEND;
368 pes.output = DMX_OUT_DECODER;
369 pes.pes_type = DMX_PES_TELETEXT;
371 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
373 eWarning("video: DMX_SET_PES_FILTER: %m");
376 if (::ioctl(m_fd_demux, DMX_START) < 0)
378 eWarning("video: DMX_START: %m");
384 void eDVBTText::stop()
386 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
387 eWarning("video: DMX_STOP: %m");
390 eDVBTText::~eDVBTText()
396 DEFINE_REF(eTSMPEGDecoder);
398 int eTSMPEGDecoder::setState()
402 int noaudio = m_is_sm || m_is_ff || m_is_trickmode;
403 int nott = noaudio; /* actually same conditions */
405 if ((noaudio && m_audio) || (!m_audio && !noaudio))
406 m_changed |= changeAudio;
408 if ((nott && m_text) || (!m_text && !nott))
409 m_changed |= changeText;
411 bool changed = !!m_changed;
412 #if HAVE_DVB_API_VERSION < 3
413 if (m_changed & changeAudio && m_audio)
415 if (m_changed & changeVideo && m_video)
417 if (m_changed & changePCR && m_pcr)
422 if (m_changed & changeAudio && m_audio)
427 if (m_changed & changeVideo && m_video)
432 if (m_changed & changePCR)
434 m_pcr = new eDVBPCR(m_demux);
435 if (m_pcr->startPid(m_pcrpid))
437 eWarning("pcr: startpid failed!");
440 m_changed &= ~changePCR;
442 if (m_changed & changeVideo)
444 m_video = new eDVBVideo(m_demux, m_decoder);
445 if (m_video->startPid(m_vpid))
447 eWarning("video: startpid failed!");
450 m_changed &= ~changeVideo;
452 if (m_changed & changeAudio)
454 m_audio = new eDVBAudio(m_demux, m_decoder);
455 if (m_audio->startPid(m_apid, m_atype))
457 eWarning("audio: startpid failed!");
460 m_changed &= ~changeAudio;
463 if (m_changed & changePCR)
468 if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
470 m_pcr = new eDVBPCR(m_demux);
471 if (m_pcr->startPid(m_pcrpid))
473 eWarning("pcr: startpid failed!");
477 m_changed &= ~changePCR;
479 if (m_changed & changeVideo)
481 eDebug("VIDEO CHANGED (to %04x)", m_vpid);
488 if ((m_vpid >= 0) && (m_vpid < 0x1FFF))
491 m_video = new eDVBVideo(m_demux, m_decoder);
492 if (m_video->startPid(m_vpid, m_vtype))
494 eWarning("video: startpid failed!");
498 m_changed &= ~changeVideo;
500 if (m_changed & changeAudio)
505 if ((m_apid >= 0) && (m_apid < 0x1FFF) && !noaudio)
507 m_audio = new eDVBAudio(m_demux, m_decoder);
508 if (m_audio->startPid(m_apid, m_atype))
510 eWarning("audio: startpid failed!");
514 m_changed &= ~changeAudio;
516 if (m_changed & changeText)
521 if ((m_textpid >= 0) && (m_textpid < 0x1FFF) && !nott)
523 m_text = new eDVBTText(m_demux);
524 if (m_text->startPid(m_textpid))
526 eWarning("text: startpid failed!");
530 m_changed &= ~changeText;
533 if (changed && !m_video && m_audio && m_radio_pic.length())
534 showSinglePic(m_radio_pic.c_str());
539 int eTSMPEGDecoder::m_pcm_delay=-1,
540 eTSMPEGDecoder::m_ac3_delay=-1;
542 RESULT eTSMPEGDecoder::setPCMDelay(int delay)
544 if (m_decoder == 0 && delay != m_pcm_delay )
546 FILE *fp = fopen("/proc/stb/audio/audio_delay_pcm", "w");
549 fprintf(fp, "%x", delay*90);
556 RESULT eTSMPEGDecoder::setAC3Delay(int delay)
558 if ( m_decoder == 0 && delay != m_ac3_delay )
560 FILE *fp = fopen("/proc/stb/audio/audio_delay_bitstream", "w");
563 fprintf(fp, "%x", delay*90);
570 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder): m_demux(demux), m_changed(0), m_decoder(decoder)
572 demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event);
573 m_is_ff = m_is_sm = m_is_trickmode = 0;
576 eTSMPEGDecoder::~eTSMPEGDecoder()
578 m_vpid = m_apid = m_pcrpid = pidNone;
583 RESULT eTSMPEGDecoder::setVideoPID(int vpid, int type)
587 m_changed |= changeVideo;
594 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
596 if ((m_apid != apid) || (m_atype != type))
598 m_changed |= changeAudio;
605 int eTSMPEGDecoder::m_audio_channel = -1;
607 RESULT eTSMPEGDecoder::setAudioChannel(int channel)
611 if (m_decoder == 0 && m_audio_channel != channel)
615 m_audio->setChannel(channel);
616 m_audio_channel=channel;
619 eDebug("eTSMPEGDecoder::setAudioChannel but no audio decoder exist");
624 int eTSMPEGDecoder::getAudioChannel()
626 return m_audio_channel == -1 ? ac_stereo : m_audio_channel;
629 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
631 if (m_pcrpid != pcrpid)
633 m_changed |= changePCR;
639 RESULT eTSMPEGDecoder::setTextPID(int textpid)
641 if (m_textpid != textpid)
643 m_changed |= changeText;
649 RESULT eTSMPEGDecoder::setSyncMaster(int who)
654 RESULT eTSMPEGDecoder::start()
659 RESULT eTSMPEGDecoder::freeze(int cont)
670 RESULT eTSMPEGDecoder::unfreeze()
681 RESULT eTSMPEGDecoder::setSinglePictureMode(int when)
686 RESULT eTSMPEGDecoder::setPictureSkipMode(int what)
691 RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip)
693 m_is_ff = frames_to_skip != 0;
698 return m_video->setFastForward(frames_to_skip);
703 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
705 m_is_sm = repeat != 0;
710 return m_video->setSlowMotion(repeat);
715 RESULT eTSMPEGDecoder::setZoom(int what)
720 RESULT eTSMPEGDecoder::flush()
729 void eTSMPEGDecoder::demux_event(int event)
733 case eDVBDemux::evtFlush:
741 RESULT eTSMPEGDecoder::setTrickmode(int what)
743 m_is_trickmode = what;
748 RESULT eTSMPEGDecoder::getPTS(int what, pts_t &pts)
750 if (what == 0) /* auto */
751 what = m_video ? 1 : 2;
753 if (what == 1) /* video */
756 return m_video->getPTS(pts);
761 if (what == 2) /* audio */
764 return m_audio->getPTS(pts);
772 RESULT eTSMPEGDecoder::setRadioPic(const std::string &filename)
774 m_radio_pic = filename;
777 RESULT eTSMPEGDecoder::showSinglePic(const char *filename)
781 FILE *f = fopen(filename, "r");
784 int vfd = open("/dev/dvb/adapter0/video0", O_RDWR);
787 fseek(f, 0, SEEK_END);
788 int length = ftell(f);
789 unsigned char *buffer = new unsigned char[length*3+9];
790 if (ioctl(vfd, VIDEO_FAST_FORWARD, 1) < 0)
791 eDebug("VIDEO_FAST_FORWARD failed (%m)");
792 if (ioctl(vfd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)
793 eDebug("VIDEO_SELECT_SOURCE MEMORY failed (%m)");
794 if (ioctl(vfd, VIDEO_PLAY) < 0)
795 eDebug("VIDEO_PLAY failed (%m)");
801 fseek(f, 0, SEEK_SET);
810 buffer[pos++]=(length*3)>>8;
811 buffer[pos++]=(length*3)&0xFF;
816 rd = fread(buffer+pos, 1, length, f);
824 write(vfd, buffer, pos);
825 usleep(75000); // i dont like this.. but i dont have a better solution :(
826 if (ioctl(vfd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX) < 0)
827 eDebug("VIDEO_SELECT_SOURCE DEMUX failed (%m)");
828 if (ioctl(vfd, VIDEO_FAST_FORWARD, 0) < 0)
829 eDebug("VIDEO_FAST_FORWARD failed (%m)");
837 eDebug("couldnt open %s", filename);
843 eDebug("only show single pics on first decoder");