X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fdvb%2Fdecoder.cpp;h=0ce22bd47211b882f71735f71d6fc98c5a800cef;hp=8ed9f43f5fed4c56788547734b3da485fbe8b45a;hb=d8e08fe0a7304ed06b3de0b9ad6d4265ec8063b8;hpb=af1080bf1a330ffa25e1d4e75c95fe0541656aa8 diff --git a/lib/dvb/decoder.cpp b/lib/dvb/decoder.cpp index 8ed9f43..0ce22bd 100644 --- a/lib/dvb/decoder.cpp +++ b/lib/dvb/decoder.cpp @@ -1,31 +1,9 @@ #include #include #include -#if HAVE_DVB_API_VERSION < 3 -#define audioStatus audio_status -#define videoStatus video_status -#define pesType pes_type -#define playState play_state -#define audioStreamSource_t audio_stream_source_t -#define videoStreamSource_t video_stream_source_t -#define streamSource stream_source -#define dmxPesFilterParams dmx_pes_filter_params -#define DMX_PES_VIDEO0 DMX_PES_VIDEO -#define DMX_PES_AUDIO0 DMX_PES_AUDIO -#define DMX_PES_PCR0 DMX_PES_PCR -#define DMX_PES_TELETEXT0 DMX_PES_TELETEXT -#define DMX_PES_VIDEO1 DMX_PES_VIDEO -#define DMX_PES_AUDIO1 DMX_PES_AUDIO -#define DMX_PES_PCR1 DMX_PES_PCR -#define DMX_PES_TELETEXT1 DMX_PES_TELETEXT -#include -#include -#include -#else #include #include #include -#endif #include #include @@ -34,209 +12,157 @@ #include #include +#include + /* these are quite new... */ #ifndef AUDIO_GET_PTS #define AUDIO_GET_PTS _IOR('o', 19, __u64) #define VIDEO_GET_PTS _IOR('o', 57, __u64) #endif +#ifndef VIDEO_SOURCE_HDMI +#define VIDEO_SOURCE_HDMI 2 +#endif +#ifndef AUDIO_SOURCE_HDMI +#define AUDIO_SOURCE_HDMI 2 +#endif + DEFINE_REF(eDVBAudio); eDVBAudio::eDVBAudio(eDVBDemux *demux, int dev) :m_demux(demux), m_dev(dev) { char filename[128]; -#if HAVE_DVB_API_VERSION < 3 - sprintf(filename, "/dev/dvb/card%d/audio%d", demux->adapter, dev); -#else - sprintf(filename, "/dev/dvb/adapter%d/audio%d", demux->adapter, dev); -#endif + sprintf(filename, "/dev/dvb/adapter%d/audio%d", demux ? demux->adapter : 0, dev); m_fd = ::open(filename, O_RDWR); if (m_fd < 0) eWarning("%s: %m", filename); -#if HAVE_DVB_API_VERSION < 3 - sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux); -#else - sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux); -#endif - m_fd_demux = ::open(filename, O_RDWR); - if (m_fd_demux < 0) - eWarning("%s: %m", filename); -} - -#if HAVE_DVB_API_VERSION < 3 -int eDVBAudio::setPid(int pid, int type) -{ - if ((m_fd < 0) || (m_fd_demux < 0)) - return -1; - - int bypass = 0; - - switch (type) + if (demux) { - case aMPEG: - bypass = 1; - break; - case aAC3: - bypass = 0; - break; - /* - case aDTS: - bypass = 2; - break; - */ + sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux); + m_fd_demux = ::open(filename, O_RDWR); + if (m_fd_demux < 0) + eWarning("%s: %m", filename); } - - if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0) - eDebug("failed (%m)"); - - dmx_pes_filter_params pes; - - pes.pid = pid; - pes.input = DMX_IN_FRONTEND; - pes.output = DMX_OUT_DECODER; - pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */ - pes.flags = 0; - eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - audio - ", pid); - if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0) + else { - eDebug("failed (%m)"); - return -errno; + m_fd_demux = -1; } - eDebug("ok"); - - return 0; -} -int eDVBAudio::startPid() -{ - eDebugNoNewLine("DEMUX_START - audio - "); - if (::ioctl(m_fd_demux, DMX_START) < 0) + if (m_fd >= 0) { - eDebug("failed (%m)"); - return -errno; + ::ioctl(m_fd, AUDIO_SELECT_SOURCE, demux ? AUDIO_SOURCE_DEMUX : AUDIO_SOURCE_HDMI); } - eDebug("ok"); - return 0; } -int eDVBAudio::start() +int eDVBAudio::startPid(int pid, int type) { - eDebugNoNewLine("AUDIO_PLAY - "); - if (::ioctl(m_fd, AUDIO_PLAY) < 0) + if (m_fd_demux >= 0) { - eDebug("failed (%m)"); - return -errno; - } - eDebug("ok"); - return 0; -} + dmx_pes_filter_params pes; -int eDVBAudio::stopPid() -{ - eDebugNoNewLine("DEMUX_STOP - audio - "); - if (::ioctl(m_fd_demux, DMX_STOP) < 0) - { - eDebug("failed (%m)"); - return -errno; + pes.pid = pid; + pes.input = DMX_IN_FRONTEND; + pes.output = DMX_OUT_DECODER; + switch (m_dev) + { + case 0: + pes.pes_type = DMX_PES_AUDIO0; + break; + case 1: + pes.pes_type = DMX_PES_AUDIO1; + break; + case 2: + pes.pes_type = DMX_PES_AUDIO2; + break; + case 3: + pes.pes_type = DMX_PES_AUDIO3; + break; + } + pes.flags = 0; + eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - audio - ", pid); + if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0) + { + eDebug("failed (%m)"); + return -errno; + } + eDebug("ok"); + eDebugNoNewLine("DEMUX_START - audio - "); + if (::ioctl(m_fd_demux, DMX_START) < 0) + { + eDebug("failed (%m)"); + return -errno; + } + eDebug("ok"); } - eDebug("ok"); - return 0; -} -int eDVBAudio::setAVSync(int val) -{ - eDebugNoNewLine("AUDIO_SET_AV_SYNC - "); - if (::ioctl(m_fd, AUDIO_SET_AV_SYNC, val) < 0) + if (m_fd >= 0) { - eDebug("failed (%m)"); - return -errno; + int bypass = 0; + + switch (type) + { + case aMPEG: + bypass = 1; + break; + case aAC3: + bypass = 0; + break; + case aDTS: + bypass = 2; + break; + case aAAC: + bypass = 8; + break; + case aAACHE: + bypass = 9; + break; + case aLPCM: + bypass = 6; + break; + case aDTSHD: + bypass = 0x10; + break; + case aDDP: + bypass = 0x22; + break; + + } + + eDebugNoNewLine("AUDIO_SET_BYPASS(%d) - ", bypass); + if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); + freeze(); // why freeze here?!? this is a problem when only a pid change is requested... because of the unfreeze logic in Decoder::setState + eDebugNoNewLine("AUDIO_PLAY - "); + if (::ioctl(m_fd, AUDIO_PLAY) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); } - eDebug("ok"); return 0; } -#else -int eDVBAudio::startPid(int pid, int type) -{ - if ((m_fd < 0) || (m_fd_demux < 0)) - return -1; - dmx_pes_filter_params pes; - pes.pid = pid; - pes.input = DMX_IN_FRONTEND; - pes.output = DMX_OUT_DECODER; - pes.pes_type = m_dev ? DMX_PES_AUDIO1 : DMX_PES_AUDIO0; /* FIXME */ - pes.flags = 0; - eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - audio - ", pid); - if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0) - { - eDebug("failed (%m)"); - return -errno; - } - eDebug("ok"); - eDebugNoNewLine("DEMUX_START - audio - "); - if (::ioctl(m_fd_demux, DMX_START) < 0) +void eDVBAudio::stop() +{ + if (m_fd >= 0) { - eDebug("failed (%m)"); - return -errno; + eDebugNoNewLine("AUDIO_STOP - "); + if (::ioctl(m_fd, AUDIO_STOP) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); } - eDebug("ok"); - int bypass = 0; - switch (type) + if (m_fd_demux >= 0) { - case aMPEG: - bypass = 1; - break; - case aAC3: - bypass = 0; - break; - case aDTS: - bypass = 2; - break; - case aAAC: - bypass = 8; - break; - case aAACHE: - bypass = 9; - break; - case aLPCM: - bypass = 6; - break; - case aDTSHD: - bypass = 0x10; - break; + eDebugNoNewLine("DEMUX_STOP - audio - "); + if (::ioctl(m_fd_demux, DMX_STOP) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); } - - eDebugNoNewLine("AUDIO_SET_BYPASS(%d) - ", bypass); - if (::ioctl(m_fd, AUDIO_SET_BYPASS_MODE, bypass) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); - freeze(); // why freeze here?!? this is a problem when only a pid change is requested... because of the unfreeze logic in Decoder::setState - eDebugNoNewLine("AUDIO_PLAY - "); - if (::ioctl(m_fd, AUDIO_PLAY) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); - return 0; -} -#endif - -void eDVBAudio::stop() -{ - eDebugNoNewLine("AUDIO_STOP - "); - if (::ioctl(m_fd, AUDIO_STOP) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); -#if HAVE_DVB_API_VERSION > 2 - eDebugNoNewLine("DEMUX_STOP - audio - "); - if (::ioctl(m_fd_demux, DMX_STOP) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); -#endif } void eDVBAudio::flush() @@ -300,19 +226,12 @@ eDVBAudio::~eDVBAudio() DEFINE_REF(eDVBVideo); -eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev) - : m_demux(demux), m_dev(dev), +eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev, bool fcc_enable) + : m_demux(demux), m_dev(dev), m_fcc_enable(fcc_enable), m_width(-1), m_height(-1), m_framerate(-1), m_aspect(-1), m_progressive(-1) { char filename[128]; -#if HAVE_DVB_API_VERSION < 3 - sprintf(filename, "/dev/dvb/card%d/video%d", demux->adapter, dev); - m_fd_video = ::open("/dev/video", O_RDWR); - if (m_fd_video < 0) - eWarning("/dev/video: %m"); -#else - sprintf(filename, "/dev/dvb/adapter%d/video%d", demux->adapter, dev); -#endif + sprintf(filename, "/dev/dvb/adapter%d/video%d", demux ? demux->adapter : 0, dev); m_fd = ::open(filename, O_RDWR); if (m_fd < 0) eWarning("%s: %m", filename); @@ -322,15 +241,26 @@ eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev) CONNECT(m_sn->activated, eDVBVideo::video_event); } eDebug("Video Device: %s", filename); -#if HAVE_DVB_API_VERSION < 3 - sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux); -#else - sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux); -#endif - m_fd_demux = ::open(filename, O_RDWR); - if (m_fd_demux < 0) - eWarning("%s: %m", filename); - eDebug("demux device: %s", filename); + + + + if (demux) + { + sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux); + m_fd_demux = ::open(filename, O_RDWR); + if (m_fd_demux < 0) + eWarning("%s: %m", filename); + eDebug("demux device: %s", filename); + } + else + { + m_fd_demux = -1; + } + + if (m_fd >= 0) + { + ::ioctl(m_fd, VIDEO_SELECT_SOURCE, demux ? VIDEO_SOURCE_DEMUX : VIDEO_SOURCE_HDMI); + } } // not finally values i think.. !! @@ -340,144 +270,122 @@ eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev) #define VIDEO_STREAMTYPE_MPEG4_Part2 4 #define VIDEO_STREAMTYPE_VC1_SM 5 #define VIDEO_STREAMTYPE_MPEG1 6 +#define VIDEO_STREAMTYPE_H265_HEVC 7 -#if HAVE_DVB_API_VERSION < 3 -int eDVBVideo::setPid(int pid) +int eDVBVideo::startPid(int pid, int type) { - if ((m_fd < 0) || (m_fd_demux < 0)) - return -1; - dmx_pes_filter_params pes; + if (m_fcc_enable) + return 0; - pes.pid = pid; - pes.input = DMX_IN_FRONTEND; - pes.output = DMX_OUT_DECODER; - pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */ - pes.flags = 0; - eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - video - ", pid); - if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0) + if (m_fd >= 0) { - eDebug("failed (%m)"); - return -errno; - } - eDebug("ok"); - return 0; -} + int streamtype = VIDEO_STREAMTYPE_MPEG2; + switch(type) + { + default: + case MPEG2: + break; + case MPEG4_H264: + streamtype = VIDEO_STREAMTYPE_MPEG4_H264; + break; + case MPEG1: + streamtype = VIDEO_STREAMTYPE_MPEG1; + break; + case MPEG4_Part2: + streamtype = VIDEO_STREAMTYPE_MPEG4_Part2; + break; + case VC1: + streamtype = VIDEO_STREAMTYPE_VC1; + break; + case VC1_SM: + streamtype = VIDEO_STREAMTYPE_VC1_SM; + break; + case H265_HEVC: + streamtype = VIDEO_STREAMTYPE_H265_HEVC; + break; + } -int eDVBVideo::startPid() -{ - eDebugNoNewLine("DEMUX_START - video - "); - if (::ioctl(m_fd_demux, DMX_START) < 0) - { - eDebug("failed (%m)"); - return -errno; + eDebugNoNewLine("VIDEO_SET_STREAMTYPE %d - ", streamtype); + if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE, streamtype) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); + } - eDebug("ok"); - return 0; -} -int eDVBVideo::start() -{ - eDebugNoNewLine("VIDEO_PLAY - "); - if (::ioctl(m_fd, VIDEO_PLAY) < 0) + if (m_fd_demux >= 0) { - eDebug("failed (%m)"); - return -errno; + dmx_pes_filter_params pes; + + pes.pid = pid; + pes.input = DMX_IN_FRONTEND; + pes.output = DMX_OUT_DECODER; + switch (m_dev) + { + case 0: + pes.pes_type = DMX_PES_VIDEO0; + break; + case 1: + pes.pes_type = DMX_PES_VIDEO1; + break; + case 2: + pes.pes_type = DMX_PES_VIDEO2; + break; + case 3: + pes.pes_type = DMX_PES_VIDEO3; + break; + } + pes.flags = 0; + eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - video - ", pid); + if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0) + { + eDebug("failed (%m)"); + return -errno; + } + eDebug("ok"); + eDebugNoNewLine("DEMUX_START - video - "); + if (::ioctl(m_fd_demux, DMX_START) < 0) + { + eDebug("failed (%m)"); + return -errno; + } + eDebug("ok"); } - eDebug("ok"); - return 0; -} -int eDVBVideo::stopPid() -{ - eDebugNoNewLine("DEMUX_STOP - video - "); - if (::ioctl(m_fd_demux, DMX_STOP) < 0) + if (m_fd >= 0) { - eDebug("failed (%m)"); - return -errno; + freeze(); // why freeze here?!? this is a problem when only a pid change is requested... because of the unfreeze logic in Decoder::setState + eDebugNoNewLine("VIDEO_PLAY - "); + if (::ioctl(m_fd, VIDEO_PLAY) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); } - eDebug("ok"); return 0; } -#else -int eDVBVideo::startPid(int pid, int type) -{ - int streamtype = VIDEO_STREAMTYPE_MPEG2; - if ((m_fd < 0) || (m_fd_demux < 0)) - return -1; - dmx_pes_filter_params pes; +void eDVBVideo::stop() +{ + if (m_fcc_enable) + return; - switch(type) + if (m_fd_demux >= 0) { - default: - case MPEG2: - break; - case MPEG4_H264: - streamtype = VIDEO_STREAMTYPE_MPEG4_H264; - break; - case MPEG1: - streamtype = VIDEO_STREAMTYPE_MPEG1; - break; - case MPEG4_Part2: - streamtype = VIDEO_STREAMTYPE_MPEG4_Part2; - break; - case VC1: - streamtype = VIDEO_STREAMTYPE_VC1; - break; - case VC1_SM: - streamtype = VIDEO_STREAMTYPE_VC1_SM; - break; + eDebugNoNewLine("DEMUX_STOP - video - "); + if (::ioctl(m_fd_demux, DMX_STOP) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); } - eDebugNoNewLine("VIDEO_SET_STREAMTYPE %d - ", streamtype); - if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE, streamtype) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); - - pes.pid = pid; - pes.input = DMX_IN_FRONTEND; - pes.output = DMX_OUT_DECODER; - pes.pes_type = m_dev ? DMX_PES_VIDEO1 : DMX_PES_VIDEO0; /* FIXME */ - pes.flags = 0; - eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - video - ", pid); - if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0) - { - eDebug("failed (%m)"); - return -errno; - } - eDebug("ok"); - eDebugNoNewLine("DEMUX_START - video - "); - if (::ioctl(m_fd_demux, DMX_START) < 0) + if (m_fd >= 0) { - eDebug("failed (%m)"); - return -errno; + eDebugNoNewLine("VIDEO_STOP - "); + if (::ioctl(m_fd, VIDEO_STOP, 1) < 0) + eDebug("failed (%m)"); + else + eDebug("ok"); } - eDebug("ok"); - freeze(); // why freeze here?!? this is a problem when only a pid change is requested... because of the unfreeze logic in Decoder::setState - eDebugNoNewLine("VIDEO_PLAY - "); - if (::ioctl(m_fd, VIDEO_PLAY) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); - return 0; -} -#endif - -void eDVBVideo::stop() -{ -#if HAVE_DVB_API_VERSION > 2 - eDebugNoNewLine("DEMUX_STOP - video - "); - if (::ioctl(m_fd_demux, DMX_STOP) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); -#endif - eDebugNoNewLine("VIDEO_STOP - "); - if (::ioctl(m_fd, VIDEO_STOP, 1) < 0) - eDebug("failed (%m)"); - else - eDebug("ok"); } void eDVBVideo::flush() @@ -531,15 +439,7 @@ int eDVBVideo::setFastForward(int skip) int eDVBVideo::getPTS(pts_t &now) { -#if HAVE_DVB_API_VERSION < 3 - #define VIDEO_GET_PTS_OLD _IOR('o', 1, unsigned int*) - unsigned int pts; - int ret = ::ioctl(m_fd_video, VIDEO_GET_PTS_OLD, &pts); - now = pts; - now *= 2; -#else int ret = ::ioctl(m_fd, VIDEO_GET_PTS, &now); -#endif if (ret < 0) eDebug("VIDEO_GET_PTS failed(%m)"); return ret; @@ -551,15 +451,10 @@ eDVBVideo::~eDVBVideo() ::close(m_fd); if (m_fd_demux >= 0) ::close(m_fd_demux); -#if HAVE_DVB_API_VERSION < 3 - if (m_fd_video >= 0) - ::close(m_fd_video); -#endif } void eDVBVideo::video_event(int) { -#if HAVE_DVB_API_VERSION >= 3 struct video_event evt; eDebugNoNewLine("VIDEO_GET_EVENT - "); if (::ioctl(m_fd, VIDEO_GET_EVENT, &evt) < 0) @@ -593,9 +488,6 @@ void eDVBVideo::video_event(int) else eDebug("unhandled DVBAPI Video Event %d", evt.type); } -#else -#warning "FIXMEE!! Video Events not implemented for old api" -#endif } RESULT eDVBVideo::connectEvent(const Slot1 &event, ePtr &conn) @@ -620,7 +512,6 @@ static int readMpegProc(const char *str, int decoder) static int readApiSize(int fd, int &xres, int &yres, int &aspect) { -#if HAVE_DVB_API_VERSION >= 3 video_size_t size; if (!::ioctl(fd, VIDEO_GET_SIZE, &size)) { @@ -630,13 +521,11 @@ static int readApiSize(int fd, int &xres, int &yres, int &aspect) return 0; } // eDebug("VIDEO_GET_SIZE failed (%m)"); -#endif return -1; } static int readApiFrameRate(int fd, int &framerate) { -#if HAVE_DVB_API_VERSION >= 3 unsigned int frate; if (!::ioctl(fd, VIDEO_GET_FRAME_RATE, &frate)) { @@ -644,7 +533,6 @@ static int readApiFrameRate(int fd, int &framerate) return 0; } // eDebug("VIDEO_GET_FRAME_RATE failed (%m)"); -#endif return -1; } @@ -696,18 +584,13 @@ DEFINE_REF(eDVBPCR); eDVBPCR::eDVBPCR(eDVBDemux *demux, int dev): m_demux(demux), m_dev(dev) { char filename[128]; -#if HAVE_DVB_API_VERSION < 3 - sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux); -#else sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux); -#endif m_fd_demux = ::open(filename, O_RDWR); if (m_fd_demux < 0) eWarning("%s: %m", filename); } -#if HAVE_DVB_API_VERSION < 3 -int eDVBPCR::setPid(int pid) +int eDVBPCR::startPid(int pid) { if (m_fd_demux < 0) return -1; @@ -716,43 +599,21 @@ int eDVBPCR::setPid(int pid) pes.pid = pid; pes.input = DMX_IN_FRONTEND; pes.output = DMX_OUT_DECODER; - pes.pes_type = DMX_PES_PCR; - pes.flags = 0; - - eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - pcr - ", pid); - if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0) - { - eDebug("failed (%m)"); - return -errno; - } - eDebug("ok"); - return 0; -} - -int eDVBPCR::startPid() -{ - if (m_fd_demux < 0) - return -1; - eDebugNoNewLine("DEMUX_START - pcr - "); - if (::ioctl(m_fd_demux, DMX_START) < 0) + switch (m_dev) { - eDebug("failed (%m)"); - return -errno; + case 0: + pes.pes_type = DMX_PES_PCR0; + break; + case 1: + pes.pes_type = DMX_PES_PCR1; + break; + case 2: + pes.pes_type = DMX_PES_PCR2; + break; + case 3: + pes.pes_type = DMX_PES_PCR3; + break; } - eDebug("ok"); - return 0; -} -#else -int eDVBPCR::startPid(int pid) -{ - if (m_fd_demux < 0) - return -1; - dmx_pes_filter_params pes; - - pes.pid = pid; - pes.input = DMX_IN_FRONTEND; - pes.output = DMX_OUT_DECODER; - pes.pes_type = m_dev ? DMX_PES_PCR1 : DMX_PES_PCR0; /* FIXME */ pes.flags = 0; eDebugNoNewLine("DMX_SET_PES_FILTER(0x%02x) - pcr - ", pid); if (::ioctl(m_fd_demux, DMX_SET_PES_FILTER, &pes) < 0) @@ -770,7 +631,6 @@ int eDVBPCR::startPid(int pid) eDebug("ok"); return 0; } -#endif void eDVBPCR::stop() { @@ -793,11 +653,7 @@ eDVBTText::eDVBTText(eDVBDemux *demux, int dev) :m_demux(demux), m_dev(dev) { char filename[128]; -#if HAVE_DVB_API_VERSION < 3 - sprintf(filename, "/dev/dvb/card%d/demux%d", demux->adapter, demux->demux); -#else sprintf(filename, "/dev/dvb/adapter%d/demux%d", demux->adapter, demux->demux); -#endif m_fd_demux = ::open(filename, O_RDWR); if (m_fd_demux < 0) eWarning("%s: %m", filename); @@ -866,77 +722,6 @@ int eTSMPEGDecoder::setState() eDebug("decoder state: %s, vpid=%d, apid=%d", decoder_states[m_state], m_vpid, m_apid); int changed = m_changed; -#if HAVE_DVB_API_VERSION < 3 - bool checkAVSync = m_changed & (changeAudio|changeVideo|changePCR); - if (m_changed & changeAudio && m_audio) - m_audio->stopPid(); - if (m_changed & changeVideo && m_video) - m_video->stopPid(); - if (m_changed & changePCR && m_pcr) - { - m_pcr->stop(); - m_pcr=0; - if (!(m_pcrpid >= 0 && m_pcrpid < 0x1ff)) - m_changed &= ~changePCR; - } - if (m_changed & changeAudio && m_audio) - { - m_audio->stop(); - m_audio=0; - if (!(m_apid >= 0 && m_apid < 0x1ff)) - m_changed &= ~changeAudio; - } - if (m_changed & changeVideo && m_video) - { - m_video->stop(); - m_video=0; - m_video_event_conn=0; - if (!(m_vpid >= 0 && m_vpid < 0x1ff)) - m_changed &= ~changeVideo; - } - if (m_changed & changeVideo) - { - m_video = new eDVBVideo(m_demux, m_decoder); - m_video->connectEvent(slot(*this, &eTSMPEGDecoder::video_event), m_video_event_conn); - if (m_video->setPid(m_vpid)) - res -1; - } - if (m_changed & changePCR) - { - m_pcr = new eDVBPCR(m_demux, m_decoder); - if (m_pcr->setPid(m_pcrpid)) - res = -1; - } - if (m_changed & changeAudio) - { - m_audio = new eDVBAudio(m_demux, m_decoder); - if (m_audio->setPid(m_apid, m_atype)) - res = -1; - } - if (m_changed & changePCR) - { - if (m_pcr->startPid()) - res = -1; - m_changed &= ~changePCR; - } - else if (checkAVSync && m_audio && m_video) - { - if (m_audio->setAVSync(1)) - res = -1; - } - if (m_changed & changeVideo) - { - if (m_video->startPid() || m_video->start()) - res = -1; - m_changed &= ~changeVideo; - } - if (m_changed & changeAudio) - { - if (m_audio->start() || m_audio->startPid()) - res = -1; - m_changed &= ~changeAudio; - } -#else if (m_changed & changePCR) { if (m_pcr) @@ -988,7 +773,7 @@ int eTSMPEGDecoder::setState() { if ((m_vpid >= 0) && (m_vpid < 0x1FFF)) { - m_video = new eDVBVideo(m_demux, m_decoder); + m_video = new eDVBVideo(m_demux, m_decoder, m_fcc_enable); m_video->connectEvent(slot(*this, &eTSMPEGDecoder::video_event), m_video_event_conn); if (m_video->startPid(m_vpid, m_vtype)) res = -1; @@ -1005,7 +790,6 @@ int eTSMPEGDecoder::setState() } m_changed &= ~changeText; } -#endif if (changed & (changeState|changeVideo|changeAudio)) { @@ -1094,9 +878,13 @@ RESULT eTSMPEGDecoder::setAC3Delay(int delay) eTSMPEGDecoder::eTSMPEGDecoder(eDVBDemux *demux, int decoder) : m_demux(demux), m_vpid(-1), m_vtype(-1), m_apid(-1), m_atype(-1), m_pcrpid(-1), m_textpid(-1), - m_changed(0), m_decoder(decoder), m_video_clip_fd(-1), m_showSinglePicTimer(eTimer::create(eApp)) + m_changed(0), m_decoder(decoder), m_video_clip_fd(-1), m_showSinglePicTimer(eTimer::create(eApp)), + m_fcc_fd(-1), m_fcc_enable(false), m_fcc_state(fcc_state_stop), m_fcc_feid(-1), m_fcc_vpid(-1), m_fcc_vtype(-1), m_fcc_pcrpid(-1) { - demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event_conn); + if (m_demux) + { + demux->connectEvent(slot(*this, &eTSMPEGDecoder::demux_event), m_demux_event_conn); + } CONNECT(m_showSinglePicTimer->timeout, eTSMPEGDecoder::finishShowSinglePic); m_state = stateStop; } @@ -1107,6 +895,8 @@ eTSMPEGDecoder::~eTSMPEGDecoder() m_vpid = m_apid = m_pcrpid = m_textpid = pidNone; m_changed = -1; setState(); + fccStop(); + fccFreeFD(); } RESULT eTSMPEGDecoder::setVideoPID(int vpid, int type) @@ -1302,9 +1092,10 @@ RESULT eTSMPEGDecoder::showSinglePic(const char *filename) if (f >= 0) { struct stat s; + size_t written=0; fstat(f, &s); if (m_video_clip_fd == -1) - m_video_clip_fd = open("/dev/dvb/adapter0/video0", O_WRONLY|O_NONBLOCK); + m_video_clip_fd = open("/dev/dvb/adapter0/video0", O_WRONLY); if (m_video_clip_fd >= 0) { bool seq_end_avail = false; @@ -1412,3 +1203,242 @@ int eTSMPEGDecoder::getVideoAspect() return m_video->getAspect(); return -1; } + +#define FCC_SET_VPID 100 +#define FCC_SET_APID 101 +#define FCC_SET_PCRPID 102 +#define FCC_SET_VCODEC 103 +#define FCC_SET_ACODEC 104 +#define FCC_SET_FRONTEND_ID 105 +#define FCC_START 106 +#define FCC_STOP 107 +#define FCC_DECODER_START 108 +#define FCC_DECODER_STOP 109 + +RESULT eTSMPEGDecoder::prepareFCC(int fe_id, int vpid, int vtype, int pcrpid) +{ + //eDebug("[eTSMPEGDecoder::prepareFCC] vp : %d, vt : %d, pp : %d, fe : %d", vpid, vtype, pcrpid, fe_id); + + if ((fccGetFD() == -1) || (fccSetPids(fe_id, vpid, vtype, pcrpid) < 0) || (fccStart() < 0)) + { + fccFreeFD(); + return -1; + } + + m_fcc_enable = true; + + return 0; +} + +RESULT eTSMPEGDecoder::fccDecoderStart() +{ + if (m_fcc_fd == -1) + return -1; + + if (m_fcc_state != fcc_state_ready) + { + eDebug("FCC decoder is already in decoding state."); + return 0; + } + + if (ioctl(m_fcc_fd, FCC_DECODER_START) < 0) + { + eDebug("ioctl FCC_DECODER_START failed! (%m)"); + return -1; + } + + m_fcc_state = fcc_state_decoding; + + eDebug("[eTSMPEGDecoder] FCC_DECODER_START OK!"); + return 0; +} + +RESULT eTSMPEGDecoder::fccDecoderStop() +{ + if (m_fcc_fd == -1) + return -1; + + if (m_fcc_state != fcc_state_decoding) + { + eDebug("FCC decoder is not in decoding state."); + } + else if (ioctl(m_fcc_fd, FCC_DECODER_STOP) < 0) + { + eDebug("ioctl FCC_DECODER_STOP failed! (%m)"); + return -1; + } + + m_fcc_state = fcc_state_ready; + + /* stop pcr, video, audio, text */ + finishShowSinglePic(); + + m_vpid = m_apid = m_pcrpid = m_textpid = pidNone; + m_changed = -1; + setState(); + + eDebug("[eTSMPEGDecoder] FCC_DECODER_STOP OK!"); + return 0; +} + +RESULT eTSMPEGDecoder::fccUpdatePids(int fe_id, int vpid, int vtype, int pcrpid) +{ + //eDebug("[eTSMPEGDecoder] vp : %d, vt : %d, pp : %d, fe : %d", vpid, vtype, pcrpid, fe_id); + + if ((fe_id != m_fcc_feid) || (vpid != m_fcc_vpid) || (vtype != m_fcc_vtype) || (pcrpid != m_fcc_pcrpid)) + { + int cur_fcc_state = m_fcc_state; + fccStop(); + if (prepareFCC(fe_id, vpid, vtype, pcrpid)) + { + eDebug("[eTSMPEGDecoder] prepare FCC failed!"); + return -1; + } + } + return 0; +} + +RESULT eTSMPEGDecoder::fccStart() +{ + if (m_fcc_fd == -1) + return -1; + + if (m_fcc_state != fcc_state_stop) + { + eDebug("[eTSMPEGDecoder] FCC is already started!"); + return 0; + } + else if (ioctl(m_fcc_fd, FCC_START) < 0) + { + eDebug("ioctl FCC_START failed! (%m)"); + return -1; + } + + eDebug("[eTSMPEGDecoder] FCC_START OK!"); + + m_fcc_state = fcc_state_ready; + return 0; +} + +RESULT eTSMPEGDecoder::fccStop() +{ + if (m_fcc_fd == -1) + return -1; + + if (m_fcc_state == fcc_state_stop) + { + eDebug("[eTSMPEGDecoder] FCC is already stopped!"); + return 0; + } + + else if (m_fcc_state == fcc_state_decoding) + { + fccDecoderStop(); + } + + if (ioctl(m_fcc_fd, FCC_STOP) < 0) + { + eDebug("ioctl FCC_STOP failed! (%m)"); + return -1; + } + + m_fcc_state = fcc_state_stop; + + eDebug("[eTSMPEGDecoder] FCC_STOP OK!"); + return 0; +} + +RESULT eTSMPEGDecoder::fccSetPids(int fe_id, int vpid, int vtype, int pcrpid) +{ + int streamtype = VIDEO_STREAMTYPE_MPEG2; + + if (m_fcc_fd == -1) + return -1; + + if (ioctl(m_fcc_fd, FCC_SET_FRONTEND_ID, fe_id) < 0) + { + eDebug("[eTSMPEGDecoder] FCC_SET_FRONTEND_ID failed! (%m)"); + return -1; + } + + else if(ioctl(m_fcc_fd, FCC_SET_PCRPID, pcrpid) < 0) + { + eDebug("[eTSMPEGDecoder] FCC_SET_PCRPID failed! (%m)"); + return -1; + } + + else if (ioctl(m_fcc_fd, FCC_SET_VPID, vpid) < 0) + { + eDebug("[eTSMPEGDecoder] FCC_SET_VPID failed! (%m)"); + return -1; + } + + switch(vtype) + { + default: + case eDVBVideo::MPEG2: + break; + case eDVBVideo::MPEG4_H264: + streamtype = VIDEO_STREAMTYPE_MPEG4_H264; + break; + case eDVBVideo::MPEG1: + streamtype = VIDEO_STREAMTYPE_MPEG1; + break; + case eDVBVideo::MPEG4_Part2: + streamtype = VIDEO_STREAMTYPE_MPEG4_Part2; + break; + case eDVBVideo::VC1: + streamtype = VIDEO_STREAMTYPE_VC1; + break; + case eDVBVideo::VC1_SM: + streamtype = VIDEO_STREAMTYPE_VC1_SM; + break; + case eDVBVideo::H265_HEVC: + streamtype = VIDEO_STREAMTYPE_H265_HEVC; + break; + } + + if(ioctl(m_fcc_fd, FCC_SET_VCODEC, streamtype) < 0) + { + eDebug("[eTSMPEGDecoder] FCC_SET_VCODEC failed! (%m)"); + return -1; + } + + m_fcc_feid = fe_id; + m_fcc_vpid = vpid; + m_fcc_vtype = vtype; + m_fcc_pcrpid = pcrpid; + + //eDebug("[eTSMPEGDecoder] SET PIDS OK!"); + return 0; +} + +RESULT eTSMPEGDecoder::fccGetFD() +{ + if (m_fcc_fd == -1) + { + eFCCDecoder* fcc = eFCCDecoder::getInstance(); + if (fcc != NULL) + { + m_fcc_fd = fcc->allocateFcc(); + } + } + + return m_fcc_fd; +} + +RESULT eTSMPEGDecoder::fccFreeFD() +{ + if (m_fcc_fd != -1) + { + eFCCDecoder* fcc = eFCCDecoder::getInstance(); + if (fcc != NULL) + { + fcc->freeFcc(m_fcc_fd); + m_fcc_fd = -1; + } + } + + return 0; +} +