Exemplo n.º 1
0
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));
	handle->os = ogg_stream_create(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_bufferin(handle->oy, OVD_STREAM_BUF_LEN);
	buf->len = OVD_STREAM_BUF_LEN;
	return TRUE;
fail:
//	ogg_sync_init(&handle->oy);
	handle->oy = ogg_sync_create();
	buf->buf = ogg_sync_bufferin(handle->oy, OVD_STREAM_BUF_LEN);
	buf->len = OVD_STREAM_BUF_LEN;
	return FALSE;
}
Exemplo n.º 2
0
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));
	handle->os = ogg_stream_create(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_bufferin(handle->oy, OVD_STREAM_BUF_LEN);
	buf->len = OVD_STREAM_BUF_LEN;
	return TRUE;
}
Exemplo n.º 3
0
Arquivo: ogg.c Projeto: Erikhht/TCPMP
static int FillQueue(ogg* p,format_reader* Reader)
{
	for (;;)
	{
		int Bytes = ogg_sync_pageseek(p->OggSync,&p->OggPage);

		if (Bytes == 0) // need more data
		{
			int Result;
			format_buffer* Buffer;

			if (!Reader->BufferAvailable && (!p->Format.SyncMode || p->Format.SyncRead<=0))
				return ERR_NEED_MORE_DATA;

			Buffer = Format_BufferRemove(Reader);
			if (!Buffer && p->Format.SyncMode && p->Format.SyncRead>0 && Format_ReadBuffer(Reader,0))
				Buffer = Format_BufferRemove(Reader);

			Result = AddBuffer(p,Buffer);
			if (Result != ERR_NONE)
				return Result;
		}
		else		
		if (Bytes < 0)
			Reader->FilePos -= Bytes;
		else
		if (Bytes > 0)
		{
			int StreamNo;
			oggstream* s;
			int Id;
			
			Reader->FilePos += Bytes;

			Id = ogg_page_serialno(&p->OggPage);
		
			DEBUG_MSG4(DEBUG_FORMAT,T("OGG Page id:%d size:%d gran:%d filepos:%d"),Id,p->OggPage.body_len,(int)ogg_page_granulepos(&p->OggPage),Reader->FilePos - Bytes);

			for (StreamNo=0;StreamNo<p->Format.StreamCount;++StreamNo)
				if (p->Format.Streams[StreamNo]->Id == Id)
					break;

			if (StreamNo==p->Format.StreamCount)
			{
				// check for restarted audio http streaming (comments changed)
				if (p->Format.StreamCount==1 && 
					p->Format.Streams[0]->Format.Type == PACKET_AUDIO &&
					p->Format.Streams[0]->LastTime>0)
				{
					StreamNo = 0;
					s = (oggstream*) p->Format.Streams[0];
					if (s->Vorbis)
					{
						// vorbis decoder have to release s->Info
						s->Stream.Format.Extra = NULL;
						s->Stream.Format.ExtraLength = 0;
						ConnectionUpdate((node*)&p->Format,FORMAT_STREAM+0,s->Stream.Pin.Node,s->Stream.Pin.No);
					}
					FreeStream(p,s);
				}
				else
				{
					s = (oggstream*) Format_AddStream(&p->Format,sizeof(oggstream));
					if (!s)	continue;
				}

				// init stream
				s->Stream.Id = Id;
				s->OggStream = ogg_stream_create(Id);
				s->NeedMorePage = 1;
				s->MediaTime = 0;
				s->Invalid = 0;
				s->Vorbis = 0;
				s->Native = 0;
				s->PacketNo = 0;

				vorbis_info_init(&s->Info);
				vorbis_comment_init(&s->Comment);
			}

			s = (oggstream*) p->Format.Streams[StreamNo];

			if (s->Invalid) // drop invalid streams
				continue;

			if (s->PacketNo>=3)
			{
				if (!s->Stream.Pin.Node) // drop unused streams
					continue;

				if (p->Format.InSeek)
				{
					// reftime needed for SeekByPacket
					if ((s->MediaTime = ogg_page_granulepos(&p->OggPage)) != -1)
					{
						// no need for GlobalOffset here
						s->Stream.LastTime = (tick_t)(s->MediaTime * s->MediaRateDen / s->MediaRateNum);
						if (s->Stream.Format.Type == PACKET_AUDIO)
						{
							s->Stream.LastTime += p->Format.AVOffset;
							if (s->Stream.LastTime < 0)
								s->Stream.LastTime = 0;
						}
					}
				}
			}

			// add page to stream
			if (ogg_stream_pagein(s->OggStream,&p->OggPage) >= 0)
			{
				if (s->PacketNo<3) // header packet needed?
				{
					int i = ogg_stream_packetout(s->OggStream,&s->OggPacket);
					if (i == 0) // stream needs more pages
						continue;
					
					if (++s->PacketNo==1) // first packet?
					{
						ogg_reference* Ref;
						const void* Data;
						int Length;

						if (i < 0)
						{
							// first header packet is a must have
							s->Invalid = 1;
							continue;
						}

						if (p->Format.UseBufferBlock)
						{
							for (Length=0,Ref=s->OggPacket.packet;Ref;Ref=Ref->next)
								Length += Ref->length;

							if (s->Stream.BufferBlockLength<Length && !Format_AllocBufferBlock(&p->Format,&s->Stream,Length))
							{
								Length = 0;
								Data = NULL;
							}
							else
							{
								for (Length=0,Ref=s->OggPacket.packet;Ref;Ref=Ref->next)
								{
									WriteBlock(&s->Stream.BufferBlock,Length,Ref->buffer->data + Ref->begin,Ref->length);
									Length += Ref->length;
								}
								Data = s->Stream.BufferBlock.Ptr;
							}
						}
						else
						{
							BufferDrop(&s->Stream.BufferMem);
							for (Ref=s->OggPacket.packet;Ref;Ref=Ref->next)
								BufferWrite(&s->Stream.BufferMem,Ref->buffer->data + Ref->begin, Ref->length, 16384);
							Data = s->Stream.BufferMem.Data;
							Length = s->Stream.BufferMem.WritePos;
						}

						if (OGMHeader(p,s,(char*)Data,Length) || SpeexHeader(p,s,(char*)Data,Length))
						{
							PacketFormatDefault(&s->Stream.Format);
							s->PacketNo = 3; // no more headers
						}
						else
						if (!VorbisHeader(p,s))
						{
							s->Invalid = 1;
							continue;
						}

						while (s->MediaRateNum > (1<<30))
						{
							s->MediaRateDen >>= 1;
							s->MediaRateNum >>= 1;
						}

						Format_PrepairStream(&p->Format,&s->Stream);
						continue;
					}
					else
					{
						assert(s->Vorbis);

						// error in second or third header packet will not cause fatal error
						vorbis_synthesis_headerin(&s->Info,&s->Comment,&s->OggPacket); 

						if (s->PacketNo == 3)
						{
							// got the three header packets: reinit codec with vorbis_info
							s->Stream.Format.Extra = &s->Info;
							s->Stream.Format.ExtraLength = -1;
							ConnectionUpdate((node*)&p->Format,FORMAT_STREAM+StreamNo,s->Stream.Pin.Node,s->Stream.Pin.No);
							SendComments(s);
						}
						continue;
					}
				}