📄 vorbislmc.cpp
字号:
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;
}
Error VorbisLMC::ChangePosition(int32 position)
{
m_newPos = position;
return kError_NoErr;
}
int VorbisLMC::SeekWrapper(void *stream, ogg_int64_t offset, int whence)
{
return ((VorbisLMC *)stream)->Seek((int32)offset, whence);
}
int VorbisLMC::Seek(long offset, int whence)
{
int32 ret = -1;
if (m_pPmi->IsStreaming())
return -1;
m_pPmi->Seek(ret, offset, whence);
return ret;
}
long VorbisLMC::TellWrapper(void *stream)
{
return ((VorbisLMC *)stream)->Tell();
}
long VorbisLMC::Tell(void)
{
int32 ret = -1;
if (m_pPmi->IsStreaming())
return -1;
m_pPmi->Tell(ret);
return ret;
}
int VorbisLMC::CloseWrapper(void *stream)
{
return 0;
}
size_t VorbisLMC::ReadWrapper(void *buf, size_t size, size_t num, void *stream)
{
return ((VorbisLMC *)stream)->Read(buf, size, num);
}
size_t VorbisLMC::Read(void *buf, size_t size, size_t num)
{
size_t bytes = size * num;
void *ptr;
Error Err;
for(;;)
{
Err = m_pInputBuffer->BeginRead(ptr, bytes);
if (Err == kError_NoDataAvail)
{
m_pPmi->Wake();
usleep(10000);
continue;
}
if (Err == kError_EndOfStream)
{
bytes = m_pInputBuffer->GetNumBytesInBuffer();
if (bytes == 0)
return (size_t)0;
continue;
}
break;
}
if (Err != kError_NoErr)
{
return (size_t)-1;
}
memcpy(buf, ptr, bytes);
m_pInputBuffer->EndRead(bytes);
return bytes / size;
}
Error VorbisLMC::SetDecodeInfo(DecodeInfo &info)
{
m_decodeInfo = info;
return kError_NoErr;
}
const string VorbisLMC::ConvertToISO(const char *utf8)
{
unsigned char *in, *buf;
unsigned char *out, *end;
string ret;
in = (unsigned char *)utf8;
buf = out = new unsigned char[strlen(utf8) + 1];
end = in + strlen(utf8);
for(;*in != 0x00 && in <= end; in++, out++)
{
if (*in < 0x80)
{ /* lower 7-bits unchanged */
*out = *in;
}
else
if (*in > 0xC3)
{ /* discard anything above 0xFF */
*out = '?';
}
else
if (*in & 0xC0)
{ /* parse upper 7-bits */
if (in >= end)
*out = 0;
else
{
*out = (((*in) & 0x1F) << 6) | (0x3F & (*(++in)));
}
}
else
{
*out = '?'; /* this should never happen */
}
}
*out = 0x00; /* append null */
ret = string((char *)buf);
delete buf;
return ret;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -