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

📄 qcdmp4.c

📁 the mpeg2/4 aac decoder
💻 C
📖 第 1 页 / 共 5 页
字号:
    {        show_error(module.hMainWindow, "Number of channels not supported for playback.");        faacDecClose(mp4state.hDecoder);        if (mp4state.filetype)            fclose(mp4state.aacfile);        else            MP4Close(mp4state.mp4file);        return -1;    }    if (m_downmix && (mp4state.channels == 5 || mp4state.channels == 6))        mp4state.channels = 2;	wf.wFormatTag = WAVE_FORMAT_PCM;	wf.cbSize = 0;	wf.nChannels = mp4state.channels;	wf.wBitsPerSample = res_table[m_resolution];	wf.nSamplesPerSec = mp4state.samplerate;	wf.nBlockAlign = wf.nChannels * wf.wBitsPerSample / 8;	wf.nAvgBytesPerSec = wf.nSamplesPerSec * wf.nBlockAlign;	if (!module.QCDCallbacks.toPlayer.OutputOpen(mp4state.filename, &wf)) // error opening device    {        faacDecClose(mp4state.hDecoder);        if (mp4state.filetype)            fclose(mp4state.aacfile);        else            MP4Close(mp4state.mp4file);        return -1;    }    mp4state.paused        =  0;    mp4state.decode_pos_ms =  0;    mp4state.seek_needed   = -1;    //// initialize vis stuff    //module.SAVSAInit(maxlatency, mp4state.samplerate);    //module.VSASetInfo((int)mp4state.channels, mp4state.samplerate);    br = (int)floor(((float)avg_bitrate + 500.0)/1000.0 + 0.5);    sr = (int)floor((float)mp4state.samplerate/1000.0 + 0.5);	ai.struct_size = sizeof(AudioInfo);	ai.frequency = sr*1000;	ai.bitrate = br*1000;	ai.mode = (mp4state.channels == 2) ? 0 : 3;	ai.layer = 0;	ai.level = 0;	strcpy(ai.text, mp4state.filetype ? "AAC" : "MP4");	module.QCDCallbacks.Service(opSetAudioInfo, &ai, sizeof(AudioInfo), 0);    //module.outMod->SetVolume(-666); // set the output plug-ins default volume    killPlayThread = 0;    if (mp4state.filetype)    {        if ((play_thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)AACPlayThread,            (void *)&killPlayThread, 0, &thread_id)) == NULL)        {            show_error(module.hMainWindow, "Cannot create playback thread");            faacDecClose(mp4state.hDecoder);            fclose(mp4state.aacfile);            return -1;        }    } else {        if ((play_thread_handle = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)MP4PlayThread,            (void *)&killPlayThread, 0, &thread_id)) == NULL)        {            show_error(module.hMainWindow, "Cannot create playback thread");            faacDecClose(mp4state.hDecoder);            MP4Close(mp4state.mp4file);            return -1;        }    }    SetThreadAffinityMask(play_thread_handle, 1);    SetThreadPriority(play_thread_handle, priority_table[m_priority]);	}    return 1;}//-----------------------------------------------------------------------------int Pause(const char* medianame, int flags){#ifdef DEBUG_OUTPUT    in_mp4_DebugOutput("pause");#endif    mp4state.paused = flags;	if (module.QCDCallbacks.toPlayer.OutputPause(flags))		return 1;	mp4state.paused = !flags;	return 0;}//void unpause()//{//#ifdef DEBUG_OUTPUT//    in_mp4_DebugOutput("unpause");//#endif////    mp4state.paused = 0;//    module.outMod->Pause(0);//}////int ispaused()//{//#ifdef DEBUG_OUTPUT//    in_mp4_DebugOutput("ispaused");//#endif////    return mp4state.paused;//}//-----------------------------------------------------------------------------void SetVolume(int levelleft, int levelright, int flags){#ifdef DEBUG_OUTPUT    in_mp4_DebugOutput("setvolume");#endif	module.QCDCallbacks.toPlayer.OutputSetVol(levelleft, levelright, flags);}//void setpan(int pan)//{//#ifdef DEBUG_OUTPUT//    in_mp4_DebugOutput("setpan");//#endif////    module.outMod->SetPan(pan);//}//-----------------------------------------------------------------------------int Stop(const char* medianame, int flags){    struct seek_list *target = mp4state.m_head;#ifdef DEBUG_OUTPUT    in_mp4_DebugOutput("stop");#endif	if (medianame && *medianame && stricmp(mp4state.filename, medianame) == 0)	{	module.QCDCallbacks.toPlayer.OutputStop(flags);    killPlayThread = 1;    if (play_thread_handle != INVALID_HANDLE_VALUE)    {        if (WaitForSingleObject(play_thread_handle, INFINITE) == WAIT_TIMEOUT)            TerminateThread(play_thread_handle,0);        CloseHandle(play_thread_handle);        play_thread_handle = INVALID_HANDLE_VALUE;    }    if (mp4state.m_aac_buffer)        free(mp4state.m_aac_buffer);    while (target)    {        struct seek_list *tmp = target;        target = target->next;        if (tmp) free(tmp);    }    faacDecClose(mp4state.hDecoder);    if (mp4state.filetype)        fclose(mp4state.aacfile);    else        MP4Close(mp4state.mp4file);    //module.outMod->Close();    //module.SAVSADeInit();	mp4state.filename[0] = '\0';	mp4state.paused = 0;	}	return 1;}int getsonglength(const char *fn){    long msDuration = 0;    if(!stricmp(fn + strlen(fn) - 3,"MP4") || !stricmp(fn + strlen(fn) - 3,"M4A"))    {        int track;        MP4Duration length;        MP4FileHandle file;        file = MP4Read(fn, 0);        if (!file)            return 0;        if ((track = GetAACTrack(file)) < 0)        {            MP4Close(file);            return -1;        }        length = MP4GetTrackDuration(file, track);        msDuration = MP4ConvertFromTrackDuration(file, track,            length, MP4_MSECS_TIME_SCALE);        MP4Close(file);        return msDuration;    } else {        int tagsize = 0;        int bread = 0;        double length = 0.;        __int64 bitrate = 128;        struct seek_list *target;        state len_state;        memset(&len_state, 0, sizeof(state));        if (!(len_state.aacfile = fopen(fn, "rb")))        {            // error            return 0;        }        len_state.m_at_eof = 0;        if (!(len_state.m_aac_buffer = (unsigned char*)malloc(768*6)))        {            //console::error("Memory allocation error.", "foo_mp4");            return 0;        }        memset(len_state.m_aac_buffer, 0, 768*6);        bread = fread(len_state.m_aac_buffer, 1, 768*6, len_state.aacfile);        len_state.m_aac_bytes_into_buffer = bread;        len_state.m_aac_bytes_consumed = 0;        len_state.m_file_offset = 0;        if (bread != 768*6)            len_state.m_at_eof = 1;        if (!memcmp(len_state.m_aac_buffer, "ID3", 3))        {            /* high bit is not used */            tagsize = (len_state.m_aac_buffer[6] << 21) | (len_state.m_aac_buffer[7] << 14) |                (len_state.m_aac_buffer[8] <<  7) | (len_state.m_aac_buffer[9] <<  0);            tagsize += 10;            advance_buffer(&len_state, tagsize);        }        len_state.m_head = (struct seek_list*)malloc(sizeof(struct seek_list));        len_state.m_tail = len_state.m_head;        len_state.m_tail->next = NULL;        len_state.m_header_type = 0;        if ((len_state.m_aac_buffer[0] == 0xFF) && ((len_state.m_aac_buffer[1] & 0xF6) == 0xF0))        {            if (1) //(m_reader->can_seek())            {                adts_parse(&len_state, &bitrate, &length);                fseek(len_state.aacfile, tagsize, SEEK_SET);                bread = fread(len_state.m_aac_buffer, 1, 768*6, len_state.aacfile);                if (bread != 768*6)                    len_state.m_at_eof = 1;                else                    len_state.m_at_eof = 0;                len_state.m_aac_bytes_into_buffer = bread;                len_state.m_aac_bytes_consumed = 0;                len_state.m_header_type = 1;            }        } else if (memcmp(len_state.m_aac_buffer, "ADIF", 4) == 0) {            int skip_size = (len_state.m_aac_buffer[4] & 0x80) ? 9 : 0;            bitrate = ((unsigned int)(len_state.m_aac_buffer[4 + skip_size] & 0x0F)<<19) |                ((unsigned int)len_state.m_aac_buffer[5 + skip_size]<<11) |                ((unsigned int)len_state.m_aac_buffer[6 + skip_size]<<3) |                ((unsigned int)len_state.m_aac_buffer[7 + skip_size] & 0xE0);            length = (double)file_length(len_state.aacfile);            if (length == -1)                length = 0;            else                length = ((double)length*8.)/((double)bitrate) + 0.5;            len_state.m_header_type = 2;        } else {            length = (double)file_length(len_state.aacfile);            length = ((double)length*8.)/((double)bitrate*1000.) + 0.5;            len_state.m_header_type = 0;        }        if (len_state.m_aac_buffer)            free(len_state.m_aac_buffer);        target = len_state.m_head;        while (target)        {            struct seek_list *tmp = target;            target = target->next;            if (tmp) free(tmp);        }        fclose(len_state.aacfile);        return (int)(length*1000.);    }}//int getlength()//{//    if (!mp4state.filetype)//    {//        int track;//        long msDuration;//        MP4Duration length;////        if ((track = GetAACTrack(mp4state.mp4file)) < 0)//        {//            return -1;//        }////        length = MP4GetTrackDuration(mp4state.mp4file, track);////        msDuration = MP4ConvertFromTrackDuration(mp4state.mp4file, track,//            length, MP4_MSECS_TIME_SCALE);////        return msDuration;//    } else {//        return mp4state.m_length;//    }//    return 0;//}//-----------------------------------------------------------------------------int GetCurrentPosition(const char* medianame, long *track, long *offset){	return module.QCDCallbacks.toPlayer.OutputGetCurrentPosition((UINT*)offset, 0);}//void setoutputtime(int time_in_ms)//{//#ifdef DEBUG_OUTPUT//    in_mp4_DebugOutput("setoutputtime");//#endif////    mp4state.seek_needed = time_in_ms;//}//-----------------------------------------------------------------------------int GetTrackExtents(const char* medianame, TrackExtents *ext, int flags){	int len;	FILE *fh;	len = getsonglength((char *)medianame);	fh = fopen(medianame, "rb");	if (len <= 0 || !fh)		return 0;	ext->track = 1;	ext->start = 0;	ext->end = len;	ext->bytesize = file_length(fh);	fclose(fh);	ext->unitpersec = 1000;	return 1;}//void eq_set(int on, char data[10], int preamp)//{//}static void remap_channels(unsigned char *data, unsigned int samples, unsigned int bps){    unsigned int i;    switch (bps)    {    case 8:        {            unsigned char r1, r2, r3, r4, r5, r6;            for (i = 0; i < samples; i += 6)            {                r1 = data[i];                r2 = data[i+1];                r3 = data[i+2];                r4 = data[i+3];                r5 = data[i+4];                r6 = data[i+5];                data[i] = r2;                data[i+1] = r3;                data[i+2] = r1;                data[i+3] = r6;                data[i+4] = r4;                data[i+5] = r5;            }        }        break;    case 16:    default:        {            unsigned short r1, r2, r3, r4, r5, r6;            unsigned short *sample_buffer = (unsigned short *)data;            for (i = 0; i < samples; i += 6)            {                r1 = sample_buffer[i];                r2 = sample_buffer[i+1];                r3 = sample_buffer[i+2];                r4 = sample_buffer[i+3];                r5 = sample_buffer[i+4];                r6 = sample_buffer[i+5];                sample_buffer[i] = r2;                sample_buffer[i+1] = r3;                sample_buffer[i+2] = r1;                sample_buffer[i+3] = r6;                sample_buffer[i+4] = r4;                sample_buffer[i+5] = r5;            }        }        break;    case 24:    case 32:        {            unsigned int r1, r2, r3, r4, r5, r6;            unsigned int *sample_buffer = (unsigned int *)data;            for (i = 0; i < samples; i += 6)            {                r1 = sample_buffer[i];                r2 = sample_buffer[i+1];                r3 = sample_buffer[i+2];                r4 = sample_buffer[

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -