⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpi_player_codec_mpeg.c

📁 VC++视频开发实例集锦(包括“远程视频监控”"语音识别系统"等13个经典例子)
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 + -