diff options
author | Hendrik Leppkes <h.leppkes@gmail.com> | 2012-05-28 20:33:51 +0400 |
---|---|---|
committer | Hendrik Leppkes <h.leppkes@gmail.com> | 2012-05-28 20:33:51 +0400 |
commit | 4c5e569ec2d4b4a96c06bd094de27ba1e357d741 (patch) | |
tree | 003b2bed076a002602365de709c77fff0ae28b49 /decoder/LAVAudio | |
parent | dbf4fd9eb9a812462c884e6ed7ef4fff03c329c5 (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.cpp | 26 | ||||
-rw-r--r-- | decoder/LAVAudio/DTSDecoder.cpp | 31 | ||||
-rw-r--r-- | decoder/LAVAudio/LAVAudio.cpp | 37 | ||||
-rw-r--r-- | decoder/LAVAudio/LAVAudio.h | 2 |
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; |