HX_RESULT CRN1CloakPOSTHandler::HandlePOSTData(IHXBuffer* pBuf) { IHXBuffer* pDecBuf = NULL; CBaseCloakGETHandler* pGETHandler = NULL; BYTE* pData = (BYTE*)pBuf->GetBuffer(); UINT32 uDataLen = pBuf->GetSize(); if (m_bOnClosedCalled) { return HXR_OK; } if (m_pConn) { m_pConn->GetGETHandler(pGETHandler); } if (!pGETHandler) { QueuePendingData(pData, uDataLen); // m_pGETHandler is guaranteed to not exist here. HX_RELEASE(pGETHandler); return HXR_OK; } // We were unable to process a fragment of the previous // packet, so append this packet to it and try to process them // both as one bigger packet. if (m_pPendingData) { // If we're processing it, it shouldn't be in the queue anymore! HX_ASSERT(!m_bProcessingPendingData); QueuePendingData(pData, uDataLen); ProcessPendingData(); return HXR_OK; } HX_ASSERT(pGETHandler); pGETHandler->Release(); pGETHandler = NULL; while (!m_bOnClosedCalled && uDataLen) { BOOL bPostDone = FALSE; UINT32 n = decodeBuf(pData, uDataLen, pDecBuf, bPostDone); if (n == 0) { if (uDataLen < MAX_POST_MESSAGE_LENGTH) { QueuePendingData(pData, uDataLen); } else { // We're already trying to process a fragment. // We don't want to use too much memory, so stop now. DPRINTF(0x10000000, ("RN Cloak v1 -- Max POST length exceeded\n")); m_pDemux->Close(HXR_FAIL); CleanupConn(HXR_FAIL); } break; } pData += n; uDataLen -= n; if (pDecBuf->GetSize() == 1 && pDecBuf->GetBuffer()[0] == HTTP_DONE) { // Client is done with this cloak connection. Close all GET // and POST requests associated with this GUID. CleanupConn(HXR_FAIL); break; } HX_ASSERT(m_pConn); m_pConn->OnPOSTData(pDecBuf); HX_RELEASE(pDecBuf); // if m_pGETHandler is invalid at this point then there is an extra // m_pGETHandler->release() somewhere that needs to b found. if ((m_pConn->GetCloakMode() & CLOAK_MODE_MULTIPOST) && bPostDone) { // Client is in multi-POST mode and it is done with this POST. // Close this POST, leaving any other requests alone. m_pDemux->Close(HXR_OK); // Do not remove from the GUID dict, since other POSTs may follow. CleanupConn(HXR_OK); break; } } HX_RELEASE(pDecBuf); return HXR_OK; }
bool CSoundFile::ReadOpusSample(SAMPLEINDEX sample, FileReader &file) { file.Rewind(); #if defined(MPT_WITH_OPUSFILE) int rate = 0; int channels = 0; std::vector<int16> raw_sample_data; FileReader initial = file.GetChunk(65536); // 512 is recommended by libopusfile if(op_test(NULL, initial.GetRawData<unsigned char>(), initial.GetLength()) != 0) { return false; } OggOpusFile *of = op_open_memory(file.GetRawData<unsigned char>(), file.GetLength(), NULL); if(!of) { return false; } rate = 48000; channels = op_channel_count(of, -1); if(rate <= 0 || channels <= 0) { op_free(of); of = NULL; return false; } if(channels > 2 || op_link_count(of) != 1) { // We downmix multichannel to stereo as recommended by Opus specification in // case we are not able to handle > 2 channels. // We also decode chained files as stereo even if they start with a mono // stream, which simplifies handling of link boundaries for us. channels = 2; } std::vector<int16> decodeBuf(120 * 48000 / 1000); // 120ms (max Opus packet), 48kHz bool eof = false; while(!eof) { int framesRead = 0; if(channels == 2) { framesRead = op_read_stereo(of, &(decodeBuf[0]), static_cast<int>(decodeBuf.size())); } else if(channels == 1) { framesRead = op_read(of, &(decodeBuf[0]), static_cast<int>(decodeBuf.size()), NULL); } if(framesRead > 0) { raw_sample_data.insert(raw_sample_data.end(), decodeBuf.begin(), decodeBuf.begin() + (framesRead * channels)); } else if(framesRead == 0) { eof = true; } else if(framesRead == OP_HOLE) { // continue } else { // other errors are fatal, stop decoding eof = true; } } op_free(of); of = NULL; if(raw_sample_data.empty()) { return false; } DestroySampleThreadsafe(sample); strcpy(m_szNames[sample], ""); Samples[sample].Initialize(); Samples[sample].nC5Speed = rate; Samples[sample].nLength = raw_sample_data.size() / channels; Samples[sample].uFlags.set(CHN_16BIT); Samples[sample].uFlags.set(CHN_STEREO, channels == 2); Samples[sample].AllocateSample(); std::copy(raw_sample_data.begin(), raw_sample_data.end(), Samples[sample].pSample16); Samples[sample].Convert(MOD_TYPE_IT, GetType()); Samples[sample].PrecomputeLoops(*this, false); return Samples[sample].pSample != nullptr; #else // !MPT_WITH_OPUSFILE MPT_UNREFERENCED_PARAMETER(sample); MPT_UNREFERENCED_PARAMETER(file); return false; #endif // MPT_WITH_OPUSFILE }