Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mpc-hc/LAVFilters.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHendrik Leppkes <h.leppkes@gmail.com>2012-05-28 20:33:51 +0400
committerHendrik Leppkes <h.leppkes@gmail.com>2012-05-28 20:33:51 +0400
commit4c5e569ec2d4b4a96c06bd094de27ba1e357d741 (patch)
tree003b2bed076a002602365de709c77fff0ae28b49 /decoder/LAVAudio
parentdbf4fd9eb9a812462c884e6ed7ef4fff03c329c5 (diff)
Avoid needless copying of the encoded audio buffer.
This can lead to drastic performance increase in some formats (most notably MPEG-4 ALS), because the source format will have very large packets that the decoder only consumes very slowly, which means the whole packet would get copied over and over again. Now, we try to avoid this copy completely if we trust the source to properly pad the data buffer (only LAV for now), or if we don't, we only copy it to the buffer once, and no longer multiple times.
Diffstat (limited to 'decoder/LAVAudio')
-rw-r--r--decoder/LAVAudio/Bitstream.cpp26
-rw-r--r--decoder/LAVAudio/DTSDecoder.cpp31
-rw-r--r--decoder/LAVAudio/LAVAudio.cpp37
-rw-r--r--decoder/LAVAudio/LAVAudio.h2
4 files changed, 59 insertions, 37 deletions
diff --git a/decoder/LAVAudio/Bitstream.cpp b/decoder/LAVAudio/Bitstream.cpp
index 89a9f900..953909da 100644
--- a/decoder/LAVAudio/Bitstream.cpp
+++ b/decoder/LAVAudio/Bitstream.cpp
@@ -282,10 +282,9 @@ void CLAVAudio::ActivateDTSHDMuxing()
DbgLog((LOG_TRACE, 20, L"::ActivateDTSHDMuxing(): Found DTS-HD marker - switching to DTS-HD muxing mode"));
}
-HRESULT CLAVAudio::Bitstream(const BYTE *p, int buffsize, int &consumed, HRESULT *hrDeliver)
+HRESULT CLAVAudio::Bitstream(const BYTE *buffer, int buffsize, int &consumed, HRESULT *hrDeliver)
{
int ret = 0;
- const BYTE *pDataInBuff = p;
BOOL bEOF = (buffsize == -1);
if (buffsize == -1) buffsize = 1;
@@ -293,18 +292,26 @@ HRESULT CLAVAudio::Bitstream(const BYTE *p, int buffsize, int &consumed, HRESULT
av_init_packet(&avpkt);
avpkt.duration = 1;
- ASSERT(pDataInBuff || bEOF);
+ ASSERT(buffer || bEOF);
+
+ // Copy data onto our properly padded data buffer (to avoid overreads)
+ const uint8_t *pDataBuffer = NULL;
+ if (!m_bInputPadded) {
+ if (!bEOF) {
+ COPY_TO_BUFFER(buffer, buffsize);
+ }
+ pDataBuffer = m_pFFBuffer;
+ } else {
+ pDataBuffer = buffer;
+ }
consumed = 0;
while (buffsize > 0) {
if (bEOF) buffsize = 0;
- else {
- COPY_TO_BUFFER(pDataInBuff, buffsize);
- }
BYTE *pOut = NULL;
int pOut_size = 0;
- int used_bytes = av_parser_parse2(m_pParser, m_pAVCtx, &pOut, &pOut_size, m_pFFBuffer, buffsize, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
+ int used_bytes = av_parser_parse2(m_pParser, m_pAVCtx, &pOut, &pOut_size, pDataBuffer, buffsize, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
if (used_bytes < 0) {
DbgLog((LOG_TRACE, 50, L"::Bitstream() - audio parsing failed (ret: %d)", -used_bytes));
return E_FAIL;
@@ -323,7 +330,7 @@ HRESULT CLAVAudio::Bitstream(const BYTE *p, int buffsize, int &consumed, HRESULT
if (!bEOF && used_bytes > 0) {
buffsize -= used_bytes;
- pDataInBuff += used_bytes;
+ pDataBuffer += used_bytes;
consumed += used_bytes;
}
@@ -333,8 +340,7 @@ HRESULT CLAVAudio::Bitstream(const BYTE *p, int buffsize, int &consumed, HRESULT
ActivateDTSHDMuxing();
}
- COPY_TO_BUFFER(pOut, pOut_size);
- avpkt.data = m_pFFBuffer;
+ avpkt.data = pOut;
avpkt.size = pOut_size;
// Write SPDIF muxed frame
diff --git a/decoder/LAVAudio/DTSDecoder.cpp b/decoder/LAVAudio/DTSDecoder.cpp
index b21f8237..dbb69dc7 100644
--- a/decoder/LAVAudio/DTSDecoder.cpp
+++ b/decoder/LAVAudio/DTSDecoder.cpp
@@ -281,30 +281,37 @@ int CLAVAudio::SafeDTSDecode(BYTE *pInput, int len, BYTE *pOutput, int unk1, int
return nPCMLen;
};
-HRESULT CLAVAudio::DecodeDTS(const BYTE * const p, int buffsize, int &consumed, HRESULT *hrDeliver)
+HRESULT CLAVAudio::DecodeDTS(const BYTE * const buffer, int buffsize, int &consumed, HRESULT *hrDeliver)
{
HRESULT hr = S_FALSE;
int nPCMLength = 0;
- const BYTE *pDataInBuff = p;
BOOL bEOF = (buffsize == -1);
if (buffsize == -1) buffsize = 1;
BufferDetails out;
+ // Copy data onto our properly padded data buffer (to avoid overreads)
+ const uint8_t *pDataBuffer = NULL;
+ if (!m_bInputPadded) {
+ if (!bEOF) {
+ COPY_TO_BUFFER(buffer, buffsize);
+ }
+ pDataBuffer = m_pFFBuffer;
+ } else {
+ pDataBuffer = buffer;
+ }
+
consumed = 0;
while (buffsize > 0) {
nPCMLength = 0;
if (bEOF) buffsize = 0;
- else {
- COPY_TO_BUFFER(pDataInBuff, buffsize);
- }
ASSERT(m_pParser);
BYTE *pOut = NULL;
int pOut_size = 0;
- int used_bytes = av_parser_parse2(m_pParser, m_pAVCtx, &pOut, &pOut_size, m_pFFBuffer, buffsize, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
+ int used_bytes = av_parser_parse2(m_pParser, m_pAVCtx, &pOut, &pOut_size, pDataBuffer, buffsize, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
if (used_bytes < 0) {
return E_FAIL;
} else if(used_bytes == 0 && pOut_size == 0) {
@@ -323,15 +330,13 @@ HRESULT CLAVAudio::DecodeDTS(const BYTE * const p, int buffsize, int &consumed,
if (!bEOF && used_bytes > 0) {
buffsize -= used_bytes;
- pDataInBuff += used_bytes;
+ pDataBuffer += used_bytes;
consumed += used_bytes;
}
- if (pOut_size > 0) {
- COPY_TO_BUFFER(pOut, pOut_size);
-
+ if (pOut && pOut_size > 0) {
// Parse DTS headers
- m_bsParser.Parse(CODEC_ID_DTS, m_pFFBuffer, pOut_size, NULL);
+ m_bsParser.Parse(CODEC_ID_DTS, pOut, pOut_size, NULL);
unsigned decode_channels = dts_determine_decode_channels(m_bsParser.m_DTSHeader);
// Init Decoder with new Parameters, if required
@@ -344,7 +349,7 @@ HRESULT CLAVAudio::DecodeDTS(const BYTE * const p, int buffsize, int &consumed,
int bitdepth = 0, channels = 0, CoreSampleRate = 0, HDSampleRate = 0, profile = 0;
int unk4 = 0, unk5 = 0;
- nPCMLength = SafeDTSDecode(m_pFFBuffer, pOut_size, m_pDTSDecoderContext->dtsPCMBuffer, 0, 8, &bitdepth, &channels, &CoreSampleRate, &unk4, &HDSampleRate, &unk5, &profile);
+ nPCMLength = SafeDTSDecode(pOut, pOut_size, m_pDTSDecoderContext->dtsPCMBuffer, 0, 8, &bitdepth, &channels, &CoreSampleRate, &unk4, &HDSampleRate, &unk5, &profile);
if (nPCMLength > 0 && bitdepth != m_DTSBitDepth) {
int decodeBits = bitdepth > 16 ? 24 : 16;
@@ -354,7 +359,7 @@ HRESULT CLAVAudio::DecodeDTS(const BYTE * const p, int buffsize, int &consumed,
m_DTSBitDepth = decodeBits;
FlushDTSDecoder();
- nPCMLength = SafeDTSDecode(m_pFFBuffer, pOut_size, m_pDTSDecoderContext->dtsPCMBuffer, 0, 2, &bitdepth, &channels, &CoreSampleRate, &unk4, &HDSampleRate, &unk5, &profile);
+ nPCMLength = SafeDTSDecode(pOut, pOut_size, m_pDTSDecoderContext->dtsPCMBuffer, 0, 2, &bitdepth, &channels, &CoreSampleRate, &unk4, &HDSampleRate, &unk5, &profile);
}
}
if (nPCMLength <= 0) {
diff --git a/decoder/LAVAudio/LAVAudio.cpp b/decoder/LAVAudio/LAVAudio.cpp
index 632a9962..ff859179 100644
--- a/decoder/LAVAudio/LAVAudio.cpp
+++ b/decoder/LAVAudio/LAVAudio.cpp
@@ -82,6 +82,7 @@ CLAVAudio::CLAVAudio(LPUNKNOWN pUnk, HRESULT* phr)
, m_bFallback16Int(FALSE)
, m_bNeedSyncpoint(FALSE)
, m_dRate(1.0)
+ , m_bInputPadded(FALSE)
{
#ifdef DEBUG
DbgSetModuleLevel (LOG_CUSTOM1, DWORD_MAX); // FFMPEG messages use custom1
@@ -987,6 +988,8 @@ HRESULT CLAVAudio::ffmpeg_init(CodecID codec, const void *format, const GUID for
}
}
+ m_bInputPadded = FilterInGraphSafe(m_pInput, CLSID_LAVSplitter) || FilterInGraphSafe(m_pInput, CLSID_LAVSplitterSource);
+
// If the codec is bitstreaming, and enabled for it, go there now
if (IsBitstreaming(codec)) {
WAVEFORMATEX *wfe = (format_type == FORMAT_WaveFormatEx) ? (WAVEFORMATEX *)format : NULL;
@@ -1505,10 +1508,9 @@ static DWORD get_lav_channel_layout(uint64_t layout)
return (DWORD)layout;
}
-HRESULT CLAVAudio::Decode(const BYTE * const p, int buffsize, int &consumed, HRESULT *hrDeliver)
+HRESULT CLAVAudio::Decode(const BYTE * const buffer, int buffsize, int &consumed, HRESULT *hrDeliver)
{
int got_frame = 0;
- const BYTE *pDataInBuff = p;
BYTE *tmpProcessBuf = NULL;
HRESULT hr = S_FALSE;
@@ -1520,6 +1522,17 @@ HRESULT CLAVAudio::Decode(const BYTE * const p, int buffsize, int &consumed, HRE
BufferDetails out;
+ // Copy data onto our properly padded data buffer (to avoid overreads)
+ const uint8_t *pDataBuffer = NULL;
+ if (!m_bInputPadded) {
+ if (!bEOF) {
+ COPY_TO_BUFFER(buffer, buffsize);
+ }
+ pDataBuffer = m_pFFBuffer;
+ } else {
+ pDataBuffer = buffer;
+ }
+
if (m_raData.deint_id == MKBETAG('g', 'e', 'n', 'r') || m_raData.deint_id == MKBETAG('s', 'i', 'p', 'r')) {
int w = m_raData.audio_framesize;
int h = m_raData.sub_packet_h;
@@ -1530,7 +1543,7 @@ HRESULT CLAVAudio::Decode(const BYTE * const p, int buffsize, int &consumed, HRE
// "genr" deinterleaving is used for COOK and ATRAC
if (m_raData.deint_id == MKBETAG('g', 'e', 'n', 'r')) {
- const BYTE *srcBuf = pDataInBuff;
+ const BYTE *srcBuf = pDataBuffer;
for(int y = 0; y < h; y++) {
for(int x = 0, w2 = w / sps; x < w2; x++) {
memcpy(tmpProcessBuf + sps*(h*x+((h+1)/2)*(y&1)+(y>>1)), srcBuf, sps);
@@ -1539,11 +1552,11 @@ HRESULT CLAVAudio::Decode(const BYTE * const p, int buffsize, int &consumed, HRE
}
// "sipr" deinterleaving is used for ... SIPR
} else if (m_raData.deint_id == MKBETAG('s', 'i', 'p', 'r')) {
- memcpy(tmpProcessBuf, pDataInBuff, len);
+ memcpy(tmpProcessBuf, pDataBuffer, len);
ff_rm_reorder_sipr_data(tmpProcessBuf, h, w);
}
- pDataInBuff = tmpProcessBuf;
+ pDataBuffer = tmpProcessBuf;
buffsize = len;
m_rtStartInput = m_rtStartInputCache;
@@ -1565,14 +1578,11 @@ HRESULT CLAVAudio::Decode(const BYTE * const p, int buffsize, int &consumed, HRE
while (buffsize > 0) {
got_frame = 0;
if (bEOF) buffsize = 0;
- else {
- COPY_TO_BUFFER(pDataInBuff, buffsize);
- }
if (m_pParser) {
BYTE *pOut = NULL;
int pOut_size = 0;
- int used_bytes = av_parser_parse2(m_pParser, m_pAVCtx, &pOut, &pOut_size, m_pFFBuffer, buffsize, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
+ int used_bytes = av_parser_parse2(m_pParser, m_pAVCtx, &pOut, &pOut_size, pDataBuffer, buffsize, AV_NOPTS_VALUE, AV_NOPTS_VALUE, 0);
if (used_bytes < 0) {
DbgLog((LOG_TRACE, 50, L"::Decode() - audio parsing failed (ret: %d)", -used_bytes));
goto fail;
@@ -1592,13 +1602,12 @@ HRESULT CLAVAudio::Decode(const BYTE * const p, int buffsize, int &consumed, HRE
if (!bEOF && used_bytes > 0) {
buffsize -= used_bytes;
- pDataInBuff += used_bytes;
+ pDataBuffer += used_bytes;
consumed += used_bytes;
}
if (pOut_size > 0) {
- COPY_TO_BUFFER(pOut, pOut_size);
- avpkt.data = m_pFFBuffer;
+ avpkt.data = pOut;
avpkt.size = pOut_size;
int ret2 = avcodec_decode_audio4(m_pAVCtx, m_pFrame, &got_frame, &avpkt);
@@ -1619,7 +1628,7 @@ HRESULT CLAVAudio::Decode(const BYTE * const p, int buffsize, int &consumed, HRE
} else if(bEOF) {
return S_FALSE;
} else {
- avpkt.data = (uint8_t *)m_pFFBuffer;
+ avpkt.data = (uint8_t *)pDataBuffer;
avpkt.size = buffsize;
int used_bytes = avcodec_decode_audio4(m_pAVCtx, m_pFrame, &got_frame, &avpkt);
@@ -1631,7 +1640,7 @@ HRESULT CLAVAudio::Decode(const BYTE * const p, int buffsize, int &consumed, HRE
break;
}
buffsize -= used_bytes;
- pDataInBuff += used_bytes;
+ pDataBuffer += used_bytes;
consumed += used_bytes;
// Send current input time to the delivery function
diff --git a/decoder/LAVAudio/LAVAudio.h b/decoder/LAVAudio/LAVAudio.h
index 7af3c83e..fce78f0f 100644
--- a/decoder/LAVAudio/LAVAudio.h
+++ b/decoder/LAVAudio/LAVAudio.h
@@ -254,6 +254,8 @@ private:
BOOL m_bSampleSupport[SampleFormat_NB];
+ BOOL m_bInputPadded;
+
// Settings
struct AudioSettings {
BOOL DRCEnabled;