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

📄 ogmreader.cpp

📁 一个播放器 使用了evc 大家可以参考下 哦
💻 CPP
📖 第 1 页 / 共 2 页
字号:
 /***************************************************************************************
 *This program is free software; you can redistribute it and/or modify					*
 * it under the terms of the GNU General Public License as published by					*
 * the Free Software Foundation; either version 2 of the License, or					*
 * (at your option) any later version.													*
 *																						*
 * The GPL can be found at: http://www.gnu.org/copyleft/gpl.html						*
 *																						*
 *																						*	
 ****************************************************************************************
 * Authors:																			  *
 *          Marc Dukette                                                              *
 **************************************************************************************/



#include "OGMReader.h"
#include "OGGStream.h"
//#include "../ogglib/lib/vorbis_codec.h"
#include "../ogglib/lib/ogg.h"
#include "../ogglib/lib/ivorbiscodec.h"
#include "../ogglib/lib/misc.h"

int CacheSize;
videoinfo viddata;
ogminfo thisvid;
typedef int (CALLBACK* pInputMediaRead)(char *data, unsigned int size);
typedef int (CALLBACK* pInputMediaSeek)(int   size, unsigned int method);
typedef int (CALLBACK* pInputMediaOpen)(LPTSTR lpFilename, int mode, int type, int reserve, int maxsize);
typedef void (CALLBACK* pInputMediaClose)();

pInputMediaRead InputMediaRead;
pInputMediaSeek InputMediaSeek;
pInputMediaOpen InputMediaOpen;
pInputMediaClose InputMediaClose;
HMODULE hDLL;
	ogg_sync_state   oy; /* sync and verify incoming physical bitstream */
	ogg_page         og; /* one Ogg bitstream page.  Vorbis packets are inside */
	ogg_packet       op; /* one raw packet of data for decode */

	stream_state os[2]; 
	vorbis_info      vi; /* struct that stores all the static vorbis bitstream
		  settings */
	vorbis_comment   vc; /* struct that stores all the bitstream user comments */
	stream_header*	 sh[2];

	vorbis_dsp_state vd; /* central working state for the packet->PCM decoder */
	vorbis_block     vb; /* local working space for packet->PCM decode */

//	int  bytes;
	int gotaudio;
	int gotvideo;

	//int i;
	int stream_init=0;
	ogg_int32_t **pcm;
	int samples;
	int readpage=1;
	int readpagea=1;
	int fsize;
	__int64 lastpos;

	int leftover=0;
	//char* convbuffer[8000];
//	stream_header* hi;
	//unsigned char temp[32000];
	//ogg_int16_t convbuffer[4096]; /* take 8k out of the data segment, not the stack */
	int convsize=4096;
	vorbis_info      viv;
	vorbis_comment   vcv; 

/*
 * Reading Functions
 *
 */

/*
 * Tries to open an AVI
 * with and without an index
 */
int FillHeader(LPTSTR lpFilename,int CacheSize)
{
	int i=0;
	int stream=0;
	int bytes;
	char inbuff[4096];
	char *buffer;
	lastpos=0;
	gotvideo=0;
	ogg_sync_init(&oy); /* Now we can read pages */
	if (!wcsstr(lpFilename,_T("://")))
	{
		InputMediaSeek(fsize-100000,SEEK_SET);
		bytes=4096;
		InputMediaRead(inbuff, 4096);
		buffer=ogg_sync_buffer(&oy,bytes);
		memcpy(buffer,inbuff,bytes);
		ogg_sync_wrote(&oy,bytes);
		stream_state_init(&os[0],0);

		while(1)
		{

			int result=ogg_sync_pageout(&oy,&og);
			if(result<=0)
			{
				int bytes=InputMediaRead(inbuff, 4096);
				if (!bytes) break;
				buffer=ogg_sync_buffer(&oy,bytes);
				memcpy(buffer,inbuff,bytes);
				ogg_sync_wrote(&oy,bytes);
				continue;
			}
			/* Don't complain about missing or corrupt data yet.  We'll
			catch it at the packet output phase */
			if(result==1)
			{
				stream=ogg_page_serialno(&og);
				if (stream==0) ogg_stream_pagein(&os[stream].os,&og); 
				else continue;
			}
			while(1)
			{
				result=ogg_stream_packetout(&os[0].os,&op);
				if (result==0)
				{
					InputMediaRead(inbuff, 4096);
					buffer=ogg_sync_buffer(&oy,bytes);
					memcpy(buffer,inbuff,bytes);
					ogg_sync_wrote(&oy,bytes);
					break;
				}
				if (result<0)
				{ 
					/* no page? must not be vorbis */
					break;
				}
				if (op.granulepos!=-1)
				{
					viddata.video_frames=op.granulepos+1;
				}
			}		
		}
		InputMediaClose();
		fsize=InputMediaOpen(lpFilename,0,0,4000000,CacheSize);

	//	InputMediaSeek(0,SEEK_SET);
		stream=0;
		ogg_stream_clear(&os[0].os);
	}
	else
	{
		viddata.video_frames=250000;
	}
	if (viddata.video_frames==0)
		viddata.video_frames=250000;

	
	ogg_sync_init(&oy); /* Now we can read pages */
	gotaudio=false;
	gotvideo=false;
//	if(vidinfo.input != NULL) {
		bytes=4096;
		i=0;
		InputMediaRead(inbuff, 4096);
		buffer=ogg_sync_buffer(&oy,bytes);
		memcpy(buffer,inbuff,bytes);
		ogg_sync_wrote(&oy,bytes);
//		i=1;
	while(!gotaudio||(!gotvideo))
	{
			//convbuffer=(ogg_int16_t*) outmemory;
			/* submit a 4k block to libvorbis' Ogg layer */
			/* Get the first page. */
			int result=ogg_sync_pageout(&oy,&og);
			if (result==0)
			{
				InputMediaRead(inbuff, 4096);
				buffer=ogg_sync_buffer(&oy,bytes);
				memcpy(buffer,inbuff,bytes);
				ogg_sync_wrote(&oy,bytes);
				continue;
			}
			if (result<0)
			{
				return -1;
			}
			//ogg_stream_init(&os.os,ogg_page_serialno(&og));
			stream_state_init(&os[i],ogg_page_serialno(&og));
			stream=ogg_page_serialno(&og);

			if(ogg_stream_pagein(&os[stream].os,&og)<0)
			{ 
				/* error; stream version mismatch perhaps */
				return -1;
			}

			result=ogg_stream_packetout(&os[i].os,&op);
			if (result==0)
			{
				if (i==0)
					gotvideo=-1;
				if (i==1) 
					gotaudio=-1;
				InputMediaRead(inbuff, 4096);
				buffer=ogg_sync_buffer(&oy,bytes);
				memcpy(buffer,inbuff,bytes);
				ogg_sync_wrote(&oy,bytes);
				continue;
			}
			if (result<0)
			{ 
				/* no page? must not be vorbis */
				return -1;
			}


			/* extract the initial header from the first page and verify that the
			   Ogg bitstream is in fact Vorbis data */

			/* I handle the initial header first instead of just having the code
			   read all three Vorbis headers at once because reading the initial
			   header is an easy way to identify a Vorbis bitstream and it's
			   useful to see that functionality seperated out. */
			if (stream_header_in(&sh[i],&op)!=0)
			{
				vorbis_info_init(&vi);
				vorbis_comment_init(&vc);
				if(vorbis_synthesis_headerin(&vi,&vc,&op)<0)
				{ 
					/* error case; not a vorbis header */
					return -1;
				}
				gotaudio=1;
//				stream_state_init(&os[i],ogg_page_serialno(&og));
				//if(ogg_stream_pagein(&os[i].os,&og)<0)
				//{ 
				//	/* error; stream version mismatch perhaps */
				//	return -1;
				//}

			}
			else
			{
				if (strcmp(sh[i]->streamtype,MT_Video)) gotaudio=1;
				else gotvideo=1;
			}
//			else
			/* Get the serial number and set up the rest of decode. */
			/* serialno first; use it to set up a logical stream */

//			stream_init=1;
			i++;
	}

	if (gotvideo>0)
	{
		int i=0;

		while(!i)
		{
			while(!i)
			{
				int result=ogg_sync_pageout(&oy,&og);
				if(result==0)
				{
					InputMediaRead(inbuff, 4096);
					buffer=ogg_sync_buffer(&oy,bytes);
					memcpy(buffer,inbuff,bytes);
					ogg_sync_wrote(&oy,bytes);
					continue;
				}
				if(result==1)
				{
					stream=ogg_page_serialno(&og);
					ogg_stream_pagein(&os[stream].os,&og);
					while(!i)
					{
						result=ogg_stream_packetout(&os[0].os,&op);
						if(result==0)
						{
							InputMediaRead(inbuff, 4096);
							buffer=ogg_sync_buffer(&oy,bytes);
							memcpy(buffer,inbuff,bytes);
							ogg_sync_wrote(&oy,bytes);
							break;
						}
						if(result<0)
						{
							return -1;
						}
						vorbis_info_init(&viv);
						vorbis_comment_init(&vcv);
						viv.rate=1;
						if(vorbis_synthesis_headerin(&viv,&vcv,&op)<0)
						{ 
							return -1;
						}
						int c=0;
						int j=0;
#if (_WIN32_WCE >= 300)
						while ((c<vcv.comments)&&(_strnicmp(vcv.user_comments[c],"CHAPTER",7))) c++;
#else
						while ((c<vcv.comments)&&(strncmp(vcv.user_comments[c],"CHAPTER",7))) c++;
#endif
						c++;
#if (_WIN32_WCE >= 300)
						for (;c<vcv.comments&&(!_strnicmp(vcv.user_comments[c],"CHAPTER",7));c+=2)
#else
						for (;c<vcv.comments&&(!strncmp(vcv.user_comments[c],"CHAPTER",7));c+=2)
#endif
						{
							MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,vcv.user_comments[c]+14,-1,viddata.ChapterDisplay[j],vcv.comment_lengths[c]-14);
							//MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,vcv.user_comments[(c-1)]+10,-1,thisvid.ChapterDisplay[(c-1)/2]+vcv.comment_lengths[c]-14,8);
							j++;
						}
						viddata.ChapterCount=j;
						i++;
					}
				}
			}
		}	
	
	}

	if (gotaudio>0)
	{
		int i=0;

		while(i<2)
		{
			while(i<2)
			{
				int result=ogg_sync_pageout(&oy,&og);
				if(result==0)
				{
					InputMediaRead(inbuff, 4096);
					buffer=ogg_sync_buffer(&oy,bytes);
					memcpy(buffer,inbuff,bytes);
					ogg_sync_wrote(&oy,bytes);
					continue;
				}
				if(result==1)
				{
					stream=ogg_page_serialno(&og);
					ogg_stream_pagein(&os[stream].os,&og);
					while(i<2)
					{
						result=ogg_stream_packetout(&os[1].os,&op);
						if(result==0)
						{
							InputMediaRead(inbuff, 4096);
							buffer=ogg_sync_buffer(&oy,bytes);
							memcpy(buffer,inbuff,bytes);
							ogg_sync_wrote(&oy,bytes);
							break;
						}
						if(result<0)
						{
							return -1;
						}
						if (!sh[1])
						{
							if(vorbis_synthesis_headerin(&vi,&vc,&op)<0)
							{ 
								return -1;
							}
						}
						else
						{
							i++;
						}
						i++;
					}
				}
			}
		}	
	
	}
	
	
		stream_init=0;
		if (!sh[1]&&(gotaudio>0))
		{
			vorbis_synthesis_init(&vd,&vi); 
			vorbis_block_init(&vd,&vb);     
			convsize=4096/vi.channels;
		}
	return 1;
}

int AVIDecaps_Open(LPTSTR lpFilename, int Cache, int CacheSize,videoinfo** vidinfo)
{
	int ret=0;
	::CacheSize=CacheSize;

	if (wcsstr(lpFilename,_T("://")))
		hDLL=LoadLibrary(_T("InputMediaHTTP.dll"));
	else if (Cache)
		hDLL=LoadLibrary(_T("InputMediaCache.dll"));
	else
		hDLL=LoadLibrary(_T("InputMedia.dll"));

	if (!hDLL) return 0;
	leftover=0;
	InputMediaRead=(pInputMediaRead)GetProcAddress(hDLL,_T("InputMediaRead"));
	InputMediaSeek=(pInputMediaSeek)GetProcAddress(hDLL,_T("InputMediaSeek"));
	InputMediaOpen=(pInputMediaOpen)GetProcAddress(hDLL,_T("InputMediaOpen"));
	InputMediaClose=(pInputMediaClose)GetProcAddress(hDLL,_T("InputMediaClose"));
	if ((fsize=InputMediaOpen(lpFilename, 0, 0,-1,1000000))==0)
	{
		FreeLibrary(hDLL);
		hDLL=NULL;
		return 0;
	}
	thisvid.hIOMutex = CreateMutex (NULL, FALSE, NULL);

	viddata.video_pos  = 0;
	
	FillHeader(lpFilename,CacheSize);
	viddata.audio_bytes=0;
	//thisvid.video_frames=100000;
	//thisvid.audio_bytes=10584000;
	strncpy(viddata.compressor,sh[0]->subtype,4);
	viddata.width=sh[0]->video.width;
	viddata.height=sh[0]->video.height;
	viddata.fps=((double)10000000)/((double)sh[0]->time_unit);
	if (gotaudio>0)
	{
		if (!sh[1])
		{
			viddata.a_fmt=0;
			viddata.a_chans=vi.channels;
			viddata.a_rate=vi.rate;
			viddata.a_bits=vi.bitrate_nominal;
			viddata.audio_bytes=((double)((double)viddata.video_frames)/viddata.fps)*(double)viddata.a_rate*viddata.a_chans*2;
		}
		else
		{
			viddata.a_fmt=atoi(sh[1]->subtype);
			viddata.a_chans=sh[1]->samples_per_unit;
			viddata.a_rate=sh[1]->audio.channels;
			viddata.audio_bytes=((double)((double)viddata.video_frames)/viddata.fps)*(double)sh[1]->audio.avgbytespersec;

		}
	}
	*vidinfo=&::viddata;
	return 1;
}

bool didseek=false;
char oneframe[48000];
int oneframelen;
__int64  video_reftime;
__int64  audio_reftime;
/*
 * Reads the next video Frame into
 * buffer, return the actual size of
 * the frame.
 *
 */
#define VIDEO_STREAM 0
int AVIDecaps_NextVideoFrame(char *buffer, int drop)
{

	int stream=0;
	int eos=0;
	int bytes;
	if (!didseek&&(oneframelen))
	{
		memcpy(buffer,oneframe,oneframelen);
		bytes=oneframelen;
		oneframelen=0;
		return bytes;
	}
	WaitForSingleObject(thisvid.hIOMutex, INFINITE);
	while(!eos)
	{
		if (readpage)
		{
			int result=ogg_sync_pageout(&oy,&og);
			readpage=0;
			if(result==0) /* missing or corrupt data at this page position */
			{
				bytes=4096;
				char* buff=ogg_sync_buffer(&oy,bytes);
				bytes=InputMediaRead(buff, 4096);
					if (bytes==0)
					{
					    ReleaseMutex(thisvid.hIOMutex);
						return -1;
					}
				if (ogg_sync_wrote(&oy,bytes)==-1)
				{
					int error=1;
				}
				readpage=1;
				continue;
			}
			else if (result<0)
			{
				readpage=1;
				continue;
			}
			stream=ogg_page_serialno(&og);
			ogg_stream_pagein(&os[stream].os,&og); 
		}							 
		if (stream==VIDEO_STREAM)
		{
			int result;
			unsigned char* temp;

⌨️ 快捷键说明

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