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

📄 in_mp4.cpp

📁 WINCE mp4 format source
💻 CPP
📖 第 1 页 / 共 3 页
字号:
            }
        }
        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[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;
    }
}

int mp4open(TCHAR *fn)
{
    unsigned char *buffer;
    int buffer_size;
    NeAACDecConfigurationPtr config;
    unsigned char header[8];
    FILE *hMP4File;

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

    hMP4File = _tfopen(mp4state.filename, _T("rb"));
    if (!hMP4File)
    {
        return -1;
    }
    fread(header, 1, 8, hMP4File);
    fclose(hMP4File);

    if (header[4] != 'f' || header[5] != 't' || header[6] != 'y' || header[7] != 'p')
        return -1;

    mp4state.hDecoder = NeAACDecOpen();
    if (!mp4state.hDecoder)
    {
        return -1;
    }

    config = NeAACDecGetCurrentConfiguration(mp4state.hDecoder);
    config->outputFormat = FAAD_FMT_16BIT;
    config->downMatrix = 1;
    NeAACDecSetConfiguration(mp4state.hDecoder, config);

    mp4state.mp4File = _tfopen(mp4state.filename, _T("rb"));
    mp4state.mp4cb.read = read_callback;
    mp4state.mp4cb.seek = seek_callback;
    mp4state.mp4cb.user_data = mp4state.mp4File;


    mp4state.mp4file = mp4ff_open_read(&mp4state.mp4cb);
    if (!mp4state.mp4file)
    {
        close();
        return -1;
    }

    if ((mp4state.mp4track = GetAACTrack(mp4state.mp4file)) < 0)
    {
        close();
        return -1;
    }

    buffer = NULL;
    buffer_size = 0;
    mp4ff_get_decoder_config(mp4state.mp4file, mp4state.mp4track,
        &buffer, (unsigned int*)&buffer_size);
    if (!buffer)
    {
        close();
        return -1;
    }

    if(NeAACDecInit2(mp4state.hDecoder, buffer, buffer_size,
        (unsigned long*)&mp4state.samplerate, &mp4state.channels) < 0)
    {
        /* If some error initializing occured, skip the file */
        if (buffer) free (buffer);
		close();
        return -1;
    }

    /* for gapless decoding */
    {
        mp4AudioSpecificConfig mp4ASC;

        mp4state.timescale = mp4ff_time_scale(mp4state.mp4file, mp4state.mp4track);
        mp4state.framesize = 1024;
        mp4state.useAacLength = 0;

        if (buffer)
        {
            if (NeAACDecAudioSpecificConfig(buffer, buffer_size, &mp4ASC) >= 0)
            {
                if (mp4ASC.frameLengthFlag == 1) mp4state.framesize = 960;
                if (mp4ASC.sbr_present_flag == 1) mp4state.framesize *= 2;
            }
        }
    }

    free(buffer);

    mp4state.avg_bitrate = mp4ff_get_avg_bitrate(mp4state.mp4file, mp4state.mp4track);

    mp4state.numSamples = mp4ff_num_samples(mp4state.mp4file, mp4state.mp4track);
    mp4state.sampleId = 0;

    {
        double timescale_div = 1.0 / (double)mp4ff_time_scale(mp4state.mp4file, mp4state.mp4track);
        int64_t duration = mp4ff_get_track_duration_use_offsets(mp4state.mp4file, mp4state.mp4track);
        if (duration == -1)
        {
            mp4state.m_length = 0;
        } else {
            mp4state.m_length = (int)((double)duration * timescale_div * 1000.0);
        }
    }

    mp4state.is_seekable = 1;

    if (mp4state.channels == 0)
    {
        close();
        return -1;
    }

    if (/*m_downmix && */(mp4state.channels == 5 || mp4state.channels == 6))
        mp4state.channels = 2;

    mp4state.paused        =  0;
    mp4state.decode_pos_ms =  0;
    mp4state.seek_needed   = -1;

	mp4state.filetype = 0;
	NeAACDecPostSeekReset(mp4state.hDecoder, -1);
	return 0;
}

int aacopen(TCHAR *fn)
{
    unsigned char *buffer;
    int buffer_size;
    NeAACDecConfigurationPtr config;
    unsigned char header[8];
    FILE *hMP4File;
	int tmp = 0, init;
    int bread = 0;
    double length = 0.;
    __int64 bitrate = 128;

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

    mp4state.is_seekable = 1;

    if (!(mp4state.aacfile = _tfopen(mp4state.filename, _T("rb"))))
    {
		close();   
        return -1;
    }

    mp4state.m_tagsize = skip_id3v2_tag();
	if (mp4state.m_tagsize<0)
	{
		close();
		return 0;
	}

    if (!(mp4state.m_aac_buffer = (unsigned char*)malloc(768*6)))
    {
		close();
        return -1;
    }

    for (init=0; init<2; init++)
    {
        mp4state.hDecoder = NeAACDecOpen();
        if (!mp4state.hDecoder)
        {
			close();
            return -1;
        }

        config = NeAACDecGetCurrentConfiguration(mp4state.hDecoder);
        config->outputFormat = FAAD_FMT_16BIT;
        config->downMatrix = 1;
        NeAACDecSetConfiguration(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)
        {
            NeAACDecFrameInfo frameInfo;

            fill_buffer(&mp4state);

            if ((mp4state.m_aac_bytes_consumed = NeAACDecInit(mp4state.hDecoder,
                mp4state.m_aac_buffer, mp4state.m_aac_bytes_into_buffer,
                (unsigned long*)&mp4state.samplerate, &mp4state.channels)) < 0)
            {
				close();
                return -1;
            }
            advance_buffer(&mp4state, mp4state.m_aac_bytes_consumed);

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

            if (frameInfo.error)
            {
				close();
                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;
            */

            NeAACDecClose(mp4state.hDecoder);
            fseek(mp4state.aacfile, mp4state.m_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, mp4state.m_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)
        {
            mp4state.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;

        mp4state.is_seekable = 1;
    }

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

    fill_buffer(&mp4state);
    if ((mp4state.m_aac_bytes_consumed = NeAACDecInit(mp4state.hDecoder,
        mp4state.m_aac_buffer, mp4state.m_aac_bytes_into_buffer,
        (unsigned long*)&mp4state.samplerate, &mp4state.channels)) < 0)
    {
		close();
        return -1;
    }
    advance_buffer(&mp4state, mp4state.m_aac_bytes_consumed);

    if (mp4state.m_header_type == 2)
        mp4state.avg_bitrate = bitrate;
    else
        mp4state.avg_bitrate = bitrate*1000;

	if (/*m_downmix && */(mp4state.channels == 5 || mp4state.channels == 6))
        mp4state.channels = 2;

	mp4state.filetype = 1;
	NeAACDecPostSeekReset(mp4state.hDecoder, -1);
	return 0;
}

int open(TCHAR *fn)
{
	if (!mp4open(fn))
		return 0;
	if (!aacopen(fn))
		return 0;

	return -1;
}

void close()
{
	struct seek_list *target = mp4state.m_head;
	
	if (mp4state.m_aac_buffer)
        free(mp4state.m_aac_buffer);

    while (target)
    {
        struct seek_list *tmp = target;
        target = target->next;
        if (tmp) free(tmp);
    }
	if (mp4state.hDecoder) {
		NeAACDecClose(mp4state.hDecoder);
	}

	if (mp4state.aacfile) {
		fclose(mp4state.aacfile);
	}

	if (mp4state.mp4file) {
		mp4ff_close(mp4state.mp4file);
	}
	if (mp4state.mp4File) {
		fclose(mp4state.mp4File);
	}

	flushleftbuf();

    memset(&mp4state, 0, sizeof(state));
}

int mp4setoutputtime(int time_in_ms)
{
	int64_t duration;
	int32_t skip_samples = 0;

	if (!mp4state.mp4File)
		return -1;

	if (!mp4state.is_seekable)
		return -1;

    duration = (int64_t)(time_in_ms/1000.0 * mp4state.samplerate + 0.5);
	mp4state.sampleId = mp4ff_find_sample_use_offsets(mp4state.mp4file, mp4state.mp4track, duration, &skip_samples);
	mp4state.decode_pos_ms = time_in_ms;

	flushleftbuf();

	return time_in_ms;
}

int aacsetoutputtime(int time_in_ms)
{
	double ms;

	if (!mp4state.aacfile)
		return -1;

    ms = (double)time_in_ms/1000;
    if (aac_seek(&mp4state, ms)!=0)
    {
        mp4state.cur_pos_sec = ms;
        mp4state.decode_pos_ms = time_in_ms;

		flushleftbuf();

		return time_in_ms;
    }
	return -1;
}

int setoutputtime(int time_in_ms)
{
	if (mp4state.filetype)
		return aacsetoutputtime(time_in_ms);
	else
		return mp4setoutputtime(time_in_ms);
}

int start()
{
	if (!mp4state.mp4File && !mp4state.aacfile)
		return 0;

	mp4state.last_frame = 0;
    mp4state.initial = 1;

	return 1;
}

void stop()
{
	flushleftbuf();
}

int mp4decode(uint8_t *outbuf, uint32_t outbuflen, uint32_t *outlen)
{
	unsigned char *buffer = NULL;
    int buffer_size = 0;
	NeAACDecFrameInfo frameInfo = {0};
	void *sample_buffer;
	unsigned int sample_count;
    unsigned int delay = 0;
	char *buf;

	*outlen = 0;

	if (!mp4state.mp4File)
		return PLUGIN_RET_ERROR;

	if (leftoutbuf && leftoutbuflen) {
		if (outbuflen < leftoutbuflen) {
			memcpy(outbuf, leftoutbuf, outbuflen);
			*outlen = outbuflen;

			memmove(leftoutbuf, leftoutbuf + outbuflen, leftoutbuflen - outbuflen);
			leftoutbuflen -= outbuflen;
			return PLUGIN_RET_SUCCESS;
		}
		else {
			memcpy(outbuf, leftoutbuf, leftoutbuflen);
			outbuf += leftoutbuflen;
			*outlen += leftoutbuflen;
			
			free(leftoutbuf);
			leftoutbuflen = 0;
		}
	}

	while (outbuflen - *outlen && !mp4state.last_frame) {
		buffer = NULL;
		buffer_size = 0;

		long dur = mp4ff_get_sample_duration(mp4state.mp4file, mp4state.mp4track, mp4state.sampleId);
		if (dur == -1)
			break;
		int rc = mp4ff_read_sample(mp4state.mp4file, mp4state.mp4track, mp4state.sampleId++, &buffer,  (unsigned int*)&buffer_size);
		if (rc == 0 || buffer == NULL) {
			mp4state.last_frame = 1;
			sample_buffer = NULL;
			frameInfo.samples = 0;
		} 
		else {
			sample_buffer = NeAACDecDecode(mp4state.hDecoder, &frameInfo, buffer, buffer_size);
		}
	
		if (mp4state.sampleId >= mp4state.numSamples)
			mp4state.last_frame = 1;

		if (buffer) {
			free(buffer);
		}
		if (frameInfo.error > 0) {
			return PLUGIN_RET_ERROR;
		} 
		if (frameInfo.samplerate != mp4state.samplerate) {
			return PLUGIN_RET_ERROR;

⌨️ 快捷键说明

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