CSSLHelper::CSSLHelper(const byte * BufPtr, const int BufBytes): contentType(0), major(0), minor(0), length(0), handshakeType(0), handshakeLength(0), OriginalBufPtr(BufPtr), DataPtr(BufPtr), MaxBufBytes(BufBytes) { decoded = (BufPtr != nullptr) && CanDecode(); }
void VorbisLMC::DecodeWork() { void *pOutBuffer; Error Err; int32 iValue; int32 section, ret; OutputInfo *info; vorbis_info *vi; uint32 bytesCopied, bytesPerFrame; int bitrateLoops = 0; assert(m_pPmi); assert(m_pPmo); m_pSleepSem->Wait(); m_pPmi->Wake(); Err = CanDecode(); if (Err == kError_Interrupt) return; if (Err != kError_NoErr) { m_pContext->log->Error("CanDecode returned false.\n"); if (m_decodeInfo.sendInfo) { ReportStatus(szCannotDecode); m_pTarget->AcceptEvent(new Event(INFO_DoneOutputtingDueToError)); } else ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(new PMOErrorEvent()); return; } Err = ExtractMediaInfo(); if (Err == kError_Interrupt) return; if (IsError(Err)) { m_pContext->log->Error("ExtractMediaInfo failed: %d\n", Err); if (m_decodeInfo.sendInfo) { ReportStatus(szCannotDecode); m_pTarget->AcceptEvent(new Event(INFO_DoneOutputtingDueToError)); } else ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(new PMOErrorEvent()); return; } if (!m_bInit) { Err = InitDecoder(); if (Err == kError_Interrupt) return; if (IsError(Err)) { m_pContext->log->Error("Initializing the decoder failed: %d\n", Err); ReportError("Initializing the decoder failed."); return; } } m_pContext->prefs->GetPrefInt32(kDecoderThreadPriorityPref, &iValue); m_decoderThread->SetPriority(iValue); bytesCopied = 0; bytesPerFrame = 1; for (m_frameCounter = 0; !m_bExit;) { if (m_bPause) { m_pPauseSem->Wait(); if (m_bExit) break; } if (m_newPos >= 0) { ov_time_seek(&m_vf, (double)(m_newPos / iFramesPerSecond)); m_frameCounter = m_newPos - 1; m_newPos = -1; bytesCopied = bytesPerFrame; } if (bytesCopied >= bytesPerFrame) { m_frameCounter += bytesCopied / bytesPerFrame; bytesCopied %= bytesPerFrame; ((EventBuffer *)m_pOutputBuffer)->AcceptEvent( new PMOTimeInfoEvent(m_frameCounter)); bitrateLoops++; if (bitrateLoops == iBitrateLoopsPerUpdate && m_decodeInfo.sendInfo) { int b; b = ov_bitrate_instant(&m_vf), vi = ov_info(&m_vf, -1); VorbisInfoEvent *mie = new VorbisInfoEvent(b, vi->channels, vi->rate, 1. / (float)iFramesPerSecond); m_pTarget->AcceptEvent(mie); bitrateLoops = 0; } } Err = m_pOutputBuffer->BeginWrite(pOutBuffer, iDecodeBlockSize); if (Err == kError_Interrupt) { break; } if (Err == kError_BufferTooSmall) { if (Sleep()) break; continue; } if (Err != kError_NoErr) { ReportError(szFailWrite); m_pContext->log->Error("LMC: Cannot write to eventbuffer: %s (%d)\n", m_szError, Err); break; } section = -1; ret = ov_read(&m_vf, (char *)pOutBuffer, iDecodeBlockSize, 0, 2, 1, §ion); if (ret == 0) { m_pOutputBuffer->EndWrite(0); break; } if (section != m_section) { vi = ov_info(&m_vf, -1); info = new OutputInfo; info->bits_per_sample = 16; info->number_of_channels = m_channels = vi->channels; info->samples_per_second = m_rate = vi->rate; info->samples_per_frame = vi->rate / iFramesPerSecond; info->max_buffer_size = 16384; m_frameCounter = 0; bytesCopied = 0; bytesPerFrame = (vi->rate / iFramesPerSecond) * sizeof(ogg_int16_t) * vi->channels; m_section = section; m_pOutputBuffer->EndWrite(0); ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(new PMOInitEvent(info)); ((EventBuffer *)m_pOutputBuffer)->AcceptEvent( new PMOTimeInfoEvent(m_frameCounter)); Err = m_pOutputBuffer->BeginWrite(pOutBuffer, iDecodeBlockSize); if (Err != kError_NoErr) { assert(0); } vorbis_comment *comment; comment = ov_comment(&m_vf, -1); if (comment) { PlaylistItem *plItem = m_pContext->plm->GetCurrentItem(); if (plItem) { MetaData mdata = plItem->GetMetaData(); string iso; char *temp; temp = vorbis_comment_query(comment, "title", 0); if (temp) { iso = ConvertToISO(temp); mdata.SetTitle(iso); } temp = vorbis_comment_query(comment, "artist", 0); if (temp) { iso = ConvertToISO(temp); mdata.SetArtist(iso); } temp = vorbis_comment_query(comment, "album", 0); if (temp) { iso = ConvertToISO(temp); mdata.SetAlbum(iso); } temp = vorbis_comment_query(comment, "tracknumber", 0); if (temp) mdata.SetTrack(atoi(temp)); plItem->SetMetaData(&mdata); m_pContext->target->AcceptEvent( new PlaylistCurrentItemInfoEvent(plItem, m_pContext->plm)); } } } if(ret <0) ret=0; // hole/error in data - we can safely ignore this m_pOutputBuffer->EndWrite(ret); bytesCopied += ret; } ((EventBuffer *)m_pOutputBuffer)->AcceptEvent(new PMOQuitEvent()); ov_clear(&m_vf); return; }