more changes for AAC audio support (not dm7025)
[vuplus_dvbapp] / lib / dvb / decoder.cpp
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
14 #include <ost/dmx.h>
15 #include <ost/video.h>
16 #include <ost/audio.h>
17 #else
18 #include <linux/dvb/audio.h>
19 #include <linux/dvb/video.h>
20 #include <linux/dvb/dmx.h>
21 #endif
22
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <sys/ioctl.h>
26 #include <errno.h>
27
28         /* these are quite new... */
29 #ifndef AUDIO_GET_PTS
30 #define AUDIO_GET_PTS              _IOR('o', 19, __u64)
31 #define VIDEO_GET_PTS              _IOR('o', 57, __u64)
32 #endif
33
34 DEFINE_REF(eDVBAudio);
35
36 eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev): m_demux(demux), m_dev(dev)
37 {
38         char filename[128];
39 #if HAVE_DVB_API_VERSION < 3
40         sprintf(filename, "/dev/dvb/card%d/audio%d", demux->adapter, dev);      
41 #else
42         sprintf(filename, "/dev/dvb/adapter%d/audio%d", demux->adapter, dev);
43 #endif
44         m_fd = ::open(filename, O_RDWR);
45         if (m_fd < 0)
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);
49 #else
50         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
51 #endif  
52         m_fd_demux = ::open(filename, O_RDWR);
53         if (m_fd_demux < 0)
54                 eWarning("%s: %m", filename);
55 }
56         
57 int eDVBAudio::startPid(int pid, int type)
58 {       
59         if ((m_fd < 0) || (m_fd_demux < 0))
60                 return -1;
61         dmx_pes_filter_params pes;
62
63         pes.pid      = pid;
64         pes.input    = DMX_IN_FRONTEND;
65         pes.output   = DMX_OUT_DECODER;
66         pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */
67         pes.flags    = 0;
68         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
69         {
70                 eWarning("audio: DMX_SET_PES_FILTER: %m");
71                 return -errno;
72         }
73         if (::ioctl(m_fd_demux, DMX_START) < 0)
74         {
75                 eWarning("audio: DMX_START: %m");
76                 return -errno;
77         }
78         
79         int bypass = 0;
80         
81         switch (type)
82         {
83         case aMPEG:
84                 bypass = 1;
85                 break;
86         case aAC3:
87                 bypass = 0;
88                 break;
89                 /*
90         case aDTS:
91                 bypass = 2;
92                 break;
93                 */
94         }
95         
96         if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0)
97                 eWarning("audio: AUDIO_SET_BYPASS_MODE: %m");
98         
99         if (::ioctl(m_fd, AUDIO_PLAY) < 0)
100                 eWarning("audio: AUDIO_PLAY: %m");
101         return 0;
102 }
103         
104 void eDVBAudio::stop()
105 {
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");
111 #endif
112 }
113         
114 #if HAVE_DVB_API_VERSION < 3
115 void eDVBAudio::stopPid()
116 {
117         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
118                 eWarning("audio: DMX_STOP: %m");
119 }
120 #endif
121
122 void eDVBAudio::flush()
123 {
124         if (::ioctl(m_fd, AUDIO_CLEAR_BUFFER) < 0)
125                 eDebug("audio: AUDIO_CLEAR_BUFFER: %m");
126 }
127
128 void eDVBAudio::freeze()
129 {
130         if (::ioctl(m_fd, AUDIO_PAUSE) < 0)
131                 eDebug("video: AUDIO_PAUSE: %m");
132 }
133
134 void eDVBAudio::unfreeze()
135 {
136         if (::ioctl(m_fd, AUDIO_CONTINUE) < 0)
137                 eDebug("video: AUDIO_CONTINUE: %m");
138 }
139
140 void eDVBAudio::setChannel(int channel)
141 {
142         int val = AUDIO_STEREO;
143         switch (channel)
144         {
145         case aMonoLeft: val = AUDIO_MONO_LEFT; break;
146         case aMonoRight: val = AUDIO_MONO_RIGHT; break;
147         default: break;
148         }
149         if (::ioctl(m_fd, AUDIO_CHANNEL_SELECT, val) < 0)
150                 eDebug("video: AUDIO_CHANNEL_SELECT: %m");
151 }
152
153 int eDVBAudio::getPTS(pts_t &now)
154 {
155         return ::ioctl(m_fd, AUDIO_GET_PTS, &now);
156 }
157
158 eDVBAudio::~eDVBAudio()
159 {
160         if (m_fd >= 0)
161                 ::close(m_fd);
162         if (m_fd_demux >= 0)
163                 ::close(m_fd_demux);
164 }
165
166 DEFINE_REF(eDVBVideo);
167
168 eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev): m_demux(demux), m_dev(dev)
169 {
170         char filename[128];
171 #if HAVE_DVB_API_VERSION < 3
172         sprintf(filename, "/dev/dvb/card%d/video%d", demux->adapter, dev);
173 #else
174         sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev);
175 #endif
176         m_fd = ::open(filename, O_RDWR);
177         if (m_fd < 0)
178                 eWarning("%s: %m", filename);
179         
180         eDebug("Video Device: %s", filename);
181 #if HAVE_DVB_API_VERSION < 3
182         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
183 #else
184         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
185 #endif
186         m_fd_demux = ::open(filename, O_RDWR);
187         if (m_fd_demux < 0)
188                 eWarning("%s: %m", filename);
189         eDebug("demux device: %s", filename);
190 }
191
192 // not finally values i think.. !!
193 #define VIDEO_STREAMTYPE_MPEG2 0
194 #define VIDEO_STREAMTYPE_MPEG4_H264 1
195
196 int eDVBVideo::startPid(int pid, int type)
197 {       
198         if ((m_fd < 0) || (m_fd_demux < 0))
199                 return -1;
200         dmx_pes_filter_params pes;
201
202         if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE,
203                 type == MPEG4_H264 ? VIDEO_STREAMTYPE_MPEG4_H264 : VIDEO_STREAMTYPE_MPEG2) < 0)
204                 eWarning("video: VIDEO_SET_STREAMTYPE: %m");
205
206         pes.pid      = pid;
207         pes.input    = DMX_IN_FRONTEND;
208         pes.output   = DMX_OUT_DECODER;
209         pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */
210         pes.flags    = 0;
211         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
212         {
213                 eWarning("video: DMX_SET_PES_FILTER: %m");
214                 return -errno;
215         }
216         if (::ioctl(m_fd_demux, DMX_START) < 0)
217         {
218                 eWarning("video: DMX_START: %m");
219                 return -errno;
220         }
221         if (::ioctl(m_fd, VIDEO_PLAY) < 0)
222                 eWarning("video: VIDEO_PLAY: %m");
223         return 0;
224 }
225         
226 void eDVBVideo::stop()
227 {
228 #if HAVE_DVB_API_VERSION > 2
229         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
230                 eWarning("video: DMX_STOP: %m");
231 #endif
232         eDebug("VIDEO_STOP");
233         if (::ioctl(m_fd, VIDEO_STOP, 1) < 0)
234                 eWarning("video: VIDEO_STOP: %m");
235 }
236
237 #if HAVE_DVB_API_VERSION < 3
238 void eDVBVideo::stopPid()
239 {
240         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
241                 eWarning("video: DMX_STOP: %m");
242 }
243 #endif
244
245 void eDVBVideo::flush()
246 {
247         if (::ioctl(m_fd, VIDEO_CLEAR_BUFFER) < 0)
248                 eDebug("video: VIDEO_CLEAR_BUFFER: %m");
249 }
250         
251 void eDVBVideo::freeze()
252 {
253         if (::ioctl(m_fd, VIDEO_FREEZE) < 0)
254                 eDebug("video: VIDEO_FREEZE: %m");
255 }
256         
257 void eDVBVideo::unfreeze()
258 {
259         if (::ioctl(m_fd, VIDEO_CONTINUE) < 0)
260                 eDebug("video: VIDEO_CONTINUE: %m");
261 }
262         
263 int eDVBVideo::setSlowMotion(int repeat)
264 {
265         m_is_slow_motion = repeat;
266         return ::ioctl(m_fd, VIDEO_SLOWMOTION, repeat);
267 }
268
269 int eDVBVideo::setFastForward(int skip)
270 {
271         m_is_fast_forward = skip;
272         return ::ioctl(m_fd, VIDEO_FAST_FORWARD, skip);
273 }
274
275 int eDVBVideo::getPTS(pts_t &now)
276 {
277         return ::ioctl(m_fd, VIDEO_GET_PTS, &now);
278 }
279         
280 eDVBVideo::~eDVBVideo()
281 {
282         if (m_is_slow_motion)
283                 setSlowMotion(0);
284         if (m_is_fast_forward)
285                 setFastForward(0);
286         if (m_fd >= 0)
287                 ::close(m_fd);
288         if (m_fd_demux >= 0)
289                 ::close(m_fd_demux);
290 }
291
292 DEFINE_REF(eDVBPCR);
293
294 eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux)
295 {
296         char filename[128];
297 #if HAVE_DVB_API_VERSION < 3
298         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
299 #else
300         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
301 #endif
302         m_fd_demux = ::open(filename, O_RDWR);
303         if (m_fd_demux < 0)
304                 eWarning("%s: %m", filename);
305 }
306
307 int eDVBPCR::startPid(int pid)
308 {
309         if (m_fd_demux < 0)
310                 return -1;
311         dmx_pes_filter_params pes;
312
313         pes.pid      = pid;
314         pes.input    = DMX_IN_FRONTEND;
315         pes.output   = DMX_OUT_DECODER;
316         pes.pes_type = DMX_PES_PCR;
317         pes.flags    = 0;
318         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
319         {
320                 eWarning("video: DMX_SET_PES_FILTER: %m");
321                 return -errno;
322         }
323         if (::ioctl(m_fd_demux, DMX_START) < 0)
324         {
325                 eWarning("video: DMX_START: %m");
326                 return -errno;
327         }
328         return 0;
329 }
330
331 void eDVBPCR::stop()
332 {
333         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
334                 eWarning("video: DMX_STOP: %m");
335 }
336
337 eDVBPCR::~eDVBPCR()
338 {
339         if (m_fd_demux >= 0)
340                 ::close(m_fd_demux);
341 }
342
343 DEFINE_REF(eDVBTText);
344
345 eDVBTText::eDVBTText(eDVBDemux *demux): m_demux(demux)
346 {
347         char filename[128];
348 #if HAVE_DVB_API_VERSION < 3
349         sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux);
350 #else
351         sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux);
352 #endif
353         m_fd_demux = ::open(filename, O_RDWR);
354         if (m_fd_demux < 0)
355                 eWarning("%s: %m", filename);
356 }
357
358 int eDVBTText::startPid(int pid)
359 {
360         if (m_fd_demux < 0)
361                 return -1;
362         dmx_pes_filter_params pes;
363
364         pes.pid      = pid;
365         pes.input    = DMX_IN_FRONTEND;
366         pes.output   = DMX_OUT_DECODER;
367         pes.pes_type = DMX_PES_TELETEXT;
368         pes.flags    = 0;
369         if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0)
370         {
371                 eWarning("video: DMX_SET_PES_FILTER: %m");
372                 return -errno;
373         }
374         if (::ioctl(m_fd_demux, DMX_START) < 0)
375         {
376                 eWarning("video: DMX_START: %m");
377                 return -errno;
378         }
379         return 0;
380 }
381
382 void eDVBTText::stop()
383 {
384         if (::ioctl(m_fd_demux, DMX_STOP) < 0)
385                 eWarning("video: DMX_STOP: %m");
386 }
387
388 eDVBTText::~eDVBTText()
389 {
390         if (m_fd_demux >= 0)
391                 ::close(m_fd_demux);
392 }
393
394 DEFINE_REF(eTSMPEGDecoder);
395
396 int eTSMPEGDecoder::setState()
397 {
398         int res = 0;
399         
400         int noaudio = m_is_sm || m_is_ff || m_is_trickmode;
401         int nott = noaudio; /* actually same conditions */
402         
403         if ((noaudio && m_audio) || (!m_audio && !noaudio))
404                 m_changed |= changeAudio;
405         
406         if ((nott && m_text) || (!m_text && !nott))
407                 m_changed |= changeText;
408         
409 #if HAVE_DVB_API_VERSION < 3
410         if (m_changed & changeAudio && m_audio)
411                 m_audio->stopPid();
412         if (m_changed & changeVideo && m_video)
413                 m_video->stopPid();
414         if (m_changed & changePCR && m_pcr)
415         {
416                 m_pcr->stop();
417                 m_pcr=0;
418         }
419         if (m_changed & changeAudio && m_audio)
420         {
421                 m_audio->stop();
422                 m_audio=0;
423         }
424         if (m_changed & changeVideo && m_video)
425         {
426                 m_video->stop();
427                 m_video=0;
428         }
429         if (m_changed & changePCR)
430         {
431                 m_pcr = new eDVBPCR(m_demux);
432                 if (m_pcr->startPid(m_pcrpid))
433                 {
434                         eWarning("pcr: startpid failed!");
435                         res = -1;
436                 }
437                 m_changed &= ~changePCR;
438         }
439         if (m_changed & changeVideo)
440         {
441                 m_video = new eDVBVideo(m_demux, m_decoder);
442                 if (m_video->startPid(m_vpid))
443                 {
444                         eWarning("video: startpid failed!");
445                         res = -1;
446                 }
447                 m_changed &= ~changeVideo;
448         }
449         if (m_changed & changeAudio)
450         {
451                 m_audio = new eDVBAudio(m_demux, m_decoder);
452                 if (m_audio->startPid(m_apid, m_atype))
453                 {
454                         eWarning("audio: startpid failed!");
455                         res = -1;
456                 }
457                 m_changed &= ~changeAudio;
458         }
459 #else
460         if (m_changed & changePCR)
461         {
462                 if (m_pcr)
463                         m_pcr->stop();
464                 m_pcr = 0;
465                 if ((m_pcrpid >= 0) && (m_pcrpid < 0x1FFF))
466                 {
467                         m_pcr = new eDVBPCR(m_demux);
468                         if (m_pcr->startPid(m_pcrpid))
469                         {
470                                 eWarning("pcr: startpid failed!");
471                                 res = -1;
472                         }
473                 }
474                 m_changed &= ~changePCR;
475         }
476         if (m_changed & changeVideo)
477         {
478                 eDebug("VIDEO CHANGED (to %04x)", m_vpid);
479                 if (m_video)
480                 {       
481                         eDebug("STOP");
482                         m_video->stop();
483                 }
484                 m_video = 0;
485                 if ((m_vpid >= 0) && (m_vpid < 0x1FFF))
486                 {
487                         eDebug("new video");
488                         m_video = new eDVBVideo(m_demux, m_decoder);
489                         if (m_video->startPid(m_vpid, m_vtype))
490                         {
491                                 eWarning("video: startpid failed!");
492                                 res = -1;
493                         }
494                 }
495                 m_changed &= ~changeVideo;
496         }
497         if (m_changed & changeAudio)
498         {
499                 if (m_audio)
500                         m_audio->stop();
501                 m_audio = 0;
502                 if ((m_apid >= 0) && (m_apid < 0x1FFF) && !noaudio)
503                 {
504                         m_audio = new eDVBAudio(m_demux, m_decoder);
505                         if (m_audio->startPid(m_apid, m_atype))
506                         {
507                                 eWarning("audio: startpid failed!");
508                                 res = -1;
509                         }
510                 }
511                 m_changed &= ~changeAudio;
512         }
513         if (m_changed & changeText)
514         {
515                 if (m_text)
516                         m_text->stop();
517                 m_text = 0;
518                 if ((m_textpid >= 0) && (m_textpid < 0x1FFF) && !nott)
519                 {
520                         m_text = new eDVBTText(m_demux);
521                         if (m_text->startPid(m_textpid))
522                         {
523                                 eWarning("text: startpid failed!");
524                                 res = -1;
525                         }
526                 }
527                 m_changed &= ~changeText;
528         }
529 #endif
530         return res;
531 }
532
533 eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder): m_demux(demux), m_changed(0), m_decoder(decoder)
534 {
535         demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event);
536         m_is_ff = m_is_sm = m_is_trickmode = 0;
537 }
538
539 eTSMPEGDecoder::~eTSMPEGDecoder()
540 {
541         m_vpid = m_apid = m_pcrpid = pidNone;
542         m_changed = -1;
543         setState();
544 }
545
546 RESULT eTSMPEGDecoder::setVideoPID(int vpid, int type)
547 {
548         if (m_vpid != vpid)
549         {
550                 m_changed |= changeVideo;
551                 m_vpid = vpid;
552                 m_vtype = type;
553         }
554         return 0;
555 }
556
557 RESULT eTSMPEGDecoder::setAudioPID(int apid, int type)
558 {
559         if ((m_apid != apid) || (m_atype != type))
560         {
561                 m_changed |= changeAudio;
562                 m_atype = type;
563                 m_apid = apid;
564         }
565         return 0;
566 }
567
568 RESULT eTSMPEGDecoder::setAudioChannel(int channel)
569 {
570         if (m_audio)
571                 m_audio->setChannel(channel);
572         else
573                 eDebug("eTSMPEGDecoder::setAudioChannel but no audio decoder exist");
574         return 0;
575 }
576
577 RESULT eTSMPEGDecoder::setSyncPCR(int pcrpid)
578 {
579         if (m_pcrpid != pcrpid)
580         {
581                 m_changed |= changePCR;
582                 m_pcrpid = pcrpid;
583         }
584         return 0;
585 }
586
587 RESULT eTSMPEGDecoder::setTextPID(int textpid)
588 {
589         if (m_textpid != textpid)
590         {
591                 m_changed |= changeText;
592                 m_textpid = textpid;
593         }
594         return 0;
595 }
596
597 RESULT eTSMPEGDecoder::setSyncMaster(int who)
598 {
599         return -1;
600 }
601
602 RESULT eTSMPEGDecoder::start()
603 {
604         return setState();
605 }
606
607 RESULT eTSMPEGDecoder::freeze(int cont)
608 {
609         if (m_video)
610                 m_video->freeze();
611
612         if (m_audio)
613                 m_audio->freeze();
614         
615         return 0;
616 }
617
618 RESULT eTSMPEGDecoder::unfreeze()
619 {
620         if (m_video)
621                 m_video->unfreeze();
622
623         if (m_audio)
624                 m_audio->unfreeze();
625         
626         return 0;
627 }
628
629 RESULT eTSMPEGDecoder::setSinglePictureMode(int when)
630 {
631         return -1;
632 }
633
634 RESULT eTSMPEGDecoder::setPictureSkipMode(int what)
635 {
636         return -1;
637 }
638
639 RESULT eTSMPEGDecoder::setFastForward(int frames_to_skip)
640 {
641         m_is_ff = frames_to_skip != 0;
642         
643         setState();
644         
645         if (m_video)
646                 return m_video->setFastForward(frames_to_skip);
647         else
648                 return -1;
649 }
650
651 RESULT eTSMPEGDecoder::setSlowMotion(int repeat)
652 {
653         m_is_sm = repeat != 0;
654         
655         setState();
656         
657         if (m_video)
658                 return m_video->setSlowMotion(repeat);
659         else
660                 return -1;
661 }
662
663 RESULT eTSMPEGDecoder::setZoom(int what)
664 {
665         return -1;
666 }
667
668 RESULT eTSMPEGDecoder::flush()
669 {
670         if (m_audio)
671                 m_audio->flush();
672         if (m_video)
673                 m_video->flush();
674         return 0;
675 }
676
677 void eTSMPEGDecoder::demux_event(int event)
678 {
679         switch (event)
680         {
681         case eDVBDemux::evtFlush:
682                 flush();
683                 break;
684         default:
685                 break;
686         }
687 }
688
689 RESULT eTSMPEGDecoder::setTrickmode(int what)
690 {
691         m_is_trickmode = what;
692         setState();
693         return 0;
694 }
695
696 RESULT eTSMPEGDecoder::getPTS(int what, pts_t &pts)
697 {
698         if (what == 0) /* auto */
699                 what = m_video ? 1 : 2;
700
701         if (what == 1) /* video */
702         {
703                 if (m_video)
704                         return m_video->getPTS(pts);
705                 else
706                         return -1;
707         }
708
709         if (what == 2) /* audio */
710         {
711                 if (m_audio)
712                         return m_audio->getPTS(pts);
713                 else
714                         return -1;
715         }
716
717         return -1;
718 }