X-Git-Url: http://code.vuplus.com/gitweb/?p=vuplus_dvbapp;a=blobdiff_plain;f=lib%2Fdvb%2Fdecoder.cpp;h=e3d97afde68863fb8b5ff1f6ae63f6956ce1661a;hp=a89f72bbb69b021f890edabaf0ab1a03b3820bf6;hb=27e06ba9c8b055c20ea8c70a405deb0e4019edc5;hpb=a582f7d2a1ff336a1edc59a7d9d7a0707e0c8741 diff --git a/lib/dvb/decoder.cpp b/lib/dvb/decoder.cpp index a89f72b..e3d97af 100644 --- a/lib/dvb/decoder.cpp +++ b/lib/dvb/decoder.cpp @@ -34,6 +34,8 @@ #include #include +#include + /* these are quite new... */ #ifndef AUDIO_GET_PTS #define AUDIO_GET_PTS _IOR('o', 19, __u64) @@ -206,6 +208,10 @@ int eDVBAudio::startPid(int pid, int type) case aDTSHD: bypass = 0x10; break; + case aDDP: + bypass = 0x22; + break; + } eDebugNoNewLine("AUDIO_SET_BYPASS(%d) - ", bypass); @@ -300,8 +306,8 @@ 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]; @@ -340,6 +346,7 @@ 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) @@ -403,6 +410,9 @@ int eDVBVideo::startPid(int pid, int type) { int streamtype = VIDEO_STREAMTYPE_MPEG2; + if (m_fcc_enable) + return 0; + if ((m_fd < 0) || (m_fd_demux < 0)) return -1; dmx_pes_filter_params pes; @@ -427,6 +437,9 @@ int eDVBVideo::startPid(int pid, int type) case VC1_SM: streamtype = VIDEO_STREAMTYPE_VC1_SM; break; + case H265_HEVC: + streamtype = VIDEO_STREAMTYPE_H265_HEVC; + break; } eDebugNoNewLine("VIDEO_SET_STREAMTYPE %d - ", streamtype); @@ -466,6 +479,9 @@ int eDVBVideo::startPid(int pid, int type) void eDVBVideo::stop() { + if (m_fcc_enable) + return; + #if HAVE_DVB_API_VERSION > 2 eDebugNoNewLine("DEMUX_STOP - video - "); if (::ioctl(m_fd_demux, DMX_STOP) < 0) @@ -988,7 +1004,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; @@ -1094,7 +1110,8 @@ 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); CONNECT(m_showSinglePicTimer->timeout, eTSMPEGDecoder::finishShowSinglePic); @@ -1107,6 +1124,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) @@ -1413,3 +1432,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; +} +