コード例 #1
0
ファイル: ogg.c プロジェクト: jameshilliard/WECB-BH-GPL
static stream_processor *find_stream_processor(stream_set *set, ogg_page *page)
{
    ogg_uint32_t serial = ogg_page_serialno(page);
    int i, found = 0;
    int invalid = 0;
    int constraint = 0;
    stream_processor *stream;

    for(i=0; i < set->used; i++) {
        if(serial == set->streams[i].serial) {
            /* We have a match! */
            found = 1;
            stream = &(set->streams[i]);

            set->in_headers = 0;
            /* if we have detected EOS, then this can't occur here. */
            if(stream->end) {
                stream->isillegal = 1;
                stream->constraint_violated = CONSTRAINT_PAGE_AFTER_EOS;
                return stream;
            }

            stream->isnew = 0;
            stream->start = ogg_page_bos(page);
            stream->end = ogg_page_eos(page);
            stream->serial = serial;
            return stream;
        }
    }

    /* If there are streams open, and we've reached the end of the
     * headers, then we can't be starting a new stream.
     * XXX: might this sometimes catch ok streams if EOS flag is missing,
     * but the stream is otherwise ok?
     */
    if(streams_open(set) && !set->in_headers) {
        constraint = CONSTRAINT_MUXING_VIOLATED;
        invalid = 1;
    }

    set->in_headers = 1;

    if(set->allocated < set->used)
        stream = &set->streams[set->used];
    else {
        set->allocated += 5;
        set->streams = realloc(set->streams, sizeof(stream_processor)*
                set->allocated);
        stream = &set->streams[set->used];
    }
    set->used++;
    stream->num = set->used; /* We count from 1 */

    stream->isnew = 1;
    stream->isillegal = invalid;
    stream->constraint_violated = constraint;

    {
        int res;
        ogg_packet packet;

        /* We end up processing the header page twice, but that's ok. */
        ogg_stream_init(&stream->os, serial);
        ogg_stream_pagein(&stream->os, page);
        res = ogg_stream_packetout(&stream->os, &packet);
        if(res <= 0) {
            DPRINTF(E_WARN, L_SCAN, "Invalid header page, no packet found\n");
            null_start(stream);
        }
        else if(packet.bytes >= 7 && memcmp(packet.packet, "\001vorbis", 7)==0)
            vorbis_start(stream);
        else if(packet.bytes >= 8 && memcmp(packet.packet, "OggMIDI\0", 8)==0) 
            other_start(stream, "MIDI");
        else
            other_start(stream, NULL);

        res = ogg_stream_packetout(&stream->os, &packet);
        if(res > 0) {
            DPRINTF(E_WARN, L_SCAN, "Invalid header page in stream %d, "
		    "contains multiple packets\n", stream->num);
        }

        /* re-init, ready for processing */
        ogg_stream_clear(&stream->os);
        ogg_stream_init(&stream->os, serial);
   }

   stream->start = ogg_page_bos(page);
   stream->end = ogg_page_eos(page);
   stream->serial = serial;

   /*   if(stream->serial == 0 || stream->serial == -1) {
       info(_("Note: Stream %d has serial number %d, which is legal but may "
              "cause problems with some tools."), stream->num, stream->serial);
	      }*/

   return stream;
}
コード例 #2
0
ファイル: ripogg.c プロジェクト: hdijkema/libstreamripper
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;
}