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

📄 libovd.cpp

📁 PPC流行的播放软件gsplayer源码2.24版
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			int result = ogg_sync_pageout(&handle->oy, &handle->og);
			if (result == 0) 
				return FALSE; // need more data
			if (result == 1) {
				ogg_stream_pagein(&handle->os, &handle->og);
				while(handle->init < 2){
					result = ogg_stream_packetout(&handle->os, &handle->op);
					if (result == 0)
						return 0; // need more data
					if (result < 0) {
						handle->init = -1; // fatal error
						return -1;
					}

					vorbis_synthesis_headerin(&handle->vi, &handle->vc, &handle->op);
					handle->init++;
				}
			}
			else if (result = -1) return -1;
		}
		
		vorbis_synthesis_init(&handle->vd, &handle->vi);
		vorbis_block_init(&handle->vd, &handle->vb);
		return 1;
	}
	return 1;
}

BOOL ovd_parse_stream(ovd_stream_buf* buf)
{
	ovd_handle* handle = (ovd_handle*)buf->handle;

	ogg_sync_wrote(&handle->oy, buf->len);
	if (ogg_sync_pageout(&handle->oy, &handle->og) != 1)
		goto fail;

	ogg_stream_init(&handle->os, ogg_page_serialno(&handle->og));
	vorbis_info_init(&handle->vi);
    vorbis_comment_init(&handle->vc);
	if (ogg_stream_pagein(&handle->os, &handle->og) < 0)
		goto fail;

	if (ogg_stream_packetout(&handle->os,&handle->op) != 1)
		goto fail;

	if (vorbis_synthesis_headerin(&handle->vi, &handle->vc, &handle->op) < 0)
		goto fail;

	handle->init = 0;
	handle->eof = 0;
	ovd_header_init(handle);

	buf->buf = ogg_sync_buffer(&handle->oy, OVD_STREAM_BUF_LEN);
	buf->len = OVD_STREAM_BUF_LEN;
	return TRUE;
fail:
	ogg_sync_init(&handle->oy);
	buf->buf = ogg_sync_buffer(&handle->oy, OVD_STREAM_BUF_LEN);
	buf->len = OVD_STREAM_BUF_LEN;
	return FALSE;
}

BOOL ovd_get_stream_info(ovd_stream_buf* buf, ovd_info* info)
{
	ovd_handle* handle = (ovd_handle*)buf->handle;

	info->version = handle->vi.version;
	info->rate = handle->vi.rate;
	info->channels = handle->vi.channels;
	info->bitrate_lower = handle->vi.bitrate_lower;
	info->bitrate_nominal = handle->vi.bitrate_nominal;
	info->bitrate_upper = handle->vi.bitrate_upper;
	info->bitrate_window = handle->vi.bitrate_window;

	return TRUE;
}

BOOL ovd_get_stream_comment(ovd_stream_buf* buf, ovd_comment* comment)
{
	ovd_handle* handle = (ovd_handle*)buf->handle;
	
	memset(comment, 0, sizeof(ovd_comment));
	for (int i = 0; i < handle->vc.comments; i++)
	{
		LPTSTR psz = NULL;
		char* s = strchr(handle->vc.user_comments[i], '=');
		if (s)
		{
			*s = NULL;
			ovd_strupr(handle->vc.user_comments[i]);
			if (strcmp(handle->vc.user_comments[i], OVD_COMMENT_DATE) == 0)
				psz = comment->szDate;
			else if (strcmp(handle->vc.user_comments[i], OVD_COMMENT_TRACKNUM) == 0)
				psz = comment->szTrackNum;
			else if (strcmp(handle->vc.user_comments[i], OVD_COMMENT_TITLE) == 0)
				psz = comment->szTitle;
			else if (strcmp(handle->vc.user_comments[i], OVD_COMMENT_ARTIST) == 0)
				psz = comment->szArtist;
			else if (strcmp(handle->vc.user_comments[i], OVD_COMMENT_ALBUM) == 0)
				psz = comment->szAlbum;
			else if (strcmp(handle->vc.user_comments[i], OVD_COMMENT_GENRE) == 0)
				psz = comment->szGenre;
			else if (strcmp(handle->vc.user_comments[i], OVD_COMMENT_COMMENT) == 0)
				psz = comment->szComment;

			if (psz)
			{
#ifdef _UNICODE
				UTF8toUCS2(s + 1, psz, OVD_COMMENT_LEN);
#else
				WCHAR sz[OVD_COMMENT_LEN];
				UTF8toUCS2(s + 1, sz, OVD_COMMENT_LEN);
				WideCharToMultiByte(CP_ACP, 0, sz, -1, psz, OVD_COMMENT_LEN, 0, 0);
#endif	
			}
		}
	}
	return TRUE;
}

BOOL ovd_reparse_stream(ovd_stream_buf* buf)
{
	ovd_handle* handle = (ovd_handle*)buf->handle;

	if (buf->len) {
		ogg_sync_wrote(&handle->oy, buf->len);
		int result = ogg_sync_pageout(&handle->oy, &handle->og);
		if (result == 0) {
			buf->len = OVD_STREAM_BUF_LEN;
			return TRUE;
		}
		else if (result < 0)
			return FALSE;
	}

	ogg_stream_init(&handle->os, ogg_page_serialno(&handle->og));
	vorbis_info_init(&handle->vi);
    vorbis_comment_init(&handle->vc);
	if (ogg_stream_pagein(&handle->os, &handle->og) < 0)
		return FALSE;

	if (ogg_stream_packetout(&handle->os,&handle->op) != 1)
		return FALSE;

	if (vorbis_synthesis_headerin(&handle->vi, &handle->vc, &handle->op) < 0)
		return FALSE;

	handle->init = 0;
	handle->eof = 0;
	ovd_header_init(handle);

	buf->buf = ogg_sync_buffer(&handle->oy, OVD_STREAM_BUF_LEN);
	buf->len = OVD_STREAM_BUF_LEN;
	return TRUE;
}

int ovd_decode_stream(ovd_stream_buf* buf, LPBYTE pcmbuf, int pcmbuf_len, int* pcmout)
{
	int result, samples, ret = OVD_OK;
	ovd_handle* handle = (ovd_handle*)buf->handle;
	*pcmout = 0;

	if (handle->samples) {
		if (pcmbuf_len < handle->samples * handle->vi.channels * 2) {
			buf->len = 0;
			return OVD_NEED_MORE_OUTPUT;
		}

		for (int i = 0; i < handle->vi.channels; i++) {
			ogg_int32_t* src = handle->pcm[i];
			short* dest = ((short *)(pcmbuf + *pcmout)) + i;
			for (int j = 0; j < handle->samples; j++) {
				*dest = CLIP_TO_15(src[j] >> 9);
				dest += handle->vi.channels;
			}
		}

		vorbis_synthesis_read(&handle->vd, handle->samples);
		*pcmout += handle->samples * handle->vi.channels * 2;
		pcmbuf_len -= handle->samples * handle->vi.channels * 2;
		handle->samples = 0;
	}

	if (handle->eof) {
		if (!ovd_reparse_stream(buf))
			return OVD_FATAL_ERR;
		goto done;
	}

	if (buf->len) {
		ogg_sync_wrote(&handle->oy, buf->len);
		buf->len = OVD_STREAM_BUF_LEN;

		result = ovd_header_init(handle);
		if (result != 1) {
			if (result < 0)
				ret = OVD_FATAL_ERR;
			goto done;
		}

		result = ogg_sync_pageout(&handle->oy, &handle->og);
		if (result == 0)
			goto done; // need more
		if (result < 0) {
			ret = OVD_FATAL_ERR;
			handle->init = -1;
			goto done;
		}

		ogg_stream_pagein(&handle->os, &handle->og);

		while (1) {
			result = ogg_stream_packetout(&handle->os, &handle->op);

			if (result == 0)
				break;
			if (result > 0) {
				if (vorbis_synthesis(&handle->vb, &handle->op) == 0)
					vorbis_synthesis_blockin(&handle->vd, &handle->vb);

				vorbis_synthesis_headerin(&handle->vi, &handle->vc, &handle->op);

				while ((samples = vorbis_synthesis_pcmout(&handle->vd, &handle->pcm)) > 0) {
					if (pcmbuf_len < samples * handle->vi.channels * 2) {
						handle->samples = samples;
						buf->len = 0;
						return OVD_NEED_MORE_OUTPUT;
					}

					for (int i = 0; i < handle->vi.channels; i++) {
						ogg_int32_t* src = handle->pcm[i];
						short* dest = ((short *)(pcmbuf + *pcmout)) + i;
						for (int j = 0; j < samples; j++) {
							*dest = CLIP_TO_15(src[j] >> 9);
							dest += handle->vi.channels;
						}
					}

					vorbis_synthesis_read(&handle->vd, samples);
					*pcmout += samples * handle->vi.channels * 2;
					pcmbuf_len -= samples * handle->vi.channels * 2;
					handle->samples = 0;
				}
			}
		}
	}
	else {
		result = 1;
		buf->len = OVD_STREAM_BUF_LEN;
		while (1) {
			if (result > 0) {
				while ((samples = vorbis_synthesis_pcmout(&handle->vd, &handle->pcm)) > 0) {
					if (pcmbuf_len < samples * handle->vi.channels * 2) {
						handle->samples = samples;
						buf->len = 0;
						return OVD_NEED_MORE_OUTPUT;
					}

					for (int i = 0; i < handle->vi.channels; i++) {
						ogg_int32_t* src = handle->pcm[i];
						short* dest = ((short *)(pcmbuf + *pcmout)) + i;
						for (int j = 0; j < samples; j++) {
							*dest = CLIP_TO_15(src[j] >> 9);
							dest += handle->vi.channels;
						}
					}

					vorbis_synthesis_read(&handle->vd, samples);
					*pcmout += samples * handle->vi.channels * 2;
					pcmbuf_len -= samples * handle->vi.channels * 2;
					handle->samples = 0;
				}
			}

			result = ogg_stream_packetout(&handle->os, &handle->op);
			if (result == 0)
				break;
			if (result > 0) {
				if (vorbis_synthesis(&handle->vb, &handle->op) == 0)
					vorbis_synthesis_blockin(&handle->vd, &handle->vb);

				vorbis_synthesis_headerin(&handle->vi, &handle->vc, &handle->op);
			}
		}
	}

	if (ogg_page_eos(&handle->og)) {
		handle->samples = 0;
		handle->init = 0;
		ogg_stream_clear(&handle->os);
		vorbis_block_clear(&handle->vb);
		vorbis_dsp_clear(&handle->vd);
		vorbis_comment_clear(&handle->vc);
		vorbis_info_clear(&handle->vi);  /* must be called last */

		handle->eof = 1;
		buf->len = OVD_STREAM_BUF_LEN;
	}

done:
	if (buf->len) buf->buf = ogg_sync_buffer(&handle->oy, OVD_STREAM_BUF_LEN);
	return ret;
}

void ovd_uninit_stream(ovd_stream_buf* buf)
{
	ovd_handle* handle = (ovd_handle*)buf->handle;	

	vorbis_block_clear(&handle->vb);
    vorbis_dsp_clear(&handle->vd);
	vorbis_comment_clear(&handle->vc);
    vorbis_info_clear(&handle->vi);
	ogg_sync_clear(&handle->oy);
	delete handle;
	delete buf;
}

⌨️ 快捷键说明

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