/* If data == NULL, drop the log of size data_size*/ static void ipc_log_read(struct ipc_log_context *ilctxt, void *data, int data_size) { int bytes_to_read; bytes_to_read = MIN(((PAGE_SIZE - sizeof(struct ipc_log_page_header)) - ilctxt->read_page->hdr.read_offset), data_size); if (data) memcpy(data, (ilctxt->read_page->data + ilctxt->read_page->hdr.read_offset), bytes_to_read); if (bytes_to_read != data_size) { ilctxt->read_page->hdr.read_offset = 0xFFFF; ilctxt->read_page = get_next_page(ilctxt, ilctxt->read_page); ilctxt->read_page->hdr.read_offset = 0; if (data) memcpy((data + bytes_to_read), (ilctxt->read_page->data + ilctxt->read_page->hdr.read_offset), (data_size - bytes_to_read)); bytes_to_read = (data_size - bytes_to_read); } ilctxt->read_page->hdr.read_offset += bytes_to_read; ilctxt->write_avail += data_size; }
int append_record ( record r, schema_p s ) { tbl_p tbl = s->tbl; page_p pg = get_page_for_append ( s->name ); if (pg == NULL) { put_msg (FATAL, "Failed to get page for appending to \"%s\".\n", s->name); exit (EXIT_FAILURE); } if ( put_page_record (pg, r, s) == -1 ) { /* not enough space in the current page */ unpin (pg); pg = get_next_page ( pg ); if (pg == NULL) { put_msg (FATAL, "Failed to get page for \"%s\" block %d.\n", s->name, page_block_nr(pg) + 1); exit (EXIT_FAILURE); } if ( put_page_record (pg, r, s) == -1 ) { put_msg (FATAL, "Failed to put record to page for \"%s\" block %d.\n", s->name, page_block_nr(pg) + 1); exit (EXIT_FAILURE); } } tbl->current_pg = pg; tbl->num_records++; return 0; }
static page_p get_page_for_next_record ( schema_p s ) { page_p pg = s->tbl->current_pg; if (eof(pg)) return NULL; if (eob(pg)) { unpin (pg); pg = get_next_page (pg); if ( pg == NULL) { put_msg (FATAL, "get_page_for_next_record failed at block %d\n", page_block_nr(pg) + 1); exit (EXIT_FAILURE); } page_set_pos_begin (pg); s->tbl->current_pg = pg; } return pg; }
/* * Commits messages to the FIFO. If the FIFO is full, then enough * messages are dropped to create space for the new message. */ void ipc_log_write(void *ctxt, struct encode_context *ectxt) { struct ipc_log_context *ilctxt = (struct ipc_log_context *)ctxt; int bytes_to_write; unsigned long flags; if (!ilctxt || !ectxt) { pr_err("%s: Invalid ipc_log or encode context\n", __func__); return; } spin_lock_irqsave(&ipc_log_context_list_lock, flags); spin_lock(&ilctxt->ipc_log_context_lock); while (ilctxt->write_avail < ectxt->offset) msg_read(ilctxt, NULL); bytes_to_write = MIN(((PAGE_SIZE - sizeof(struct ipc_log_page_header)) - ilctxt->write_page->hdr.write_offset), ectxt->offset); memcpy((ilctxt->write_page->data + ilctxt->write_page->hdr.write_offset), ectxt->buff, bytes_to_write); if (bytes_to_write != ectxt->offset) { ilctxt->write_page->hdr.write_offset = 0xFFFF; ilctxt->write_page = get_next_page(ilctxt, ilctxt->write_page); ilctxt->write_page->hdr.write_offset = 0; memcpy((ilctxt->write_page->data + ilctxt->write_page->hdr.write_offset), (ectxt->buff + bytes_to_write), (ectxt->offset - bytes_to_write)); bytes_to_write = (ectxt->offset - bytes_to_write); } ilctxt->write_page->hdr.write_offset += bytes_to_write; ilctxt->write_avail -= ectxt->offset; complete(&ilctxt->read_avail); spin_unlock(&ilctxt->ipc_log_context_lock); spin_unlock_irqrestore(&ipc_log_context_list_lock, flags); }
static spx_int64_t seek_backwards(spx_ogg_sync_state *oy, spx_ogg_page *og, spx_int64_t wantedpos) { spx_int64_t crofs; spx_int64_t *curoffset=&crofs; *curoffset=ci->curpos; spx_int64_t begin=*curoffset; spx_int64_t end=begin; spx_int64_t ret; spx_int64_t offset=-1; spx_int64_t avgpagelen=-1; spx_int64_t lastgranule=-1; short time = -1; while (offset == -1) { begin -= SEEK_CHUNKSIZE; if (begin < 0) { if (time < 0) { begin = 0; time++; } else { LOGF("Can't seek that early:%lld\n",begin); return -3; /* too early */ } } *curoffset = begin; ci->seek_buffer(*curoffset); spx_ogg_sync_reset(oy); lastgranule = -1; while (*curoffset < end) { ret = get_next_page(oy,og,end-*curoffset); if (ret > 0) { if (lastgranule != -1) { if (avgpagelen < 0) avgpagelen = (spx_ogg_page_granulepos(og)-lastgranule); else avgpagelen=((spx_ogg_page_granulepos(og)-lastgranule) + avgpagelen) / 2; } lastgranule=spx_ogg_page_granulepos(og); if ((lastgranule - (avgpagelen/4)) < wantedpos && (lastgranule + avgpagelen + (avgpagelen/4)) > wantedpos) { /*wanted offset found Yeay!*/ /*LOGF("GnPagefound:%d,%d,%d,%d\n",ret, lastgranule,wantedpos,avgpagelen);*/ return ret; } else if (lastgranule > wantedpos) { /*too late, seek more*/ if (offset != -1) { LOGF("Toolate, returnanyway:%lld,%lld,%lld,%lld\n", ret,lastgranule,wantedpos,avgpagelen); return ret; } break; } else{ /*if (spx_ogg_page_granulepos(&og)<wantedpos)*/ /*too early*/ offset = ret; continue; } } else if (ret == -3) return(-3); else if (ret<=0) break; else if (*curoffset < end) { /*this should not be possible*/ //LOGF("Seek:get_earlier_page:Offset:not_cached by granule:"\"%d,%d,%d,%d,%d\n",*curoffset,end,begin,wantedpos,curpos); offset=ret; } } } return -1; }
static int speex_seek_page_granule(spx_int64_t pos, spx_int64_t curpos, spx_ogg_sync_state *oy, spx_int64_t headerssize) { /* TODO: Someone may want to try to implement seek to packet, instead of just to page (should be more accurate, not be any faster) */ spx_int64_t crofs; spx_int64_t *curbyteoffset = &crofs; *curbyteoffset = ci->curpos; spx_int64_t curoffset; curoffset = *curbyteoffset; spx_int64_t offset = 0; spx_ogg_page og = {0,0,0,0}; spx_int64_t avgpagelen = -1; spx_int64_t lastgranule = -1; if(abs(pos-curpos)>10000 && headerssize>0 && curoffset-headerssize>10000) { /* if seeking for more that 10sec, headersize is known & more than 10kb is played, try to guess a place to seek from the number of bytes playe for this position, this works best when the bitrate is relativly constant. */ curoffset = (((*curbyteoffset-headerssize) * pos)/curpos)*98/100; if (curoffset < 0) curoffset=0; //spx_int64_t toffset=curoffset; ci->seek_buffer(curoffset); spx_ogg_sync_reset(oy); offset = get_next_page(oy,&og,-1); if (offset < 0) { /* could not find new page,use old offset */ LOGF("Seek/guess/fault:%lld->-<-%d,%lld:%lld,%d,%ld,%d\n", curpos,0,pos,offset,0, ci->curpos,/*stream_length*/0); curoffset = *curbyteoffset; ci->seek_buffer(curoffset); spx_ogg_sync_reset(oy); } else { if (spx_ogg_page_granulepos(&og) == 0 && pos > 5000) { LOGF("SEEK/guess/fault:%lld->-<-%lld,%lld:%lld,%d,%ld,%d\n", curpos,spx_ogg_page_granulepos(&og),pos, offset,0,ci->curpos,/*stream_length*/0); curoffset = *curbyteoffset; ci->seek_buffer(curoffset); spx_ogg_sync_reset(oy); } else { curoffset = offset; curpos = spx_ogg_page_granulepos(&og); } } } /* which way do we want to seek? */ if (curpos > pos) { /* backwards */ offset = seek_backwards(oy,&og,pos); if (offset > 0) { *curbyteoffset = curoffset; return 1; } } else { /* forwards */ while ( (offset = get_next_page(oy,&og,-1)) > 0) { if (lastgranule != -1) { if (avgpagelen < 0) avgpagelen = (spx_ogg_page_granulepos(&og) - lastgranule); else avgpagelen = ((spx_ogg_page_granulepos(&og) - lastgranule) + avgpagelen) / 2; } lastgranule = spx_ogg_page_granulepos(&og); if ( ((lastgranule - (avgpagelen/4)) < pos && ( lastgranule + avgpagelen + (avgpagelen / 4)) > pos) || lastgranule > pos) { /*wanted offset found Yeay!*/ *curbyteoffset = offset; return offset; } } } ci->seek_buffer(*curbyteoffset); spx_ogg_sync_reset(oy); LOGF("Seek failed:%lld\n", offset); return -1; }
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); }