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

📄 qcdmp4.c

📁 BHE的解码程序
💻 C
📖 第 1 页 / 共 5 页
字号:

            EndDialog(hwndDlg, wParam);
            return TRUE;
        }
    }
    return FALSE;
}

void Configure(int flags)
{
    DialogBox(module.hDllInstance, MAKEINTRESOURCE(IDD_CONFIG),
		module.hMainWindow, config_dialog_proc);
}

//-----------------------------------------------------------------------------

void About(int flags)
{
	MessageBox(module.hMainWindow,
        "AudioCoding.com MPEG-4 General Audio player " FAAD2_VERSION " compiled on " __DATE__ ".\n"
        "Visit the website for more info.\n"
		"Ported to QCD by Shao Hao.\n"
        "Copyright 2002-2003 AudioCoding.com",
        "About",
        MB_OK);
}

//-----------------------------------------------------------------------------

int fill_buffer(state *st)
{
    int bread;

    if (st->m_aac_bytes_consumed > 0)
    {
        if (st->m_aac_bytes_into_buffer)
        {
            memmove((void*)st->m_aac_buffer, (void*)(st->m_aac_buffer + st->m_aac_bytes_consumed),
                st->m_aac_bytes_into_buffer*sizeof(unsigned char));
        }

        if (!st->m_at_eof)
        {
            bread = fread((void*)(st->m_aac_buffer + st->m_aac_bytes_into_buffer),
                1, st->m_aac_bytes_consumed, st->aacfile);

            if (bread != st->m_aac_bytes_consumed)
                st->m_at_eof = 1;

            st->m_aac_bytes_into_buffer += bread;
        }

        st->m_aac_bytes_consumed = 0;

        if (st->m_aac_bytes_into_buffer > 3)
        {
            if (memcmp(st->m_aac_buffer, "TAG", 3) == 0)
                st->m_aac_bytes_into_buffer = 0;
        }
        if (st->m_aac_bytes_into_buffer > 11)
        {
            if (memcmp(st->m_aac_buffer, "LYRICSBEGIN", 11) == 0)
                st->m_aac_bytes_into_buffer = 0;
        }
        if (st->m_aac_bytes_into_buffer > 8)
        {
            if (memcmp(st->m_aac_buffer, "APETAGEX", 8) == 0)
                st->m_aac_bytes_into_buffer = 0;
        }
    }

    return 1;
}

void advance_buffer(state *st, int bytes)
{
    st->m_file_offset += bytes;
    st->m_aac_bytes_consumed = bytes;
    st->m_aac_bytes_into_buffer -= bytes;
}

int adts_parse(state *st, __int64 *bitrate, double *length)
{
    static int sample_rates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000};
    int frames, frame_length;
    int t_framelength = 0;
    int samplerate;
    double frames_per_sec, bytes_per_frame;

    /* Read all frames to ensure correct time and bitrate */
    for (frames = 0; /* */; frames++)
    {
        fill_buffer(st);

        if (st->m_aac_bytes_into_buffer > 7)
        {
            /* check syncword */
            if (!((st->m_aac_buffer[0] == 0xFF)&&((st->m_aac_buffer[1] & 0xF6) == 0xF0)))
                break;

            st->m_tail->offset = st->m_file_offset;
            st->m_tail->next = (struct seek_list*)malloc(sizeof(struct seek_list));
            st->m_tail = st->m_tail->next;
            st->m_tail->next = NULL;

            if (frames == 0)
                samplerate = sample_rates[(st->m_aac_buffer[2]&0x3c)>>2];

            frame_length = ((((unsigned int)st->m_aac_buffer[3] & 0x3)) << 11)
                | (((unsigned int)st->m_aac_buffer[4]) << 3) | (st->m_aac_buffer[5] >> 5);

            t_framelength += frame_length;

            if (frame_length > st->m_aac_bytes_into_buffer)
                break;

            advance_buffer(st, frame_length);
        } else {
            break;
        }
    }

    frames_per_sec = (double)samplerate/1024.0;
    if (frames != 0)
        bytes_per_frame = (double)t_framelength/(double)(frames*1000);
    else
        bytes_per_frame = 0;
    *bitrate = (__int64)(8. * bytes_per_frame * frames_per_sec + 0.5);
    if (frames_per_sec != 0)
        *length = (double)frames/frames_per_sec;
    else
        *length = 1;

    return 1;
}

int skip_id3v2_tag()
{
    unsigned char buf[10];
    int bread, tagsize = 0;

    bread = fread(buf, 1, 10, mp4state.aacfile);
    if (bread != 10) return -1;

    if (!memcmp(buf, "ID3", 3))
    {
        /* high bit is not used */
        tagsize = (buf[6] << 21) | (buf[7] << 14) | (buf[8] << 7) | (buf[9] << 0);

        tagsize += 10;
        fseek(mp4state.aacfile, tagsize, SEEK_SET);
    } else {
        fseek(mp4state.aacfile, 0, SEEK_SET);
    }

    return tagsize;
}

int GetMediaSupported(const char* medianame, MediaInfo *mediaInfo) 
{
    int tagsize = 0, init;

	if (!medianame || !*medianame)
		return 0;

    if (!stricmp(medianame + strlen(medianame) - 3,"MP4") || !stricmp(medianame + strlen(medianame) - 3,"M4A"))
    {
		if (mediaInfo)
		{
			mediaInfo->mediaType = DIGITAL_FILE_MEDIA;
			mediaInfo->op_canSeek = 1;
		}
		return 1;
	}
	else if (m_use_for_aac && !stricmp(medianame + strlen(medianame) - 3,"AAC"))
	{
		if (mediaInfo)
		{
			mediaInfo->mediaType = DIGITAL_FILE_MEDIA;
			mediaInfo->op_canSeek = 1;

			memset(&mp4state, 0, sizeof(state));
			lstrcpy(mp4state.filename, medianame);

			if (!(mp4state.aacfile = fopen(mp4state.filename, "rb")))
			{
				// error
				return 0;
			}

			tagsize = skip_id3v2_tag();
			if (tagsize<0) return 0;

			if (!(mp4state.m_aac_buffer = (unsigned char*)malloc(768*6)))
			{
				show_error(module.hMainWindow, "Memory allocation error.");
				return 0;
			}

			for (init=0; init<2; init++)
			{
				memset(mp4state.m_aac_buffer, 0, 768*6);
				fread(mp4state.m_aac_buffer, 1, 768*6, mp4state.aacfile);

				if (init==0)
					fseek(mp4state.aacfile, tagsize, SEEK_SET);
			}

			if (memcmp(mp4state.m_aac_buffer, "ADIF", 4) == 0)
				mediaInfo->op_canSeek = (double)file_length(mp4state.aacfile) == -1 ? 0 : 1;

			free(mp4state.m_aac_buffer);

			fclose(mp4state.aacfile);
		}
		return 1;
	}

	return 0;
}

//-----------------------------------------------------------------------------

int Play(const char* medianame, int playfrom, int playto, int flags)
{
    WAVEFORMATEX wf;
    //int maxlatency;
    int thread_id;
    int avg_bitrate, br, sr;
    unsigned char *buffer;
    int buffer_size;
    faacDecConfigurationPtr config;

#ifdef DEBUG_OUTPUT
    in_mp4_DebugOutput("play");
#endif

	if (stricmp(mp4state.filename, medianame) != 0)
		Stop(mp4state.filename, STOPFLAG_PLAYDONE);

	if (mp4state.paused)
	{
		// Update the player controls to reflect the new unpaused state
		module.QCDCallbacks.toPlayer.OutputPause(0);

		Pause(medianame, 0);

		if (playfrom >= 0)
			mp4state.seek_needed = playfrom;
	}
	else if (PlayThreadAlive) // is playing
	{
		mp4state.seek_needed = playfrom;
		return 1;
	}
	else
	{
    memset(&mp4state, 0, sizeof(state));

    lstrcpy(mp4state.filename, medianame);

    if (!(mp4state.mp4file = MP4Read(mp4state.filename, 0)))
    {
        mp4state.filetype = 1;
    } else {
        MP4Close(mp4state.mp4file);
        mp4state.filetype = 0;
    }

    if (mp4state.filetype)
    {
        int tagsize = 0, tmp = 0, init;
        int bread = 0;
        double length = 0.;
        __int64 bitrate = 128;

        //module.is_seekable = 1;

        if (!(mp4state.aacfile = fopen(mp4state.filename, "rb")))
        {
            // error
            return -1;
        }

        tagsize = skip_id3v2_tag();
        if (tagsize<0) return 0;

        if (!(mp4state.m_aac_buffer = (unsigned char*)malloc(768*6)))
        {
            show_error(module.hMainWindow, "Memory allocation error.");
            return -1;
        }

        for (init=0; init<2; init++)
        {
            mp4state.hDecoder = faacDecOpen();
            if (!mp4state.hDecoder)
            {
                show_error(module.hMainWindow, "Unable to open decoder library.");
                return -1;
            }

            config = faacDecGetCurrentConfiguration(mp4state.hDecoder);
            config->outputFormat = m_resolution + 1;
            config->downMatrix = m_downmix;
            faacDecSetConfiguration(mp4state.hDecoder, config);

            memset(mp4state.m_aac_buffer, 0, 768*6);
            bread = fread(mp4state.m_aac_buffer, 1, 768*6, mp4state.aacfile);
            mp4state.m_aac_bytes_into_buffer = bread;
            mp4state.m_aac_bytes_consumed = 0;
            mp4state.m_file_offset = 0;
            mp4state.m_at_eof = (bread != 768*6) ? 1 : 0;

            if (init==0)
            {
                faacDecFrameInfo frameInfo;

                fill_buffer(&mp4state);

                if ((mp4state.m_aac_bytes_consumed = faacDecInit(mp4state.hDecoder,
                    mp4state.m_aac_buffer, mp4state.m_aac_bytes_into_buffer,
                    &mp4state.samplerate, &mp4state.channels)) < 0)
                {
                    show_error(module.hMainWindow, "Can't initialize decoder library.");
                    return -1;
                }
                advance_buffer(&mp4state, mp4state.m_aac_bytes_consumed);

                do {
                    memset(&frameInfo, 0, sizeof(faacDecFrameInfo));
                    fill_buffer(&mp4state);
                    faacDecDecode(mp4state.hDecoder, &frameInfo, mp4state.m_aac_buffer, mp4state.m_aac_bytes_into_buffer);
                } while (!frameInfo.samples && !frameInfo.error);

                if (frameInfo.error)
                {
                    show_error(module.hMainWindow, faacDecGetErrorMessage(frameInfo.error));
                    return -1;
                }

                mp4state.channels = frameInfo.channels;
                mp4state.samplerate = frameInfo.samplerate;
                mp4state.framesize = (frameInfo.channels != 0) ? frameInfo.samples/frameInfo.channels : 0;
                /*
                sbr = frameInfo.sbr;
                profile = frameInfo.object_type;
                header_type = frameInfo.header_type;
                */

                faacDecClose(mp4state.hDecoder);
                fseek(mp4state.aacfile, tagsize, SEEK_SET);
            }
        }

        mp4state.m_head = (struct seek_list*)malloc(sizeof(struct seek_list));
        mp4state.m_tail = mp4state.m_head;
        mp4state.m_tail->next = NULL;

        mp4state.m_header_type = 0;
        if ((mp4state.m_aac_buffer[0] == 0xFF) && ((mp4state.m_aac_buffer[1] & 0xF6) == 0xF0))
        {
            if (1) //(can_seek)
            {
                adts_parse(&mp4state, &bitrate, &length);
                fseek(mp4state.aacfile, tagsize, SEEK_SET);

                bread = fread(mp4state.m_aac_buffer, 1, 768*6, mp4state.aacfile);
                if (bread != 768*6)
                    mp4state.m_at_eof = 1;
                else
                    mp4state.m_at_eof = 0;
                mp4state.m_aac_bytes_into_buffer = bread;
                mp4state.m_aac_bytes_consumed = 0;

                mp4state.m_header_type = 1;
            }
        } else if (memcmp(mp4state.m_aac_buffer, "ADIF", 4) == 0) {
            int skip_size = (mp4state.m_aac_buffer[4] & 0x80) ? 9 : 0;
            bitrate = ((unsigned int)(mp4state.m_aac_buffer[4 + skip_size] & 0x0F)<<19) |
                ((unsigned int)mp4state.m_aac_buffer[5 + skip_size]<<11) |
                ((unsigned int)mp4state.m_aac_buffer[6 + skip_size]<<3) |
                ((unsigned int)mp4state.m_aac_buffer[7 + skip_size] & 0xE0);

            length = (double)file_length(mp4state.aacfile);
            if (length == -1)
            {
                //module.is_seekable = 0;
                length = 0;
            } else {
                length = ((double)length*8.)/((double)bitrate) + 0.5;
            }

            mp4state.m_header_type = 2;
        } else {
            length = (double)file_length(mp4state.aacfile);
            length = ((double)length*8.)/((double)bitrate*1000.) + 0.5;

            //module.is_seekable = 1;
        }

        mp4state.m_length = (int)(length*1000.);

        fill_buffer(&mp4state);
        if ((mp4state.m_aac_bytes_consumed = faacDecInit(mp4state.hDecoder,
            mp4state.m_aac_buffer, mp4state.m_aac_bytes_into_buffer,
            &mp4state.samplerate, &mp4state.channels)) < 0)
        {
            show_error(module.hMainWindow, "Can't initialize decoder library.");
            return -1;
        }
        advance_buffer(&mp4state, mp4state.m_aac_bytes_consumed);

        if (mp4state.m_header_type == 2)
            avg_bitrate = bitrate;
        else
            avg_bitrate = bitrate*1000;
    } else {
        mp4state.hDecoder = faacDecOpen();
        if (!mp4state.hDecoder)
        {
            show_error(module.hMainWindow, "Unable to open decoder library.");
            return -1;
        }

        config = faacDecGetCurrentConfiguration(mp4state.hDecoder);
        config->outputFormat = m_resolution + 1;
        config->downMatrix = m_downmix;
        faacDecSetConfiguration(mp4state.hDecoder, config);

⌨️ 快捷键说明

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