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 */
int scan_get_oggfileinfo(char *filename, MP3FILE *pmp3) { FILE *file = fopen(filename, "rb"); ogg_sync_state sync; ogg_page page; stream_set *processors = create_stream_set(); int gotpage = 0; ogg_int64_t written = 0; struct stat psb; if(!file) { DPRINTF(E_FATAL, L_SCAN, "Error opening input file \"%s\": %s\n", filename, strerror(errno)); return -1; } DPRINTF(E_INF, L_SCAN, "Processing file \"%s\"...\n\n", filename); if (!stat(filename, &psb)) { pmp3->time_added = psb.st_mtime; if (psb.st_ctime < pmp3->time_added) { pmp3->time_added = psb.st_ctime; } pmp3->time_modified = psb.st_mtime; } else { DPRINTF(E_WARN, L_SCAN, "Error statting: %s\n", strerror(errno)); } ogg_sync_init(&sync); while(get_next_page(file, &sync, &page, &written)) { stream_processor *p = find_stream_processor(processors, &page); gotpage = 1; if(!p) { DPRINTF(E_FATAL, L_SCAN, "Could not find a processor for stream, bailing\n"); return -1; } if(p->isillegal && !p->shownillegal) { char *constraint; switch(p->constraint_violated) { case CONSTRAINT_PAGE_AFTER_EOS: constraint = "Page found for stream after EOS flag"; break; case CONSTRAINT_MUXING_VIOLATED: constraint = "Ogg muxing constraints violated, new " "stream before EOS of all previous streams"; break; default: constraint = "Error unknown."; } DPRINTF(E_WARN, L_SCAN, "Warning: illegally placed page(s) for logical stream %d\n" "This indicates a corrupt ogg file: %s.\n", p->num, constraint); 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->isnew) { DPRINTF(E_DBG, L_SCAN, "New logical stream (#%d, serial: %08x): type %s\n", p->num, p->serial, p->type); if(!p->start) DPRINTF(E_WARN, L_SCAN, "stream start flag not set on stream %d\n", p->num); } else if(p->start) DPRINTF(E_WARN, L_SCAN, "stream start flag found in mid-stream " "on stream %d\n", p->num); if(p->seqno++ != ogg_page_pageno(&page)) { if(!p->lostseq) DPRINTF(E_WARN, L_SCAN, "sequence number gap in stream %d. Got page %ld " "when expecting page %ld. Indicates missing data.\n", p->num, ogg_page_pageno(&page), p->seqno - 1); p->seqno = ogg_page_pageno(&page); p->lostseq = 1; } else p->lostseq = 0; if(!p->isillegal) { p->process_page(p, &page, pmp3); if(p->end) { if(p->process_end) p->process_end(p, pmp3); DPRINTF(E_DBG, L_SCAN, "Logical stream %d ended\n", p->num); p->isillegal = 1; p->constraint_violated = CONSTRAINT_PAGE_AFTER_EOS; } } } free_stream_set(processors); ogg_sync_clear(&sync); fclose(file); if(!gotpage) { DPRINTF(E_FATAL, L_SCAN, "No ogg data found in file \"%s\".\n" "Input probably not ogg.\n", filename); return -1; } return 0; }
static void process_file(char *filename) { FILE *file = fopen(filename, "rb"); ogg_sync_state sync; ogg_page page; stream_set *processors = create_stream_set(); int gotpage = 0; ogg_int64_t written = 0; if(!file) { error(_("Error opening input file \"%s\": %s\n"), filename, strerror(errno)); return; } printf(_("Processing file \"%s\"...\n\n"), filename); ogg_sync_init(&sync); while(get_next_page(file, &sync, &page, &written)) { stream_processor *p = find_stream_processor(processors, &page); gotpage = 1; if(!p) { error(_("Could not find a processor for stream, bailing\n")); return; } if(p->isillegal && !p->shownillegal) { char *constraint; switch(p->constraint_violated) { case CONSTRAINT_PAGE_AFTER_EOS: constraint = _("Page found for stream after EOS flag"); break; case CONSTRAINT_MUXING_VIOLATED: constraint = _("Ogg muxing constraints violated, new " "stream before EOS of all previous streams"); break; default: constraint = _("Error unknown."); } warn(_("Warning: illegally placed page(s) for logical stream %d\n" "This indicates a corrupt ogg file: %s.\n"), p->num, constraint); 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->isnew) { info(_("New logical stream (#%d, serial: %08x): type %s\n"), p->num, p->serial, p->type); if(!p->start) warn(_("Warning: stream start flag not set on stream %d\n"), p->num); } else if(p->start) warn(_("Warning: stream start flag found in mid-stream " "on stream %d\n"), p->num); if(p->seqno++ != ogg_page_pageno(&page)) { if(!p->lostseq) warn(_("Warning: sequence number gap in stream %d. Got page " "%ld when expecting page %ld. Indicates missing data.\n" ), p->num, ogg_page_pageno(&page), p->seqno - 1); p->seqno = ogg_page_pageno(&page); p->lostseq = 1; } else p->lostseq = 0; if(!p->isillegal) { p->process_page(p, &page); if(p->end) { if(p->process_end) p->process_end(p); info(_("Logical stream %d ended\n"), p->num); p->isillegal = 1; p->constraint_violated = CONSTRAINT_PAGE_AFTER_EOS; } } } if(!gotpage) error(_("Error: No ogg data found in file \"%s\".\n" "Input probably not ogg.\n"), filename); free_stream_set(processors); ogg_sync_clear(&sync); fclose(file); }