📄 cpi_player_codec_mpeg.c
字号:
pContext = (CPs_CoDec_MPEG*)pCoDec->m_pModuleCookie;
pContext->m_pInStream = NULL;
pContext->size = 0;
pContext->options.m_iPretendOption = 42;
pContext->xing.flags = 0;
pContext->samplecount = 0;
pContext->timer = mad_timer_zero;
pContext->length = mad_timer_zero;
pContext->rate = 0;
pContext->frames = 0;
pContext->info.m_iFileLength_Secs = 0;
pContext->info.m_iBitRate_Kbs = 0;
pContext->info.m_iFreq_Hz = 0;
pContext->info.m_bStereo = TRUE;
pContext->info.m_b16bit = (SAMPLE_DEPTH == 16);
pContext->buflen = 0;
CPFA_InitialiseFileAssociations(pCoDec);
CPFA_AddFileAssociation(pCoDec, "MP3", 0L);
CPFA_AddFileAssociation(pCoDec, "MP2", 0L);
CPFA_AddFileAssociation(pCoDec, "MP1", 0L);
}
void CPP_OMMP3_Uninitialise(CPs_CoDecModule* pModule)
{
CPs_CoDec_MPEG *context = (CPs_CoDec_MPEG *)pModule->m_pModuleCookie;
CP_CHECKOBJECT(context);
cleanup(context);
free(context);
CPFA_EmptyFileAssociations(pModule);
}
BOOL CPP_OMMP3_OpenFile(CPs_CoDecModule* pModule, char const *path, DWORD dwCookie, HWND hWndOwner)
{
CPs_CoDec_MPEG *context = (CPs_CoDec_MPEG *)pModule->m_pModuleCookie;
int iStreamStart = 0;
CP_CHECKOBJECT(context);
cleanup(context);
CP_TRACE1("CPI_CoDec__OpenFile: \"%s\"", path);
context->m_pInStream = CP_CreateInStream(path, hWndOwner);
if(!context->m_pInStream)
{
CP_TRACE0("CPI_CoDec__OpenFile: failed");
return FALSE;
}
if(context->m_pInStream->IsSeekable(context->m_pInStream) == TRUE)
{
CIs_ID3v2Tag tag;
unsigned int iBytesRead;
memset(&tag, 0, sizeof(tag));
context->m_pInStream->Read(context->m_pInStream, &tag, sizeof(tag), &iBytesRead);
if(memcmp(tag.m_cTAG, "ID3", 3) == 0)
{
iStreamStart = sizeof(CIs_ID3v2Tag);
iStreamStart += (tag.m_cSize_Encoded[0] << 21)
| (tag.m_cSize_Encoded[1] << 14)
| (tag.m_cSize_Encoded[2] << 7)
| tag.m_cSize_Encoded[3];
}
context->m_pInStream->Seek(context->m_pInStream, iStreamStart);
}
mad_stream_init(&context->stream);
mad_frame_init(&context->frame);
mad_synth_init(&context->synth);
if (scan_header(context->m_pInStream,
&context->frame.header, &context->xing) == -1) {
CP_TRACE0("CPI_CoDec__OpenFile: failed to read file header");
cleanup(context);
return FALSE;
}
context->m_pInStream->Seek(context->m_pInStream, iStreamStart);
context->size = context->m_pInStream->GetLength(context->m_pInStream);
context->synth.pcm.length = 0;
context->samplecount = 0;
context->timer = mad_timer_zero;
if (context->xing.flags & XING_FRAMES) {
context->length = context->frame.header.duration;
mad_timer_multiply(&context->length, context->xing.frames);
}
else {
mad_timer_set(&context->length, 0,
1, context->frame.header.bitrate / 8);
mad_timer_multiply(&context->length, context->size);
}
context->rate = 0;
context->frames = 0;
context->info.m_iFileLength_Secs =
mad_timer_count(context->length, MAD_UNITS_SECONDS);
context->info.m_iBitRate_Kbs = context->frame.header.bitrate / 1000;
context->info.m_iFreq_Hz = context->frame.header.samplerate;
context->info.m_bStereo =
context->frame.header.mode == MAD_MODE_SINGLE_CHANNEL ? FALSE : TRUE;
context->info.m_b16bit = (SAMPLE_DEPTH == 16);
context->buflen = 0;
return TRUE;
}
void CPP_OMMP3_CloseFile(CPs_CoDecModule* pModule)
{
CPs_CoDec_MPEG *context = (CPs_CoDec_MPEG *)pModule->m_pModuleCookie;
CP_CHECKOBJECT(context);
CP_TRACE0("Close MPEG file");
cleanup(context);
}
void CPP_OMMP3_Seek(CPs_CoDecModule* pModule, int const numer, int const denom)
{
CPs_CoDec_MPEG *context = (CPs_CoDec_MPEG *)pModule->m_pModuleCookie;
double fraction;
unsigned long position;
CP_CHECKOBJECT(context);
CP_ASSERT(context->m_pInStream);
CP_ASSERT(numer >= 0 && denom > 0);
if(context->m_pInStream->IsSeekable(context->m_pInStream) == FALSE)
return;
fraction = (double) numer / denom;
position = (unsigned long)
(mad_timer_count(context->length, MAD_UNITS_MILLISECONDS) * fraction);
mad_timer_set(&context->timer, position / 1000, position % 1000, 1000);
if (context->xing.flags & XING_TOC) {
int percent, p1, p2;
percent = (int) (fraction * 100);
p1 = (percent < 100) ? context->xing.toc[percent ] : 0x100;
p2 = (percent < 99) ? context->xing.toc[percent + 1] : 0x100;
fraction = (p1 + (p2 - p1) * (fraction * 100 - percent)) / 0x100;
}
context->m_pInStream->Seek(context->m_pInStream, (LONG) (context->size * fraction));
if(context->m_pInStream->Read(context->m_pInStream, context->buffer, sizeof(context->buffer),&context->buflen) == FALSE)
context->buflen = 0;
mad_stream_buffer(&context->stream, context->buffer, context->buflen);
mad_frame_mute(&context->frame);
mad_synth_mute(&context->synth);
if (numer) {
int skip;
skip = 2;
do {
if (mad_frame_decode(&context->frame, &context->stream) == 0) {
mad_timer_add(&context->timer, context->frame.header.duration);
if (--skip == 0)
mad_synth_frame(&context->synth, &context->frame);
}
else if (!MAD_RECOVERABLE(context->stream.error))
break;
}
while (skip);
}
context->synth.pcm.length = 0;
context->samplecount = 0;
}
BOOL CPP_OMMP3_GetPCMBlock(CPs_CoDecModule* pModule, void *block, DWORD *size)
{
CPs_CoDec_MPEG *context = (CPs_CoDec_MPEG *)pModule->m_pModuleCookie;
unsigned char *samples = block;
unsigned int nsamples;
CP_CHECKOBJECT(context);
CP_ASSERT(context->m_pInStream);
nsamples = (*size / (SAMPLE_DEPTH / 8)) >>
(context->info.m_bStereo ? 1 : 0);
*size = 0;
while (nsamples) {
unsigned int count, bitrate;
count = context->synth.pcm.length - context->samplecount;
if (count > nsamples)
count = nsamples;
if (count) {
mad_fixed_t const *ch1, *ch2;
ch1 = context->synth.pcm.samples[0] + context->samplecount;
ch2 = context->synth.pcm.samples[1] + context->samplecount;
if (context->info.m_bStereo == FALSE)
ch2 = 0;
else if (context->synth.pcm.channels == 1)
ch2 = ch1;
pack_pcm(&samples, count, ch1, ch2);
context->samplecount += count;
nsamples -= count;
if (nsamples == 0)
break;
}
while (mad_frame_decode(&context->frame, &context->stream) == -1) {
DWORD bytes;
if (MAD_RECOVERABLE(context->stream.error))
continue;
if (context->stream.next_frame) {
memmove(context->buffer, context->stream.next_frame,
context->buflen = context->buffer +
context->buflen - context->stream.next_frame);
}
if(context->m_pInStream->Read(context->m_pInStream,
context->buffer + context->buflen,
sizeof(context->buffer) - context->buflen, &bytes) == FALSE
|| bytes == 0)
{
return FALSE;
}
mad_stream_buffer(&context->stream,
context->buffer, context->buflen += bytes);
}
bitrate = context->frame.header.bitrate / 1000;
context->rate += bitrate;
context->frames++;
context->info.m_iBitRate_Kbs = bitrate;
mad_synth_frame(&context->synth, &context->frame);
context->samplecount = 0;
mad_timer_add(&context->timer, context->frame.header.duration);
}
*size = samples - (unsigned char *) block;
return TRUE;
}
void CPP_OMMP3_GetFileInfo(CPs_CoDecModule* pModule, CPs_FileInfo *info)
{
CPs_CoDec_MPEG *context = (CPs_CoDec_MPEG *)pModule->m_pModuleCookie;
CP_CHECKOBJECT(context);
if (!(context->xing.flags & XING_FRAMES) && context->frames) {
mad_timer_set(&context->length, 0,
1, (context->rate / context->frames) * (1000 / 8));
mad_timer_multiply(&context->length, context->size);
if (mad_timer_compare(context->timer, context->length) > 0)
{
context->length = context->timer;
context->size = context->m_pInStream->GetLength(context->m_pInStream);
}
context->info.m_iFileLength_Secs =
mad_timer_count(context->length, MAD_UNITS_SECONDS);
}
*info = context->info;
}
int CPP_OMMP3_GetCurrentPos_secs(CPs_CoDecModule* pModule)
{
CPs_CoDec_MPEG *context = (CPs_CoDec_MPEG *)pModule->m_pModuleCookie;
CP_CHECKOBJECT(context);
return mad_timer_count(context->timer, MAD_UNITS_SECONDS);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -