Ejemplo n.º 1
0
static sf_count_t
vorbis_length_aux (SF_PRIVATE * psf)
{	ogg_sync_state osync ;
	ogg_page page ;
	sf_count_t len = 0 ;
	stream_set *processors ;

	processors = create_stream_set () ;
	if (processors == NULL)
		return 0 ;	// out of memory?

	ogg_sync_init (&osync) ;

	while (vorbis_length_get_next_page (psf, &osync, &page))
	{	stream_processor *p = find_stream_processor (processors, &page) ;

		if (!p)
		{	len = 0 ;
			break ;
		} ;

		if (p->isillegal && !p->shownillegal)
		{	p->shownillegal = 1 ;
			/* If it's a new stream, we want to continue processing this page
			** anyway to suppress additional spurious errors
			*/
			if (!p->isnew) continue ;
		} ;

		if (!p->isillegal)
		{	ogg_packet packet ;
			int header = 0 ;

			ogg_stream_pagein (&p->ostream, &page) ;
			if (p->doneheaders < 3)
				header = 1 ;

			while (ogg_stream_packetout (&p->ostream, &packet) > 0)
			{	if (p->doneheaders < 3)
				{	if (vorbis_synthesis_headerin (&p->vinfo, &p->vcomment, &packet) < 0)
						continue ;
					p->doneheaders ++ ;
				} ;
			} ;
			if (!header)
			{	sf_count_t gp = ogg_page_granulepos (&page) ;
				if (gp > 0) p->lastgranulepos = gp ;
			} ;
			if (p->end)
			{	vorbis_end (p, &len) ;
				p->isillegal = 1 ;
			} ;
		} ;
	} ;

	ogg_sync_clear (&osync) ;
	free_stream_set (processors, &len) ;

	return len ;
} /* vorbis_length_aux */
Ejemplo n.º 2
0
static void
free_stream_set (stream_set *set, sf_count_t * len)
{	int i ;

	for (i = 0 ; i < set->used ; i++)
	{	if (!set->streams [i].end)
			vorbis_end (&set->streams [i], len) ;
		ogg_stream_clear (&set->streams [i].ostream) ;
	} ;

	free (set->streams) ;
	free (set) ;
} /* free_stream_set */
Ejemplo n.º 3
0
void rip_ogg_process_chunk(RIP_MANAGER_INFO * rmi, LIST * page_list, const char *buf, u_long size, TRACK_INFO * ti)
{
	OGG_PAGE_LIST *ol;
	int header;
	int ret;
	char *buffer;
	//    static ogg_int64_t written = 0;
	//    static unsigned int written = 0;
	//    static int ogg_page2 = 0;

	INIT_LIST_HEAD(page_list);

	debug_printf("-- rip_ogg_process_chunk (%d)\n", size);

	buffer = ogg_sync_buffer(&rmi->ogg_sync, size);
	memcpy(buffer, buf, size);
	ogg_sync_wrote(&rmi->ogg_sync, size);

	do {
		switch (ret = ogg_sync_pageout(&rmi->ogg_sync, &rmi->ogg_pg)) {
		case -1:
			/* -1 if we were not properly synced and had to skip some bytes */
			debug_printf("Hole in ogg, skipping bytes\n");
			break;
		case 0:
			/* 0 if we need more data to verify a page */
			debug_printf("Ogg needs more data\n");
			break;
		case 1:
			/* 1 if we have a page */
			debug_printf("Found an ogg page!\n");

			/* Do stuff needed for decoding vorbis */
			if (ogg_page_bos(&rmi->ogg_pg)) {
				int rc;
				ogg_packet packet;
				ogg_stream_init(&rmi->stream.os, ogg_page_serialno(&rmi->ogg_pg));
				ogg_stream_pagein(&rmi->stream.os, &rmi->ogg_pg);
				rc = ogg_stream_packetout(&rmi->stream.os, &packet);
				if (rc <= 0) {
					printf("Warning: Invalid header page, no packet found\n");
					// null_start (&rmi->stream);
					exit(1);
				} else if (packet.bytes >= 7 && memcmp(packet.packet, "\001vorbis", 7) == 0) {
					vorbis_start(&rmi->stream);
				}
			}
			header = vorbis_process(rmi, &rmi->stream, &rmi->ogg_pg, ti);
			if (ogg_page_eos(&rmi->ogg_pg)) {
				vorbis_end(&rmi->stream);
			}

			/* Create ogg page boundary struct */
			ol = (OGG_PAGE_LIST *) malloc(sizeof(OGG_PAGE_LIST));
			if (!ol) {
				printf("Malloc error\n");
				exit(1);
			}
			ol->m_page_len = rmi->ogg_pg.header_len + rmi->ogg_pg.body_len;
			ol->m_page_flags = 0;

			/* *****************************************************
			   Create header buffer for relay stream. A pointer to the 
			   header buffer will attached to all pages after page 2.
			   If a relay connects in the middle of a song, we send 
			   the header to the relay. Finally, the memory for the 
			   header is freed when the last page of the song is 
			   ejected from the cbuf. 
			   ** ***************************************************** */
			if (ogg_page_bos(&rmi->ogg_pg)) {
				/* First page in song */
				ol->m_page_flags |= OGG_PAGE_BOS;
				ol->m_header_buf_ptr = 0;
				ol->m_header_buf_len = 0;
				rmi->ogg_curr_header = (char *)malloc(ol->m_page_len);
				rmi->ogg_curr_header_len = ol->m_page_len;
				memcpy(rmi->ogg_curr_header, rmi->ogg_pg.header, rmi->ogg_pg.header_len);
				memcpy(rmi->ogg_curr_header + rmi->ogg_pg.header_len,
				       rmi->ogg_pg.body, rmi->ogg_pg.body_len);
			} else if (header) {
				/* Second or third page in song */
				ol->m_page_flags |= OGG_PAGE_2;
				ol->m_header_buf_ptr = 0;
				ol->m_header_buf_len = 0;
				rmi->ogg_curr_header = (char *)
				    realloc(rmi->ogg_curr_header, rmi->ogg_curr_header_len + ol->m_page_len);
				memcpy(rmi->ogg_curr_header + rmi->ogg_curr_header_len,
				       rmi->ogg_pg.header, rmi->ogg_pg.header_len);
				memcpy(rmi->ogg_curr_header + rmi->ogg_curr_header_len
				       + rmi->ogg_pg.header_len, rmi->ogg_pg.body, rmi->ogg_pg.body_len);
				rmi->ogg_curr_header_len += ol->m_page_len;
			} else if (!ogg_page_eos(&rmi->ogg_pg)) {
				/* Middle pages in song */
				ol->m_header_buf_ptr = rmi->ogg_curr_header;
				ol->m_header_buf_len = rmi->ogg_curr_header_len;
			} else {
				/* Last page in song */
				ol->m_page_flags |= OGG_PAGE_EOS;
				ol->m_header_buf_ptr = rmi->ogg_curr_header;
				ol->m_header_buf_len = rmi->ogg_curr_header_len;
				rmi->ogg_curr_header = 0;
				rmi->ogg_curr_header_len = 0;
			}

			debug_printf("OGG_PAGE\n"
				     "  header_len = %d\n"
				     "  body_len = %d\n"
				     "  serial no = %d\n"
				     "  page no = %d\n"
				     "  bos? = %d\n"
				     "  eos? = %d\n",
				     rmi->ogg_pg.header_len,
				     rmi->ogg_pg.body_len,
				     ogg_page_serialno(&rmi->ogg_pg),
				     ogg_page_pageno(&rmi->ogg_pg),
				     ogg_page_bos(&rmi->ogg_pg), ogg_page_eos(&rmi->ogg_pg));
			list_add_tail(&(ol->m_list), page_list);
			break;
		}
	} while (ret != 0);

	debug_printf("OGG_SYNC state:\n"
		     "  storage = %d\n"
		     "  fill = %d\n"
		     "  returned = %d\n"
		     "  unsynced = %d\n"
		     "  headerbytes = %d\n"
		     "  bodybytes = %d\n",
		     rmi->ogg_sync.storage,
		     rmi->ogg_sync.fill,
		     rmi->ogg_sync.returned,
		     rmi->ogg_sync.unsynced, rmi->ogg_sync.headerbytes, rmi->ogg_sync.bodybytes);
	//    return 1;
}