From 9d11b08ad61b1f0d6d7023ce403285d8662efaed Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 4 Mar 2015 00:23:39 +0100 Subject: sync with upstream --- xbmc/cores/AudioEngine/Utils/AEChannelData.h | 128 ++ xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.cpp | 184 -- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h | 359 ---- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.cpp | 193 --- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.h | 85 - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.cpp | 404 ----- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.h | 68 - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.cpp | 197 --- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.h | 60 - .../cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp | 1767 -------------------- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h | 172 -- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.cpp | 391 ----- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.h | 68 - .../dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp | 493 ------ .../dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h | 118 -- .../dvdplayer/DVDDemuxers/DVDDemuxShoutcast.cpp | 199 --- .../dvdplayer/DVDDemuxers/DVDDemuxShoutcast.h | 60 - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.cpp | 89 - xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.h | 31 - .../cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.cpp | 247 --- xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.h | 99 -- .../dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp | 153 -- .../dvdplayer/DVDDemuxers/DVDFactoryDemuxer.h | 30 - xbmc/cores/dvdplayer/DVDDemuxers/Makefile.in | 19 - 24 files changed, 128 insertions(+), 5486 deletions(-) create mode 100644 xbmc/cores/AudioEngine/Utils/AEChannelData.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.h delete mode 100644 xbmc/cores/dvdplayer/DVDDemuxers/Makefile.in (limited to 'xbmc/cores') diff --git a/xbmc/cores/AudioEngine/Utils/AEChannelData.h b/xbmc/cores/AudioEngine/Utils/AEChannelData.h new file mode 100644 index 0000000..5d47651 --- /dev/null +++ b/xbmc/cores/AudioEngine/Utils/AEChannelData.h @@ -0,0 +1,128 @@ +#pragma once +/* + * Copyright (C) 2010-2013 Team XBMC + * http://xbmc.org + * + * This Program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This Program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with XBMC; see the file COPYING. If not, see + * . + * + */ + +/** + * The possible channels + */ +enum AEChannel +{ + AE_CH_NULL = -1, + AE_CH_RAW , + + AE_CH_FL , AE_CH_FR , AE_CH_FC , AE_CH_LFE, AE_CH_BL , AE_CH_BR , AE_CH_FLOC, + AE_CH_FROC, AE_CH_BC , AE_CH_SL , AE_CH_SR , AE_CH_TFL , AE_CH_TFR , AE_CH_TFC , + AE_CH_TC , AE_CH_TBL, AE_CH_TBR, AE_CH_TBC, AE_CH_BLOC, AE_CH_BROC, + + /* p16v devices */ + AE_CH_UNKNOWN1, + AE_CH_UNKNOWN2, + AE_CH_UNKNOWN3, + AE_CH_UNKNOWN4, + AE_CH_UNKNOWN5, + AE_CH_UNKNOWN6, + AE_CH_UNKNOWN7, + AE_CH_UNKNOWN8, + AE_CH_UNKNOWN9, + AE_CH_UNKNOWN10, + AE_CH_UNKNOWN11, + AE_CH_UNKNOWN12, + AE_CH_UNKNOWN13, + AE_CH_UNKNOWN14, + AE_CH_UNKNOWN15, + AE_CH_UNKNOWN16, + + AE_CH_MAX +}; + +/** + * Standard channel layouts + */ +enum AEStdChLayout +{ + AE_CH_LAYOUT_INVALID = -1, + + AE_CH_LAYOUT_1_0 = 0, + AE_CH_LAYOUT_2_0, + AE_CH_LAYOUT_2_1, + AE_CH_LAYOUT_3_0, + AE_CH_LAYOUT_3_1, + AE_CH_LAYOUT_4_0, + AE_CH_LAYOUT_4_1, + AE_CH_LAYOUT_5_0, + AE_CH_LAYOUT_5_1, + AE_CH_LAYOUT_7_0, + AE_CH_LAYOUT_7_1, + + AE_CH_LAYOUT_MAX +}; + +/** + * The various data formats + * LE = Little Endian, BE = Big Endian, NE = Native Endian + * @note This is ordered from the worst to best preferred formats + */ +enum AEDataFormat +{ + AE_FMT_INVALID = -1, + + AE_FMT_U8, + + AE_FMT_S16BE, + AE_FMT_S16LE, + AE_FMT_S16NE, + + AE_FMT_S32BE, + AE_FMT_S32LE, + AE_FMT_S32NE, + + AE_FMT_S24BE4, + AE_FMT_S24LE4, + AE_FMT_S24NE4, // 24 bits in lower 3 bytes + AE_FMT_S24NE4MSB, // S32 with bits_per_sample < 32 + + AE_FMT_S24BE3, + AE_FMT_S24LE3, + AE_FMT_S24NE3, /* S24 in 3 bytes */ + + AE_FMT_DOUBLE, + AE_FMT_FLOAT, + + /* Bitstream formats */ + AE_FMT_AAC, + AE_FMT_AC3, + AE_FMT_DTS, + AE_FMT_EAC3, + AE_FMT_TRUEHD, + AE_FMT_DTSHD, + AE_FMT_LPCM, + + /* planar formats */ + AE_FMT_U8P, + AE_FMT_S16NEP, + AE_FMT_S32NEP, + AE_FMT_S24NE4P, + AE_FMT_S24NE4MSBP, + AE_FMT_S24NE3P, + AE_FMT_DOUBLEP, + AE_FMT_FLOATP, + + AE_FMT_MAX +}; diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.cpp deleted file mode 100644 index 2f833c5..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.cpp +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "DVDDemux.h" -#include "DVDCodecs/DVDCodecs.h" - -void CDemuxStreamTeletext::GetStreamInfo(std::string& strInfo) -{ - strInfo = "Teletext Data Stream"; -} - -void CDemuxStreamAudio::GetStreamType(std::string& strInfo) -{ - char sInfo[64]; - - if (codec == AV_CODEC_ID_AC3) strcpy(sInfo, "AC3 "); - else if (codec == AV_CODEC_ID_DTS) - { -#ifdef FF_PROFILE_DTS_HD_MA - if (profile == FF_PROFILE_DTS_HD_MA) - strcpy(sInfo, "DTS-HD MA "); - else if (profile == FF_PROFILE_DTS_HD_HRA) - strcpy(sInfo, "DTS-HD HRA "); - else -#endif - strcpy(sInfo, "DTS "); - } - else if (codec == AV_CODEC_ID_MP2) strcpy(sInfo, "MP2 "); - else if (codec == AV_CODEC_ID_TRUEHD) strcpy(sInfo, "Dolby TrueHD "); - else strcpy(sInfo, ""); - - if (iChannels == 1) strcat(sInfo, "Mono"); - else if (iChannels == 2) strcat(sInfo, "Stereo"); - else if (iChannels == 6) strcat(sInfo, "5.1"); - else if (iChannels == 8) strcat(sInfo, "7.1"); - else if (iChannels != 0) - { - char temp[32]; - sprintf(temp, " %d%s", iChannels, "-chs"); - strcat(sInfo, temp); - } - strInfo = sInfo; -} - -int CDVDDemux::GetNrOfAudioStreams() -{ - int iCounter = 0; - - for (int i = 0; i < GetNrOfStreams(); i++) - { - CDemuxStream* pStream = GetStream(i); - if (pStream->type == STREAM_AUDIO) iCounter++; - } - - return iCounter; -} - -int CDVDDemux::GetNrOfVideoStreams() -{ - int iCounter = 0; - - for (int i = 0; i < GetNrOfStreams(); i++) - { - CDemuxStream* pStream = GetStream(i); - if (pStream->type == STREAM_VIDEO) iCounter++; - } - - return iCounter; -} - -int CDVDDemux::GetNrOfSubtitleStreams() -{ - int iCounter = 0; - - for (int i = 0; i < GetNrOfStreams(); i++) - { - CDemuxStream* pStream = GetStream(i); - if (pStream->type == STREAM_SUBTITLE) iCounter++; - } - - return iCounter; -} - -int CDVDDemux::GetNrOfTeletextStreams() -{ - int iCounter = 0; - - for (int i = 0; i < GetNrOfStreams(); i++) - { - CDemuxStream* pStream = GetStream(i); - if (pStream->type == STREAM_TELETEXT) iCounter++; - } - - return iCounter; -} - -CDemuxStreamAudio* CDVDDemux::GetStreamFromAudioId(int iAudioIndex) -{ - int counter = -1; - for (int i = 0; i < GetNrOfStreams(); i++) - { - CDemuxStream* pStream = GetStream(i); - - if (pStream->type == STREAM_AUDIO) counter++; - if (iAudioIndex == counter) - return (CDemuxStreamAudio*)pStream; - } - return NULL; -} - -CDemuxStreamVideo* CDVDDemux::GetStreamFromVideoId(int iVideoIndex) -{ - int counter = -1; - for (int i = 0; i < GetNrOfStreams(); i++) - { - CDemuxStream* pStream = GetStream(i); - - if (pStream->type == STREAM_VIDEO) counter++; - if (iVideoIndex == counter) - return (CDemuxStreamVideo*)pStream; - } - return NULL; -} - -CDemuxStreamSubtitle* CDVDDemux::GetStreamFromSubtitleId(int iSubtitleIndex) -{ - int counter = -1; - for (int i = 0; i < GetNrOfStreams(); i++) - { - CDemuxStream* pStream = GetStream(i); - - if (pStream->type == STREAM_SUBTITLE) counter++; - if (iSubtitleIndex == counter) - return (CDemuxStreamSubtitle*)pStream; - } - return NULL; -} - -CDemuxStreamTeletext* CDVDDemux::GetStreamFromTeletextId(int iTeletextIndex) -{ - int counter = -1; - for (int i = 0; i < GetNrOfStreams(); i++) - { - CDemuxStream* pStream = GetStream(i); - - if (pStream->type == STREAM_TELETEXT) counter++; - if (iTeletextIndex == counter) - return (CDemuxStreamTeletext*)pStream; - } - return NULL; -} - -void CDemuxStream::GetStreamName( std::string& strInfo ) -{ - strInfo = ""; -} - -AVDiscard CDemuxStream::GetDiscard() -{ - return AVDISCARD_NONE; -} - -void CDemuxStream::SetDiscard(AVDiscard discard) -{ - return; -} - diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h deleted file mode 100644 index fca164d..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemux.h +++ /dev/null @@ -1,359 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include -#include "system.h" -#include "DVDDemuxPacket.h" - -class CDVDInputStream; - -#ifndef __GNUC__ -#pragma warning(push) -#pragma warning(disable:4244) -#endif - -#if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS) - #include "config.h" -#endif - -extern "C" { -#include "libavcodec/avcodec.h" -} - -#ifndef __GNUC__ -#pragma warning(pop) -#endif - -enum AVDiscard; - -enum StreamType -{ - STREAM_NONE = 0,// if unknown - STREAM_AUDIO, // audio stream - STREAM_VIDEO, // video stream - STREAM_DATA, // data stream - STREAM_SUBTITLE,// subtitle stream - STREAM_TELETEXT // Teletext data stream -}; - -enum StreamSource { - STREAM_SOURCE_NONE = 0x000, - STREAM_SOURCE_DEMUX = 0x100, - STREAM_SOURCE_NAV = 0x200, - STREAM_SOURCE_DEMUX_SUB = 0x300, - STREAM_SOURCE_TEXT = 0x400, - STREAM_SOURCE_VIDEOMUX = 0x500 -}; - -#define STREAM_SOURCE_MASK(a) ((a) & 0xf00) - -/* - * CDemuxStream - * Base class for all demuxer streams - */ -class CDemuxStream -{ -public: - CDemuxStream() - { - iId = 0; - iPhysicalId = 0; - codec = (AVCodecID)0; // AV_CODEC_ID_NONE - codec_fourcc = 0; - profile = FF_PROFILE_UNKNOWN; - level = FF_LEVEL_UNKNOWN; - type = STREAM_NONE; - source = STREAM_SOURCE_NONE; - iDuration = 0; - pPrivate = NULL; - ExtraData = NULL; - ExtraSize = 0; - memset(language, 0, sizeof(language)); - disabled = false; - changes = 0; - flags = FLAG_NONE; - orig_type = 0; - } - - virtual ~CDemuxStream() - { - delete [] ExtraData; - } - - virtual void GetStreamInfo(std::string& strInfo) - { - strInfo = ""; - } - - virtual void GetStreamName(std::string& strInfo); - - virtual void SetDiscard(AVDiscard discard); - virtual AVDiscard GetDiscard(); - - int iId; // most of the time starting from 0 - int iPhysicalId; // id - AVCodecID codec; - unsigned int codec_fourcc; // if available - int profile; // encoder profile of the stream reported by the decoder. used to qualify hw decoders. - int level; // encoder level of the stream reported by the decoder. used to qualify hw decoders. - StreamType type; - int source; - - int iDuration; // in mseconds - void* pPrivate; // private pointer for the demuxer - uint8_t* ExtraData; // extra data for codec to use - unsigned int ExtraSize; // size of extra data - - char language[4]; // ISO 639 3-letter language code (empty string if undefined) - bool disabled; // set when stream is disabled. (when no decoder exists) - - int changes; // increment on change which player may need to know about - - int orig_type; // type of original source - - enum EFlags - { FLAG_NONE = 0x0000 - , FLAG_DEFAULT = 0x0001 - , FLAG_DUB = 0x0002 - , FLAG_ORIGINAL = 0x0004 - , FLAG_COMMENT = 0x0008 - , FLAG_LYRICS = 0x0010 - , FLAG_KARAOKE = 0x0020 - , FLAG_FORCED = 0x0040 - , FLAG_HEARING_IMPAIRED = 0x0080 - , FLAG_VISUAL_IMPAIRED = 0x0100 - } flags; -}; - -class CDemuxStreamVideo : public CDemuxStream -{ -public: - CDemuxStreamVideo() : CDemuxStream() - { - iFpsScale = 0; - iFpsRate = 0; - irFpsScale = 0; - irFpsRate = 0; - iHeight = 0; - iWidth = 0; - fAspect = 0.0; - bVFR = false; - bPTSInvalid = false; - bForcedAspect = false; - type = STREAM_VIDEO; - iOrientation = 0; - iBitsPerPixel = 0; - } - - virtual ~CDemuxStreamVideo() {} - int iFpsScale; // scale of 1000 and a rate of 29970 will result in 29.97 fps - int iFpsRate; - int irFpsScale; - int irFpsRate; - int iHeight; // height of the stream reported by the demuxer - int iWidth; // width of the stream reported by the demuxer - float fAspect; // display aspect of stream - bool bVFR; // variable framerate - bool bPTSInvalid; // pts cannot be trusted (avi's). - bool bForcedAspect; // aspect is forced from container - int iOrientation; // orientation of the video in degress counter clockwise - int iBitsPerPixel; - std::string stereo_mode; // expected stereo mode -}; - -class CDemuxStreamAudio : public CDemuxStream -{ -public: - CDemuxStreamAudio() : CDemuxStream() - { - iChannels = 0; - iSampleRate = 0; - iBlockAlign = 0; - iBitRate = 0; - iBitsPerSample = 0; - type = STREAM_AUDIO; - } - - virtual ~CDemuxStreamAudio() {} - - void GetStreamType(std::string& strInfo); - - int iChannels; - int iSampleRate; - int iBlockAlign; - int iBitRate; - int iBitsPerSample; -}; - -class CDemuxStreamSubtitle : public CDemuxStream -{ -public: - CDemuxStreamSubtitle() : CDemuxStream() - { - type = STREAM_SUBTITLE; - } -}; - -class CDemuxStreamTeletext : public CDemuxStream -{ -public: - CDemuxStreamTeletext() : CDemuxStream() - { - type = STREAM_TELETEXT; - } - virtual void GetStreamInfo(std::string& strInfo); -}; - -class CDVDDemux -{ -public: - - CDVDDemux() {} - virtual ~CDVDDemux() {} - - - /* - * Reset the entire demuxer (same result as closing and opening it) - */ - virtual void Reset() = 0; - - /* - * Aborts any internal reading that might be stalling main thread - * NOTICE - this can be called from another thread - */ - virtual void Abort() = 0; - - /* - * Flush the demuxer, if any data is kept in buffers, this should be freed now - */ - virtual void Flush() = 0; - - /* - * Read a packet, returns NULL on error - * - */ - virtual DemuxPacket* Read() = 0; - - /* - * Seek, time in msec calculated from stream start - */ - virtual bool SeekTime(int time, bool backwords = false, double* startpts = NULL) = 0; - - /* - * Seek to a specified chapter. - * startpts can be updated to the point where display should start - */ - virtual bool SeekChapter(int chapter, double* startpts = NULL) { return false; } - - /* - * Get the number of chapters available - */ - virtual int GetChapterCount() { return 0; } - - /* - * Get current chapter - */ - virtual int GetChapter() { return 0; } - - /* - * Get the name of a chapter - * \param strChapterName[out] Name of chapter - * \param chapterIdx -1 for current chapter, else a chapter index - */ - virtual void GetChapterName(std::string& strChapterName, int chapterIdx=-1) {} - - /* - * Get the position of a chapter - * \param chapterIdx -1 for current chapter, else a chapter index - */ - virtual int64_t GetChapterPos(int chapterIdx=-1) { return 0; } - - /* - * Set the playspeed, if demuxer can handle different - * speeds of playback - */ - virtual void SetSpeed(int iSpeed) = 0; - - /* - * returns the total time in msec - */ - virtual int GetStreamLength() = 0; - - /* - * returns the stream or NULL on error, starting from 0 - */ - virtual CDemuxStream* GetStream(int iStreamId) = 0; - - /* - * return nr of streams, 0 if none - */ - virtual int GetNrOfStreams() = 0; - - /* - * returns opened filename - */ - virtual std::string GetFileName() = 0; - /* - * return nr of audio streams, 0 if none - */ - int GetNrOfAudioStreams(); - - /* - * return nr of video streams, 0 if none - */ - int GetNrOfVideoStreams(); - - /* - * return nr of subtitle streams, 0 if none - */ - int GetNrOfSubtitleStreams(); - - /* - * return nr of teletext streams, 0 if none - */ - int GetNrOfTeletextStreams(); - - /* - * return the audio stream, or NULL if it does not exist - */ - CDemuxStreamAudio* GetStreamFromAudioId(int iAudioIndex); - - /* - * return the video stream, or NULL if it does not exist - */ - CDemuxStreamVideo* GetStreamFromVideoId(int iVideoIndex); - - /* - * return the subtitle stream, or NULL if it does not exist - */ - CDemuxStreamSubtitle* GetStreamFromSubtitleId(int iSubtitleIndex); - - /* - * return the teletext stream, or NULL if it does not exist - */ - CDemuxStreamTeletext* GetStreamFromTeletextId(int iTeletextIndex); - - /* - * return a user-presentable codec name of the given stream - */ - virtual void GetStreamCodecName(int iStreamId, std::string &strName) {}; -}; diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.cpp deleted file mode 100644 index 9786983..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.cpp +++ /dev/null @@ -1,193 +0,0 @@ -/* - * Copyright (C) 2012-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "DVDInputStreams/DVDInputStream.h" -#include "DVDDemuxBXA.h" -#include "DVDDemuxUtils.h" -#include "utils/log.h" -#include "utils/StringUtils.h" -#include "../DVDClock.h" - -// AirTunes audio Demuxer. - -using namespace std; - -class CDemuxStreamAudioBXA - : public CDemuxStreamAudio -{ - CDVDDemuxBXA *m_parent; - string m_codec; -public: - CDemuxStreamAudioBXA(CDVDDemuxBXA *parent, const string& codec) - : m_parent(parent) - , m_codec(codec) - - {} - void GetStreamInfo(string& strInfo) - { - strInfo = StringUtils::Format("%s", m_codec.c_str()); - } -}; - -CDVDDemuxBXA::CDVDDemuxBXA() : CDVDDemux() -{ - m_pInput = NULL; - m_stream = NULL; - m_bytes = 0; - memset(&m_header, 0x0, sizeof(Demux_BXA_FmtHeader)); -} - -CDVDDemuxBXA::~CDVDDemuxBXA() -{ - Dispose(); -} - -bool CDVDDemuxBXA::Open(CDVDInputStream* pInput) -{ - Abort(); - - Dispose(); - - if(!pInput || !pInput->IsStreamType(DVDSTREAM_TYPE_FILE)) - return false; - - if(pInput->Read((uint8_t *)&m_header, sizeof(Demux_BXA_FmtHeader)) < 1) - return false; - - // file valid? - if (strncmp(m_header.fourcc, "BXA ", 4) != 0 || m_header.type != BXA_PACKET_TYPE_FMT_DEMUX) - { - pInput->Seek(0, SEEK_SET); - return false; - } - - m_pInput = pInput; - - m_stream = new CDemuxStreamAudioBXA(this, "BXA"); - - if(!m_stream) - return false; - - m_stream->iSampleRate = m_header.sampleRate; - m_stream->iBitsPerSample = m_header.bitsPerSample; - m_stream->iBitRate = m_header.sampleRate * m_header.channels * m_header.bitsPerSample; - m_stream->iChannels = m_header.channels; - m_stream->type = STREAM_AUDIO; - m_stream->codec = AV_CODEC_ID_PCM_S16LE; - - return true; -} - -void CDVDDemuxBXA::Dispose() -{ - delete m_stream; - m_stream = NULL; - - m_pInput = NULL; - m_bytes = 0; - - memset(&m_header, 0x0, sizeof(Demux_BXA_FmtHeader)); -} - -void CDVDDemuxBXA::Reset() -{ - CDVDInputStream* pInputStream = m_pInput; - Dispose(); - Open(pInputStream); -} - -void CDVDDemuxBXA::Abort() -{ - if(m_pInput) - return m_pInput->Abort(); -} - -void CDVDDemuxBXA::Flush() -{ -} - -#define BXA_READ_SIZE 4096 -DemuxPacket* CDVDDemuxBXA::Read() -{ - if(!m_pInput) - return NULL; - - DemuxPacket* pPacket = CDVDDemuxUtils::AllocateDemuxPacket(BXA_READ_SIZE); - - if (!pPacket) - { - if (m_pInput) - m_pInput->Close(); - return NULL; - } - - pPacket->iSize = m_pInput->Read(pPacket->pData, BXA_READ_SIZE); - pPacket->iStreamId = 0; - - if(pPacket->iSize < 1) - { - delete pPacket; - pPacket = NULL; - } - else - { - int n = (m_header.channels * m_header.bitsPerSample * m_header.sampleRate)>>3; - if (n > 0) - { - m_bytes += pPacket->iSize; - pPacket->dts = (double)m_bytes * DVD_TIME_BASE / n; - pPacket->pts = pPacket->dts; - } - else - { - pPacket->dts = DVD_NOPTS_VALUE; - pPacket->pts = DVD_NOPTS_VALUE; - } - } - - return pPacket; -} - -CDemuxStream* CDVDDemuxBXA::GetStream(int iStreamId) -{ - if(iStreamId != 0) - return NULL; - - return m_stream; -} - -int CDVDDemuxBXA::GetNrOfStreams() -{ - return (m_stream == NULL ? 0 : 1); -} - -std::string CDVDDemuxBXA::GetFileName() -{ - if(m_pInput) - return m_pInput->GetFileName(); - else - return ""; -} - -void CDVDDemuxBXA::GetStreamCodecName(int iStreamId, std::string &strName) -{ - if (m_stream && iStreamId == 0) - strName = "BXA"; -} diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.h deleted file mode 100644 index bdb65b4..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxBXA.h +++ /dev/null @@ -1,85 +0,0 @@ -#pragma once -/* - * Copyright (C) 2012-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "DVDDemux.h" - -#ifdef TARGET_WINDOWS -#define __attribute__(dummy_val) -#else -#include -#endif - -#ifdef TARGET_WINDOWS -#pragma pack(push) -#pragma pack(1) -#endif - -typedef struct -{ - char fourcc[4]; - uint32_t type; - uint32_t channels; - uint32_t sampleRate; - uint32_t bitsPerSample; - uint64_t durationMs; -} __attribute__((__packed__)) Demux_BXA_FmtHeader; - -#ifdef TARGET_WINDOWS -#pragma pack(pop) -#endif - -#include - -#define BXA_PACKET_TYPE_FMT_DEMUX 1 - -class CDemuxStreamAudioBXA; - -class CDVDDemuxBXA : public CDVDDemux -{ -public: - - CDVDDemuxBXA(); - ~CDVDDemuxBXA(); - - bool Open(CDVDInputStream* pInput); - void Dispose(); - void Reset(); - void Abort(); - void Flush(); - DemuxPacket* Read(); - bool SeekTime(int time, bool backwords = false, double* startpts = NULL) { return false; } - void SetSpeed(int iSpeed) {}; - int GetStreamLength() { return (int)m_header.durationMs; } - CDemuxStream* GetStream(int iStreamId); - int GetNrOfStreams(); - std::string GetFileName(); - virtual void GetStreamCodecName(int iStreamId, std::string &strName); - -protected: - friend class CDemuxStreamAudioBXA; - CDVDInputStream* m_pInput; - int64_t m_bytes; - - CDemuxStreamAudioBXA *m_stream; - - Demux_BXA_FmtHeader m_header; -}; - diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.cpp deleted file mode 100644 index 24d56da..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.cpp +++ /dev/null @@ -1,404 +0,0 @@ -/* - * Copyright (C) 2005-2014 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "DVDDemuxUtils.h" -#include "DVDClock.h" -#include "DVDDemuxCC.h" -#include "cores/dvdplayer/DVDCodecs/Overlay/contrib/cc_decoder708.h" -#include "utils/log.h" - -#include - -class CBitstream -{ -public: - CBitstream(uint8_t *data, int bits) - { - m_data = data; - m_offset = 0; - m_len = bits; - m_error = false; - } - unsigned int readBits(int num) - { - int r = 0; - while (num > 0) - { - if (m_offset >= m_len) - { - m_error = true; - return 0; - } - num--; - if (m_data[m_offset / 8] & (1 << (7 - (m_offset & 7)))) - r |= 1 << num; - m_offset++; - } - return r; - } - unsigned int readGolombUE(int maxbits = 32) - { - int lzb = -1; - int bits = 0; - for (int b = 0; !b; lzb++, bits++) - { - if (bits > maxbits) - return 0; - b = readBits(1); - } - return (1 << lzb) - 1 + readBits(lzb); - } - -private: - uint8_t *m_data; - int m_offset; - int m_len; - bool m_error; -}; - -class CCaptionBlock -{ -public: - CCaptionBlock(int size) - { - m_data = (uint8_t*)malloc(size); - m_size = size; - } - virtual ~CCaptionBlock() - { - free(m_data); - } - double m_pts; - uint8_t *m_data; - int m_size; -}; - -bool reorder_sort (CCaptionBlock *lhs, CCaptionBlock *rhs) -{ - return (lhs->m_pts > rhs->m_pts); -} - -CDVDDemuxCC::CDVDDemuxCC(AVCodecID codec) -{ - m_hasData = false; - m_curPts = 0; - m_ccDecoder = NULL; - m_codec = codec; -} - -CDVDDemuxCC::~CDVDDemuxCC() -{ - Dispose(); -} - -CDemuxStream* CDVDDemuxCC::GetStream(int iStreamId) -{ - return &m_streams[iStreamId]; -} - -int CDVDDemuxCC::GetNrOfStreams() -{ - return m_streams.size(); -} - -DemuxPacket* CDVDDemuxCC::Read(DemuxPacket *pSrcPacket) -{ - DemuxPacket *pPacket = NULL; - uint32_t startcode = 0xffffffff; - int picType = 0; - int p = 0; - int len; - - if (!pSrcPacket) - { - pPacket = Decode(); - return pPacket; - } - if (pSrcPacket->pts == DVD_NOPTS_VALUE) - { - return pPacket; - } - - while (!m_ccTempBuffer.empty()) - { - m_ccReorderBuffer.push_back(m_ccTempBuffer.back()); - m_ccTempBuffer.pop_back(); - } - - while ((len = pSrcPacket->iSize - p) > 3) - { - if ((startcode & 0xffffff00) == 0x00000100) - { - if (m_codec == AV_CODEC_ID_MPEG2VIDEO) - { - int scode = startcode & 0xFF; - if (scode == 0x00) - { - if (len > 4) - { - uint8_t *buf = pSrcPacket->pData + p; - picType = (buf[1] & 0x38) >> 3; - } - } - else if (scode == 0xb2) // user data - { - uint8_t *buf = pSrcPacket->pData + p; - if (len >= 6 && - buf[0] == 'G' && buf[1] == 'A' && buf[2] == '9' && buf[3] == '4' && - buf[4] == 3 && (buf[5] & 0x40)) - { - int cc_count = buf[5] & 0x1f; - if (cc_count > 0 && len >= 7 + cc_count * 3) - { - CCaptionBlock *cc = new CCaptionBlock(cc_count * 3); - memcpy(cc->m_data, buf + 7, cc_count * 3); - cc->m_pts = pSrcPacket->pts; - if (picType == 1 || picType == 2) - m_ccTempBuffer.push_back(cc); - else - m_ccReorderBuffer.push_back(cc); - } - } - else if (len >= 6 && - buf[0] == 'C' && buf[1] == 'C' && buf[2] == 1) - { - int oddidx = (buf[4] & 0x80) ? 0 : 1; - int cc_count = (buf[4] & 0x3e) >> 1; - int extrafield = buf[4] & 0x01; - if (extrafield) - cc_count++; - - if (cc_count > 0 && len >= 5 + cc_count * 3 * 2) - { - CCaptionBlock *cc = new CCaptionBlock(cc_count * 3); - uint8_t *src = buf + 5; - uint8_t *dst = cc->m_data; - - for (int i = 0; i < cc_count; i++) - { - for (int j = 0; j < 2; j++) - { - if (i == cc_count - 1 && extrafield && j == 1) - break; - - if ((oddidx == j) && (src[0] == 0xFF)) - { - dst[0] = 0x04; - dst[1] = src[1]; - dst[2] = src[2]; - dst += 3; - } - src += 3; - } - } - cc->m_pts = pSrcPacket->pts; - m_ccReorderBuffer.push_back(cc); - picType = 1; - } - } - } - } - else if (m_codec == AV_CODEC_ID_H264) - { - int scode = startcode & 0x9F; - // slice data comes after SEI - if (scode >= 1 && scode <= 5) - { - uint8_t *buf = pSrcPacket->pData + p; - CBitstream bs(buf, len * 8); - bs.readGolombUE(); - int sliceType = bs.readGolombUE(); - if (sliceType == 2 || sliceType == 7) // I slice - picType = 1; - else if (sliceType == 0 || sliceType == 5) // P slice - picType = 2; - if (picType == 0) - { - while (!m_ccTempBuffer.empty()) - { - m_ccReorderBuffer.push_back(m_ccTempBuffer.back()); - m_ccTempBuffer.pop_back(); - } - } - } - if (scode == 0x06) // SEI - { - uint8_t *buf = pSrcPacket->pData + p; - if (len >= 12 && - buf[3] == 0 && buf[4] == 49 && - buf[5] == 'G' && buf[6] == 'A' && buf[7] == '9' && buf[8] == '4' && buf[9] == 3) - { - uint8_t *userdata = buf + 10; - int cc_count = userdata[0] & 0x1f; - if (len >= cc_count * 3 + 10) - { - CCaptionBlock *cc = new CCaptionBlock(cc_count * 3); - memcpy(cc->m_data, userdata + 2, cc_count * 3); - cc->m_pts = pSrcPacket->pts; - m_ccTempBuffer.push_back(cc); - } - } - } - } - } - startcode = startcode << 8 | pSrcPacket->pData[p++]; - } - - if ((picType == 1 || picType == 2) && !m_ccReorderBuffer.empty()) - { - if (!m_ccDecoder) - { - if (!OpenDecoder()) - return NULL; - } - std::sort(m_ccReorderBuffer.begin(), m_ccReorderBuffer.end(), reorder_sort); - pPacket = Decode(); - } - return pPacket; -} - -void CDVDDemuxCC::Handler(int service, void *userdata) -{ - CDVDDemuxCC *ctx = (CDVDDemuxCC*)userdata; - - unsigned int idx; - - // switch back from 608 fallback if we got 708 - if (ctx->m_ccDecoder->m_seen608 && ctx->m_ccDecoder->m_seen708) - { - for (idx = 0; idx < ctx->m_streamdata.size(); idx++) - { - if (ctx->m_streamdata[idx].service == 0) - break; - } - if (idx < ctx->m_streamdata.size()) - { - ctx->m_streamdata.erase(ctx->m_streamdata.begin() + idx); - ctx->m_ccDecoder->m_seen608 = false; - } - if (service == 0) - return; - } - - for (idx = 0; idx < ctx->m_streamdata.size(); idx++) - { - if (ctx->m_streamdata[idx].service == service) - break; - } - if (idx >= ctx->m_streamdata.size()) - { - CDemuxStreamSubtitle stream; - strcpy(stream.language, "cc"); - stream.codec = AV_CODEC_ID_TEXT; - stream.iPhysicalId = service; - stream.iId = idx; - ctx->m_streams.push_back(stream); - - streamdata data; - data.streamIdx = idx; - data.service = service; - ctx->m_streamdata.push_back(data); - - if (service == 0) - ctx->m_ccDecoder->m_seen608 = true; - else - ctx->m_ccDecoder->m_seen708 = true; - } - - ctx->m_streamdata[idx].pts = ctx->m_curPts; - ctx->m_streamdata[idx].hasData = true; - ctx->m_hasData = true; -} - -bool CDVDDemuxCC::OpenDecoder() -{ - m_ccDecoder = new CDecoderCC708(); - m_ccDecoder->Init(Handler, this); - return true; -} - -void CDVDDemuxCC::Dispose() -{ - m_streams.clear(); - m_streamdata.clear(); - delete m_ccDecoder; - m_ccDecoder = NULL; - - while (!m_ccReorderBuffer.empty()) - { - delete m_ccReorderBuffer.back(); - m_ccReorderBuffer.pop_back(); - } - while (!m_ccTempBuffer.empty()) - { - delete m_ccTempBuffer.back(); - m_ccTempBuffer.pop_back(); - } -} - -DemuxPacket* CDVDDemuxCC::Decode() -{ - DemuxPacket *pPacket = NULL; - - while(!m_hasData && !m_ccReorderBuffer.empty()) - { - CCaptionBlock *cc = m_ccReorderBuffer.back(); - m_ccReorderBuffer.pop_back(); - m_curPts = cc->m_pts; - m_ccDecoder->Decode(cc->m_data, cc->m_size); - delete cc; - } - - if (m_hasData) - { - for (unsigned int i=0; im_cc608decoder->text; - len = m_ccDecoder->m_cc608decoder->textlen; - } - else - { - data = m_ccDecoder->m_cc708decoders[service].text; - len = m_ccDecoder->m_cc708decoders[service].textlen; - } - - pPacket = CDVDDemuxUtils::AllocateDemuxPacket(len); - pPacket->iSize = len; - memcpy(pPacket->pData, data, pPacket->iSize); - - pPacket->iStreamId = i; - pPacket->pts = m_streamdata[i].pts; - pPacket->duration = 0; - m_streamdata[i].hasData = false; - break; - } - m_hasData = false; - } - } - return pPacket; -} diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.h deleted file mode 100644 index ae78298..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCC.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2005-2014 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#pragma once -#include "DVDDemux.h" -#include - -class CCaptionBlock; -class CDecoderCC708; - -class CDVDDemuxCC : public CDVDDemux -{ -public: - CDVDDemuxCC(AVCodecID codec); - virtual ~CDVDDemuxCC(); - - virtual void Reset() {}; - virtual void Abort() {}; - virtual void Flush() {}; - virtual DemuxPacket* Read() { return NULL; }; - virtual bool SeekTime(int time, bool backwords = false, double* startpts = NULL) {return true;}; - virtual void SetSpeed(int iSpeed) {}; - virtual int GetStreamLength() {return 0;}; - virtual CDemuxStream* GetStream(int iStreamId); - virtual int GetNrOfStreams(); - virtual std::string GetFileName() {return "";}; - - DemuxPacket* Read(DemuxPacket *packet); - static void Handler(int service, void *userdata); - -protected: - bool OpenDecoder(); - void Dispose(); - DemuxPacket* Decode(); - - struct streamdata - { - int streamIdx; - int service; - bool hasData ; - double pts; - }; - std::vector m_streamdata; - std::vector m_streams; - bool m_hasData; - double m_curPts; - std::vector m_ccReorderBuffer; - std::vector m_ccTempBuffer; - CDecoderCC708 *m_ccDecoder; - AVCodecID m_codec; -}; diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.cpp deleted file mode 100644 index 72067da..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (C) 2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "DVDInputStreams/DVDInputStream.h" -#include "DVDDemuxCDDA.h" -#include "DVDDemuxUtils.h" -#include "utils/log.h" -#include "../DVDClock.h" - -// CDDA audio demuxer based on AirTunes audio Demuxer. - -using namespace std; - -class CDemuxStreamAudioCDDA - : public CDemuxStreamAudio -{ -public: - void GetStreamInfo(string& strInfo) - { - strInfo = "pcm"; - } -}; - -CDVDDemuxCDDA::CDVDDemuxCDDA() : CDVDDemux() -{ - m_pInput = NULL; - m_stream = NULL; - m_bytes = 0; -} - -CDVDDemuxCDDA::~CDVDDemuxCDDA() -{ - Dispose(); -} - -bool CDVDDemuxCDDA::Open(CDVDInputStream* pInput) -{ - Abort(); - - Dispose(); - - if(!pInput || !pInput->IsStreamType(DVDSTREAM_TYPE_FILE)) - return false; - - m_pInput = pInput; - - m_stream = new CDemuxStreamAudioCDDA(); - - if(!m_stream) - return false; - - m_stream->iSampleRate = 44100; - m_stream->iBitsPerSample = 16; - m_stream->iBitRate = 44100 * 2 * 16; - m_stream->iChannels = 2; - m_stream->type = STREAM_AUDIO; - m_stream->codec = AV_CODEC_ID_PCM_S16LE; - - return true; -} - -void CDVDDemuxCDDA::Dispose() -{ - delete m_stream; - m_stream = NULL; - - m_pInput = NULL; - m_bytes = 0; -} - -void CDVDDemuxCDDA::Reset() -{ - CDVDInputStream* pInputStream = m_pInput; - Dispose(); - Open(pInputStream); -} - -void CDVDDemuxCDDA::Abort() -{ - if(m_pInput) - return m_pInput->Abort(); -} - -void CDVDDemuxCDDA::Flush() -{ -} - -#define CDDA_READ_SIZE 4096 -DemuxPacket* CDVDDemuxCDDA::Read() -{ - if(!m_pInput) - return NULL; - - DemuxPacket* pPacket = CDVDDemuxUtils::AllocateDemuxPacket(CDDA_READ_SIZE); - - if (!pPacket) - { - if (m_pInput) - m_pInput->Close(); - return NULL; - } - - pPacket->iSize = m_pInput->Read(pPacket->pData, CDDA_READ_SIZE); - pPacket->iStreamId = 0; - - if(pPacket->iSize < 1) - { - delete pPacket; - pPacket = NULL; - } - else - { - int n = m_stream->iBitRate>>3; - if (n > 0) - { - m_bytes += pPacket->iSize; - pPacket->dts = (double)m_bytes * DVD_TIME_BASE / n; - pPacket->pts = pPacket->dts; - } - else - { - pPacket->dts = DVD_NOPTS_VALUE; - pPacket->pts = DVD_NOPTS_VALUE; - } - } - - return pPacket; -} - -bool CDVDDemuxCDDA::SeekTime(int time, bool backwords, double* startpts) -{ - int bytes_per_second = m_stream->iBitRate>>3; - // clamp seeks to bytes per full sample - int clamp_bytes = (m_stream->iBitsPerSample>>3) * m_stream->iChannels; - - // time is in milliseconds - int64_t seekPos = m_pInput->Seek((((int64_t)time * bytes_per_second / 1000) / clamp_bytes ) * clamp_bytes, SEEK_SET) > 0; - if (seekPos > 0) - m_bytes = seekPos; - - if (startpts) - *startpts = (double)m_bytes * DVD_TIME_BASE / bytes_per_second; - - return seekPos > 0; -}; - -int CDVDDemuxCDDA::GetStreamLength() -{ - int64_t num_track_bytes = m_pInput->GetLength(); - int bytes_per_second = (m_stream->iBitRate>>3); - int64_t track_mseconds = num_track_bytes*1000 / bytes_per_second; - return (int)track_mseconds; -} - -CDemuxStream* CDVDDemuxCDDA::GetStream(int iStreamId) -{ - if(iStreamId != 0) - return NULL; - - return m_stream; -} - -int CDVDDemuxCDDA::GetNrOfStreams() -{ - return (m_stream == NULL ? 0 : 1); -} - -std::string CDVDDemuxCDDA::GetFileName() -{ - if(m_pInput) - return m_pInput->GetFileName(); - else - return ""; -} - -void CDVDDemuxCDDA::GetStreamCodecName(int iStreamId, std::string &strName) -{ - if (m_stream && iStreamId == 0) - strName = "pcm"; -} diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.h deleted file mode 100644 index 6a3c50a..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxCDDA.h +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once -/* - * Copyright (C) 2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "DVDDemux.h" -#include "utils/log.h" - -#ifdef TARGET_WINDOWS -#define __attribute__(dummy_val) -#else -#include -#endif - -class CDemuxStreamAudioCDDA; - -class CDVDDemuxCDDA : public CDVDDemux -{ -public: - - CDVDDemuxCDDA(); - ~CDVDDemuxCDDA(); - - bool Open(CDVDInputStream* pInput); - void Dispose(); - void Reset(); - void Abort(); - void Flush(); - DemuxPacket* Read(); - bool SeekTime(int time, bool backwords = false, double* startpts = NULL); - void SetSpeed(int iSpeed) {}; - int GetStreamLength() ; - CDemuxStream* GetStream(int iStreamId); - int GetNrOfStreams(); - std::string GetFileName(); - virtual void GetStreamCodecName(int iStreamId, std::string &strName); - -protected: - friend class CDemuxStreamAudioCDDA; - CDVDInputStream* m_pInput; - int64_t m_bytes; - - CDemuxStreamAudioCDDA *m_stream; -}; diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp deleted file mode 100644 index f58472f..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.cpp +++ /dev/null @@ -1,1767 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "system.h" -#ifndef __STDC_CONSTANT_MACROS -#define __STDC_CONSTANT_MACROS -#endif -#ifndef __STDC_LIMIT_MACROS -#define __STDC_LIMIT_MACROS -#endif -#ifdef TARGET_POSIX -#include "stdint.h" -#endif -#include "DVDDemuxFFmpeg.h" -#include "DVDInputStreams/DVDInputStream.h" -#include "DVDInputStreams/DVDInputStreamNavigator.h" -#ifdef HAVE_LIBBLURAY -#include "DVDInputStreams/DVDInputStreamBluray.h" -#endif -#include "DVDInputStreams/DVDInputStreamPVRManager.h" -#include "DVDInputStreams/DVDInputStreamFFmpeg.h" -#include "DVDDemuxUtils.h" -#include "DVDClock.h" // for DVD_TIME_BASE -#include "commons/Exception.h" -#include "settings/AdvancedSettings.h" -#include "settings/Settings.h" -#include "filesystem/File.h" -#include "filesystem/CurlFile.h" -#include "filesystem/Directory.h" -#include "utils/log.h" -#include "threads/Thread.h" -#include "threads/SystemClock.h" -#include "utils/TimeUtils.h" -#include "utils/StringUtils.h" -#include "URL.h" -#include "cores/FFmpeg.h" - -extern "C" { -#include "libavutil/opt.h" -} - -struct StereoModeConversionMap -{ - const char* name; - const char* mode; -}; - -// we internally use the matroska string representation of stereoscopic modes. -// This struct is a conversion map to convert stereoscopic mode values -// from asf/wmv to the internally used matroska ones -static const struct StereoModeConversionMap WmvToInternalStereoModeMap[] = -{ - { "SideBySideRF", "right_left" }, - { "SideBySideLF", "left_right" }, - { "OverUnderRT", "bottom_top" }, - { "OverUnderLT", "top_bottom" }, - {} -}; - -#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - FF_INPUT_BUFFER_PADDING_SIZE) - -void CDemuxStreamAudioFFmpeg::GetStreamInfo(std::string& strInfo) -{ - if(!m_stream) return; - char temp[128]; - avcodec_string(temp, 128, m_stream->codec, 0); - strInfo = temp; -} - -void CDemuxStreamAudioFFmpeg::GetStreamName(std::string& strInfo) -{ - if(!m_stream) return; - if(!m_description.empty()) - strInfo = m_description; - else - CDemuxStream::GetStreamName(strInfo); -} - -void CDemuxStreamSubtitleFFmpeg::GetStreamName(std::string& strInfo) -{ - if(!m_stream) return; - if(!m_description.empty()) - strInfo = m_description; - else - CDemuxStream::GetStreamName(strInfo); -} - -void CDemuxStreamVideoFFmpeg::GetStreamInfo(std::string& strInfo) -{ - if(!m_stream) return; - char temp[128]; - avcodec_string(temp, 128, m_stream->codec, 0); - strInfo = temp; -} - -void CDemuxStreamSubtitleFFmpeg::GetStreamInfo(std::string& strInfo) -{ - if(!m_stream) return; - char temp[128]; - avcodec_string(temp, 128, m_stream->codec, 0); - strInfo = temp; -} - -static int interrupt_cb(void* ctx) -{ - CDVDDemuxFFmpeg* demuxer = static_cast(ctx); - if(demuxer && demuxer->Aborted()) - return 1; - return 0; -} - - -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// -/* -static int dvd_file_open(URLContext *h, const char *filename, int flags) -{ - return -1; -} -*/ - -static int dvd_file_read(void *h, uint8_t* buf, int size) -{ - if(interrupt_cb(h)) - return AVERROR_EXIT; - - CDVDInputStream* pInputStream = static_cast(h)->m_pInput; - return pInputStream->Read(buf, size); -} -/* -static int dvd_file_write(URLContext *h, uint8_t* buf, int size) -{ - return -1; -} -*/ -static int64_t dvd_file_seek(void *h, int64_t pos, int whence) -{ - if(interrupt_cb(h)) - return AVERROR_EXIT; - - CDVDInputStream* pInputStream = static_cast(h)->m_pInput; - if(whence == AVSEEK_SIZE) - return pInputStream->GetLength(); - else - return pInputStream->Seek(pos, whence & ~AVSEEK_FORCE); -} - -//////////////////////////////////////////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////////////////////// - -CDVDDemuxFFmpeg::CDVDDemuxFFmpeg() : CDVDDemux() -{ - m_pFormatContext = NULL; - m_pInput = NULL; - m_ioContext = NULL; - m_currentPts = DVD_NOPTS_VALUE; - m_bMatroska = false; - m_bAVI = false; - m_speed = DVD_PLAYSPEED_NORMAL; - m_program = UINT_MAX; - m_pkt.result = -1; - memset(&m_pkt.pkt, 0, sizeof(AVPacket)); - m_streaminfo = true; /* set to true if we want to look for streams before playback */ - m_checkvideo = false; -} - -CDVDDemuxFFmpeg::~CDVDDemuxFFmpeg() -{ - Dispose(); - ff_flush_avutil_log_buffers(); -} - -bool CDVDDemuxFFmpeg::Aborted() -{ - if(m_timeout.IsTimePast()) - return true; - - CDVDInputStreamFFmpeg * input = dynamic_cast(m_pInput); - if(input && input->Aborted()) - return true; - - return false; -} - -bool CDVDDemuxFFmpeg::Open(CDVDInputStream* pInput, bool streaminfo, bool fileinfo) -{ - AVInputFormat* iformat = NULL; - std::string strFile; - m_streaminfo = streaminfo; - m_currentPts = DVD_NOPTS_VALUE; - m_speed = DVD_PLAYSPEED_NORMAL; - m_program = UINT_MAX; - const AVIOInterruptCB int_cb = { interrupt_cb, this }; - - if (!pInput) return false; - - m_pInput = pInput; - strFile = m_pInput->GetFileName(); - - if( m_pInput->GetContent().length() > 0 ) - { - std::string content = m_pInput->GetContent(); - StringUtils::ToLower(content); - - /* check if we can get a hint from content */ - if ( content.compare("video/x-vobsub") == 0 ) - iformat = av_find_input_format("mpeg"); - else if( content.compare("video/x-dvd-mpeg") == 0 ) - iformat = av_find_input_format("mpeg"); - else if( content.compare("video/mp2t") == 0 ) - iformat = av_find_input_format("mpegts"); - else if( content.compare("multipart/x-mixed-replace") == 0 ) - iformat = av_find_input_format("mjpeg"); - } - - // open the demuxer - m_pFormatContext = avformat_alloc_context(); - m_pFormatContext->interrupt_callback = int_cb; - - // try to abort after 30 seconds - m_timeout.Set(30000); - - if( m_pInput->IsStreamType(DVDSTREAM_TYPE_FFMPEG) ) - { - // special stream type that makes avformat handle file opening - // allows internal ffmpeg protocols to be used - CURL url = m_pInput->GetURL(); - - AVDictionary *options = GetFFMpegOptionsFromURL(url); - - int result=-1; - if (url.IsProtocol("mms")) - { - // try mmsh, then mmst - url.SetProtocol("mmsh"); - url.SetProtocolOptions(""); - result = avformat_open_input(&m_pFormatContext, url.Get().c_str(), iformat, &options); - if (result < 0) - { - url.SetProtocol("mmst"); - strFile = url.Get(); - } - } - if (result < 0 && avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, &options) < 0 ) - { - CLog::Log(LOGDEBUG, "Error, could not open file %s", CURL::GetRedacted(strFile).c_str()); - Dispose(); - av_dict_free(&options); - return false; - } - av_dict_free(&options); - } - else - { - unsigned char* buffer = (unsigned char*)av_malloc(FFMPEG_FILE_BUFFER_SIZE); - m_ioContext = avio_alloc_context(buffer, FFMPEG_FILE_BUFFER_SIZE, 0, this, dvd_file_read, NULL, dvd_file_seek); - m_ioContext->max_packet_size = m_pInput->GetBlockSize(); - if(m_ioContext->max_packet_size) - m_ioContext->max_packet_size *= FFMPEG_FILE_BUFFER_SIZE / m_ioContext->max_packet_size; - - if(m_pInput->Seek(0, SEEK_POSSIBLE) == 0) - m_ioContext->seekable = 0; - - std::string content = m_pInput->GetContent(); - StringUtils::ToLower(content); - if (StringUtils::StartsWith(content, "audio/l16")) - iformat = av_find_input_format("s16be"); - - if( iformat == NULL ) - { - // let ffmpeg decide which demuxer we have to open - - bool trySPDIFonly = (m_pInput->GetContent() == "audio/x-spdif-compressed"); - - if (!trySPDIFonly) - av_probe_input_buffer(m_ioContext, &iformat, strFile.c_str(), NULL, 0, 0); - - // Use the more low-level code in case we have been built against an old - // FFmpeg without the above av_probe_input_buffer(), or in case we only - // want to probe for spdif (DTS or IEC 61937) compressed audio - // specifically, or in case the file is a wav which may contain DTS or - // IEC 61937 (e.g. ac3-in-wav) and we want to check for those formats. - if (trySPDIFonly || (iformat && strcmp(iformat->name, "wav") == 0)) - { - AVProbeData pd; - uint8_t probe_buffer[FFMPEG_FILE_BUFFER_SIZE + AVPROBE_PADDING_SIZE]; - - // init probe data - pd.buf = probe_buffer; - pd.filename = strFile.c_str(); - - // av_probe_input_buffer might have changed the buffer_size beyond our allocated amount - int buffer_size = std::min((int) FFMPEG_FILE_BUFFER_SIZE, m_ioContext->buffer_size); - // read data using avformat's buffers - pd.buf_size = avio_read(m_ioContext, pd.buf, m_ioContext->max_packet_size ? m_ioContext->max_packet_size : buffer_size); - if (pd.buf_size <= 0) - { - CLog::Log(LOGERROR, "%s - error reading from input stream, %s", __FUNCTION__, CURL::GetRedacted(strFile).c_str()); - return false; - } - memset(pd.buf+pd.buf_size, 0, AVPROBE_PADDING_SIZE); - - // restore position again - avio_seek(m_ioContext , 0, SEEK_SET); - - // the advancedsetting is for allowing the user to force outputting the - // 44.1 kHz DTS wav file as PCM, so that an A/V receiver can decode - // it (this is temporary until we handle 44.1 kHz passthrough properly) - if (trySPDIFonly || (iformat && strcmp(iformat->name, "wav") == 0 && !g_advancedSettings.m_dvdplayerIgnoreDTSinWAV)) - { - // check for spdif and dts - // This is used with wav files and audio CDs that may contain - // a DTS or AC3 track padded for S/PDIF playback. If neither of those - // is present, we assume it is PCM audio. - // AC3 is always wrapped in iec61937 (ffmpeg "spdif"), while DTS - // may be just padded. - AVInputFormat *iformat2; - iformat2 = av_find_input_format("spdif"); - - if (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4) - { - iformat = iformat2; - } - else - { - // not spdif or no spdif demuxer, try dts - iformat2 = av_find_input_format("dts"); - - if (iformat2 && iformat2->read_probe(&pd) > AVPROBE_SCORE_MAX / 4) - { - iformat = iformat2; - } - else if (trySPDIFonly) - { - // not dts either, return false in case we were explicitely - // requested to only check for S/PDIF padded compressed audio - CLog::Log(LOGDEBUG, "%s - not spdif or dts file, fallbacking", __FUNCTION__); - return false; - } - } - } - } - - if(!iformat) - { - std::string content = m_pInput->GetContent(); - - /* check if we can get a hint from content */ - if( content.compare("audio/aacp") == 0 ) - iformat = av_find_input_format("aac"); - else if( content.compare("audio/aac") == 0 ) - iformat = av_find_input_format("aac"); - else if( content.compare("video/flv") == 0 ) - iformat = av_find_input_format("flv"); - else if( content.compare("video/x-flv") == 0 ) - iformat = av_find_input_format("flv"); - } - - if (!iformat) - { - CLog::Log(LOGERROR, "%s - error probing input format, %s", __FUNCTION__, CURL::GetRedacted(strFile).c_str()); - return false; - } - else - { - if (iformat->name) - CLog::Log(LOGDEBUG, "%s - probing detected format [%s]", __FUNCTION__, iformat->name); - else - CLog::Log(LOGDEBUG, "%s - probing detected unnamed format", __FUNCTION__); - } - } - - - m_pFormatContext->pb = m_ioContext; - - AVDictionary *options = NULL; - if (iformat->name && (strcmp(iformat->name, "mp3") == 0 || strcmp(iformat->name, "mp2") == 0)) - { - CLog::Log(LOGDEBUG, "%s - setting usetoc to 0 for accurate VBR MP3 seek", __FUNCTION__); - av_dict_set(&options, "usetoc", "0", 0); - } - - if (StringUtils::StartsWith(content, "audio/l16")) - { - int channels = 2; - int samplerate = 44100; - GetL16Parameters(channels, samplerate); - av_dict_set_int(&options, "channels", channels, 0); - av_dict_set_int(&options, "sample_rate", samplerate, 0); - } - - if (avformat_open_input(&m_pFormatContext, strFile.c_str(), iformat, &options) < 0) - { - CLog::Log(LOGERROR, "%s - Error, could not open file %s", __FUNCTION__, CURL::GetRedacted(strFile).c_str()); - Dispose(); - av_dict_free(&options); - return false; - } - av_dict_free(&options); - } - - // Avoid detecting framerate if advancedsettings.xml says so - if (g_advancedSettings.m_videoFpsDetect == 0) - m_pFormatContext->fps_probe_size = 0; - - // analyse very short to speed up mjpeg playback start - if (iformat && (strcmp(iformat->name, "mjpeg") == 0) && m_ioContext->seekable == 0) - av_opt_set_int(m_pFormatContext, "analyzeduration", 500000, 0); - - bool skipCreateStreams = false; - bool isBluray = pInput->IsStreamType(DVDSTREAM_TYPE_BLURAY); - if (iformat && (strcmp(iformat->name, "mpegts") == 0) && !fileinfo && !isBluray) - { - av_opt_set_int(m_pFormatContext, "analyzeduration", 500000, 0); - m_checkvideo = true; - skipCreateStreams = true; - } - else if (!iformat || (strcmp(iformat->name, "mpegts") != 0)) - { - m_streaminfo = true; - } - - // we need to know if this is matroska or avi later - m_bMatroska = strncmp(m_pFormatContext->iformat->name, "matroska", 8) == 0; // for "matroska.webm" - m_bAVI = strcmp(m_pFormatContext->iformat->name, "avi") == 0; - - if (m_streaminfo) - { - /* to speed up dvd switches, only analyse very short */ - if(m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD)) - av_opt_set_int(m_pFormatContext, "analyzeduration", 500000, 0); - - CLog::Log(LOGDEBUG, "%s - avformat_find_stream_info starting", __FUNCTION__); - int iErr = avformat_find_stream_info(m_pFormatContext, NULL); - if (iErr < 0) - { - CLog::Log(LOGWARNING,"could not find codec parameters for %s", CURL::GetRedacted(strFile).c_str()); - if (m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD) - || m_pInput->IsStreamType(DVDSTREAM_TYPE_BLURAY) - || (m_pFormatContext->nb_streams == 1 && m_pFormatContext->streams[0]->codec->codec_id == AV_CODEC_ID_AC3)) - { - // special case, our codecs can still handle it. - } - else - { - Dispose(); - return false; - } - } - CLog::Log(LOGDEBUG, "%s - av_find_stream_info finished", __FUNCTION__); - - if (m_checkvideo) - { - // make sure we start video with an i-frame - ResetVideoStreams(); - } - } - else - { - m_program = 0; - m_checkvideo = true; - skipCreateStreams = true; - } - - // reset any timeout - m_timeout.SetInfinite(); - - // if format can be nonblocking, let's use that - m_pFormatContext->flags |= AVFMT_FLAG_NONBLOCK; - - // print some extra information - av_dump_format(m_pFormatContext, 0, strFile.c_str(), 0); - - UpdateCurrentPTS(); - - // in case of mpegts and we have not seen pat/pmt, defer creation of streams - if (!skipCreateStreams || m_pFormatContext->nb_programs > 0) - CreateStreams(); - - // allow IsProgramChange to return true - if (skipCreateStreams && GetNrOfStreams() == 0) - m_program = 0; - - return true; -} - -void CDVDDemuxFFmpeg::Dispose() -{ - m_pkt.result = -1; - av_free_packet(&m_pkt.pkt); - - if (m_pFormatContext) - { - if (m_ioContext && m_pFormatContext->pb && m_pFormatContext->pb != m_ioContext) - { - CLog::Log(LOGWARNING, "CDVDDemuxFFmpeg::Dispose - demuxer changed our byte context behind our back, possible memleak"); - m_ioContext = m_pFormatContext->pb; - } - avformat_close_input(&m_pFormatContext); - } - - if(m_ioContext) - { - av_free(m_ioContext->buffer); - av_free(m_ioContext); - } - - m_ioContext = NULL; - m_pFormatContext = NULL; - m_speed = DVD_PLAYSPEED_NORMAL; - - DisposeStreams(); - - m_pInput = NULL; -} - -void CDVDDemuxFFmpeg::Reset() -{ - CDVDInputStream* pInputStream = m_pInput; - Dispose(); - Open(pInputStream, m_streaminfo); -} - -void CDVDDemuxFFmpeg::Flush() -{ - // naughty usage of an internal ffmpeg function - if (m_pFormatContext) - av_read_frame_flush(m_pFormatContext); - - m_currentPts = DVD_NOPTS_VALUE; - - m_pkt.result = -1; - av_free_packet(&m_pkt.pkt); -} - -void CDVDDemuxFFmpeg::Abort() -{ - m_timeout.SetExpired(); -} - -void CDVDDemuxFFmpeg::SetSpeed(int iSpeed) -{ - if(!m_pFormatContext) - return; - - if(m_speed != DVD_PLAYSPEED_PAUSE && iSpeed == DVD_PLAYSPEED_PAUSE) - { - m_pInput->Pause(m_currentPts); - av_read_pause(m_pFormatContext); - } - else if(m_speed == DVD_PLAYSPEED_PAUSE && iSpeed != DVD_PLAYSPEED_PAUSE) - { - m_pInput->Pause(m_currentPts); - av_read_play(m_pFormatContext); - } - m_speed = iSpeed; - - AVDiscard discard = AVDISCARD_NONE; - if(m_speed > 4*DVD_PLAYSPEED_NORMAL) - discard = AVDISCARD_NONKEY; - else if(m_speed > 2*DVD_PLAYSPEED_NORMAL) - discard = AVDISCARD_BIDIR; - else if(m_speed < DVD_PLAYSPEED_PAUSE) - discard = AVDISCARD_NONKEY; - - - for(unsigned int i = 0; i < m_pFormatContext->nb_streams; i++) - { - if(m_pFormatContext->streams[i]) - { - if(m_pFormatContext->streams[i]->discard != AVDISCARD_ALL) - m_pFormatContext->streams[i]->discard = discard; - } - } -} - -AVDictionary *CDVDDemuxFFmpeg::GetFFMpegOptionsFromURL(const CURL &url) -{ - - AVDictionary *options = NULL; - - if (url.IsProtocol("http") || url.IsProtocol("https")) - { - std::map protocolOptions; - url.GetProtocolOptions(protocolOptions); - std::string headers; - bool hasUserAgent = false; - for(std::map::const_iterator it = protocolOptions.begin(); it != protocolOptions.end(); ++it) - { - std::string name = it->first; StringUtils::ToLower(name); - const std::string &value = it->second; - - if (name == "seekable") - av_dict_set(&options, "seekable", value.c_str(), 0); - else if (name == "user-agent") - { - av_dict_set(&options, "user-agent", value.c_str(), 0); - hasUserAgent = true; - } - else if (name != "auth" && name != "encoding") - // all other protocol options can be added as http header. - headers.append(it->first).append(": ").append(value).append("\r\n"); - } - if (!hasUserAgent) - // set default xbmc user-agent. - av_dict_set(&options, "user-agent", g_advancedSettings.m_userAgent.c_str(), 0); - - if (!headers.empty()) - av_dict_set(&options, "headers", headers.c_str(), 0); - - std::string cookies; - if (XFILE::CCurlFile::GetCookies(url, cookies)) - av_dict_set(&options, "cookies", cookies.c_str(), 0); - - } - return options; -} - -double CDVDDemuxFFmpeg::ConvertTimestamp(int64_t pts, int den, int num) -{ - if (pts == (int64_t)AV_NOPTS_VALUE) - return DVD_NOPTS_VALUE; - - // do calculations in floats as they can easily overflow otherwise - // we don't care for having a completly exact timestamp anyway - double timestamp = (double)pts * num / den; - double starttime = 0.0f; - - // for dvd's we need the original time - if(CDVDInputStream::IMenus* menu = dynamic_cast(m_pInput)) - starttime = menu->GetTimeStampCorrection() / DVD_TIME_BASE; - else if (m_pFormatContext->start_time != (int64_t)AV_NOPTS_VALUE) - starttime = (double)m_pFormatContext->start_time / AV_TIME_BASE; - - if(timestamp > starttime) - timestamp -= starttime; - // allow for largest possible difference in pts and dts for a single packet - else if( timestamp + 0.5f > starttime ) - timestamp = 0; - - return timestamp*DVD_TIME_BASE; -} - -DemuxPacket* CDVDDemuxFFmpeg::Read() -{ - DemuxPacket* pPacket = NULL; - // on some cases where the received packet is invalid we will need to return an empty packet (0 length) otherwise the main loop (in CDVDPlayer) - // would consider this the end of stream and stop. - bool bReturnEmpty = false; - { CSingleLock lock(m_critSection); // open lock scope - if (m_pFormatContext) - { - // assume we are not eof - if(m_pFormatContext->pb) - m_pFormatContext->pb->eof_reached = 0; - - // check for saved packet after a program change - if (m_pkt.result < 0) - { - // keep track if ffmpeg doesn't always set these - m_pkt.pkt.size = 0; - m_pkt.pkt.data = NULL; - - // timeout reads after 100ms - m_timeout.Set(20000); - m_pkt.result = av_read_frame(m_pFormatContext, &m_pkt.pkt); - m_timeout.SetInfinite(); - } - - if (m_pkt.result == AVERROR(EINTR) || m_pkt.result == AVERROR(EAGAIN)) - { - // timeout, probably no real error, return empty packet - bReturnEmpty = true; - } - else if (m_pkt.result < 0) - { - Flush(); - } - else if (IsProgramChange()) - { - // update streams - CreateStreams(m_program); - - pPacket = CDVDDemuxUtils::AllocateDemuxPacket(0); - pPacket->iStreamId = DMX_SPECIALID_STREAMCHANGE; - - return pPacket; - } - // check size and stream index for being in a valid range - else if (m_pkt.pkt.size < 0 || - m_pkt.pkt.stream_index < 0 || - m_pkt.pkt.stream_index >= (int)m_pFormatContext->nb_streams) - { - // XXX, in some cases ffmpeg returns a negative packet size - if(m_pFormatContext->pb && !m_pFormatContext->pb->eof_reached) - { - CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::Read() no valid packet"); - bReturnEmpty = true; - Flush(); - } - else - CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::Read() returned invalid packet and eof reached"); - - m_pkt.result = -1; - av_free_packet(&m_pkt.pkt); - } - else - { - ParsePacket(&m_pkt.pkt); - - AVStream *stream = m_pFormatContext->streams[m_pkt.pkt.stream_index]; - - if (IsVideoReady()) - { - if (m_program != UINT_MAX) - { - /* check so packet belongs to selected program */ - for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) - { - if(m_pkt.pkt.stream_index == (int)m_pFormatContext->programs[m_program]->stream_index[i]) - { - pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size); - break; - } - } - - if (!pPacket) - bReturnEmpty = true; - } - else - pPacket = CDVDDemuxUtils::AllocateDemuxPacket(m_pkt.pkt.size); - } - else - bReturnEmpty = true; - - if (pPacket) - { - // lavf sometimes bugs out and gives 0 dts/pts instead of no dts/pts - // since this could only happens on initial frame under normal - // circomstances, let's assume it is wrong all the time - if(m_pkt.pkt.dts == 0) - m_pkt.pkt.dts = AV_NOPTS_VALUE; - if(m_pkt.pkt.pts == 0) - m_pkt.pkt.pts = AV_NOPTS_VALUE; - - if(m_bMatroska && stream->codec && stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) - { // matroska can store different timestamps - // for different formats, for native stored - // stuff it is pts, but for ms compatibility - // tracks, it is really dts. sadly ffmpeg - // sets these two timestamps equal all the - // time, so we select it here instead - if(stream->codec->codec_tag == 0) - m_pkt.pkt.dts = AV_NOPTS_VALUE; - else - m_pkt.pkt.pts = AV_NOPTS_VALUE; - } - - // we need to get duration slightly different for matroska embedded text subtitels - if(m_bMatroska && stream->codec && stream->codec->codec_id == AV_CODEC_ID_TEXT && m_pkt.pkt.convergence_duration != 0) - m_pkt.pkt.duration = m_pkt.pkt.convergence_duration; - - if(m_bAVI && stream->codec && stream->codec->codec_type == AVMEDIA_TYPE_VIDEO) - { - // AVI's always have borked pts, specially if m_pFormatContext->flags includes - // AVFMT_FLAG_GENPTS so always use dts - m_pkt.pkt.pts = AV_NOPTS_VALUE; - } - - // copy contents into our own packet - pPacket->iSize = m_pkt.pkt.size; - - // maybe we can avoid a memcpy here by detecting where pkt.destruct is pointing too? - if (m_pkt.pkt.data) - memcpy(pPacket->pData, m_pkt.pkt.data, pPacket->iSize); - - pPacket->pts = ConvertTimestamp(m_pkt.pkt.pts, stream->time_base.den, stream->time_base.num); - pPacket->dts = ConvertTimestamp(m_pkt.pkt.dts, stream->time_base.den, stream->time_base.num); - pPacket->duration = DVD_SEC_TO_TIME((double)m_pkt.pkt.duration * stream->time_base.num / stream->time_base.den); - - // used to guess streamlength - if (pPacket->dts != DVD_NOPTS_VALUE && (pPacket->dts > m_currentPts || m_currentPts == DVD_NOPTS_VALUE)) - m_currentPts = pPacket->dts; - - - // check if stream has passed full duration, needed for live streams - bool bAllowDurationExt = (stream->codec && (stream->codec->codec_type == AVMEDIA_TYPE_VIDEO || stream->codec->codec_type == AVMEDIA_TYPE_AUDIO)); - if(bAllowDurationExt && m_pkt.pkt.dts != (int64_t)AV_NOPTS_VALUE) - { - int64_t duration; - duration = m_pkt.pkt.dts; - if(stream->start_time != (int64_t)AV_NOPTS_VALUE) - duration -= stream->start_time; - - if(duration > stream->duration) - { - stream->duration = duration; - duration = av_rescale_rnd(stream->duration, (int64_t)stream->time_base.num * AV_TIME_BASE, stream->time_base.den, AV_ROUND_NEAR_INF); - if ((m_pFormatContext->duration == (int64_t)AV_NOPTS_VALUE) - || (m_pFormatContext->duration != (int64_t)AV_NOPTS_VALUE && duration > m_pFormatContext->duration)) - m_pFormatContext->duration = duration; - } - } - - // store internal id until we know the continuous id presented to player - // the stream might not have been created yet - pPacket->iStreamId = m_pkt.pkt.stream_index; - } - m_pkt.result = -1; - av_free_packet(&m_pkt.pkt); - } - } - } // end of lock scope - if (bReturnEmpty && !pPacket) - pPacket = CDVDDemuxUtils::AllocateDemuxPacket(0); - - if (!pPacket) return NULL; - - // check streams, can we make this a bit more simple? - if (pPacket && pPacket->iStreamId >= 0) - { - CDemuxStream *stream = GetStreamInternal(pPacket->iStreamId); - if (!stream || - stream->pPrivate != m_pFormatContext->streams[pPacket->iStreamId] || - stream->codec != m_pFormatContext->streams[pPacket->iStreamId]->codec->codec_id) - { - // content has changed, or stream did not yet exist - stream = AddStream(pPacket->iStreamId); - } - // we already check for a valid m_streams[pPacket->iStreamId] above - else if (stream->type == STREAM_AUDIO) - { - if (((CDemuxStreamAudio*)stream)->iChannels != m_pFormatContext->streams[pPacket->iStreamId]->codec->channels || - ((CDemuxStreamAudio*)stream)->iSampleRate != m_pFormatContext->streams[pPacket->iStreamId]->codec->sample_rate) - { - // content has changed - stream = AddStream(pPacket->iStreamId); - } - } - else if (stream->type == STREAM_VIDEO) - { - if (((CDemuxStreamVideo*)stream)->iWidth != m_pFormatContext->streams[pPacket->iStreamId]->codec->width || - ((CDemuxStreamVideo*)stream)->iHeight != m_pFormatContext->streams[pPacket->iStreamId]->codec->height) - { - // content has changed - stream = AddStream(pPacket->iStreamId); - } - } - if (!stream) - { - CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::AddStream - internal error, stream is null"); - CDVDDemuxUtils::FreeDemuxPacket(pPacket); - return NULL; - } - // set continuous stream id for player - pPacket->iStreamId = stream->iId; - } - return pPacket; -} - -bool CDVDDemuxFFmpeg::SeekTime(int time, bool backwords, double *startpts) -{ - if (!m_pInput) - return false; - - if(time < 0) - time = 0; - - m_pkt.result = -1; - av_free_packet(&m_pkt.pkt); - - CDVDInputStream::ISeekTime* ist = dynamic_cast(m_pInput); - if (ist) - { - if (!ist->SeekTime(time)) - return false; - - if(startpts) - *startpts = DVD_NOPTS_VALUE; - - Flush(); - - // also empty the internal ffmpeg buffer - m_ioContext->buf_ptr = m_ioContext->buf_end; - - return true; - } - - if(!m_pInput->Seek(0, SEEK_POSSIBLE) - && !m_pInput->IsStreamType(DVDSTREAM_TYPE_FFMPEG)) - { - CLog::Log(LOGDEBUG, "%s - input stream reports it is not seekable", __FUNCTION__); - return false; - } - - int64_t seek_pts = (int64_t)time * (AV_TIME_BASE / 1000); - bool ismp3 = m_pFormatContext->iformat && (strcmp(m_pFormatContext->iformat->name, "mp3") == 0); - if (m_pFormatContext->start_time != (int64_t)AV_NOPTS_VALUE && !ismp3) - seek_pts += m_pFormatContext->start_time; - - int ret; - { - CSingleLock lock(m_critSection); - ret = av_seek_frame(m_pFormatContext, -1, seek_pts, backwords ? AVSEEK_FLAG_BACKWARD : 0); - - // demuxer will return failure, if you seek behind eof - if (ret < 0 && m_pFormatContext->duration && seek_pts >= (m_pFormatContext->duration + m_pFormatContext->start_time)) - ret = 0; - else if (ret < 0 && m_pInput->IsEOF()) - ret = 0; - - if(ret >= 0) - UpdateCurrentPTS(); - } - - if(m_currentPts == DVD_NOPTS_VALUE) - CLog::Log(LOGDEBUG, "%s - unknown position after seek", __FUNCTION__); - else - CLog::Log(LOGDEBUG, "%s - seek ended up on time %d", __FUNCTION__, (int)(m_currentPts / DVD_TIME_BASE * 1000)); - - // in this case the start time is requested time - if(startpts) - *startpts = DVD_MSEC_TO_TIME(time); - - return (ret >= 0); -} - -bool CDVDDemuxFFmpeg::SeekByte(int64_t pos) -{ - CSingleLock lock(m_critSection); - int ret = av_seek_frame(m_pFormatContext, -1, pos, AVSEEK_FLAG_BYTE); - - if(ret >= 0) - UpdateCurrentPTS(); - - m_pkt.result = -1; - av_free_packet(&m_pkt.pkt); - - return (ret >= 0); -} - -void CDVDDemuxFFmpeg::UpdateCurrentPTS() -{ - m_currentPts = DVD_NOPTS_VALUE; - - int idx = av_find_default_stream_index(m_pFormatContext); - if (idx >= 0) - { - AVStream *stream = m_pFormatContext->streams[idx]; - if(stream && stream->cur_dts != (int64_t)AV_NOPTS_VALUE) - { - double ts = ConvertTimestamp(stream->cur_dts, stream->time_base.den, stream->time_base.num); - if(m_currentPts == DVD_NOPTS_VALUE || m_currentPts > ts ) - m_currentPts = ts; - } - } -} - -int CDVDDemuxFFmpeg::GetStreamLength() -{ - if (!m_pFormatContext) - return 0; - - if (m_pFormatContext->duration < 0) - return 0; - - return (int)(m_pFormatContext->duration / (AV_TIME_BASE / 1000)); -} - -/** - * @brief Finds stream based on demuxer index - */ -CDemuxStream* CDVDDemuxFFmpeg::GetStream(int iStreamId) -{ - if(iStreamId >= 0 && (size_t)iStreamId < m_stream_index.size()) - return m_stream_index[iStreamId]->second; - else - return NULL; -} - -/** - * @brief Finds stream based on ffmpeg index - */ -CDemuxStream* CDVDDemuxFFmpeg::GetStreamInternal(int iId) -{ - std::map::iterator it = m_streams.find(iId); - if (it == m_streams.end()) - return NULL; - else - return it->second; -} - -int CDVDDemuxFFmpeg::GetNrOfStreams() -{ - return m_stream_index.size(); -} - -static double SelectAspect(AVStream* st, bool* forced) -{ - *forced = false; - /* if stream aspect is 1:1 or 0:0 use codec aspect */ - if((st->sample_aspect_ratio.den == 1 || st->sample_aspect_ratio.den == 0) - && (st->sample_aspect_ratio.num == 1 || st->sample_aspect_ratio.num == 0) - && st->codec->sample_aspect_ratio.num != 0) - return av_q2d(st->codec->sample_aspect_ratio); - - *forced = true; - if(st->sample_aspect_ratio.num != 0) - return av_q2d(st->sample_aspect_ratio); - - return 0.0; -} - -void CDVDDemuxFFmpeg::CreateStreams(unsigned int program) -{ - DisposeStreams(); - - // add the ffmpeg streams to our own stream map - if (m_pFormatContext->nb_programs) - { - // check if desired program is available - if (program < m_pFormatContext->nb_programs && m_pFormatContext->programs[program]->nb_stream_indexes > 0) - { - m_program = program; - } - else - m_program = UINT_MAX; - - // look for first non empty stream and discard nonselected programs - for (unsigned int i = 0; i < m_pFormatContext->nb_programs; i++) - { - if(m_program == UINT_MAX && m_pFormatContext->programs[i]->nb_stream_indexes > 0) - { - m_program = i; - } - - if(i != m_program) - m_pFormatContext->programs[i]->discard = AVDISCARD_ALL; - } - if(m_program != UINT_MAX) - { - // add streams from selected program - for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) - AddStream(m_pFormatContext->programs[m_program]->stream_index[i]); - } - } - else - m_program = UINT_MAX; - - // if there were no programs or they were all empty, add all streams - if (m_program == UINT_MAX) - { - for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++) - AddStream(i); - } -} - -void CDVDDemuxFFmpeg::DisposeStreams() -{ - std::map::iterator it; - for(it = m_streams.begin(); it != m_streams.end(); ++it) - delete it->second; - m_streams.clear(); - m_stream_index.clear(); -} - -CDemuxStream* CDVDDemuxFFmpeg::AddStream(int iId) -{ - AVStream* pStream = m_pFormatContext->streams[iId]; - if (pStream) - { - CDemuxStream* stream = NULL; - - switch (pStream->codec->codec_type) - { - case AVMEDIA_TYPE_AUDIO: - { - CDemuxStreamAudioFFmpeg* st = new CDemuxStreamAudioFFmpeg(this, pStream); - stream = st; - st->iChannels = pStream->codec->channels; - st->iSampleRate = pStream->codec->sample_rate; - st->iBlockAlign = pStream->codec->block_align; - st->iBitRate = pStream->codec->bit_rate; - st->iBitsPerSample = pStream->codec->bits_per_raw_sample; - if (st->iBitsPerSample == 0) - st->iBitsPerSample = pStream->codec->bits_per_coded_sample; - - if(av_dict_get(pStream->metadata, "title", NULL, 0)) - st->m_description = av_dict_get(pStream->metadata, "title", NULL, 0)->value; - - break; - } - case AVMEDIA_TYPE_VIDEO: - { - CDemuxStreamVideoFFmpeg* st = new CDemuxStreamVideoFFmpeg(this, pStream); - stream = st; - if(strcmp(m_pFormatContext->iformat->name, "flv") == 0) - st->bVFR = true; - else - st->bVFR = false; - - // never trust pts in avi files with h264. - if (m_bAVI && pStream->codec->codec_id == AV_CODEC_ID_H264) - st->bPTSInvalid = true; - -#if defined(AVFORMAT_HAS_STREAM_GET_R_FRAME_RATE) - AVRational r_frame_rate = av_stream_get_r_frame_rate(pStream); -#else - AVRational r_frame_rate = pStream->r_frame_rate; -#endif - - //average fps is more accurate for mkv files - if (m_bMatroska && pStream->avg_frame_rate.den && pStream->avg_frame_rate.num) - { - st->iFpsRate = pStream->avg_frame_rate.num; - st->iFpsScale = pStream->avg_frame_rate.den; - } - else if(r_frame_rate.den && r_frame_rate.num) - { - st->iFpsRate = r_frame_rate.num; - st->iFpsScale = r_frame_rate.den; - } - else - { - st->iFpsRate = 0; - st->iFpsScale = 0; - } - - // added for aml hw decoder, mkv frame-rate can be wrong. - if (r_frame_rate.den && r_frame_rate.num) - { - st->irFpsRate = r_frame_rate.num; - st->irFpsScale = r_frame_rate.den; - } - else - { - st->irFpsRate = 0; - st->irFpsScale = 0; - } - - if (pStream->codec_info_nb_frames > 0 - && pStream->codec_info_nb_frames <= 2 - && m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD)) - { - CLog::Log(LOGDEBUG, "%s - fps may be unreliable since ffmpeg decoded only %d frame(s)", __FUNCTION__, pStream->codec_info_nb_frames); - st->iFpsRate = 0; - st->iFpsScale = 0; - } - - st->iWidth = pStream->codec->width; - st->iHeight = pStream->codec->height; - st->fAspect = SelectAspect(pStream, &st->bForcedAspect) * pStream->codec->width / pStream->codec->height; - st->iOrientation = 0; - st->iBitsPerPixel = pStream->codec->bits_per_coded_sample; - - AVDictionaryEntry *rtag = av_dict_get(pStream->metadata, "rotate", NULL, 0); - if (rtag) - st->iOrientation = atoi(rtag->value); - - // detect stereoscopic mode - std::string stereoMode = GetStereoModeFromMetadata(pStream->metadata); - // check for metadata in file if detection in stream failed - if (stereoMode.empty()) - stereoMode = GetStereoModeFromMetadata(m_pFormatContext->metadata); - if (!stereoMode.empty()) - st->stereo_mode = stereoMode; - - - if ( m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD) ) - { - if (pStream->codec->codec_id == AV_CODEC_ID_PROBE) - { - // fix MPEG-1/MPEG-2 video stream probe returning AV_CODEC_ID_PROBE for still frames. - // ffmpeg issue 1871, regression from ffmpeg r22831. - if ((pStream->id & 0xF0) == 0xE0) - { - pStream->codec->codec_id = AV_CODEC_ID_MPEG2VIDEO; - pStream->codec->codec_tag = MKTAG('M','P','2','V'); - CLog::Log(LOGERROR, "%s - AV_CODEC_ID_PROBE detected, forcing AV_CODEC_ID_MPEG2VIDEO", __FUNCTION__); - } - } - } - break; - } - case AVMEDIA_TYPE_DATA: - { - stream = new CDemuxStream(); - stream->type = STREAM_DATA; - break; - } - case AVMEDIA_TYPE_SUBTITLE: - { - if (pStream->codec->codec_id == AV_CODEC_ID_DVB_TELETEXT && CSettings::Get().GetBool("videoplayer.teletextenabled")) - { - CDemuxStreamTeletext* st = new CDemuxStreamTeletext(); - stream = st; - stream->type = STREAM_TELETEXT; - break; - } - else - { - CDemuxStreamSubtitleFFmpeg* st = new CDemuxStreamSubtitleFFmpeg(this, pStream); - stream = st; - - if(av_dict_get(pStream->metadata, "title", NULL, 0)) - st->m_description = av_dict_get(pStream->metadata, "title", NULL, 0)->value; - - break; - } - } - case AVMEDIA_TYPE_ATTACHMENT: - { //mkv attachments. Only bothering with fonts for now. - if(pStream->codec->codec_id == AV_CODEC_ID_TTF - || pStream->codec->codec_id == AV_CODEC_ID_OTF - ) - { - std::string fileName = "special://temp/fonts/"; - XFILE::CDirectory::Create(fileName); - AVDictionaryEntry *nameTag = av_dict_get(pStream->metadata, "filename", NULL, 0); - if (!nameTag) - { - CLog::Log(LOGERROR, "%s: TTF attachment has no name", __FUNCTION__); - } - else - { - fileName += nameTag->value; - XFILE::CFile file; - if(pStream->codec->extradata && file.OpenForWrite(fileName)) - { - if (file.Write(pStream->codec->extradata, pStream->codec->extradata_size) != pStream->codec->extradata_size) - { - file.Close(); - XFILE::CFile::Delete(fileName); - CLog::Log(LOGDEBUG, "%s: Error saving font file \"%s\"", __FUNCTION__, fileName.c_str()); - } - } - } - } - stream = new CDemuxStream(); - stream->type = STREAM_NONE; - break; - } - default: - { - stream = new CDemuxStream(); - stream->type = STREAM_NONE; - break; - } - } - - // set ffmpeg type - stream->orig_type = pStream->codec->codec_type; - - // generic stuff - if (pStream->duration != (int64_t)AV_NOPTS_VALUE) - stream->iDuration = (int)((pStream->duration / AV_TIME_BASE) & 0xFFFFFFFF); - - stream->codec = pStream->codec->codec_id; - stream->codec_fourcc = pStream->codec->codec_tag; - stream->profile = pStream->codec->profile; - stream->level = pStream->codec->level; - - stream->source = STREAM_SOURCE_DEMUX; - stream->pPrivate = pStream; - stream->flags = (CDemuxStream::EFlags)pStream->disposition; - - AVDictionaryEntry *langTag = av_dict_get(pStream->metadata, "language", NULL, 0); - if (langTag) - strncpy(stream->language, langTag->value, 3); - - if( pStream->codec->extradata && pStream->codec->extradata_size > 0 ) - { - stream->ExtraSize = pStream->codec->extradata_size; - stream->ExtraData = new uint8_t[pStream->codec->extradata_size]; - memcpy(stream->ExtraData, pStream->codec->extradata, pStream->codec->extradata_size); - } - -#ifdef HAVE_LIBBLURAY - if( m_pInput->IsStreamType(DVDSTREAM_TYPE_BLURAY) ) - static_cast(m_pInput)->GetStreamInfo(pStream->id, stream->language); -#endif - if( m_pInput->IsStreamType(DVDSTREAM_TYPE_DVD) ) - { - // this stuff is really only valid for dvd's. - // this is so that the physicalid matches the - // id's reported from libdvdnav - switch(stream->codec) - { - case AV_CODEC_ID_AC3: - stream->iPhysicalId = pStream->id - 128; - break; - case AV_CODEC_ID_DTS: - stream->iPhysicalId = pStream->id - 136; - break; - case AV_CODEC_ID_MP2: - stream->iPhysicalId = pStream->id - 448; - break; - case AV_CODEC_ID_PCM_S16BE: - stream->iPhysicalId = pStream->id - 160; - break; - case AV_CODEC_ID_DVD_SUBTITLE: - stream->iPhysicalId = pStream->id - 0x20; - break; - default: - stream->iPhysicalId = pStream->id & 0x1f; - break; - } - } - else - stream->iPhysicalId = pStream->id; - - AddStream(iId, stream); - return stream; - } - else - return NULL; -} - -/** - * @brief Adds or updates a demux stream based in ffmpeg id - */ -void CDVDDemuxFFmpeg::AddStream(int iId, CDemuxStream* stream) -{ - std::pair::iterator, bool> res; - - res = m_streams.insert(std::make_pair(iId, stream)); - if(res.second) - { - /* was new stream */ - stream->iId = m_stream_index.size(); - m_stream_index.push_back(res.first); - } - else - { - /* replace old stream, keeping old index */ - stream->iId = res.first->second->iId; - - delete res.first->second; - res.first->second = stream; - } - if(g_advancedSettings.m_logLevel > LOG_LEVEL_NORMAL) - CLog::Log(LOGDEBUG, "CDVDDemuxFFmpeg::AddStream(%d, ...) -> %d", iId, stream->iId); -} - - -std::string CDVDDemuxFFmpeg::GetFileName() -{ - if(m_pInput) - return m_pInput->GetFileName(); - else - return ""; -} - -int CDVDDemuxFFmpeg::GetChapterCount() -{ - CDVDInputStream::IChapter* ich = dynamic_cast(m_pInput); - if(ich) - return ich->GetChapterCount(); - - if(m_pFormatContext == NULL) - return 0; - - return m_pFormatContext->nb_chapters; -} - -int CDVDDemuxFFmpeg::GetChapter() -{ - CDVDInputStream::IChapter* ich = dynamic_cast(m_pInput); - if(ich) - return ich->GetChapter(); - - if(m_pFormatContext == NULL - || m_currentPts == DVD_NOPTS_VALUE) - return 0; - - for(unsigned i = 0; i < m_pFormatContext->nb_chapters; i++) - { - AVChapter *chapter = m_pFormatContext->chapters[i]; - if(m_currentPts >= ConvertTimestamp(chapter->start, chapter->time_base.den, chapter->time_base.num) - && m_currentPts < ConvertTimestamp(chapter->end, chapter->time_base.den, chapter->time_base.num)) - return i + 1; - } - - return 0; -} - -void CDVDDemuxFFmpeg::GetChapterName(std::string& strChapterName, int chapterIdx) -{ - if (chapterIdx <= 0 || chapterIdx > GetChapterCount()) - chapterIdx = GetChapter(); - CDVDInputStream::IChapter* ich = dynamic_cast(m_pInput); - if(ich) - ich->GetChapterName(strChapterName, chapterIdx); - else - { - if(chapterIdx <= 0) - return; - - AVDictionaryEntry *titleTag = av_dict_get(m_pFormatContext->chapters[chapterIdx-1]->metadata, - "title", NULL, 0); - if (titleTag) - strChapterName = titleTag->value; - } -} - -int64_t CDVDDemuxFFmpeg::GetChapterPos(int chapterIdx) -{ - if (chapterIdx <= 0 || chapterIdx > GetChapterCount()) - chapterIdx = GetChapter(); - if(chapterIdx <= 0) - return 0; - - CDVDInputStream::IChapter* ich = dynamic_cast(m_pInput); - if(ich) - return ich->GetChapterPos(chapterIdx); - - return m_pFormatContext->chapters[chapterIdx-1]->start*av_q2d(m_pFormatContext->chapters[chapterIdx-1]->time_base); -} - -bool CDVDDemuxFFmpeg::SeekChapter(int chapter, double* startpts) -{ - if(chapter < 1) - chapter = 1; - - CDVDInputStream::IChapter* ich = dynamic_cast(m_pInput); - if(ich) - { - CLog::Log(LOGDEBUG, "%s - chapter seeking using input stream", __FUNCTION__); - if(!ich->SeekChapter(chapter)) - return false; - - if(startpts) - { - *startpts = DVD_SEC_TO_TIME(ich->GetChapterPos(chapter)); - } - - Flush(); - return true; - } - - if(m_pFormatContext == NULL) - return false; - - if(chapter < 1 || chapter > (int)m_pFormatContext->nb_chapters) - return false; - - AVChapter *ch = m_pFormatContext->chapters[chapter-1]; - double dts = ConvertTimestamp(ch->start, ch->time_base.den, ch->time_base.num); - return SeekTime(DVD_TIME_TO_MSEC(dts), true, startpts); -} - -void CDVDDemuxFFmpeg::GetStreamCodecName(int iStreamId, std::string &strName) -{ - CDemuxStream *stream = GetStream(iStreamId); - if (stream) - { - unsigned int in = stream->codec_fourcc; - // FourCC codes are only valid on video streams, audio codecs in AVI/WAV - // are 2 bytes and audio codecs in transport streams have subtle variation - // e.g AC-3 instead of ac3 - if (stream->type == STREAM_VIDEO && in != 0) - { - char fourcc[5]; -#if defined(__powerpc__) - fourcc[0] = in & 0xff; - fourcc[1] = (in >> 8) & 0xff; - fourcc[2] = (in >> 16) & 0xff; - fourcc[3] = (in >> 24) & 0xff; -#else - memcpy(fourcc, &in, 4); -#endif - fourcc[4] = 0; - // fourccs have to be 4 characters - if (strlen(fourcc) == 4) - { - strName = fourcc; - StringUtils::ToLower(strName); - return; - } - } - -#ifdef FF_PROFILE_DTS_HD_MA - /* use profile to determine the DTS type */ - if (stream->codec == AV_CODEC_ID_DTS) - { - if (stream->profile == FF_PROFILE_DTS_HD_MA) - strName = "dtshd_ma"; - else if (stream->profile == FF_PROFILE_DTS_HD_HRA) - strName = "dtshd_hra"; - else - strName = "dca"; - return; - } -#endif - - AVCodec *codec = avcodec_find_decoder(stream->codec); - if (codec) - strName = codec->name; - } -} - -bool CDVDDemuxFFmpeg::IsProgramChange() -{ - if (m_program == UINT_MAX) - return false; - - if (m_program == 0 && !m_pFormatContext->nb_programs) - return false; - - if(m_pFormatContext->programs[m_program]->nb_stream_indexes != m_streams.size()) - return true; - - if (m_program >= m_pFormatContext->nb_programs) - return true; - - for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) - { - int idx = m_pFormatContext->programs[m_program]->stream_index[i]; - CDemuxStream *stream = GetStreamInternal(idx); - if(!stream) - return true; - if(m_pFormatContext->streams[idx]->codec->codec_type != stream->orig_type) - return true; - } - return false; -} - -std::string CDVDDemuxFFmpeg::GetStereoModeFromMetadata(AVDictionary *pMetadata) -{ - std::string stereoMode; - AVDictionaryEntry *tag = NULL; - - // matroska - tag = av_dict_get(pMetadata, "stereo_mode", NULL, 0); - if (tag && tag->value) - stereoMode = tag->value; - - // asf / wmv - if (stereoMode.empty()) - { - tag = av_dict_get(pMetadata, "Stereoscopic", NULL, 0); - if (tag && tag->value) - { - tag = av_dict_get(pMetadata, "StereoscopicLayout", NULL, 0); - if (tag && tag->value) - stereoMode = ConvertCodecToInternalStereoMode(tag->value, WmvToInternalStereoModeMap); - } - } - - return stereoMode; -} - -std::string CDVDDemuxFFmpeg::ConvertCodecToInternalStereoMode(const std::string &mode, const StereoModeConversionMap *conversionMap) -{ - size_t i = 0; - while (conversionMap[i].name) - { - if (mode == conversionMap[i].name) - return conversionMap[i].mode; - i++; - } - return ""; -} - -void CDVDDemuxFFmpeg::ParsePacket(AVPacket *pkt) -{ - AVStream *st = m_pFormatContext->streams[pkt->stream_index]; - CDemuxStream *stream = GetStreamInternal(pkt->stream_index); - - // if the stream is new, tell ffmpeg to parse the stream - if (!stream && !st->parser) - { - st->need_parsing = AVSTREAM_PARSE_FULL; - } - - // split extradata - if(st->parser && st->parser->parser->split && !st->codec->extradata) - { - int i = st->parser->parser->split(st->codec, pkt->data, pkt->size); - if (i > 0 && i < FF_MAX_EXTRADATA_SIZE) - { - // Found extradata, fill it in. This will cause - // a new stream to be created and used. - st->codec->extradata_size = i; - st->codec->extradata = (uint8_t*)av_malloc(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE); - if (st->codec->extradata) - { - CLog::Log(LOGDEBUG, "CDVDDemuxFFmpeg::Read() fetching extradata, extradata_size(%d)", st->codec->extradata_size); - memcpy(st->codec->extradata, pkt->data, st->codec->extradata_size); - memset(st->codec->extradata + i, 0, FF_INPUT_BUFFER_PADDING_SIZE); - } - else - { - st->codec->extradata_size = 0; - } - } - } - - // for video we need a decoder to get desired information into codec context - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO && st->codec->extradata && - (!st->codec->width || st->codec->pix_fmt == PIX_FMT_NONE)) - { - // open a decoder, it will be cleared down by ffmpeg on closing the stream - if (!st->codec->codec) - { - const AVCodec* codec; - AVDictionary *thread_opt = NULL; - codec = avcodec_find_decoder(st->codec->codec_id); - // Force thread count to 1 since the h264 decoder will not extract - // SPS and PPS to extradata during multi-threaded decoding - av_dict_set(&thread_opt, "threads", "1", 0); - int res = avcodec_open2(st->codec, codec, &thread_opt); - if(res < 0) - CLog::Log(LOGERROR, "CDVDDemuxFFmpeg::ParsePacket() unable to open codec %d", res); - av_dict_free(&thread_opt); - } - - // We don't need to actually decode here - // we just want to transport SPS data into codec context - st->codec->skip_idct = AVDISCARD_ALL; - // extradata is not decoded if skip_frame >= AVDISCARD_NONREF -// st->codec->skip_frame = AVDISCARD_ALL; - st->codec->skip_loop_filter = AVDISCARD_ALL; - - // We are looking for an IDR frame - AVFrame picture; - memset(&picture, 0, sizeof(AVFrame)); - picture.pts = picture.pkt_dts = picture.pkt_pts = picture.best_effort_timestamp = AV_NOPTS_VALUE; - picture.pkt_pos = -1; - picture.key_frame = 1; - picture.format = -1; - - int got_picture = 0; - avcodec_decode_video2(st->codec, &picture, &got_picture, pkt); - } -} - -bool CDVDDemuxFFmpeg::IsVideoReady() -{ - AVStream *st; - bool hasVideo = false; - - if(!m_checkvideo) - return true; - - if (m_program == 0 && !m_pFormatContext->nb_programs) - return false; - - if(m_program != UINT_MAX) - { - for (unsigned int i = 0; i < m_pFormatContext->programs[m_program]->nb_stream_indexes; i++) - { - int idx = m_pFormatContext->programs[m_program]->stream_index[i]; - st = m_pFormatContext->streams[idx]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) - { - if (st->codec->width && st->codec->pix_fmt != PIX_FMT_NONE) - return true; - hasVideo = true; - } - } - } - else - { - for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++) - { - st = m_pFormatContext->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) - { - if (st->codec->width && st->codec->pix_fmt != PIX_FMT_NONE) - return true; - hasVideo = true; - } - } - } - return !hasVideo; -} - -void CDVDDemuxFFmpeg::ResetVideoStreams() -{ - AVStream *st; - for (unsigned int i = 0; i < m_pFormatContext->nb_streams; i++) - { - st = m_pFormatContext->streams[i]; - if (st->codec->codec_type == AVMEDIA_TYPE_VIDEO) - { - if (st->codec->extradata) - av_free(st->codec->extradata); - st->codec->extradata = NULL; - st->codec->width = 0; - } - } -} - -void CDVDDemuxFFmpeg::GetL16Parameters(int &channels, int &samplerate) -{ - std::string content; - if (XFILE::CCurlFile::GetContentType(m_pInput->GetURL(), content)) - { - StringUtils::ToLower(content); - const size_t len = content.length(); - size_t pos = content.find(';'); - while (pos < len) - { - // move to the next non-whitespace character - pos = content.find_first_not_of(" \t", pos + 1); - - if (pos != std::string::npos) - { - if (content.compare(pos, 9, "channels=", 9) == 0) - { - pos += 9; // move position to char after 'channels=' - size_t len = content.find(';', pos); - if (len != std::string::npos) - len -= pos; - std::string no_channels(content, pos, len); - // as we don't support any charset with ';' in name - StringUtils::Trim(no_channels, " \t"); - if (!no_channels.empty()) - { - int val = strtol(no_channels.c_str(), NULL, 0); - if (val > 0) - channels = val; - else - CLog::Log(LOGDEBUG, "CDVDDemuxFFmpeg::%s - no parameter for channels", __FUNCTION__); - } - } - else if (content.compare(pos, 5, "rate=", 5) == 0) - { - pos += 5; // move position to char after 'rate=' - size_t len = content.find(';', pos); - if (len != std::string::npos) - len -= pos; - std::string rate(content, pos, len); - // as we don't support any charset with ';' in name - StringUtils::Trim(rate, " \t"); - if (!rate.empty()) - { - int val = strtol(rate.c_str(), NULL, 0); - if (val > 0) - samplerate = val; - else - CLog::Log(LOGDEBUG, "CDVDDemuxFFmpeg::%s - no parameter for samplerate", __FUNCTION__); - } - } - pos = content.find(';', pos); // find next parameter - } - } - } -} diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h deleted file mode 100644 index d180e40..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxFFmpeg.h +++ /dev/null @@ -1,172 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "DVDDemux.h" -#include "threads/CriticalSection.h" -#include "threads/SystemClock.h" -#include -#include - -extern "C" { -#include "libavformat/avformat.h" -} - -class CDVDDemuxFFmpeg; -class CURL; - -class CDemuxStreamVideoFFmpeg - : public CDemuxStreamVideo -{ - CDVDDemuxFFmpeg *m_parent; - AVStream* m_stream; -public: - CDemuxStreamVideoFFmpeg(CDVDDemuxFFmpeg *parent, AVStream* stream) - : m_parent(parent) - , m_stream(stream) - {} - virtual void GetStreamInfo(std::string& strInfo); -}; - - -class CDemuxStreamAudioFFmpeg - : public CDemuxStreamAudio -{ - CDVDDemuxFFmpeg *m_parent; - AVStream* m_stream; -public: - CDemuxStreamAudioFFmpeg(CDVDDemuxFFmpeg *parent, AVStream* stream) - : m_parent(parent) - , m_stream(stream) - {} - std::string m_description; - - virtual void GetStreamInfo(std::string& strInfo); - virtual void GetStreamName(std::string& strInfo); -}; - -class CDemuxStreamSubtitleFFmpeg - : public CDemuxStreamSubtitle -{ - CDVDDemuxFFmpeg *m_parent; - AVStream* m_stream; -public: - CDemuxStreamSubtitleFFmpeg(CDVDDemuxFFmpeg *parent, AVStream* stream) - : m_parent(parent) - , m_stream(stream) - {} - std::string m_description; - - virtual void GetStreamInfo(std::string& strInfo); - virtual void GetStreamName(std::string& strInfo); - -}; - -#define FFMPEG_FILE_BUFFER_SIZE 32768 // default reading size for ffmpeg -#define FFMPEG_DVDNAV_BUFFER_SIZE 2048 // for dvd's - -struct StereoModeConversionMap; - -class CDVDDemuxFFmpeg : public CDVDDemux -{ -public: - CDVDDemuxFFmpeg(); - virtual ~CDVDDemuxFFmpeg(); - - bool Open(CDVDInputStream* pInput, bool streaminfo = true, bool fileinfo = false); - void Dispose(); - void Reset(); - void Flush(); - void Abort(); - void SetSpeed(int iSpeed); - virtual std::string GetFileName(); - - DemuxPacket* Read(); - - bool SeekTime(int time, bool backwords = false, double* startpts = NULL); - bool SeekByte(int64_t pos); - int GetStreamLength(); - CDemuxStream* GetStream(int iStreamId); - int GetNrOfStreams(); - - bool SeekChapter(int chapter, double* startpts = NULL); - int GetChapterCount(); - int GetChapter(); - void GetChapterName(std::string& strChapterName, int chapterIdx=-1); - int64_t GetChapterPos(int chapterIdx=-1); - virtual void GetStreamCodecName(int iStreamId, std::string &strName); - - bool Aborted(); - - AVFormatContext* m_pFormatContext; - CDVDInputStream* m_pInput; - -protected: - friend class CDemuxStreamAudioFFmpeg; - friend class CDemuxStreamVideoFFmpeg; - friend class CDemuxStreamSubtitleFFmpeg; - - int ReadFrame(AVPacket *packet); - CDemuxStream* AddStream(int iId); - void AddStream(int iId, CDemuxStream* stream); - CDemuxStream* GetStreamInternal(int iStreamId); - void CreateStreams(unsigned int program = UINT_MAX); - void DisposeStreams(); - void ParsePacket(AVPacket *pkt); - bool IsVideoReady(); - void ResetVideoStreams(); - - AVDictionary *GetFFMpegOptionsFromURL(const CURL &url); - double ConvertTimestamp(int64_t pts, int den, int num); - void UpdateCurrentPTS(); - bool IsProgramChange(); - - std::string GetStereoModeFromMetadata(AVDictionary *pMetadata); - std::string ConvertCodecToInternalStereoMode(const std::string &mode, const StereoModeConversionMap *conversionMap); - - void GetL16Parameters(int &channels, int &samplerate); - - CCriticalSection m_critSection; - std::map m_streams; - std::vector::iterator> m_stream_index; - - AVIOContext* m_ioContext; - - double m_currentPts; // used for stream length estimation - bool m_bMatroska; - bool m_bAVI; - int m_speed; - unsigned m_program; - XbmcThreads::EndTime m_timeout; - - // Due to limitations of ffmpeg, we only can detect a program change - // with a packet. This struct saves the packet for the next read and - // signals STREAMCHANGE to player - struct - { - AVPacket pkt; // packet ffmpeg returned - int result; // result from av_read_packet - }m_pkt; - - bool m_streaminfo; - bool m_checkvideo; -}; - diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.cpp deleted file mode 100644 index 3674416..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.cpp +++ /dev/null @@ -1,391 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - - -#include "DVDCodecs/DVDCodecs.h" -#include "DVDInputStreams/DVDInputStream.h" -#include "DVDInputStreams/DVDInputStreamHTSP.h" -#include "DVDDemuxHTSP.h" -#include "DVDDemuxUtils.h" -#include "DVDClock.h" -#include "dialogs/GUIDialogKaiToast.h" -#include "utils/log.h" -#include "utils/StringUtils.h" -#include - -extern "C" { -#include "lib/libhts/net.h" -#include "lib/libhts/htsmsg.h" -#include "lib/libhts/htsmsg_binary.h" -} - -using namespace std; -using namespace HTSP; - -class CDemuxStreamVideoHTSP - : public CDemuxStreamVideo -{ - CDVDDemuxHTSP *m_parent; - string m_codec; -public: - CDemuxStreamVideoHTSP(CDVDDemuxHTSP *parent, const string& codec) - : m_parent(parent) - , m_codec(codec) - {} - void GetStreamInfo(std::string& strInfo) - { - strInfo = StringUtils::Format("%s, delay: %u, drops: %ub %up %ui" - , m_codec.c_str() - , m_parent->m_QueueStatus.delay - , m_parent->m_QueueStatus.bdrops - , m_parent->m_QueueStatus.pdrops - , m_parent->m_QueueStatus.idrops); - } -}; - -class CDemuxStreamAudioHTSP - : public CDemuxStreamAudio -{ - CDVDDemuxHTSP *m_parent; - string m_codec; -public: - CDemuxStreamAudioHTSP(CDVDDemuxHTSP *parent, const string& codec) - : m_parent(parent) - , m_codec(codec) - - {} - void GetStreamInfo(string& strInfo) - { - strInfo = StringUtils::Format("%s", m_codec.c_str()); - } -}; - -CDVDDemuxHTSP::CDVDDemuxHTSP() - : CDVDDemux() - , m_Input(NULL) - , m_StatusCount(0) -{ -} - -CDVDDemuxHTSP::~CDVDDemuxHTSP() -{ - Dispose(); -} - -bool CDVDDemuxHTSP::Open(CDVDInputStream* input) -{ - Dispose(); - - if(!input->IsStreamType(DVDSTREAM_TYPE_HTSP)) - return false; - - m_Input = (CDVDInputStreamHTSP*)input; - m_StatusCount = 0; - - while(m_Streams.empty() && m_StatusCount == 0) - { - DemuxPacket* pkg = Read(); - if(!pkg) - return false; - CDVDDemuxUtils::FreeDemuxPacket(pkg); - } - - return true; -} - -void CDVDDemuxHTSP::Dispose() -{ -} - -void CDVDDemuxHTSP::Reset() -{ -} - - -void CDVDDemuxHTSP::Flush() -{ -} - -bool CDVDDemuxHTSP::ReadStream(uint8_t* buf, int len) -{ - while(len > 0) - { - int ret = m_Input->Read(buf, len); - if(ret <= 0) - return false; - len -= ret; - buf += ret; - } - return true; -} - -htsmsg_t* CDVDDemuxHTSP::ReadStream() -{ - if(m_Input->IsStreamType(DVDSTREAM_TYPE_HTSP)) - return ((CDVDInputStreamHTSP*)m_Input)->ReadStream(); - - uint32_t l; - if(!ReadStream((uint8_t*)&l, 4)) - return NULL; - - l = ntohl(l); - if(l == 0) - return htsmsg_create_map(); - - uint8_t* buf = (uint8_t*)malloc(l); - if(!buf) - return NULL; - - if(!ReadStream(buf, l)) - return NULL; - - return htsmsg_binary_deserialize(buf, l, buf); /* consumes 'buf' */ -} - -DemuxPacket* CDVDDemuxHTSP::Read() -{ - htsmsg_t * msg; - while((msg = ReadStream())) - { - const char* method = htsmsg_get_str(msg, "method"); - if(method == NULL) - break; - - if (strcmp("subscriptionStart", method) == 0) - SubscriptionStart(msg); - else if(strcmp("subscriptionStop", method) == 0) - SubscriptionStop (msg); - else if(strcmp("subscriptionStatus", method) == 0) - SubscriptionStatus(msg); - else if(strcmp("queueStatus" , method) == 0) - CHTSPSession::ParseQueueStatus(msg, m_QueueStatus); - else if(strcmp("muxpkt" , method) == 0) - { - uint32_t index, duration; - const void* bin; - size_t binlen; - int64_t ts; - - if(htsmsg_get_u32(msg, "stream" , &index) || - htsmsg_get_bin(msg, "payload", &bin, &binlen)) - break; - - DemuxPacket* pkt = CDVDDemuxUtils::AllocateDemuxPacket(binlen); - - memcpy(pkt->pData, bin, binlen); - pkt->iSize = binlen; - - if(!htsmsg_get_u32(msg, "duration", &duration)) - pkt->duration = (double)duration * DVD_TIME_BASE / 1000000; - - if(!htsmsg_get_s64(msg, "dts", &ts)) - pkt->dts = (double)ts * DVD_TIME_BASE / 1000000; - else - pkt->dts = DVD_NOPTS_VALUE; - - if(!htsmsg_get_s64(msg, "pts", &ts)) - pkt->pts = (double)ts * DVD_TIME_BASE / 1000000; - else - pkt->pts = DVD_NOPTS_VALUE; - - pkt->iStreamId = -1; - for(int i = 0; i < (int)m_Streams.size(); i++) - { - if(m_Streams[i]->iPhysicalId == (int)index) - { - pkt->iStreamId = i; - break; - } - } - - htsmsg_destroy(msg); - return pkt; - } - - break; - } - - if(msg) - { - htsmsg_destroy(msg); - return CDVDDemuxUtils::AllocateDemuxPacket(0); - } - return NULL; -} - -void CDVDDemuxHTSP::SubscriptionStart (htsmsg_t *m) -{ - htsmsg_t *streams; - htsmsg_t *info; - htsmsg_field_t *f; - - if((info = htsmsg_get_map(m, "sourceinfo"))) - { - HTSMSG_FOREACH(f, info) - { - if(f->hmf_type != HMF_STR) - continue; - CLog::Log(LOGDEBUG, "CDVDDemuxHTSP::SubscriptionStart - %s: %s", f->hmf_name, htsmsg_field_get_string(f)); - } - } - - if((streams = htsmsg_get_list(m, "streams")) == NULL) - { - CLog::Log(LOGERROR, "CDVDDemuxHTSP::SubscriptionStart - malformed message"); - return; - } - - for(int i = 0; i < (int)m_Streams.size(); i++) - delete m_Streams[i]; - m_Streams.clear(); - - HTSMSG_FOREACH(f, streams) - { - uint32_t index; - const char* type; - const char* lang; - htsmsg_t* sub; - - if(f->hmf_type != HMF_MAP) - continue; - sub = &f->hmf_msg; - - if((type = htsmsg_get_str(sub, "type")) == NULL) - continue; - - if(htsmsg_get_u32(sub, "index", &index)) - continue; - - union { - CDemuxStream* g; - CDemuxStreamAudio* a; - CDemuxStreamVideo* v; - CDemuxStreamSubtitle* s; - CDemuxStreamTeletext* t; - } st; - - CLog::Log(LOGDEBUG, "CDVDDemuxHTSP::SubscriptionStart - id: %d, type: %s", index, type); - - if(!strcmp(type, "AC3")) { - st.a = new CDemuxStreamAudioHTSP(this, type); - st.a->codec = AV_CODEC_ID_AC3; - } else if(!strcmp(type, "EAC3")) { - st.a = new CDemuxStreamAudioHTSP(this, type); - st.a->codec = AV_CODEC_ID_EAC3; - } else if(!strcmp(type, "MPEG2AUDIO")) { - st.a = new CDemuxStreamAudioHTSP(this, type); - st.a->codec = AV_CODEC_ID_MP2; - } else if(!strcmp(type, "AAC")) { - st.a = new CDemuxStreamAudioHTSP(this, type); - st.a->codec = AV_CODEC_ID_AAC; - } else if(!strcmp(type, "MPEG2VIDEO")) { - st.v = new CDemuxStreamVideoHTSP(this, type); - st.v->codec = AV_CODEC_ID_MPEG2VIDEO; - st.v->iWidth = htsmsg_get_u32_or_default(sub, "width" , 0); - st.v->iHeight = htsmsg_get_u32_or_default(sub, "height", 0); - } else if(!strcmp(type, "H264")) { - st.v = new CDemuxStreamVideoHTSP(this, type); - st.v->codec = AV_CODEC_ID_H264; - st.v->iWidth = htsmsg_get_u32_or_default(sub, "width" , 0); - st.v->iHeight = htsmsg_get_u32_or_default(sub, "height", 0); - } else if(!strcmp(type, "DVBSUB")) { - st.s = new CDemuxStreamSubtitle(); - st.s->codec = AV_CODEC_ID_DVB_SUBTITLE; - uint32_t composition_id = 0, ancillary_id = 0; - htsmsg_get_u32(sub, "composition_id", &composition_id); - htsmsg_get_u32(sub, "ancillary_id" , &ancillary_id); - if(composition_id || ancillary_id) - { - st.s->ExtraData = new uint8_t[4]; - st.s->ExtraSize = 4; - st.s->ExtraData[0] = (composition_id >> 8) & 0xff; - st.s->ExtraData[1] = (composition_id >> 0) & 0xff; - st.s->ExtraData[2] = (ancillary_id >> 8) & 0xff; - st.s->ExtraData[3] = (ancillary_id >> 0) & 0xff; - } - } else if(!strcmp(type, "TEXTSUB")) { - st.s = new CDemuxStreamSubtitle(); - st.s->codec = AV_CODEC_ID_TEXT; - } else if(!strcmp(type, "TELETEXT")) { - st.t = new CDemuxStreamTeletext(); - st.t->codec = AV_CODEC_ID_DVB_TELETEXT; - } else { - continue; - } - - if((lang = htsmsg_get_str(sub, "language"))) - { - strncpy(st.g->language, lang, sizeof(st.g->language)); - st.g->language[sizeof(st.g->language) - 1] = '\0'; - } - - st.g->iId = m_Streams.size(); - st.g->iPhysicalId = index; - m_Streams.push_back(st.g); - } -} -void CDVDDemuxHTSP::SubscriptionStop (htsmsg_t *m) -{ - for(int i = 0; i < (int)m_Streams.size(); i++) - delete m_Streams[i]; - m_Streams.clear(); -} - -void CDVDDemuxHTSP::SubscriptionStatus(htsmsg_t *m) -{ - const char* status; - status = htsmsg_get_str(m, "status"); - if(status == NULL) - m_Status = ""; - else - { - m_StatusCount++; - m_Status = status; - CLog::Log(LOGDEBUG, "CDVDDemuxHTSP::SubscriptionStatus - %s", status); - CGUIDialogKaiToast::QueueNotification(CGUIDialogKaiToast::Info, "TVHeadend Status", status, TOAST_DISPLAY_TIME, false); - } -} - -CDemuxStream* CDVDDemuxHTSP::GetStream(int iStreamId) -{ - if(iStreamId >= 0 && iStreamId < (int)m_Streams.size()) - return m_Streams[iStreamId]; - - return NULL; -} - -int CDVDDemuxHTSP::GetNrOfStreams() -{ - return m_Streams.size(); -} - -std::string CDVDDemuxHTSP::GetFileName() -{ - if(m_Input) - return m_Input->GetFileName(); - else - return ""; -} - -void CDVDDemuxHTSP::Abort() -{ - if(m_Input) - return m_Input->Abort(); -} diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.h deleted file mode 100644 index 6d73a9d..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxHTSP.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#pragma once -#include "DVDDemux.h" -#include "filesystem/HTSPSession.h" - -class CDVDInputStreamHTSP; -typedef struct htsmsg htsmsg_t; - -class CDVDDemuxHTSP : public CDVDDemux -{ -public: - CDVDDemuxHTSP(); - virtual ~CDVDDemuxHTSP(); - - bool Open(CDVDInputStream* input); - void Dispose(); - void Reset(); - void Flush(); - void Abort(); - void SetSpeed(int iSpeed){}; - - std::string GetFileName(); - - DemuxPacket* Read(); - - bool SeekTime(int time, bool backwords = false, double* startpts = NULL) { return false; } - int GetStreamLength() { return 0; } - - CDemuxStream* GetStream(int iStreamId); - int GetNrOfStreams(); - -protected: - friend class CDemuxStreamVideoHTSP; - - void SubscriptionStart (htsmsg_t *m); - void SubscriptionStop (htsmsg_t *m); - void SubscriptionStatus(htsmsg_t *m); - - htsmsg_t* ReadStream(); - bool ReadStream(uint8_t* buf, int len); - - typedef std::vector TStreams; - - CDVDInputStream* m_Input; - TStreams m_Streams; - std::string m_Status; - int m_StatusCount; - HTSP::SQueueStatus m_QueueStatus; -}; diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp deleted file mode 100644 index 4ed2d5c..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.cpp +++ /dev/null @@ -1,493 +0,0 @@ -/* - * Copyright (C) 2012-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "DVDInputStreams/DVDInputStream.h" -#include "DVDDemuxPVRClient.h" -#include "DVDDemuxUtils.h" -#include "utils/log.h" -#include "pvr/PVRManager.h" -#include "pvr/addons/PVRClients.h" -#include "../DVDClock.h" - -#define FF_MAX_EXTRADATA_SIZE ((1 << 28) - FF_INPUT_BUFFER_PADDING_SIZE) - -using namespace PVR; - -CDemuxStreamPVRInternal::CDemuxStreamPVRInternal(CDVDDemuxPVRClient *parent) - : m_parent(parent) - , m_parser(NULL) - , m_context(NULL) - , m_parser_split(false) -{ -} - -CDemuxStreamPVRInternal::~CDemuxStreamPVRInternal() -{ - DisposeParser(); -} - -void CDemuxStreamPVRInternal::DisposeParser() -{ - if (m_parser) - { - av_parser_close(m_parser); - m_parser = NULL; - } - if (m_context) - { - avcodec_close(m_context); - m_context = NULL; - } -} - -void CDemuxStreamVideoPVRClient::GetStreamInfo(std::string& strInfo) -{ - switch (codec) - { - case AV_CODEC_ID_MPEG2VIDEO: - strInfo = "mpeg2video"; - break; - case AV_CODEC_ID_H264: - strInfo = "h264"; - break; - default: - break; - } -} - -void CDemuxStreamAudioPVRClient::GetStreamInfo(std::string& strInfo) -{ - switch (codec) - { - case AV_CODEC_ID_AC3: - strInfo = "ac3"; - break; - case AV_CODEC_ID_EAC3: - strInfo = "eac3"; - break; - case AV_CODEC_ID_MP2: - strInfo = "mpeg2audio"; - break; - case AV_CODEC_ID_AAC: - strInfo = "aac"; - break; - case AV_CODEC_ID_DTS: - strInfo = "dts"; - break; - default: - break; - } -} - -void CDemuxStreamSubtitlePVRClient::GetStreamInfo(std::string& strInfo) -{ -} - -CDVDDemuxPVRClient::CDVDDemuxPVRClient() : CDVDDemux() -{ - m_pInput = NULL; - for (int i = 0; i < MAX_STREAMS; i++) m_streams[i] = NULL; -} - -CDVDDemuxPVRClient::~CDVDDemuxPVRClient() -{ - Dispose(); -} - -bool CDVDDemuxPVRClient::Open(CDVDInputStream* pInput) -{ - Abort(); - - m_pInput = pInput; - if (!g_PVRClients->GetPlayingClient(m_pvrClient)) - return false; - - return true; -} - -void CDVDDemuxPVRClient::Dispose() -{ - for (int i = 0; i < MAX_STREAMS; i++) - { - delete m_streams[i]; - m_streams[i] = NULL; - } - - m_pInput = NULL; -} - -void CDVDDemuxPVRClient::DisposeStream(int iStreamId) -{ - if (iStreamId < 0 || iStreamId >= MAX_STREAMS) - return; - delete m_streams[iStreamId]; - m_streams[iStreamId] = NULL; -} - -void CDVDDemuxPVRClient::Reset() -{ - if(m_pInput && g_PVRManager.IsStarted()) - m_pvrClient->DemuxReset(); - - CDVDInputStream* pInputStream = m_pInput; - Dispose(); - Open(pInputStream); -} - -void CDVDDemuxPVRClient::Abort() -{ - if(m_pInput) - m_pvrClient->DemuxAbort(); -} - -void CDVDDemuxPVRClient::Flush() -{ - if(m_pInput && g_PVRManager.IsStarted()) - m_pvrClient->DemuxFlush(); -} - -void CDVDDemuxPVRClient::ParsePacket(DemuxPacket* pkt) -{ - CDemuxStream* st = m_streams[pkt->iStreamId]; - if (st == NULL) - return; - - if (st->ExtraSize) - return; - - CDemuxStreamPVRInternal* pvr = dynamic_cast(st); - - if(pvr == NULL - || pvr->m_parser == NULL) - return; - - if(pvr->m_context == NULL) - { - AVCodec *codec = avcodec_find_decoder(st->codec); - if (codec == NULL) - { - CLog::Log(LOGERROR, "%s - can't find decoder", __FUNCTION__); - pvr->DisposeParser(); - return; - } - - pvr->m_context = avcodec_alloc_context3(codec); - if(pvr->m_context == NULL) - { - CLog::Log(LOGERROR, "%s - can't allocate context", __FUNCTION__); - pvr->DisposeParser(); - return; - } - pvr->m_context->time_base.num = 1; - pvr->m_context->time_base.den = DVD_TIME_BASE; - } - - if(pvr->m_parser_split && pvr->m_parser->parser->split) - { - int len = pvr->m_parser->parser->split(pvr->m_context, pkt->pData, pkt->iSize); - if (len > 0 && len < FF_MAX_EXTRADATA_SIZE) - { - if (st->ExtraData) - delete[] (uint8_t*)st->ExtraData; - st->changes++; - st->disabled = false; - st->ExtraSize = len; - st->ExtraData = new uint8_t[len+FF_INPUT_BUFFER_PADDING_SIZE]; - memcpy(st->ExtraData, pkt->pData, len); - memset((uint8_t*)st->ExtraData + len, 0 , FF_INPUT_BUFFER_PADDING_SIZE); - pvr->m_parser_split = false; - } - } - - - uint8_t *outbuf = NULL; - int outbuf_size = 0; - int len = av_parser_parse2(pvr->m_parser - , pvr->m_context, &outbuf, &outbuf_size - , pkt->pData, pkt->iSize - , (int64_t)(pkt->pts * DVD_TIME_BASE) - , (int64_t)(pkt->dts * DVD_TIME_BASE) - , 0); - /* our parse is setup to parse complete frames, so we don't care about outbufs */ - if(len >= 0) - { -#define CHECK_UPDATE(st, trg, src, invalid) do { \ - if(src != invalid \ - && src != st->trg) { \ - CLog::Log(LOGDEBUG, "%s - {%d} " #trg " changed from %d to %d", __FUNCTION__, st->iId, st->trg, src); \ - st->trg = src; \ - st->changes++; \ - st->disabled = false; \ - } \ - } while(0) - - - CHECK_UPDATE(st, profile, pvr->m_context->profile , FF_PROFILE_UNKNOWN); - CHECK_UPDATE(st, level , pvr->m_context->level , FF_LEVEL_UNKNOWN); - - switch (st->type) - { - case STREAM_AUDIO: { - CDemuxStreamAudioPVRClient* sta = static_cast(st); - CHECK_UPDATE(sta, iChannels , pvr->m_context->channels , 0); - CHECK_UPDATE(sta, iSampleRate , pvr->m_context->sample_rate, 0); - break; - } - case STREAM_VIDEO: { - CDemuxStreamVideoPVRClient* stv = static_cast(st); - CHECK_UPDATE(stv, iWidth , pvr->m_context->width , 0); - CHECK_UPDATE(stv, iHeight , pvr->m_context->height, 0); - break; - } - - default: - break; - } - -#undef CHECK_UPDATE - } - else - CLog::Log(LOGDEBUG, "%s - parser returned error %d", __FUNCTION__, len); - - return; -} - -DemuxPacket* CDVDDemuxPVRClient::Read() -{ - if (!g_PVRManager.IsStarted()) - return CDVDDemuxUtils::AllocateDemuxPacket(0); - - DemuxPacket* pPacket = m_pvrClient->DemuxRead(); - if (!pPacket) - { - if (m_pInput) - m_pInput->Close(); - return NULL; - } - - if (pPacket->iStreamId == DMX_SPECIALID_STREAMINFO) - { - RequestStreams(); - CDVDDemuxUtils::FreeDemuxPacket(pPacket); - return CDVDDemuxUtils::AllocateDemuxPacket(0); - } - else if (pPacket->iStreamId == DMX_SPECIALID_STREAMCHANGE) - { - RequestStreams(); - } - else if (pPacket->iStreamId >= 0 - && pPacket->iStreamId < MAX_STREAMS - && m_streams[pPacket->iStreamId]) - { - ParsePacket(pPacket); - } - - return pPacket; -} - -CDemuxStream* CDVDDemuxPVRClient::GetStream(int iStreamId) -{ - if (iStreamId < 0 || iStreamId >= MAX_STREAMS) return NULL; - return m_streams[iStreamId]; -} - -void CDVDDemuxPVRClient::RequestStreams() -{ - if (!g_PVRManager.IsStarted()) - return; - - PVR_STREAM_PROPERTIES props = {}; - m_pvrClient->GetStreamProperties(&props); - unsigned int i; - - for (i = 0; i < props.iStreamCount; ++i) - { - CDemuxStream *stm = m_streams[i]; - - if (props.stream[i].iCodecType == XBMC_CODEC_TYPE_AUDIO) - { - CDemuxStreamAudioPVRClient* st = NULL; - if (stm) - { - st = dynamic_cast(stm); - if (!st || (st->codec != (AVCodecID)props.stream[i].iCodecId)) - DisposeStream(i); - } - if (!m_streams[i]) - { - st = new CDemuxStreamAudioPVRClient(this); - st->m_parser = av_parser_init(props.stream[i].iCodecId); - if(st->m_parser) - st->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; - } - st->iChannels = props.stream[i].iChannels; - st->iSampleRate = props.stream[i].iSampleRate; - st->iBlockAlign = props.stream[i].iBlockAlign; - st->iBitRate = props.stream[i].iBitRate; - st->iBitsPerSample = props.stream[i].iBitsPerSample; - m_streams[i] = st; - st->m_parser_split = true; - st->changes++; - } - else if (props.stream[i].iCodecType == XBMC_CODEC_TYPE_VIDEO) - { - CDemuxStreamVideoPVRClient* st = NULL; - if (stm) - { - st = dynamic_cast(stm); - if (!st - || (st->codec != (AVCodecID)props.stream[i].iCodecId) - || (st->iWidth != props.stream[i].iWidth) - || (st->iHeight != props.stream[i].iHeight)) - DisposeStream(i); - } - if (!m_streams[i]) - { - st = new CDemuxStreamVideoPVRClient(this); - st->m_parser = av_parser_init(props.stream[i].iCodecId); - if(st->m_parser) - st->m_parser->flags |= PARSER_FLAG_COMPLETE_FRAMES; - } - st->iFpsScale = props.stream[i].iFPSScale; - st->iFpsRate = props.stream[i].iFPSRate; - st->iHeight = props.stream[i].iHeight; - st->iWidth = props.stream[i].iWidth; - st->fAspect = props.stream[i].fAspect; - st->stereo_mode = "mono"; - m_streams[i] = st; - st->m_parser_split = true; - } - else if (props.stream[i].iCodecId == AV_CODEC_ID_DVB_TELETEXT) - { - if (stm) - { - if (stm->codec != (AVCodecID)props.stream[i].iCodecId) - DisposeStream(i); - } - if (!m_streams[i]) - m_streams[i] = new CDemuxStreamTeletext(); - } - else if (props.stream[i].iCodecType == XBMC_CODEC_TYPE_SUBTITLE) - { - CDemuxStreamSubtitlePVRClient* st = NULL; - if (stm) - { - st = dynamic_cast(stm); - if (!st || (st->codec != (AVCodecID)props.stream[i].iCodecId)) - DisposeStream(i); - } - if (!m_streams[i]) - { - st = new CDemuxStreamSubtitlePVRClient(this); - } - if(props.stream[i].iIdentifier) - { - st->ExtraData = new uint8_t[4]; - st->ExtraSize = 4; - st->ExtraData[0] = (props.stream[i].iIdentifier >> 8) & 0xff; - st->ExtraData[1] = (props.stream[i].iIdentifier >> 0) & 0xff; - st->ExtraData[2] = (props.stream[i].iIdentifier >> 24) & 0xff; - st->ExtraData[3] = (props.stream[i].iIdentifier >> 16) & 0xff; - } - m_streams[i] = st; - } - else - { - if (m_streams[i]) - DisposeStream(i); - m_streams[i] = new CDemuxStream(); - } - - m_streams[i]->codec = (AVCodecID)props.stream[i].iCodecId; - m_streams[i]->iId = i; - m_streams[i]->iPhysicalId = props.stream[i].iPhysicalId; - m_streams[i]->language[0] = props.stream[i].strLanguage[0]; - m_streams[i]->language[1] = props.stream[i].strLanguage[1]; - m_streams[i]->language[2] = props.stream[i].strLanguage[2]; - m_streams[i]->language[3] = props.stream[i].strLanguage[3]; - - CLog::Log(LOGDEBUG,"CDVDDemuxPVRClient::RequestStreams(): added/updated stream %d:%d with codec_id %d", - m_streams[i]->iId, - m_streams[i]->iPhysicalId, - m_streams[i]->codec); - } - // check if we need to dispose any streams no longer in props - for (unsigned int j = i; j < MAX_STREAMS; j++) - { - if (m_streams[j]) - { - CLog::Log(LOGDEBUG,"CDVDDemuxPVRClient::RequestStreams(): disposed stream %d:%d with codec_id %d", - m_streams[j]->iId, - m_streams[j]->iPhysicalId, - m_streams[j]->codec); - DisposeStream(j); - } - } -} - -int CDVDDemuxPVRClient::GetNrOfStreams() -{ - int i = 0; - while (i < MAX_STREAMS && m_streams[i]) i++; - return i; -} - -std::string CDVDDemuxPVRClient::GetFileName() -{ - if(m_pInput) - return m_pInput->GetFileName(); - else - return ""; -} - -void CDVDDemuxPVRClient::GetStreamCodecName(int iStreamId, std::string &strName) -{ - CDemuxStream *stream = GetStream(iStreamId); - if (stream) - { - if (stream->codec == AV_CODEC_ID_AC3) - strName = "ac3"; - else if (stream->codec == AV_CODEC_ID_MP2) - strName = "mp2"; - else if (stream->codec == AV_CODEC_ID_AAC) - strName = "aac"; - else if (stream->codec == AV_CODEC_ID_DTS) - strName = "dca"; - else if (stream->codec == AV_CODEC_ID_MPEG2VIDEO) - strName = "mpeg2video"; - else if (stream->codec == AV_CODEC_ID_H264) - strName = "h264"; - else if (stream->codec == AV_CODEC_ID_EAC3) - strName = "eac3"; - } -} - -bool CDVDDemuxPVRClient::SeekTime(int timems, bool backwards, double *startpts) -{ - if (m_pInput) - return m_pvrClient->SeekTime(timems, backwards, startpts); - return false; -} - -void CDVDDemuxPVRClient::SetSpeed ( int speed ) -{ - if (m_pInput) - m_pvrClient->SetSpeed(speed); -} diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h deleted file mode 100644 index 2fc3c63..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxPVRClient.h +++ /dev/null @@ -1,118 +0,0 @@ -#pragma once -/* - * Copyright (C) 2012-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "DVDDemux.h" -#include -#include "pvr/addons/PVRClient.h" - -extern "C" { -#include "libavcodec/avcodec.h" -#include "libavformat/avformat.h" -} - -class CDVDDemuxPVRClient; -struct PVR_STREAM_PROPERTIES; - -class CDemuxStreamPVRInternal -{ -public: - CDemuxStreamPVRInternal(CDVDDemuxPVRClient *parent); - ~CDemuxStreamPVRInternal(); - - void DisposeParser(); - - CDVDDemuxPVRClient * m_parent; - AVCodecParserContext* m_parser; - AVCodecContext * m_context; - bool m_parser_split; -}; - -class CDemuxStreamVideoPVRClient - : public CDemuxStreamVideo - , public CDemuxStreamPVRInternal -{ -public: - CDemuxStreamVideoPVRClient(CDVDDemuxPVRClient *parent) - : CDemuxStreamPVRInternal(parent) - {} - virtual void GetStreamInfo(std::string& strInfo); -}; - -class CDemuxStreamAudioPVRClient - : public CDemuxStreamAudio - , public CDemuxStreamPVRInternal -{ -public: - CDemuxStreamAudioPVRClient(CDVDDemuxPVRClient *parent) - : CDemuxStreamPVRInternal(parent) - {} - virtual void GetStreamInfo(std::string& strInfo); -}; - -class CDemuxStreamSubtitlePVRClient - : public CDemuxStreamSubtitle - , public CDemuxStreamPVRInternal -{ -public: - CDemuxStreamSubtitlePVRClient(CDVDDemuxPVRClient *parent) - : CDemuxStreamPVRInternal(parent) - {} - virtual void GetStreamInfo(std::string& strInfo); -}; - - -class CDVDDemuxPVRClient : public CDVDDemux -{ - friend class CDemuxStreamPVRInternal; - -public: - - CDVDDemuxPVRClient(); - ~CDVDDemuxPVRClient(); - - bool Open(CDVDInputStream* pInput); - void Dispose(); - void Reset(); - void Abort(); - void Flush(); - DemuxPacket* Read(); - bool SeekTime(int time, bool backwords = false, double* startpts = NULL); - void SetSpeed(int iSpeed); - int GetStreamLength() { return 0; } - CDemuxStream* GetStream(int iStreamId); - int GetNrOfStreams(); - std::string GetFileName(); - virtual void GetStreamCodecName(int iStreamId, std::string &strName); - -protected: - CDVDInputStream* m_pInput; -#ifndef MAX_STREAMS - #define MAX_STREAMS 100 -#endif - CDemuxStream* m_streams[MAX_STREAMS]; // maximum number of streams that ffmpeg can handle - std::shared_ptr m_pvrClient; - -private: - void RequestStreams(); - void ParsePacket(DemuxPacket* pPacket); - void DisposeStream(int iStreamId); -}; - diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.cpp deleted file mode 100644 index a69342a..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "DVDCodecs/DVDCodecs.h" -#include "DVDInputStreams/DVDInputStreamHttp.h" -#include "DVDDemuxShoutcast.h" -#include "DVDDemuxUtils.h" -#include "DVDClock.h" // for DVD_TIME_BASE -#include "../../../utils/HttpHeader.h" - -#define ICY_NOTICE1 "icy-notice1" // string -#define ICY_NOTICE2 "icy-notice2" // string -#define ICY_NAME "icy-name" // string -#define ICY_GENRE "icy-genre" // string -#define ICY_URL "icy-url" // string -#define ICY_PUBLIC "icy-pub" // int (1 / 0) -#define ICY_BITRATE "icy-br" // int (bitrate = val * 1000 ?) -#define ICY_METAINTERVAL "icy-metaint" // int - -#define CONTENT_TYPE_MP3 "audio/mpeg" -#define CONTENT_TYPE_AAC "audio/aac" -#define CONTENT_TYPE_AACPLUS "audio/aacp" - -// class CDemuxStreamVideoFFmpeg -void CDemuxStreamAudioShoutcast::GetStreamInfo(std::string& strInfo) -{ - strInfo = "Shoutcast"; -} - -CDVDDemuxShoutcast::CDVDDemuxShoutcast() : CDVDDemux() -{ - m_pInput = NULL; - m_pDemuxStream = NULL; - m_iMetaStreamInterval = 0; -} - -CDVDDemuxShoutcast::~CDVDDemuxShoutcast() -{ - Dispose(); -} - -bool CDVDDemuxShoutcast::Open(CDVDInputStream* pInput) -{ - Dispose(); - - m_pInput = pInput; - - // the input stream should be a http stream - if (!pInput->IsStreamType(DVDSTREAM_TYPE_HTTP)) return false; - CDVDInputStreamHttp* pInputStreamHttp = (CDVDInputStreamHttp*)pInput; - - CHttpHeader* pHeader = pInputStreamHttp->GetHttpHeader(); - - std::string strMetaInt = pHeader->GetValue(ICY_METAINTERVAL); - std::string strMimeType = pHeader->GetMimeType(); - - // create new demuxer stream - m_pDemuxStream = new CDemuxStreamAudioShoutcast(); - m_pDemuxStream->iId = 0; - m_pDemuxStream->iPhysicalId = 0; - m_pDemuxStream->iDuration = 0; - m_pDemuxStream->iChannels = 2; - m_pDemuxStream->iSampleRate = 0; - - // set meta interval - m_iMetaStreamInterval = atoi(strMetaInt.c_str()); - - if (stricmp(strMimeType.c_str(), CONTENT_TYPE_AAC) == 0 || - stricmp(strMimeType.c_str(), CONTENT_TYPE_AACPLUS) == 0) - { - // need an aac decoder first - m_pDemuxStream->codec = AV_CODEC_ID_AAC; - } - else // (stricmp(strMimeType, CONTENT_TYPE_MP3) == 0) - { - // default to mp3 - m_pDemuxStream->codec = AV_CODEC_ID_MP3; - } - - return true; -} - -void CDVDDemuxShoutcast::Dispose() -{ - if (m_pDemuxStream) delete m_pDemuxStream; - m_pDemuxStream = NULL; - - m_pInput = NULL; -} - -void CDVDDemuxShoutcast::Reset() -{ - CDVDInputStream* pInputStream = m_pInput; - Dispose(); - Open(pInputStream); -} - -void CDVDDemuxShoutcast::Flush() -{ -} - -DemuxPacket* CDVDDemuxShoutcast::Read() -{ - // XXX - // if meta interval is greater than FileCurl's max read size (currently 64k) - // it will simply fail becuse the meta-interval will get incorrect - - int iDataToRead = SHOUTCAST_BUFFER_SIZE; - if (m_iMetaStreamInterval > 0) iDataToRead = m_iMetaStreamInterval; - - DemuxPacket* pPacket; - pPacket = CDVDDemuxUtils::AllocateDemuxPacket(iDataToRead); - if (pPacket) - { - pPacket->dts = DVD_NOPTS_VALUE; - pPacket->pts = DVD_NOPTS_VALUE; - pPacket->iStreamId = 0; - - // read the data - int iRead = m_pInput->Read(pPacket->pData, iDataToRead); - - pPacket->iSize = iRead; - - if (iRead <= 0) - { - CDVDDemuxUtils::FreeDemuxPacket(pPacket); - pPacket = NULL; - } - } - - if (m_iMetaStreamInterval > 0) - { - // we already have read m_iMetaStreamInterval bytes of streaming data - // metadata follows - uint8_t l; - int iRead = m_pInput->Read(&l, 1); - if (iRead > 0) - { - int iMetaLength = l * 16; - - if (iMetaLength > 0) - { - // iMetaLength cannot be larger then 16 * 255 - uint8_t buffer[16 * 255]; - - // skip meta data for now - m_pInput->Read(buffer, iMetaLength); - } - } - } - - return pPacket; -} - -bool CDVDDemuxShoutcast::SeekTime(int time, bool backwords, double* startpts) -{ - return false; -} - -int CDVDDemuxShoutcast::GetStreamLength() -{ - return 0; -} - -CDemuxStream* CDVDDemuxShoutcast::GetStream(int iStreamId) -{ - return m_pDemuxStream; -} - -int CDVDDemuxShoutcast::GetNrOfStreams() -{ - return 1; -} - -std::string CDVDDemuxShoutcast::GetFileName() -{ - if(m_pInput) - return m_pInput->GetFileName(); - else - return ""; -} - diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.h deleted file mode 100644 index a802167..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxShoutcast.h +++ /dev/null @@ -1,60 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "DVDDemux.h" - -class CDemuxStreamAudioShoutcast : public CDemuxStreamAudio -{ -public: - virtual void GetStreamInfo(std::string& strInfo); -}; - -#define SHOUTCAST_BUFFER_SIZE 1024 * 32 - -class CDVDDemuxShoutcast : public CDVDDemux -{ -public: - CDVDDemuxShoutcast(); - virtual ~CDVDDemuxShoutcast(); - - bool Open(CDVDInputStream* pInput); - void Dispose(); - void Reset(); - void Flush(); - void Abort(){} - void SetSpeed(int iSpeed){}; - virtual std::string GetFileName(); - - DemuxPacket* Read(); - - bool SeekTime(int time, bool backwords = false, double* startpts = NULL); - int GetStreamLength(); - CDemuxStream* GetStream(int iStreamId); - int GetNrOfStreams(); - -protected: - - CDemuxStreamAudioShoutcast* m_pDemuxStream; - - int m_iMetaStreamInterval; - CDVDInputStream* m_pInput; -}; diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.cpp deleted file mode 100644 index ab298b2..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.cpp +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#if (defined HAVE_CONFIG_H) && (!defined TARGET_WINDOWS) - #include "config.h" -#endif -#include "DVDDemuxUtils.h" -#include "DVDClock.h" -#include "utils/log.h" - -extern "C" { -#include "libavcodec/avcodec.h" -} - -void CDVDDemuxUtils::FreeDemuxPacket(DemuxPacket* pPacket) -{ - if (pPacket) - { - try { - if (pPacket->pData) _aligned_free(pPacket->pData); - delete pPacket; - } - catch(...) { - CLog::Log(LOGERROR, "%s - Exception thrown while freeing packet", __FUNCTION__); - } - } -} - -DemuxPacket* CDVDDemuxUtils::AllocateDemuxPacket(int iDataSize) -{ - DemuxPacket* pPacket = new DemuxPacket; - if (!pPacket) return NULL; - - try - { - memset(pPacket, 0, sizeof(DemuxPacket)); - - if (iDataSize > 0) - { - // need to allocate a few bytes more. - // From avcodec.h (ffmpeg) - /** - * Required number of additionally allocated bytes at the end of the input bitstream for decoding. - * this is mainly needed because some optimized bitstream readers read - * 32 or 64 bit at once and could read over the end
- * Note, if the first 23 bits of the additional bytes are not 0 then damaged - * MPEG bitstreams could cause overread and segfault - */ - pPacket->pData =(uint8_t*)_aligned_malloc(iDataSize + FF_INPUT_BUFFER_PADDING_SIZE, 16); - if (!pPacket->pData) - { - FreeDemuxPacket(pPacket); - return NULL; - } - - // reset the last 8 bytes to 0; - memset(pPacket->pData + iDataSize, 0, FF_INPUT_BUFFER_PADDING_SIZE); - } - - // setup defaults - pPacket->dts = DVD_NOPTS_VALUE; - pPacket->pts = DVD_NOPTS_VALUE; - pPacket->iStreamId = -1; - } - catch(...) - { - CLog::Log(LOGERROR, "%s - Exception thrown", __FUNCTION__); - FreeDemuxPacket(pPacket); - pPacket = NULL; - } - return pPacket; -} diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.h deleted file mode 100644 index 2c12df3..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxUtils.h +++ /dev/null @@ -1,31 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "DVDDemuxPacket.h" - -class CDVDDemuxUtils -{ -public: - static void FreeDemuxPacket(DemuxPacket* pPacket); - static DemuxPacket* AllocateDemuxPacket(int iDataSize = 0); -}; - diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.cpp deleted file mode 100644 index 9625a19..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.cpp +++ /dev/null @@ -1,247 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "DVDDemuxVobsub.h" -#include "DVDInputStreams/DVDFactoryInputStream.h" -#include "DVDInputStreams/DVDInputStream.h" -#include "DVDStreamInfo.h" -#include "DVDCodecs/DVDCodecs.h" -#include "DVDDemuxers/DVDDemuxFFmpeg.h" -#include "DVDDemuxers/DVDDemuxUtils.h" -#include "DVDClock.h" -#include "DVDSubtitles/DVDSubtitleStream.h" - -#include - -using namespace std; - -CDVDDemuxVobsub::CDVDDemuxVobsub() -{ -} - -CDVDDemuxVobsub::~CDVDDemuxVobsub() -{ - for(unsigned i=0;i pStream(new CDVDSubtitleStream()); - if(!pStream->Open(filename)) - return false; - - string vobsub = subfilename; - if ( vobsub == "") - { - vobsub = filename; - vobsub.erase(vobsub.rfind('.'), vobsub.size()); - vobsub += ".sub"; - } - - m_Input.reset(CDVDFactoryInputStream::CreateInputStream(NULL, vobsub, "")); - if(!m_Input.get() || !m_Input->Open(vobsub.c_str(), "video/x-vobsub")) - return false; - - m_Demuxer.reset(new CDVDDemuxFFmpeg()); - if(!m_Demuxer->Open(m_Input.get())) - return false; - - CDVDStreamInfo hints; - CDVDCodecOptions options; - hints.codec = AV_CODEC_ID_DVD_SUBTITLE; - - char line[2048]; - DECLARE_UNUSED(bool,res) - - SState state; - state.delay = 0; - state.id = -1; - - while( pStream->ReadLine(line, sizeof(line)) ) - { - if (*line == 0 || *line == '\r' || *line == '\n' || *line == '#') - continue; - else if (strncmp("langidx:", line, 8) == 0) - res = ParseLangIdx(state, line + 8); - else if (strncmp("delay:", line, 6) == 0) - res = ParseDelay(state, line + 6); - else if (strncmp("id:", line, 3) == 0) - res = ParseId(state, line + 3); - else if (strncmp("timestamp:", line, 10) == 0) - res = ParseTimestamp(state, line + 10); - else if (strncmp("palette:", line, 8) == 0 - || strncmp("size:", line, 5) == 0 - || strncmp("org:", line, 4) == 0 - || strncmp("custom colors:", line, 14) == 0 - || strncmp("scale:", line, 6) == 0 - || strncmp("alpha:", line, 6) == 0 - || strncmp("fadein/out:", line, 11) == 0 - || strncmp("forced subs:", line, 12) == 0) - res = ParseExtra(state, line); - else - continue; - } - - struct sorter s; - sort(m_Timestamps.begin(), m_Timestamps.end(), s); - m_Timestamp = m_Timestamps.begin(); - - for(unsigned i=0;iExtraSize = state.extra.length()+1; - m_Streams[i]->ExtraData = new uint8_t[m_Streams[i]->ExtraSize]; - strcpy((char*)m_Streams[i]->ExtraData, state.extra.c_str()); - } - - return true; -} - -void CDVDDemuxVobsub::Reset() -{ - Flush(); -} - -void CDVDDemuxVobsub::Flush() -{ - m_Demuxer->Flush(); -} - -bool CDVDDemuxVobsub::SeekTime(int time, bool backwords, double* startpts) -{ - double pts = DVD_MSEC_TO_TIME(time); - m_Timestamp = m_Timestamps.begin(); - for(;m_Timestamp != m_Timestamps.end();++m_Timestamp) - { - if(m_Timestamp->pts > pts) - break; - } - for(unsigned i=0;i::iterator current; - do { - if(m_Timestamp == m_Timestamps.end()) - return NULL; - - current = m_Timestamp++; - } while(m_Streams[current->id]->m_discard == AVDISCARD_ALL); - - if(!m_Demuxer->SeekByte(current->pos)) - return NULL; - - DemuxPacket *packet = m_Demuxer->Read(); - if(!packet) - return NULL; - - packet->iStreamId = current->id; - packet->pts = current->pts; - packet->dts = current->pts; - - return packet; -} - -bool CDVDDemuxVobsub::ParseLangIdx(SState& state, char* line) -{ - return true; -} - -bool CDVDDemuxVobsub::ParseDelay(SState& state, char* line) -{ - int h,m,s,ms; - bool negative = false; - - while(*line == ' ') line++; - if(*line == '-') - { - line++; - negative = true; - } - if(sscanf(line, "%d:%d:%d:%d", &h, &m, &s, &ms) != 4) - return false; - state.delay = h*3600.0 + m*60.0 + s + ms*0.001; - if(negative) - state.delay *= -1; - return true; -} - -bool CDVDDemuxVobsub::ParseId(SState& state, char* line) -{ - unique_ptr stream(new CStream(this)); - - while(*line == ' ') line++; - strncpy(stream->language, line, 2); - stream->language[2] = '\0'; - line+=2; - - while(*line == ' ' || *line == ',') line++; - if (strncmp("index:", line, 6) == 0) - { - line+=6; - while(*line == ' ') line++; - stream->iPhysicalId = atoi(line); - } - else - stream->iPhysicalId = -1; - - stream->codec = AV_CODEC_ID_DVD_SUBTITLE; - stream->iId = m_Streams.size(); - stream->source = STREAM_SOURCE_DEMUX_SUB; - - state.id = stream->iId; - m_Streams.push_back(stream.release()); - return true; -} - -bool CDVDDemuxVobsub::ParseExtra(SState& state, char* line) -{ - state.extra += line; - state.extra += '\n'; - return true; -} - -bool CDVDDemuxVobsub::ParseTimestamp(SState& state, char* line) -{ - if(state.id < 0) - return false; - - int h,m,s,ms; - STimestamp timestamp; - - while(*line == ' ') line++; - if(sscanf(line, "%d:%d:%d:%d, filepos:%" PRIx64, &h, &m, &s, &ms, ×tamp.pos) != 5) - return false; - - timestamp.id = state.id; - timestamp.pts = DVD_SEC_TO_TIME(state.delay + h*3600.0 + m*60.0 + s + ms*0.001); - m_Timestamps.push_back(timestamp); - return true; -} diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.h deleted file mode 100644 index 0c75c4a..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDDemuxVobsub.h +++ /dev/null @@ -1,99 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "DVDDemux.h" - -#include -#include - -class CDVDOverlayCodecFFmpeg; -class CDVDInputStream; -class CDVDDemuxFFmpeg; - -class CDVDDemuxVobsub : public CDVDDemux -{ -public: - CDVDDemuxVobsub(); - virtual ~CDVDDemuxVobsub(); - - virtual bool Open(const std::string& filename, const std::string& subfilename = ""); - virtual void Reset(); - virtual void Abort() {}; - virtual void Flush(); - virtual DemuxPacket* Read(); - virtual bool SeekTime(int time, bool backwords, double* startpts = NULL); - virtual void SetSpeed(int speed) {} - virtual CDemuxStream* GetStream(int index) { return m_Streams[index]; } - virtual int GetNrOfStreams() { return m_Streams.size(); } - virtual int GetStreamLength() { return 0; } - virtual std::string GetFileName() { return m_Filename; } - -private: - class CStream - : public CDemuxStreamSubtitle - { - public: - CStream(CDVDDemuxVobsub* parent) - : m_discard(AVDISCARD_NONE), m_parent(parent) - {} - virtual void SetDiscard(AVDiscard discard) { m_discard = discard; } - virtual AVDiscard GetDiscard() { return m_discard; } - - AVDiscard m_discard; - CDVDDemuxVobsub* m_parent; - }; - - typedef struct STimestamp - { - int64_t pos; - double pts; - int id; - } STimestamp; - - std::string m_Filename; - std::unique_ptr m_Input; - std::unique_ptr m_Demuxer; - std::vector m_Timestamps; - std::vector::iterator m_Timestamp; - std::vector m_Streams; - - typedef struct SState - { - int id; - double delay; - std::string extra; - } SState; - - struct sorter - { - bool operator()(const STimestamp &p1, const STimestamp &p2) - { - return p1.pts < p2.pts || (p1.pts == p2.pts && p1.id < p2.id); - } - }; - - bool ParseLangIdx(SState& state, char* line); - bool ParseDelay(SState& state, char* line); - bool ParseId(SState& state, char* line); - bool ParseExtra(SState& state, char* line); - bool ParseTimestamp(SState& state, char* line); -}; diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp deleted file mode 100644 index f909c32..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -#include "system.h" -#include "DVDFactoryDemuxer.h" - -#include "DVDInputStreams/DVDInputStream.h" -#include "DVDInputStreams/DVDInputStreamHttp.h" -#include "DVDInputStreams/DVDInputStreamPVRManager.h" - -#include "DVDDemuxFFmpeg.h" -#include "DVDDemuxShoutcast.h" -#ifdef HAS_FILESYSTEM_HTSP -#include "DVDDemuxHTSP.h" -#endif -#include "DVDDemuxBXA.h" -#include "DVDDemuxCDDA.h" -#include "DVDDemuxPVRClient.h" -#include "pvr/PVRManager.h" -#include "pvr/addons/PVRClients.h" - -using namespace std; -using namespace PVR; - -CDVDDemux* CDVDFactoryDemuxer::CreateDemuxer(CDVDInputStream* pInputStream, bool fileinfo) -{ - if (!pInputStream) - return NULL; - - // Try to open the AirTunes demuxer - if (pInputStream->IsStreamType(DVDSTREAM_TYPE_FILE) && pInputStream->GetContent().compare("audio/x-xbmc-pcm") == 0 ) - { - // audio/x-xbmc-pcm this is the used codec for AirTunes - // (apples audio only streaming) - unique_ptr demuxer(new CDVDDemuxBXA()); - if(demuxer->Open(pInputStream)) - return demuxer.release(); - else - return NULL; - } - - // Try to open CDDA demuxer - if (pInputStream->IsStreamType(DVDSTREAM_TYPE_FILE) && pInputStream->GetContent().compare("application/octet-stream") == 0) - { - std::string filename = pInputStream->GetFileName(); - if (filename.substr(0, 7) == "cdda://") - { - CLog::Log(LOGDEBUG, "DVDFactoryDemuxer: Stream is probably CD audio. Creating CDDA demuxer."); - - unique_ptr demuxer(new CDVDDemuxCDDA()); - if (demuxer->Open(pInputStream)) - { - return demuxer.release(); - } - } - } - - if (pInputStream->IsStreamType(DVDSTREAM_TYPE_HTTP)) - { - CDVDInputStreamHttp* pHttpStream = (CDVDInputStreamHttp*)pInputStream; - CHttpHeader *header = pHttpStream->GetHttpHeader(); - - /* check so we got the meta information as requested in our http header */ - if( header->GetValue("icy-metaint").length() > 0 ) - { - unique_ptr demuxer(new CDVDDemuxShoutcast()); - if(demuxer->Open(pInputStream)) - return demuxer.release(); - else - return NULL; - } - } - -#ifdef HAS_FILESYSTEM_HTSP - if (pInputStream->IsStreamType(DVDSTREAM_TYPE_HTSP)) - { - unique_ptr demuxer(new CDVDDemuxHTSP()); - if(demuxer->Open(pInputStream)) - return demuxer.release(); - else - return NULL; - } -#endif - - bool streaminfo = true; /* Look for streams before playback */ - if (pInputStream->IsStreamType(DVDSTREAM_TYPE_PVRMANAGER)) - { - CDVDInputStreamPVRManager* pInputStreamPVR = (CDVDInputStreamPVRManager*)pInputStream; - CDVDInputStream* pOtherStream = pInputStreamPVR->GetOtherStream(); - - /* Don't parse the streaminfo for some cases of streams to reduce the channel switch time */ - bool useFastswitch = URIUtils::IsUsingFastSwitch(pInputStream->GetFileName()); - streaminfo = !useFastswitch; - - if(pOtherStream) - { - /* Used for MediaPortal PVR addon (uses PVR otherstream for playback of rtsp streams) */ - if (pOtherStream->IsStreamType(DVDSTREAM_TYPE_FFMPEG)) - { - unique_ptr demuxer(new CDVDDemuxFFmpeg()); - if(demuxer->Open(pOtherStream, streaminfo)) - return demuxer.release(); - else - return NULL; - } - } - - /* Use PVR demuxer only for live streams */ - if (URIUtils::IsPVRChannel(pInputStream->GetFileName())) - { - std::shared_ptr client; - if (g_PVRClients->GetPlayingClient(client) && - client->HandlesDemuxing()) - { - unique_ptr demuxer(new CDVDDemuxPVRClient()); - if(demuxer->Open(pInputStream)) - return demuxer.release(); - else - return NULL; - } - } - } - - if (pInputStream->IsStreamType(DVDSTREAM_TYPE_FFMPEG)) - { - bool useFastswitch = URIUtils::IsUsingFastSwitch(pInputStream->GetFileName()); - streaminfo = !useFastswitch; - } - - unique_ptr demuxer(new CDVDDemuxFFmpeg()); - if(demuxer->Open(pInputStream, streaminfo, fileinfo)) - return demuxer.release(); - else - return NULL; -} - diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.h b/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.h deleted file mode 100644 index 8281d28..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/DVDFactoryDemuxer.h +++ /dev/null @@ -1,30 +0,0 @@ -#pragma once - -/* - * Copyright (C) 2005-2013 Team XBMC - * http://xbmc.org - * - * This Program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This Program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with XBMC; see the file COPYING. If not, see - * . - * - */ - -class CDVDDemux; -class CDVDInputStream; - -class CDVDFactoryDemuxer -{ -public: - static CDVDDemux* CreateDemuxer(CDVDInputStream* pInputStream, bool fileinfo = false); -}; diff --git a/xbmc/cores/dvdplayer/DVDDemuxers/Makefile.in b/xbmc/cores/dvdplayer/DVDDemuxers/Makefile.in deleted file mode 100644 index 98493fe..0000000 --- a/xbmc/cores/dvdplayer/DVDDemuxers/Makefile.in +++ /dev/null @@ -1,19 +0,0 @@ -INCLUDES+=-I@abs_top_srcdir@/xbmc/cores/dvdplayer - -SRCS = DVDDemux.cpp -SRCS += DVDDemuxBXA.cpp -SRCS += DVDDemuxCDDA.cpp -SRCS += DVDDemuxFFmpeg.cpp -SRCS += DVDDemuxHTSP.cpp -SRCS += DVDDemuxPVRClient.cpp -SRCS += DVDDemuxShoutcast.cpp -SRCS += DVDDemuxUtils.cpp -SRCS += DVDDemuxVobsub.cpp -SRCS += DVDDemuxCC.cpp -SRCS += DVDFactoryDemuxer.cpp - -LIB = DVDDemuxers.a - -include @abs_top_srcdir@/Makefile.include --include $(patsubst %.cpp,%.P,$(patsubst %.c,%.P,$(SRCS))) - -- cgit v1.2.3