From 6e16107fdcc5f838f681d6f5d49e30124ebe5d74 Mon Sep 17 00:00:00 2001 From: ghost Date: Tue, 16 Dec 2008 15:02:48 +0100 Subject: move some functions to better place (aspect / size / framerate / progressive handling) --- lib/dvb/decoder.cpp | 133 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 128 insertions(+), 5 deletions(-) (limited to 'lib/dvb/decoder.cpp') diff --git a/lib/dvb/decoder.cpp b/lib/dvb/decoder.cpp index 6ad39225..79c4bd1e 100644 --- a/lib/dvb/decoder.cpp +++ b/lib/dvb/decoder.cpp @@ -300,6 +300,7 @@ DEFINE_REF(eDVBVideo); eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev) :m_demux(demux), m_dev(dev), m_is_slow_motion(0), m_is_fast_forward(0), m_is_freezed(0) + ,m_width(-1), m_height(-1), m_framerate(-1), m_aspect(-1), m_progressive(-1) { char filename[128]; #if HAVE_DVB_API_VERSION < 3 @@ -556,23 +557,23 @@ void eDVBVideo::video_event(int) { struct iTSMPEGDecoder::videoEvent event; event.type = iTSMPEGDecoder::videoEvent::eventSizeChanged; - event.aspect = evt.u.size.aspect_ratio; - event.height = evt.u.size.h; - event.width = evt.u.size.w; + m_aspect = event.aspect = evt.u.size.aspect_ratio; + m_height = event.height = evt.u.size.h; + m_width = event.width = evt.u.size.w; /* emit */ m_event(event); } else if (evt.type == VIDEO_EVENT_FRAME_RATE_CHANGED) { struct iTSMPEGDecoder::videoEvent event; event.type = iTSMPEGDecoder::videoEvent::eventFrameRateChanged; - event.framerate = evt.u.frame_rate; + m_framerate = event.framerate = evt.u.frame_rate; /* emit */ m_event(event); } else if (evt.type == 16 /*VIDEO_EVENT_PROGRESSIVE_CHANGED*/) { struct iTSMPEGDecoder::videoEvent event; event.type = iTSMPEGDecoder::videoEvent::eventProgressiveChanged; - event.progressive = evt.u.frame_rate; + m_progressive = event.progressive = evt.u.frame_rate; /* emit */ m_event(event); } else @@ -589,6 +590,93 @@ RESULT eDVBVideo::connectEvent(const Slot1= 3 + video_size_t size; + if (!::ioctl(fd, VIDEO_GET_SIZE, &size)) + { + xres = size.w; + yres = size.h; + aspect = size.aspect_ratio; + 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)) + { + framerate = frate; + return 0; + } +// eDebug("VIDEO_GET_FRAME_RATE failed (%m)"); +#endif + return -1; +} + +int eDVBVideo::getWidth() +{ + if (m_width == -1) + readApiSize(m_fd, m_width, m_height, m_aspect); + if (m_width == -1) + m_width = readMpegProc("xres", m_dev); + return m_width; +} + +int eDVBVideo::getHeight() +{ + if (m_height == -1) + readApiSize(m_fd, m_width, m_height, m_aspect); + if (m_height == -1) + m_height = readMpegProc("yres", m_dev); + return m_height; +} + +int eDVBVideo::getAspect() +{ + if (m_aspect == -1) + readApiSize(m_fd, m_width, m_height, m_aspect); + if (m_aspect == -1) + m_aspect = readMpegProc("aspect", m_dev); + return m_aspect; +} + +int eDVBVideo::getProgressive() +{ + if (m_progressive == -1) + m_progressive = readMpegProc("progressive", m_dev); + return m_progressive; +} + +int eDVBVideo::getFrameRate() +{ + if (m_framerate == -1) + readApiFrameRate(m_fd, m_framerate); + if (m_framerate == -1) + m_framerate = readMpegProc("framerate", m_dev); + return m_framerate; +} + DEFINE_REF(eDVBPCR); eDVBPCR::eDVBPCR(eDVBDemux *demux): m_demux(demux) @@ -1245,3 +1333,38 @@ void eTSMPEGDecoder::video_event(struct videoEvent event) { /* emit */ m_video_event(event); } + +int eTSMPEGDecoder::getVideoWidth() +{ + if (m_video) + return m_video->getWidth(); + return -1; +} + +int eTSMPEGDecoder::getVideoHeight() +{ + if (m_video) + return m_video->getHeight(); + return -1; +} + +int eTSMPEGDecoder::getVideoProgressive() +{ + if (m_video) + return m_video->getProgressive(); + return -1; +} + +int eTSMPEGDecoder::getVideoFrameRate() +{ + if (m_video) + return m_video->getFrameRate(); + return -1; +} + +int eTSMPEGDecoder::getVideoAspect() +{ + if (m_video) + return m_video->getAspect(); + return -1; +} -- cgit v1.2.3 From 00cc3e8df7fec482a953416c1bb76d7be7f7a8ba Mon Sep 17 00:00:00 2001 From: ghost Date: Tue, 16 Dec 2008 15:59:35 +0100 Subject: convert dvb api aspect to etsi aspect --- lib/dvb/decoder.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/dvb/decoder.cpp') diff --git a/lib/dvb/decoder.cpp b/lib/dvb/decoder.cpp index 79c4bd1e..8bc07e60 100644 --- a/lib/dvb/decoder.cpp +++ b/lib/dvb/decoder.cpp @@ -557,7 +557,7 @@ void eDVBVideo::video_event(int) { struct iTSMPEGDecoder::videoEvent event; event.type = iTSMPEGDecoder::videoEvent::eventSizeChanged; - m_aspect = event.aspect = evt.u.size.aspect_ratio; + m_aspect = event.aspect = evt.u.size.aspect_ratio == 0 ? 2 : 3; // convert dvb api to etsi m_height = event.height = evt.u.size.h; m_width = event.width = evt.u.size.w; /* emit */ m_event(event); @@ -612,7 +612,7 @@ static int readApiSize(int fd, int &xres, int &yres, int &aspect) { xres = size.w; yres = size.h; - aspect = size.aspect_ratio; + aspect = size.aspect_ratio == 0 ? 2 : 3; // convert dvb api to etsi return 0; } // eDebug("VIDEO_GET_SIZE failed (%m)"); -- cgit v1.2.3 From a0f0f0b446b7b0fd941194299fa4840b609df1f0 Mon Sep 17 00:00:00 2001 From: ghost Date: Tue, 20 Jan 2009 23:39:33 +0100 Subject: support much more audio/video codecs encapsulated in TS files (not all stb hardware can handle all codecs!!!) --- lib/dvb/decoder.cpp | 41 +++++++++++++++++++++++++---- lib/dvb/decoder.h | 4 +-- lib/dvb/pmt.cpp | 65 +++++++++++++++++++++++++++++++++++++++++++--- lib/dvb/pmt.h | 4 +-- lib/service/servicedvb.cpp | 2 ++ 5 files changed, 104 insertions(+), 12 deletions(-) (limited to 'lib/dvb/decoder.cpp') diff --git a/lib/dvb/decoder.cpp b/lib/dvb/decoder.cpp index 8bc07e60..065a49c2 100644 --- a/lib/dvb/decoder.cpp +++ b/lib/dvb/decoder.cpp @@ -187,11 +187,15 @@ int eDVBAudio::startPid(int pid, int type) case aAC3: bypass = 0; break; - /* case aDTS: bypass = 2; break; - */ + case aAAC: + bypass = 8; + break; + case aAACHE: + bypass = 9; + break; } eDebugNoNewLine("AUDIO_SET_BYPASS - "); @@ -334,6 +338,10 @@ eDVBVideo::eDVBVideo(eDVBDemux *demux, int dev) // not finally values i think.. !! #define VIDEO_STREAMTYPE_MPEG2 0 #define VIDEO_STREAMTYPE_MPEG4_H264 1 +#define VIDEO_STREAMTYPE_VC1 3 +#define VIDEO_STREAMTYPE_MPEG4_Part2 4 +#define VIDEO_STREAMTYPE_VC1_SM 5 +#define VIDEO_STREAMTYPE_MPEG1 6 #if HAVE_DVB_API_VERSION < 3 int eDVBVideo::setPid(int pid) @@ -395,13 +403,36 @@ int eDVBVideo::stopPid() #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; - eDebugNoNewLine("VIDEO_SET_STREAMTYPE %d - ",type == MPEG4_H264 ? VIDEO_STREAMTYPE_MPEG4_H264 : VIDEO_STREAMTYPE_MPEG2); - if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE, - type == MPEG4_H264 ? VIDEO_STREAMTYPE_MPEG4_H264 : VIDEO_STREAMTYPE_MPEG2) < 0) + 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; + } + + eDebugNoNewLine("VIDEO_SET_STREAMTYPE %d - ", streamtype); + if (::ioctl(m_fd, VIDEO_SET_STREAMTYPE, streamtype) < 0) eDebug("failed (%m)"); else eDebug("ok"); diff --git a/lib/dvb/decoder.h b/lib/dvb/decoder.h index 5b9d352a..f2e10bb9 100644 --- a/lib/dvb/decoder.h +++ b/lib/dvb/decoder.h @@ -13,7 +13,7 @@ private: ePtr m_demux; int m_fd, m_fd_demux, m_dev, m_is_freezed; public: - enum { aMPEG, aAC3, aDTS, aAAC }; + enum { aMPEG, aAC3, aDTS, aAAC, aAACHE }; eDVBAudio(eDVBDemux *demux, int dev); enum { aMonoLeft, aStereo, aMonoRight }; void setChannel(int channel); @@ -49,7 +49,7 @@ private: Signal1 m_event; int m_width, m_height, m_framerate, m_aspect, m_progressive; public: - enum { MPEG2, MPEG4_H264 }; + enum { MPEG2, MPEG4_H264, MPEG1, MPEG4_Part2, VC1, VC1_SM }; eDVBVideo(eDVBDemux *demux, int dev); void stop(); #if HAVE_DVB_API_VERSION < 3 diff --git a/lib/dvb/pmt.cpp b/lib/dvb/pmt.cpp index 0c21272a..279ec74f 100644 --- a/lib/dvb/pmt.cpp +++ b/lib/dvb/pmt.cpp @@ -16,6 +16,7 @@ #include #include #include +#include eDVBServicePMTHandler::eDVBServicePMTHandler() :m_ca_servicePtr(0), m_dvb_scan(0), m_decode_demux_num(0xFF) @@ -217,25 +218,49 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) audioStream audio; audio.component_tag=video.component_tag=-1; video.type = videoStream::vtMPEG2; + audio.type = audioStream::atMPEG; switch ((*es)->getType()) { case 0x1b: // AVC Video Stream (MPEG4 H264) video.type = videoStream::vtMPEG4_H264; + isvideo = 1; + //break; fall through !!! + case 0x10: // MPEG 4 Part 2 + if (!isvideo) + { + video.type = videoStream::vtMPEG4_Part2; + isvideo = 1; + } + //break; fall through !!! case 0x01: // MPEG 1 video + if (!isvideo) + video.type = videoStream::vtMPEG1; + //break; fall through !!! case 0x02: // MPEG 2 video isvideo = 1; //break; fall through !!! case 0x03: // MPEG 1 audio case 0x04: // MPEG 2 audio: if (!isvideo) + isaudio = 1; + //break; fall through !!! + case 0x0f: // MPEG 2 AAC + if (!isvideo && !isaudio) { isaudio = 1; - audio.type = audioStream::atMPEG; + audio.type = audioStream::atAAC; } //break; fall through !!! + case 0x11: // MPEG 4 AAC + if (!isvideo && !isaudio) + { + isaudio = 1; + audio.type = audioStream::atAACHE; + } case 0x06: // PES Private case 0x81: // user private + case 0xEA: // TS_PSI_ST_SMPTE_VC1 for (DescriptorConstIterator desc = (*es)->getDescriptors()->begin(); desc != (*es)->getDescriptors()->end(); ++desc) { @@ -246,6 +271,17 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) check descriptors to get the exakt type. */ switch (tag) { + case AUDIO_STREAM_DESCRIPTOR: + isaudio = 1; + break; + case VIDEO_STREAM_DESCRIPTOR: + { + isvideo = 1; + VideoStreamDescriptor *d = (VideoStreamDescriptor*)(*desc); + if (d->getMpeg1OnlyFlag()) + video.type = videoStream::vtMPEG1; + break; + } case SUBTITLING_DESCRIPTOR: { SubtitlingDescriptor *d = (SubtitlingDescriptor*)(*desc); @@ -304,9 +340,14 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) isaudio = 1; audio.type = audioStream::atDTS; break; + case 0x2B: // TS_PSI_DT_MPEG2_AAC + isaudio = 1; + audio.type = audioStream::atAAC; // MPEG2-AAC + break; + case 0x1C: // TS_PSI_DT_MPEG4_Audio case AAC_DESCRIPTOR: isaudio = 1; - audio.type = audioStream::atAAC; + audio.type = audioStream::atAACHE; // MPEG4-AAC break; case AC3_DESCRIPTOR: isaudio = 1; @@ -315,7 +356,7 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) case REGISTRATION_DESCRIPTOR: /* some services don't have a separate AC3 descriptor */ { /* libdvbsi++ doesn't yet support this descriptor type, so work around. */ - if ((*desc)->getLength() != 4) + if ((*desc)->getLength() < 4) break; unsigned char descr[6]; (*desc)->writeToBuffer(descr); @@ -326,11 +367,29 @@ int eDVBServicePMTHandler::getProgramInfo(struct program &program) isaudio = 1; audio.type = audioStream::atAC3; break; + case 0x56432d31: + if (descr[6] == 0x01) // subdescriptor tag + { + if (descr[7] >= 0x90) // profile_level + video.type = videoStream::vtVC1; // advanced profile + else + video.type = videoStream::vtVC1_SM; // simple main + isvideo = 1; + } + break; default: break; } break; } + case 0x28: // TS_PSI_DT_AVC + isvideo = 1; + video.type = videoStream::vtMPEG4_H264; + break; + case 0x1B: // TS_PSI_DT_MPEG4_Video + isvideo = 1; + video.type = videoStream::vtMPEG4_Part2; + break; default: break; } diff --git a/lib/dvb/pmt.h b/lib/dvb/pmt.h index ff0ef046..3e22174b 100644 --- a/lib/dvb/pmt.h +++ b/lib/dvb/pmt.h @@ -135,14 +135,14 @@ public: { int pid; int component_tag; - enum { vtMPEG2, vtMPEG4_H264 }; + enum { vtMPEG2, vtMPEG4_H264, vtMPEG1, vtMPEG4_Part2, vtVC1, vtVC1_SM }; int type; }; struct audioStream { int pid; - enum { atMPEG, atAC3, atDTS, atAAC }; + enum { atMPEG, atAC3, atDTS, atAAC, atAACHE }; int type; // mpeg2, ac3, dts, ... int component_tag; diff --git a/lib/service/servicedvb.cpp b/lib/service/servicedvb.cpp index 59831680..d4a3a562 100644 --- a/lib/service/servicedvb.cpp +++ b/lib/service/servicedvb.cpp @@ -1600,6 +1600,8 @@ RESULT eDVBServicePlay::getTrackInfo(struct iAudioTrackInfo &info, unsigned int info.m_description = "AC3"; else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAAC) info.m_description = "AAC"; + else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atAACHE) + info.m_description = "AAC-HE"; else if (program.audioStreams[i].type == eDVBServicePMTHandler::audioStream::atDTS) info.m_description = "DTS"; else -- cgit v1.2.3