rendered paste bodydiff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.cpp b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.cpp
index 96958da..1c1d330 100644
--- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.cpp
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.cpp
@@ -26,6 +26,9 @@
#include "Settings.h"
#include "utils/log.h"
+#include "../DVDFactoryCodec.h"
+#include "Encoders/DVDAudioEncoderAC3.h"
+
//These values are forced to allow spdif out
#define OUT_SAMPLESIZE 16
#define OUT_CHANNELS 2
@@ -40,6 +43,7 @@ CDVDAudioCodecPassthroughFFmpeg::CDVDAudioCodecPassthroughFFmpeg(void)
m_pFormat = NULL;
m_pStream = NULL;
m_pSyncFrame = NULL;
+ m_codec = NULL;
m_OutputSize = 0;
m_OutputBuffer = (BYTE*)_aligned_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE + FF_INPUT_BUFFER_PADDING_SIZE, 16);
@@ -52,34 +56,57 @@ CDVDAudioCodecPassthroughFFmpeg::~CDVDAudioCodecPassthroughFFmpeg(void)
Dispose();
}
-bool CDVDAudioCodecPassthroughFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
+bool CDVDAudioCodecPassthroughFFmpeg::SetupEncoder(CDVDStreamInfo &hints)
{
- bool bSupportsAC3Out = false;
- bool bSupportsDTSOut = false;
- bool bSupportsAACOut = false;
- bool bSupportsMP1Out = false;
- bool bSupportsMP2Out = false;
- bool bSupportsMP3Out = false;
+ /* there is no point encoding < 2 channel sources, and we dont support anything but AC3 at the moment */
+ if (hints.channels <= 2 || !m_bSupportsAC3Out)
+ return false;
+
+ /* we need to decode the incoming audio data, so we can re-encode it as we need it */
+ m_codec = CDVDFactoryCodec::CreateAudioCodec(hints, false);
+ if (!m_codec)
+ return false;
+
+ /* try to open the encoder */
+ m_encoder = new CDVDAudioEncoderAC3();
+ if (!m_encoder->Initialize(m_codec->GetChannels(), m_codec->GetChannelMap(), m_codec->GetBitsPerSample(), m_codec->GetSampleRate()))
+ {
+ Dispose();
+ return false;
+ }
+
+ /* adjust the hints according to the encorders output */
+ hints.codec = m_encoder->GetCodecID ();
+ hints.channels = m_encoder->GetChannels ();
+ hints.bitrate = m_encoder->GetBitRate ();
+ hints.samplerate = m_encoder->GetSampleRate();
+
+ return true;
+}
+bool CDVDAudioCodecPassthroughFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptions &options)
+{
// TODO - move this stuff somewhere else
if (g_guiSettings.GetInt("audiooutput.mode") == AUDIO_DIGITAL)
{
- bSupportsAC3Out = g_guiSettings.GetBool("audiooutput.ac3passthrough");
- bSupportsDTSOut = g_guiSettings.GetBool("audiooutput.dtspassthrough");
- bSupportsAACOut = g_guiSettings.GetBool("audiooutput.aacpassthrough");
- bSupportsMP1Out = g_guiSettings.GetBool("audiooutput.mp1passthrough");
- bSupportsMP2Out = g_guiSettings.GetBool("audiooutput.mp2passthrough");
- bSupportsMP3Out = g_guiSettings.GetBool("audiooutput.mp3passthrough");
+ m_bSupportsAC3Out = g_guiSettings.GetBool("audiooutput.ac3passthrough");
+ m_bSupportsDTSOut = g_guiSettings.GetBool("audiooutput.dtspassthrough");
+ m_bSupportsAACOut = g_guiSettings.GetBool("audiooutput.aacpassthrough");
+ m_bSupportsMP1Out = g_guiSettings.GetBool("audiooutput.mp1passthrough");
+ m_bSupportsMP2Out = g_guiSettings.GetBool("audiooutput.mp2passthrough");
+ m_bSupportsMP3Out = g_guiSettings.GetBool("audiooutput.mp3passthrough");
}
+ else
+ return false;
//Samplerate cannot be checked here as we don't know it at this point in time.
//We should probably have a way to try to decode data so that we know what samplerate it is.
- if ((hints.codec == CODEC_ID_AC3 && bSupportsAC3Out)
- || (hints.codec == CODEC_ID_DTS && bSupportsDTSOut)
- || (hints.codec == CODEC_ID_AAC && bSupportsAACOut)
- || (hints.codec == CODEC_ID_MP1 && bSupportsMP1Out)
- || (hints.codec == CODEC_ID_MP2 && bSupportsMP2Out)
- || (hints.codec == CODEC_ID_MP3 && bSupportsMP3Out))
+ if ((hints.codec == CODEC_ID_AC3 && m_bSupportsAC3Out)
+ || (hints.codec == CODEC_ID_DTS && m_bSupportsDTSOut)
+ || (hints.codec == CODEC_ID_AAC && m_bSupportsAACOut)
+ || (hints.codec == CODEC_ID_MP1 && m_bSupportsMP1Out)
+ || (hints.codec == CODEC_ID_MP2 && m_bSupportsMP2Out)
+ || (hints.codec == CODEC_ID_MP3 && m_bSupportsMP3Out))
{
// TODO - this is only valid for video files, and should be moved somewhere else
@@ -108,19 +135,28 @@ bool CDVDAudioCodecPassthroughFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptio
/* see if the muxer supports our codec (see spdif.c for supported formats) */
m_pSyncFrame = NULL;
- switch(hints.codec) {
- case CODEC_ID_AC3: m_pSyncFrame = &CDVDAudioCodecPassthroughFFmpeg::SyncAC3; break;
- case CODEC_ID_DTS: m_pSyncFrame = &CDVDAudioCodecPassthroughFFmpeg::SyncDTS; break;
- case CODEC_ID_MP1:
- case CODEC_ID_MP2:
- case CODEC_ID_MP3:
- case CODEC_ID_AAC:
- break;
-
- default:
- CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::Open - ffmpeg SPDIF muxer does not support this codec");
- Dispose();
- return false;
+ bool setupEncoder = true;
+ while(true) {
+ switch(hints.codec) {
+ case CODEC_ID_AC3: m_pSyncFrame = &CDVDAudioCodecPassthroughFFmpeg::SyncAC3; break;
+ case CODEC_ID_DTS: m_pSyncFrame = &CDVDAudioCodecPassthroughFFmpeg::SyncDTS; break;
+ case CODEC_ID_MP1:
+ case CODEC_ID_MP2:
+ case CODEC_ID_MP3:
+ case CODEC_ID_AAC:
+ break;
+
+ default:
+ if (setupEncoder && SetupEncoder(hints))
+ {
+ setupEncoder = false;
+ continue;
+ }
+ CLog::Log(LOGERROR, "CDVDAudioCodecPassthroughFFmpeg::Open - FFmpeg SPDIF muxer does not support this codec");
+ Dispose();
+ return false;
+ }
+ break;
}
/* allocate a the format context */
@@ -186,7 +222,20 @@ bool CDVDAudioCodecPassthroughFFmpeg::Open(CDVDStreamInfo &hints, CDVDCodecOptio
void CDVDAudioCodecPassthroughFFmpeg::Dispose()
{
- if (m_pFormat) {
+ if (m_encoder)
+ {
+ delete m_encoder;
+ m_encoder = NULL;
+ }
+
+ if (m_codec)
+ {
+ delete m_codec;
+ m_codec = NULL;
+ }
+
+ if (m_pFormat)
+ {
if (m_pFormat->pb)
m_dllAvUtil.av_freep(&m_pFormat->pb);
m_dllAvUtil.av_freep(&m_pFormat);
@@ -280,11 +329,11 @@ int CDVDAudioCodecPassthroughFFmpeg::SyncDTS(BYTE* pData, int iSize, int *fSize)
) continue;
/* if it is not a termination frame, check the next 6 bits */
- if (pData[4] & 0x80 != 0 && pData[4] & 0x7C != 0x7C)
+ if ((pData[4] & 0x80) != 0 && (pData[4] & 0x7C) != 0x7C)
continue;
/* get and validate the framesize */
- *fSize = ((pData[5] & 0x3) << 8 | pData[6]) << 4 | ((pData[7] & 0xF0) >> 4) + 1;
+ *fSize = ((((pData[5] & 0x3) << 8 | pData[6]) << 4) | ((pData[7] & 0xF0) >> 4)) + 1;
if (*fSize < 95 || *fSize > 16383)
continue;
@@ -298,12 +347,32 @@ int CDVDAudioCodecPassthroughFFmpeg::SyncDTS(BYTE* pData, int iSize, int *fSize)
int CDVDAudioCodecPassthroughFFmpeg::Decode(BYTE* pData, int iSize)
{
- int fSize = iSize;
- if (m_pSyncFrame)
+ int used, fSize;
+ used = fSize = iSize;
+
+ /* if we are encoding */
+ if (m_encoder)
{
- int skip = (this->*m_pSyncFrame)(pData, iSize, &fSize);
- if (skip > 0)
- return skip;
+ BYTE *decData;
+ BYTE encData[6144];
+ used = m_codec ->Decode (pData, iSize);
+ iSize = m_codec ->GetData(&decData);
+ iSize = m_encoder->Encode (decData, iSize);
+ fSize = m_encoder->GetData(encData, 6144);
+ pData = encData;
+
+ /* if the encoder has not got anything yet, return the consumed bytes */
+ if (iSize == 0)
+ return used;
+ }
+ else
+ {
+ if (m_pSyncFrame)
+ {
+ int skip = (this->*m_pSyncFrame)(pData, iSize, &fSize);
+ if (skip > 0)
+ return skip;
+ }
}
AVPacket pkt;
@@ -314,7 +383,8 @@ int CDVDAudioCodecPassthroughFFmpeg::Decode(BYTE* pData, int iSize)
m_dllAvFormat.av_write_header (m_pFormat);
m_dllAvFormat.av_write_frame (m_pFormat, &pkt);
m_dllAvFormat.av_write_trailer(m_pFormat);
- return fSize;
+
+ return used;
}
int CDVDAudioCodecPassthroughFFmpeg::GetData(BYTE** dst)
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.h b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.h
index 1971c56..25d6f50 100644
--- a/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.h
+++ b/xbmc/cores/dvdplayer/DVDCodecs/Audio/DVDAudioCodecPassthroughFFmpeg.h
@@ -26,6 +26,7 @@
#include "Codecs/DllAvCodec.h"
#include "DVDAudioCodec.h"
+#include "Encoders/IDVDAudioEncoder.h"
class CDVDAudioCodecPassthroughFFmpeg : public CDVDAudioCodec
{
@@ -46,6 +47,17 @@ public:
virtual const char* GetName() { return "PassthroughFFmpeg"; }
private:
+ bool m_bSupportsAC3Out;
+ bool m_bSupportsDTSOut;
+ bool m_bSupportsAACOut;
+ bool m_bSupportsMP1Out;
+ bool m_bSupportsMP2Out;
+ bool m_bSupportsMP3Out;
+
+ CDVDAudioCodec *m_codec ;
+ IDVDAudioEncoder *m_encoder;
+ bool SetupEncoder(CDVDStreamInfo &hints);
+
int (CDVDAudioCodecPassthroughFFmpeg::*m_pSyncFrame)(BYTE* pData, int iSize, int *fSize);
int SyncAC3(BYTE* pData, int iSize, int *fSize);
int SyncDTS(BYTE* pData, int iSize, int *fSize);
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp
index 2530221..f802616 100644
--- a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp
+++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.cpp
@@ -177,18 +177,21 @@ CDVDVideoCodec* CDVDFactoryCodec::CreateVideoCodec( CDVDStreamInfo &hint )
return NULL;
}
-CDVDAudioCodec* CDVDFactoryCodec::CreateAudioCodec( CDVDStreamInfo &hint )
+CDVDAudioCodec* CDVDFactoryCodec::CreateAudioCodec( CDVDStreamInfo &hint, bool passthrough /* = true */)
{
CDVDAudioCodec* pCodec = NULL;
CDVDCodecOptions options;
+ if (passthrough)
+ {
#if defined(USE_LIBA52_DECODER) || defined(USE_LIBDTS_DECODER)
- pCodec = OpenCodec( new CDVDAudioCodecPassthrough(), hint, options );
- if( pCodec ) return pCodec;
+ pCodec = OpenCodec( new CDVDAudioCodecPassthrough(), hint, options );
+ if( pCodec ) return pCodec;
#endif
- pCodec = OpenCodec( new CDVDAudioCodecPassthroughFFmpeg(), hint, options);
- if ( pCodec ) return pCodec;
+ pCodec = OpenCodec( new CDVDAudioCodecPassthroughFFmpeg(), hint, options);
+ if ( pCodec ) return pCodec;
+ }
switch (hint.codec)
{
diff --git a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.h b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.h
index 09885b0..317100e 100644
--- a/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.h
+++ b/xbmc/cores/dvdplayer/DVDCodecs/DVDFactoryCodec.h
@@ -36,7 +36,7 @@ class CDVDFactoryCodec
{
public:
static CDVDVideoCodec* CreateVideoCodec(CDVDStreamInfo &hint );
- static CDVDAudioCodec* CreateAudioCodec(CDVDStreamInfo &hint );
+ static CDVDAudioCodec* CreateAudioCodec(CDVDStreamInfo &hint, bool passthrough = true );
static CDVDOverlayCodec* CreateOverlayCodec(CDVDStreamInfo &hint );
static CDVDAudioCodec* OpenCodec(CDVDAudioCodec* pCodec, CDVDStreamInfo &hint, CDVDCodecOptions &options );