1 #include <lib/base/ebase.h>
2 #include <lib/base/eerror.h>
3 #include <lib/dvb/decoder.h>
4 #if HAVE_DVB_API_VERSION < 3
5 #define audioStatus audio_status
6 #define videoStatus video_status
7 #define pesType pes_type
8 #define playState play_state
9 #define audioStreamSource_t audio_stream_source_t
10 #define videoStreamSource_t video_stream_source_t
11 #define streamSource stream_source
12 #define dmxPesFilterParams dmx_pes_filter_params
13 #define DMX_PES_VIDEO0 DMX_PES_VIDEO
14 #define DMX_PES_AUDIO0 DMX_PES_AUDIO
15 #define DMX_PES_VIDEO1 DMX_PES_VIDEO
16 #define DMX_PES_AUDIO1 DMX_PES_AUDIO
18 #include <ost/video.h>
19 #include <ost/audio.h>
21 #include <linux/dvb/audio.h>
22 #include <linux/dvb/video.h>
23 #include <linux/dvb/dmx.h>
28 #include <sys/ioctl.h>
31 /* these are quite new... */
33 #define AUDIO_GET_PTS _IOR('o', 19, __u64)
34 #define VIDEO_GET_PTS _IOR('o', 57, __u64)
37 DEFINE_REF(eDVBAudio);
39 eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev): m_demux(demux), m_dev(dev)
42 #if HAVE_DVB_API_VERSION < 3
43 sprintf(filename, "/dev/dvb/card%d/audio%d", demux->adapter, dev);
45 sprintf(filename, "/dev/dvb/adapter%d/audio%d", demux->adapter, dev);
47 m_fd = ::open(filename, O_RDWR);
49 eWarning("%s: %m", filename);
50 #if HAVE_DVB_API_VERSION < 3
51 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
53 sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
55 m_fd_demux = ::open(filename, O_RDWR);
57 eWarning("%s: %m", filename);
60 #if HAVE_DVB_API_VERSION < 3
61 int eDVBAudio::setPid(int pid, int type)
63 if ((m_fd < 0) || (m_fd_demux < 0))
83 if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
84 eWarning("audio: AUDIO_SET_BYPASS_MODE: %m");
86 dmx_pes_filter_params pes;
89 pes.input = DMX_IN_FRONTEND;
90 pes.output = DMX_OUT_DECODER;
91 pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */
93 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
95 eWarning("audio: DMX_SET_PES_FILTER: %m");
102 int eDVBAudio::startPid()
104 if (::ioctl(m_fd_demux, DMX_START) < 0)
106 eWarning("audio: DMX_START: %m");
112 int eDVBAudio::start()
114 if (::ioctl(m_fd, AUDIO_PLAY) < 0)
116 eWarning("audio: AUDIO_PLAY: %m");
122 int eDVBAudio::stopPid()
124 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
126 eWarning("audio: DMX_STOP: %m");
132 int eDVBAudio::setAVSync(int val)
134 if (::ioctl(m_fd, AUDIO_SET_AV_SYNC, val) < 0)
136 eWarning("audio: AUDIO_SET_AV_SYNC: %m");
142 int eDVBAudio::startPid(int pid, int type)
144 if ((m_fd < 0) || (m_fd_demux < 0))
146 dmx_pes_filter_params pes;
149 pes.input = DMX_IN_FRONTEND;
150 pes.output = DMX_OUT_DECODER;
151 pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */
153 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
155 eWarning("audio: DMX_SET_PES_FILTER: %m");
158 if (::ioctl(m_fd_demux, DMX_START) < 0)
160 eWarning("audio: DMX_START: %m");
181 if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
182 eWarning("audio: AUDIO_SET_BYPASS_MODE: %m");
186 if (::ioctl(m_fd, AUDIO_PLAY) < 0)
187 eWarning("audio: AUDIO_PLAY: %m");
192 void eDVBAudio::stop()
194 #if HAVE_DVB_API_VERSION > 2
197 if (::ioctl(m_fd, AUDIO_STOP) < 0)
198 eWarning("audio: AUDIO_STOP: %m");
199 #if HAVE_DVB_API_VERSION > 2
200 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
201 eWarning("audio: DMX_STOP: %m");
205 void eDVBAudio::flush()
207 if (::ioctl(m_fd, AUDIO_CLEAR_BUFFER) < 0)
208 eDebug("audio: AUDIO_CLEAR_BUFFER: %m");
211 void eDVBAudio::freeze()
213 if (::ioctl(m_fd, AUDIO_PAUSE) < 0)
214 eDebug("video: AUDIO_PAUSE: %m");
217 void eDVBAudio::unfreeze()
219 if (::ioctl(m_fd, AUDIO_CONTINUE) < 0)
220 eDebug("video: AUDIO_CONTINUE: %m");
223 void eDVBAudio::setChannel(int channel)
225 int val = AUDIO_STEREO;
228 case aMonoLeft: val = AUDIO_MONO_LEFT; break;
229 case aMonoRight: val = AUDIO_MONO_RIGHT; break;
232 if (::ioctl(m_fd, AUDIO_CHANNEL_SELECT, val) < 0)
233 eDebug("video: AUDIO_CHANNEL_SELECT: %m");
236 int eDVBAudio::getPTS(pts_t &now)
238 return ::ioctl(m_fd, AUDIO_GET_PTS, &now);
241 eDVBAudio::~eDVBAudio()
250 DEFINE_REF(eDVBVideo);
252 eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev): m_demux(demux), m_dev(dev)
255 #if HAVE_DVB_API_VERSION < 3
256 sprintf(filename, "/dev/dvb/card%d/video%d", demux->adapter, dev);
258 sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev);
260 m_fd = ::open(filename, O_RDWR);
262 eWarning("%s: %m", filename);
265 m_sn = new eSocketNotifier(eApp, m_fd, eSocketNotifier::Priority);
266 CONNECT(m_sn->activated, eDVBVideo::video_event);
268 eDebug("Video Device: %s", filename);
269 #if HAVE_DVB_API_VERSION < 3
270 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
272 sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
274 m_fd_demux = ::open(filename, O_RDWR);
276 eWarning("%s: %m", filename);
277 eDebug("demux device: %s", filename);
280 // not finally values i think.. !!
281 #define VIDEO_STREAMTYPE_MPEG2 0
282 #define VIDEO_STREAMTYPE_MPEG4_H264 1
284 #if HAVE_DVB_API_VERSION < 3
285 int eDVBVideo::setPid(int pid)
287 if ((m_fd < 0) || (m_fd_demux < 0))
289 dmx_pes_filter_params pes;
292 pes.input = DMX_IN_FRONTEND;
293 pes.output = DMX_OUT_DECODER;
294 pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */
296 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
298 eWarning("video: DMX_SET_PES_FILTER: %m");
304 int eDVBVideo::startPid()
306 if (::ioctl(m_fd_demux, DMX_START) < 0)
308 eWarning("video: DMX_START: %m");
314 int eDVBVideo::start()
316 if (::ioctl(m_fd, VIDEO_PLAY) < 0)
318 eWarning("video: VIDEO_PLAY: %m");
324 int eDVBVideo::stopPid()
326 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
328 eWarning("video: DMX_STOP: %m");
334 int eDVBVideo::startPid(int pid, int type)
336 if ((m_fd < 0) || (m_fd_demux < 0))
338 dmx_pes_filter_params pes;
340 if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE,
341 type == MPEG4_H264 ? VIDEO_STREAMTYPE_MPEG4_H264 : VIDEO_STREAMTYPE_MPEG2) < 0)
342 eWarning("video: VIDEO_SET_STREAMTYPE: %m");
345 pes.input = DMX_IN_FRONTEND;
346 pes.output = DMX_OUT_DECODER;
347 pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */
349 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
351 eWarning("video: DMX_SET_PES_FILTER: %m");
354 if (::ioctl(m_fd_demux, DMX_START) < 0)
356 eWarning("video: DMX_START: %m");
363 if (::ioctl(m_fd, VIDEO_PLAY) < 0)
364 eWarning("video: VIDEO_PLAY: %m");
369 void eDVBVideo::stop()
371 #if HAVE_DVB_API_VERSION > 2
372 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
373 eWarning("video: DMX_STOP: %m");
375 eDebug("VIDEO_STOP");
376 if (::ioctl(m_fd, VIDEO_STOP, 1) < 0)
377 eWarning("video: VIDEO_STOP: %m");
380 void eDVBVideo::flush()
382 if (::ioctl(m_fd, VIDEO_CLEAR_BUFFER) < 0)
383 eDebug("video: VIDEO_CLEAR_BUFFER: %m");
386 void eDVBVideo::freeze()
388 eDebug("VIDEO_FREEZE");
389 if (::ioctl(m_fd, VIDEO_FREEZE) < 0)
390 eDebug("video: VIDEO_FREEZE: %m");
393 void eDVBVideo::unfreeze()
395 eDebug("VIDEO_CONTINUE");
396 if (::ioctl(m_fd, VIDEO_CONTINUE) < 0)
397 eDebug("video: VIDEO_CONTINUE: %m");
400 int eDVBVideo::setSlowMotion(int repeat)
402 m_is_slow_motion = repeat;
403 return ::ioctl(m_fd, VIDEO_SLOWMOTION, repeat);
406 int eDVBVideo::setFastForward(int skip)
408 m_is_fast_forward = skip;
409 return ::ioctl(m_fd, VIDEO_FAST_FORWARD, skip);
412 int eDVBVideo::getPTS(pts_t &now)
414 return ::ioctl(m_fd, VIDEO_GET_PTS, &now);
417 eDVBVideo::~eDVBVideo()
421 if (m_is_slow_motion)
423 if (m_is_fast_forward)
432 void eDVBVideo::video_event(int)
434 #if HAVE_DVB_API_VERSION >= 3
435 struct video_event evt;
436 if (::ioctl(m_fd, VIDEO_GET_EVENT, &evt) < 0)
437 eDebug("VIDEO_GET_EVENT failed(%m)");
440 if (evt.type == VIDEO_EVENT_SIZE_CHANGED)
442 struct iTSMPEGDecoder::videoEvent event;
443 event.type = iTSMPEGDecoder::videoEvent::eventSizeChanged;
444 event.aspect = evt.u.size.aspect_ratio;
445 event.height = evt.u.size.h;
446 event.width = evt.u.size.w;
447 /* emit */ m_event(event);
450 eDebug("unhandled DVBAPI Video Event %d", evt.type);
453 #warning "FIXMEE!! Video Events not implemented for old api"
457 RESULT eDVBVideo::connectEvent(const Slot1<void, struct iTSMPEGDecoder::videoEvent> &event, ePtr<eConnection> &conn)
459 conn = new eConnection(this, m_event.connect(event));
465 eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux)
468 #if HAVE_DVB_API_VERSION < 3
469 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
471 sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
473 m_fd_demux = ::open(filename, O_RDWR);
475 eWarning("%s: %m", filename);
478 #if HAVE_DVB_API_VERSION < 3
479 int eDVBPCR::setPid(int pid)
483 dmx_pes_filter_params pes;
486 pes.input = DMX_IN_FRONTEND;
487 pes.output = DMX_OUT_DECODER;
488 pes.pes_type = DMX_PES_PCR;
490 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
492 eWarning("video: DMX_SET_PES_FILTER: %m");
498 int eDVBPCR::startPid()
502 if (::ioctl(m_fd_demux, DMX_START) < 0)
504 eWarning("video: DMX_START: %m");
510 int eDVBPCR::startPid(int pid)
514 dmx_pes_filter_params pes;
517 pes.input = DMX_IN_FRONTEND;
518 pes.output = DMX_OUT_DECODER;
519 pes.pes_type = DMX_PES_PCR;
521 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
523 eWarning("video: DMX_SET_PES_FILTER: %m");
526 if (::ioctl(m_fd_demux, DMX_START) < 0)
528 eWarning("video: DMX_START: %m");
537 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
538 eWarning("video: DMX_STOP: %m");
547 DEFINE_REF(eDVBTText);
549 eDVBTText::eDVBTText(eDVBDemux *demux): m_demux(demux)
552 #if HAVE_DVB_API_VERSION < 3
553 sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
555 sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
557 m_fd_demux = ::open(filename, O_RDWR);
559 eWarning("%s: %m", filename);
562 int eDVBTText::startPid(int pid)
566 dmx_pes_filter_params pes;
569 pes.input = DMX_IN_FRONTEND;
570 pes.output = DMX_OUT_DECODER;
571 pes.pes_type = DMX_PES_TELETEXT;
573 if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
575 eWarning("video: DMX_SET_PES_FILTER: %m");
578 if (::ioctl(m_fd_demux, DMX_START) < 0)
580 eWarning("video: DMX_START: %m");
586 void eDVBTText::stop()
588 if (::ioctl(m_fd_demux, DMX_STOP) < 0)
589 eWarning("video: DMX_STOP: %m");
592 eDVBTText::~eDVBTText()
598 DEFINE_REF(eTSMPEGDecoder);
600 int eTSMPEGDecoder::setState()
604 int noaudio = m_is_sm || m_is_ff || m_is_trickmode;
605 int nott = noaudio; /* actually same conditions */
607 if ((noaudio && m_audio) || (!m_audio && !noaudio))
608 m_changed |= changeAudio;
610 if ((nott && m_text) || (!m_text && !nott))
611 m_changed |= changeText;
613 bool changed = !!m_changed;
614 #if HAVE_DVB_API_VERSION < 3
615 if (m_changed & changeAudio && m_audio)
617 if (m_changed & changeVideo && m_video)
619 if (m_changed & changePCR && m_pcr)
624 if (m_changed & changeAudio && m_audio)
629 if (m_changed & changeVideo && m_video)
633 m_video_event_conn=0;
635 if (m_changed & changeVideo)
637 m_video = new eDVBVideo(m_demux, m_decoder);
638 m_video->connectEvent(slot(*this, &eTSMPEGDecoder::video_event), m_video_event_conn);
639 if (m_video->setPid(m_vpid))
642 if (m_changed & changePCR)
644 m_pcr = new eDVBPCR(m_demux);
645 if (m_pcr->setPid(m_pcrpid))
648 if (m_changed & changeAudio)
650 m_audio = new eDVBAudio(m_demux, m_decoder);
651 if (m_audio->setPid(m_apid, m_atype))
654 if (m_changed & changePCR && m_pcrpid != -1)
656 if (m_pcr->startPid())
658 m_changed &= ~changePCR;
660 else if (m_apid != -1 && m_vpid != -1) // playback
662 if (m_audio->setAVSync(1))
666 if (m_changed & changeVideo)
668 if (m_video->startPid() || m_video->start())
670 m_changed &= ~changeVideo;
672 if (m_changed & changeAudio)
674 if (m_audio->start() || m_audio->startPid())
676 m_changed &= ~changeAudio;
679 if (m_changed & changePCR)
684 if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
686 m_pcr = new eDVBPCR(m_demux);
687 if (m_pcr->startPid(m_pcrpid))
689 eWarning("pcr: startpid failed!");
693 m_changed &= ~changePCR;
695 if (m_changed & changeVideo)
697 eDebug("VIDEO CHANGED (to %04x)", m_vpid);
703 m_video_event_conn = 0;
705 if ((m_vpid >= 0) && (m_vpid < 0x1FFF))
708 m_video = new eDVBVideo(m_demux, m_decoder);
709 m_video->connectEvent(slot(*this, &eTSMPEGDecoder::video_event), m_video_event_conn);
710 if (m_video->startPid(m_vpid, m_vtype))
712 eWarning("video: startpid failed!");
716 m_changed &= ~changeVideo;
718 if (m_changed & changeAudio)
723 if ((m_apid >= 0) && (m_apid < 0x1FFF) && !noaudio)
725 m_audio = new eDVBAudio(m_demux, m_decoder);
726 if (m_audio->startPid(m_apid, m_atype))
728 eWarning("audio: startpid failed!");
732 m_changed &= ~changeAudio;
734 if (m_changed & changeText)
739 if ((m_textpid >= 0) && (m_textpid < 0x1FFF) && !nott)
741 m_text = new eDVBTText(m_demux);
742 if (m_text->startPid(m_textpid))
744 eWarning("text: startpid failed!");
748 m_changed &= ~changeText;
751 if (changed && !m_video && m_audio && m_radio_pic.length())
752 showSinglePic(m_radio_pic.c_str());
757 int eTSMPEGDecoder::m_pcm_delay=-1,
758 eTSMPEGDecoder::m_ac3_delay=-1;
760 RESULT eTSMPEGDecoder::setPCMDelay(int delay)
762 if (m_decoder == 0 && delay != m_pcm_delay )
764 FILE *fp = fopen("/proc/stb/audio/audio_delay_pcm", "w");
767 fprintf(fp, "%x", delay*90);
776 RESULT eTSMPEGDecoder::setAC3Delay(int delay)
778 if ( m_decoder == 0 && delay != m_ac3_delay )
780 FILE *fp = fopen("/proc/stb/audio/audio_delay_bitstream", "w");
783 fprintf(fp, "%x", delay*90);
792 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder): m_demux(demux), m_changed(0), m_decoder(decoder)
794 demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event_conn);
795 m_is_ff = m_is_sm = m_is_trickmode = 0;
798 eTSMPEGDecoder::~eTSMPEGDecoder()
800 m_vpid = m_apid = m_pcrpid = pidNone;
805 RESULT eTSMPEGDecoder::setVideoPID(int vpid, int type)
809 m_changed |= changeVideo;
816 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
818 if ((m_apid != apid) || (m_atype != type))
820 m_changed |= changeAudio;
827 int eTSMPEGDecoder::m_audio_channel = -1;
829 RESULT eTSMPEGDecoder::setAudioChannel(int channel)
833 if (m_decoder == 0 && m_audio_channel != channel)
837 m_audio->setChannel(channel);
838 m_audio_channel=channel;
841 eDebug("eTSMPEGDecoder::setAudioChannel but no audio decoder exist");
846 int eTSMPEGDecoder::getAudioChannel()
848 return m_audio_channel == -1 ? ac_stereo : m_audio_channel;
851 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
853 if (m_pcrpid != pcrpid)
855 m_changed |= changePCR;
861 RESULT eTSMPEGDecoder::setTextPID(int textpid)
863 if (m_textpid != textpid)
865 m_changed |= changeText;
871 RESULT eTSMPEGDecoder::setSyncMaster(int who)
876 RESULT eTSMPEGDecoder::start()
885 /* preroll is start in freezed mode. */
886 RESULT eTSMPEGDecoder::preroll()
891 RESULT eTSMPEGDecoder::freeze(int cont)
902 RESULT eTSMPEGDecoder::unfreeze()
913 RESULT eTSMPEGDecoder::setSinglePictureMode(int when)
918 RESULT eTSMPEGDecoder::setPictureSkipMode(int what)
923 RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip)
925 m_is_ff = frames_to_skip != 0;
930 return m_video->setFastForward(frames_to_skip);
935 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
937 m_is_sm = repeat != 0;
942 return m_video->setSlowMotion(repeat);
947 RESULT eTSMPEGDecoder::setZoom(int what)
952 RESULT eTSMPEGDecoder::flush()
961 void eTSMPEGDecoder::demux_event(int event)
965 case eDVBDemux::evtFlush:
973 RESULT eTSMPEGDecoder::setTrickmode(int what)
975 m_is_trickmode = what;
980 RESULT eTSMPEGDecoder::getPTS(int what, pts_t &pts)
982 if (what == 0) /* auto */
983 what = m_video ? 1 : 2;
985 if (what == 1) /* video */
988 return m_video->getPTS(pts);
993 if (what == 2) /* audio */
996 return m_audio->getPTS(pts);
1004 RESULT eTSMPEGDecoder::setRadioPic(const std::string &filename)
1006 m_radio_pic = filename;
1010 RESULT eTSMPEGDecoder::showSinglePic(const char *filename)
1014 FILE *f = fopen(filename, "r");
1017 int vfd = open("/dev/dvb/adapter0/video0", O_RDWR);
1020 fseek(f, 0, SEEK_END);
1021 int length = ftell(f);
1022 unsigned char *buffer = new unsigned char[length*2+9];
1023 if (ioctl(vfd, VIDEO_FAST_FORWARD, 1) < 0)
1024 eDebug("VIDEO_FAST_FORWARD failed (%m)");
1025 if (ioctl(vfd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_MEMORY) < 0)
1026 eDebug("VIDEO_SELECT_SOURCE MEMORY failed (%m)");
1027 if (ioctl(vfd, VIDEO_PLAY) < 0)
1028 eDebug("VIDEO_PLAY failed (%m)");
1029 if (::ioctl(vfd, VIDEO_CONTINUE) < 0)
1030 eDebug("video: VIDEO_CONTINUE: %m");
1036 fseek(f, 0, SEEK_SET);
1043 buffer[pos++]=(length*2)>>8;
1044 buffer[pos++]=(length*2)&0xFF;
1051 rd = fread(buffer+pos, 1, length, f);
1059 write(vfd, buffer, pos);
1060 usleep(75000); // i dont like this.. but i dont have a better solution :(
1061 if (ioctl(vfd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX) < 0)
1062 eDebug("VIDEO_SELECT_SOURCE DEMUX failed (%m)");
1063 if (ioctl(vfd, VIDEO_FAST_FORWARD, 0) < 0)
1064 eDebug("VIDEO_FAST_FORWARD failed (%m)");
1072 eDebug("couldnt open %s", filename);
1078 eDebug("only show single pics on first decoder");
1084 RESULT eTSMPEGDecoder::connectVideoEvent(const Slot1<void, struct videoEvent> &event, ePtr<eConnection> &conn)
1086 conn = new eConnection(this, m_video_event.connect(event));
1090 void eTSMPEGDecoder::video_event(struct videoEvent event)
1092 /* emit */ m_video_event(event);