static int64_t mp_seek(void *opaque, int64_t pos, int whence) { demuxer_t *demuxer = opaque; stream_t *stream = demuxer->stream; int64_t current_pos; mp_msg(MSGT_HEADER,MSGL_DBG2,"mp_seek(%p, %"PRId64", %d)\n", stream, pos, whence); if(whence == SEEK_CUR) pos +=stream_tell(stream); else if(whence == SEEK_END && stream->end_pos > 0) pos += stream->end_pos; else if(whence == SEEK_SET) pos += stream->start_pos; else if(whence == AVSEEK_SIZE && stream->end_pos > 0) { uint64_t size; stream_control(stream, STREAM_CTRL_GET_SIZE, &size); if (size > stream->end_pos) stream->end_pos = size; return stream->end_pos - stream->start_pos; } else return -1; if(pos<0) return -1; current_pos = stream_tell(stream); if(stream_seek(stream, pos)==0) { stream_reset(stream); stream_seek(stream, current_pos); return -1; } return pos - stream->start_pos; }
// Runs in the cache thread static void cache_execute_control(struct priv *s) { uint64_t old_pos = stream_tell(s->stream); s->control_flush = false; switch (s->control) { case STREAM_CTRL_SET_CACHE_SIZE: s->control_res = resize_cache(s, *(int64_t *)s->control_arg); break; default: s->control_res = stream_control(s->stream, s->control, s->control_arg); } bool pos_changed = old_pos != stream_tell(s->stream); bool ok = s->control_res == STREAM_OK; if (pos_changed && !ok) { MP_ERR(s, "STREAM_CTRL changed stream pos but " "returned error, this is not allowed!\n"); } else if (pos_changed || (ok && control_needs_flush(s->control))) { MP_VERBOSE(s, "Dropping cache due to control()\n"); s->read_filepos = stream_tell(s->stream); s->control_flush = true; cache_drop_contents(s); } update_cached_controls(s); s->control = CACHE_CTRL_NONE; pthread_cond_signal(&s->wakeup); }
UINT32 update_pack_index(psion_pack *pack) { UINT8 data, type; UINT16 size; UINT16 index = 0; memset(pack->pack_index, 0, sizeof(psion_file) * MAXFILES); // start at the first record stream_seek(pack->stream, 0x10, SEEK_SET); do { stream_read(pack->stream, &data, 1); if(data == 0xff) { pack->eop = stream_tell(pack->stream) - 1; return TRUE; } else if (data == 0x02) { // long record without name are ignored stream_read(pack->stream, &data, 1); size = get_long_rec_size(pack->stream); stream_seek(pack->stream, size, SEEK_CUR); } else { stream_read(pack->stream, &type, 1); // deleted record are not listed if (type < 0x90 && (type & 0x80)) { pack->pack_index[index].type = type; stream_read(pack->stream, &pack->pack_index[index].filename, 8); stream_read(pack->stream, &pack->pack_index[index].id, 1); pack->pack_index[index].name_rec = stream_tell(pack->stream) - 11; //check for data record stream_read(pack->stream, &data, 1); if (data == 0x02) pack->pack_index[index].data_rec = stream_tell(pack->stream) - 1; stream_seek(pack->stream, -1, SEEK_CUR); index++; } else stream_seek(pack->stream, data, SEEK_CUR); } } while (stream_size(pack->stream) > stream_tell(pack->stream)); // corrupted image return FALSE; }
static int64_t skip_cb(struct archive *arch, void *priv, int64_t request) { struct mp_archive_volume *vol = priv; if (!volume_seek(vol)) return -1; int64_t old = stream_tell(vol->src); stream_skip(vol->src, request); return stream_tell(vol->src) - old; }
// return value: // 0 = EOF or no stream found // 1 = successfully read a packet static int demux_y4m_fill_buffer(demuxer_t *demux, demux_stream_t *dsds) { demux_stream_t *ds=demux->video; demux_packet_t *dp; y4m_priv_t *priv=demux->priv; y4m_frame_info_t fi; unsigned char *buf[3]; int err, size; y4m_init_frame_info(&fi); demux->filepos=stream_tell(demux->stream); size = ((sh_video_t*)ds->sh)->disp_w*((sh_video_t*)ds->sh)->disp_h; dp = new_demux_packet(3*size/2); /* swap U and V components */ buf[0] = dp->buffer; buf[1] = dp->buffer + 5*size/4; buf[2] = dp->buffer + size; if (priv->is_older) { int c; c = stream_read_char(demux->stream); /* F */ if (c == -256) return 0; /* EOF */ if (c != 'F') { mp_msg(MSGT_DEMUX, MSGL_V, "Bad frame at %d\n", (int)stream_tell(demux->stream)-1); return 0; } stream_skip(demux->stream, 5); /* RAME\n */ stream_read(demux->stream, buf[0], size); stream_read(demux->stream, buf[1], size/4); stream_read(demux->stream, buf[2], size/4); } else { if ((err=y4m_read_frame(demux->stream, priv->si, &fi, buf)) != Y4M_OK) { mp_msg(MSGT_DEMUX, MSGL_V, "error reading frame %s\n", y4m_strerr(err)); return 0; } } /* This seems to be the right way to calculate the presentation time stamp */ dp->pts=(float)priv->framenum/((sh_video_t*)ds->sh)->fps; priv->framenum++; dp->pos=demux->filepos; dp->flags=0; ds_add_packet(ds, dp); return 1; }
// return value: // 0 = EOF or no stream found // 1 = successfully read a packet static int demux_avi_fill_buffer_nini(demuxer_t *demux, demux_stream_t *ds) { avi_priv_t *priv=demux->priv; unsigned int id=0; unsigned int len; int ret=0; off_t *fpos=NULL; if(ds==demux->video) fpos=&priv->idx_pos_v; else if(ds==demux->audio) fpos=&priv->idx_pos_a; else return 0; stream_seek(demux->stream,fpos[0]); do{ demux->filepos=stream_tell(demux->stream); if(demux->filepos>=demux->movi_end && (demux->movi_end>demux->movi_start)){ ds->eof=1; return 0; } id=avi_find_id(demux->stream); len=stream_read_dword_le(demux->stream); if(stream_eof(demux->stream)) return 0; if(id==mmioFOURCC('L','I','S','T')){ id=stream_read_dword_le(demux->stream); // list type continue; } if(id==mmioFOURCC('R','I','F','F')){ mp_msg(MSGT_DEMUX,MSGL_V,"additional RIFF header...\n"); id=stream_read_dword_le(demux->stream); // "AVIX" continue; } if(ds==demux_avi_select_stream(demux,id)){ // read it! ret=demux_avi_read_packet(demux,ds,id,len,priv->idx_pos-1,0); } else { // skip it! int skip=(len+1)&(~1); // total bytes in this chunk stream_skip(demux->stream,skip); } } while(ret!=1); fpos[0]=stream_tell(demux->stream); return 1; }
static off_t mp_seek(void * h, long long pos, int whence) { stream_t * stream = (stream_t*)h; if (stream->end_pos < stream_tell(stream)) stream->end_pos = stream_tell(stream); if (whence == SEEK_CUR) pos += stream_tell(stream); else if (whence == SEEK_END) pos += stream->end_pos; else if (whence != SEEK_SET) return -1; if (pos < stream->end_pos && stream->eof) stream_reset(stream); if (stream_seek(stream, pos) == 0) return -1; return pos; }
/// returns DEMUXER_TYPE_AAC if it finds 8 ADTS frames in 32768 bytes, 0 otherwise static int demux_aac_probe(demuxer_t *demuxer) { int cnt = 0, c, len, srate, num; loff_t init, probed; aac_priv_t *priv; if(! demux_aac_init(demuxer)) { mp_msg(MSGT_DEMUX, MSGL_ERR, "COULDN'T INIT aac_demux, exit\n"); return 0; } priv = (aac_priv_t *) demuxer->priv; init = probed = stream_tell(demuxer->stream); while(probed-init <= 32768 && cnt < 8) { c = 0; while(c != 0xFF) { c = stream_read_char(demuxer->stream); if(c < 0) goto fail; } priv->buf[0] = 0xFF; if(stream_read(demuxer->stream, &(priv->buf[1]), 7) < 7) goto fail; len = aac_parse_frame(priv->buf, &srate, &num); if(len > 0) { cnt++; stream_skip(demuxer->stream, len - 8); } probed = stream_tell(demuxer->stream); } stream_seek(demuxer->stream, init); if(cnt < 8) goto fail; mp_msg(MSGT_DEMUX, MSGL_V, "demux_aac_probe, INIT: %"PRIu64", PROBED: %"PRIu64", cnt: %d\n", init, probed, cnt); return DEMUXER_TYPE_AAC; fail: mp_msg(MSGT_DEMUX, MSGL_V, "demux_aac_probe, failed to detect an AAC stream\n"); return 0; }
static void demux_seek_y4m(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags) { sh_video_t* sh = demuxer->video->sh; y4m_priv_t* priv = demuxer->priv; int rel_seek_frames = sh->fps*rel_seek_secs; int size = 3*sh->disp_w*sh->disp_h/2; off_t curr_pos = stream_tell(demuxer->stream); if (priv->framenum + rel_seek_frames < 0) rel_seek_frames = -priv->framenum; //printf("seektoframe=%d rel_seek_secs=%f seektooffset=%ld\n", priv->framenum + rel_seek_frames, rel_seek_secs, curr_pos + rel_seek_frames*(size+6)); //printf("framenum=%d, curr_pos=%ld, currpos/(size+6)=%f\n", priv->framenum, curr_pos, (float)curr_pos/(float)(size+6)); priv->framenum += rel_seek_frames; if (priv->is_older) { /* Well this is easy: every frame takes up size+6 bytes * in the stream and we may assume that the stream pointer * is always at the beginning of a frame. * framenum is the number of the frame that is about to be * demuxed (counting from ONE (see demux_open_y4m)) */ stream_seek(demuxer->stream, curr_pos + rel_seek_frames*(size+6)); } else { /* should never come here, because seeking for YUV4MPEG2 * is disabled. */ mp_msg(MSGT_DEMUX, MSGL_WARN, "Seeking for YUV4MPEG2 not yet implemented!\n"); } }
UINT16 put_opl(imgtool_stream *instream, imgtool_stream *outstream) { UINT16 out_size = 0; UINT32 rec_start = stream_tell(outstream); char *line; // reset stream stream_seek(instream, 0, SEEK_SET); stream_fill(outstream, 0x00, 4); // replace all eol with 0x00 while ((line = stream_getline(instream, 256))) { // replace tab with space for (int i=0; i<strlen(line); i++) if (line[i] == '\t') line[i] = ' '; stream_write(outstream, line, strlen(line)); stream_putc(outstream, 0x00); out_size += strlen(line) + 1; free(line); } // end of pack stream_fill(outstream, 0xff, 2); // update the size in the head stream_seek(outstream, rec_start + 2, SEEK_SET); stream_putc(outstream, (out_size>>8) & 0xff); stream_putc(outstream, out_size & 0xff); return out_size + 4; }
char *stream_getline(imgtool_stream *source, UINT16 max_len) { UINT16 pos = 0; char data; char *line = (char*)malloc(max_len); memset(line, 0, max_len); while (pos < max_len && stream_size(source) > stream_tell(source)) { stream_read(source, &data, 1); switch(data) { case '\r': stream_read(source, &data, 1); if (data != '\n') stream_seek(source, -1, SEEK_CUR); case '\n': return line; default: line[pos++] = data; break; } } if (pos) return line; free(line); return NULL; }
unsigned int stream_available_read( stream_t* stream ) { FOUNDATION_ASSERT( stream ); if( stream->vtable->available_read ) return (unsigned int)stream->vtable->available_read( stream ); return (unsigned int)( stream_size( stream ) - stream_tell( stream ) ); }
void stream_determine_binary_mode(stream_t* stream, size_t num) { char fixed_buffer[32]; char* buf; size_t cur; size_t actual_read, i; if (!(stream->mode & STREAM_IN) || stream_is_sequential(stream)) return; if (!num) num = 8; buf = (num <= sizeof(fixed_buffer)) ? fixed_buffer : memory_allocate(0, num, 0, MEMORY_TEMPORARY); memset(buf, 32, num); cur = stream_tell(stream); actual_read = stream_read(stream, buf, num); stream_seek(stream, (ssize_t)cur, STREAM_SEEK_BEGIN); stream->mode &= ~STREAM_BINARY; for (i = 0; i < actual_read; ++i) { //TODO: What about UTF-8? if (((buf[i] < 0x20) && (buf[i] != 0x09) && (buf[i] != 0x0a) && (buf[i] != 0x0d)) || (buf[i] > 0x7e)) { stream->mode |= STREAM_BINARY; break; } } if (buf != fixed_buffer) memory_deallocate(buf); }
// =========================================================================== static int tmf_load_chunk( demuxer_t *demux, TiVoInfo *tivo, unsigned char *buff, int readChunk ) { loff_t fileoffset; int count; mp_msg( MSGT_DEMUX, MSGL_DBG3, "\ntmf_load_chunk() begin %d\n", readChunk ); fileoffset = tmf_filetooffset(tivo, readChunk); if (fileoffset == -1 || !stream_seek(demux->stream, fileoffset)) { mp_msg( MSGT_DEMUX, MSGL_ERR, "Read past EOF()\n" ); return 0; } count = stream_read( demux->stream, buff, CHUNKSIZE ); demux->filepos = stream_tell( demux->stream ); mp_msg( MSGT_DEMUX, MSGL_DBG3, "tmf_load_chunk() count %x\n", count ); mp_msg( MSGT_DEMUX, MSGL_DBG3, "tmf_load_chunk() bytes %x %x %x %x %x %x %x %x\n", buff[ 0 ], buff[ 1 ], buff[ 2 ], buff[ 3 ], buff[ 4 ], buff[ 5 ], buff[ 6 ], buff[ 7 ] ); mp_msg( MSGT_DEMUX, MSGL_DBG3, "tmf_load_chunk() end\n" ); return count; }
// =========================================================================== static int ty_tmf_filetoparts( demuxer_t *demux, TiVoInfo *tivo ) { int parts = 0; stream_seek(demux->stream, 0); mp_msg( MSGT_DEMUX, MSGL_DBG3, "Dumping tar contents\n" ); while (!demux->stream->eof) { char header[ 512 ]; char *name; char *extension; char *sizestr; int size; loff_t skip; if (stream_read(demux->stream, header, 512) < 512) { mp_msg( MSGT_DEMUX, MSGL_DBG3, "Read bad\n" ); break; } name = header; name[99] = 0; sizestr = &header[124]; sizestr[11] = 0; size = strtol(sizestr, NULL, 8); mp_msg( MSGT_DEMUX, MSGL_DBG3, "name %-20.20s size %-12.12s %d\n", name, sizestr, size ); extension = strrchr(name, '.'); if (extension && strcmp(extension, ".ty") == 0) { if ( parts >= MAX_TMF_PARTS ) { mp_msg( MSGT_DEMUX, MSGL_ERR, "ty:tmf too big\n" ); break; } tivo->tmfparts[ parts ].fileSize = size; tivo->tmfparts[ parts ].startOffset = stream_tell(demux->stream); tivo->tmfparts[ parts ].chunks = size / CHUNKSIZE; mp_msg(MSGT_DEMUX, MSGL_DBG3, "tmf_filetoparts(): index %d, chunks %d\n" "tmf_filetoparts(): size %"PRId64"\n" "tmf_filetoparts(): startOffset %"PRId64"\n", parts, tivo->tmfparts[ parts ].chunks, tivo->tmfparts[ parts ].fileSize, tivo->tmfparts[ parts ].startOffset ); parts++; } // size rounded up to blocks skip = (size + 511) & ~511; stream_skip(demux->stream, skip); } stream_reset(demux->stream); tivo->tmf_totalparts = parts; mp_msg( MSGT_DEMUX, MSGL_DBG3, "tmf_filetoparts(): No More Part Files %d\n", parts ); return 1; }
void stream_determine_binary_mode( stream_t* stream, unsigned int num ) { char* buf; int64_t cur; uint64_t actual_read, i; FOUNDATION_ASSERT( stream ); if( !( stream->mode & STREAM_IN ) || stream_is_sequential( stream ) ) return; if( !num ) num = 8; buf = memory_allocate( num, 0, MEMORY_TEMPORARY ); memset( buf, 32, num ); cur = stream_tell( stream ); actual_read = stream_read( stream, buf, num ); stream_seek( stream, cur, STREAM_SEEK_BEGIN ); stream->mode &= ~STREAM_BINARY; for( i = 0; i < actual_read; ++i ) { //TODO: What about UTF-8? if( ( ( buf[i] < 0x20 ) && ( buf[i] != 0x09 ) && ( buf[i] != 0x0a ) && ( buf[i] != 0x0d ) ) || ( buf[i] > 0x7e ) ) { stream->mode |= STREAM_BINARY; break; } } memory_deallocate( buf ); }
static int y4m_check_file(demuxer_t* demuxer){ int orig_pos = stream_tell(demuxer->stream); char buf[10]; y4m_priv_t* priv; mp_msg(MSGT_DEMUX, MSGL_V, "Checking for YUV4MPEG2\n"); if(stream_read(demuxer->stream, buf, 9)!=9) return 0; buf[9] = 0; if (strncmp("YUV4MPEG2", buf, 9) && strncmp("YUV4MPEG ", buf, 9)) { return 0; } demuxer->priv = malloc(sizeof(y4m_priv_t)); priv = demuxer->priv; priv->is_older = 0; if (!strncmp("YUV4MPEG ", buf, 9)) { mp_msg(MSGT_DEMUX, MSGL_V, "Found older YUV4MPEG format (used by xawtv)\n"); priv->is_older = 1; } mp_msg(MSGT_DEMUX,MSGL_DBG2,"Success: YUV4MPEG2\n"); stream_seek(demuxer->stream, orig_pos); return DEMUXER_TYPE_Y4M; }
// return value: // 0 = EOF or no stream found // 1 = successfully read a packet static int demux_smjpeg_fill_buffer(demuxer_t *demux, demux_stream_t *ds) { int dtype, dsize, dpts; demux->filepos = stream_tell(demux->stream); dtype = stream_read_dword_le(demux->stream); dpts = stream_read_dword(demux->stream); dsize = stream_read_dword(demux->stream); switch(dtype) { case mmioFOURCC('s','n','d','D'): /* fixme, but no decoder implemented yet */ ds_read_packet(demux->audio, demux->stream, dsize, (float)dpts/1000.0, demux->filepos, 0); break; case mmioFOURCC('v','i','d','D'): ds_read_packet(demux->video, demux->stream, dsize, (float)dpts/1000.0, demux->filepos, 0); break; case mmioFOURCC('D','O','N','E'): return 1; default: return 0; } return 1; }
/* * Skip the current element, or on error, call ebml_resync_cluster(). */ int ebml_read_skip_or_resync_cluster(stream_t *s, uint64_t *length) { uint64_t len; int l; len = ebml_read_length(s, &l); if (len == EBML_UINT_INVALID) goto resync; if (length) *length = len + l; int64_t pos = stream_tell(s); // When reading corrupted elements, len will often be a random high number, // and stream_skip() will fail when skipping past EOF. if (!stream_skip(s, len)) { stream_seek(s, pos); goto resync; } return 0; resync: return ebml_resync_cluster(s) < 0 ? -1 : 1; }
static int smjpeg_check_file(demuxer_t* demuxer){ int orig_pos = stream_tell(demuxer->stream); char buf[8]; int version; mp_msg(MSGT_DEMUX, MSGL_V, "Checking for SMJPEG\n"); if (stream_read_word(demuxer->stream) == 0xA) { stream_read(demuxer->stream, buf, 6); buf[7] = 0; if (strncmp("SMJPEG", buf, 6)) { mp_msg(MSGT_DEMUX, MSGL_DBG2, "Failed: SMJPEG\n"); return 0; } } else return 0; version = stream_read_dword(demuxer->stream); if (version != 0) { mp_msg(MSGT_DEMUX, MSGL_ERR, "Unknown version (%d) of SMJPEG. Please report!\n", version); return 0; } stream_seek(demuxer->stream, orig_pos); return DEMUXER_TYPE_SMJPEG; }
/// Open an mpg physical stream static demuxer_t* demux_mpg_open(demuxer_t* demuxer) { stream_t *s = demuxer->stream; mpg_demuxer_t* mpg_d; if (!ds_fill_buffer(demuxer->video)) return 0; mpg_d = calloc(1,sizeof(mpg_demuxer_t)); if(mpg_d) { demuxer->priv = mpg_d; mpg_d->last_pts = -1.0; mpg_d->first_pts = -1.0; //if seeking is allowed set has_valid_timestamps if appropriate if(demuxer->seekable && (demuxer->stream->type == STREAMTYPE_FILE || demuxer->stream->type == STREAMTYPE_VCD) && demuxer->movi_start != demuxer-> movi_end ) { //We seek to the beginning of the stream, to somewhere in the //middle, and to the end of the stream, while remembering the pts //at each of the three positions. With these pts, we check whether //or not the pts are "linear enough" to justify seeking by the pts //of the stream //The position where the stream is now off_t pos = stream_tell(s); float first_pts = read_first_mpeg_pts_at_position(demuxer, demuxer->movi_start); if(first_pts != -1.0) { float middle_pts = read_first_mpeg_pts_at_position(demuxer, (demuxer->movi_end + demuxer->movi_start)/2); if(middle_pts != -1.0) { float final_pts = read_first_mpeg_pts_at_position(demuxer, demuxer->movi_end - TIMESTAMP_PROBE_LEN); if(final_pts != -1.0) { // found proper first, middle, and final pts. float proportion = (middle_pts-first_pts==0) ? -1 : (final_pts-middle_pts)/(middle_pts-first_pts); // if they are linear enough set has_valid_timestamps if((0.5 < proportion) && (proportion < 2)) { mpg_d->first_pts = first_pts; mpg_d->first_to_final_pts_len = final_pts - first_pts; mpg_d->has_valid_timestamps = 1; } } } } //Cleaning up from seeking in stream demuxer->stream->eof=0; demuxer->video->eof=0; demuxer->audio->eof=0; stream_seek(s,pos); ds_fill_buffer(demuxer->video); } // if ( demuxer->seekable ) } // if ( mpg_d ) return demuxer; }
static int demux_lavf_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){ lavf_priv_t *priv= demux->priv; AVPacket pkt; demux_packet_t *dp; demux_stream_t *ds; int id; mp_msg(MSGT_DEMUX,MSGL_DBG2,"demux_lavf_fill_buffer()\n"); demux->filepos=stream_tell(demux->stream); if(av_read_frame(priv->avfc, &pkt) < 0) return 0; id= pkt.stream_index; if(id==demux->audio->id){ // audio ds=demux->audio; if(!ds->sh){ ds->sh=demux->a_streams[id]; mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF audio ID = %d\n",ds->id); } } else if(id==demux->video->id){ // video ds=demux->video; if(!ds->sh){ ds->sh=demux->v_streams[id]; mp_msg(MSGT_DEMUX,MSGL_V,"Auto-selected LAVF video ID = %d\n",ds->id); } } else { av_free_packet(&pkt); return 1; } if(0/*pkt.destruct == av_destruct_packet*/){ //ok kids, dont try this at home :) dp=malloc(sizeof(demux_packet_t)); dp->len=pkt.size; dp->next=NULL; dp->refcount=1; dp->master=NULL; dp->buffer=pkt.data; pkt.destruct= NULL; }else{ dp=new_demux_packet(pkt.size); memcpy(dp->buffer, pkt.data, pkt.size); av_free_packet(&pkt); } if(pkt.pts != AV_NOPTS_VALUE){ dp->pts=pkt.pts * av_q2d(priv->avfc->streams[id]->time_base); priv->last_pts= dp->pts * AV_TIME_BASE; } dp->pos=demux->filepos; dp->flags= !!(pkt.flags&PKT_FLAG_KEY); // append packet to DS stream: ds_add_packet(ds,dp); return 1; }
StreamError stream_seekFromCurrent(stream_dt *stream, streampos_dt offset) { StreamError err; streampos_dt curr_pos; if (StreamError_Success != stream_tell(stream, &curr_pos)) return err; return stream_seek(stream, offset, curr_pos); }
void streamPositionIs(streampos_dt expected) { streampos_dt curr_pos; if (StreamError_Success == stream_tell(test_stream, &curr_pos)) TEST_ASSERT_EQUAL_INT(expected, curr_pos); else TEST_FAIL_MESSAGE("Stream error"); }
static void avifile_write_chunk(muxer_stream_t *s,size_t len,unsigned int flags, double dts, double pts){ off_t rifflen; muxer_t *muxer=s->muxer; struct avi_stream_info *si = s->priv; struct avi_stream_info *vsi = muxer->def_v->priv; int paddedlen = len + (len&1); if (s->type == MUXER_TYPE_VIDEO && !s->h.dwSuggestedBufferSize) { off_t pos=stream_tell(muxer->stream); stream_seek(muxer->stream, 0); avifile_write_header(muxer); stream_seek(muxer->stream, pos); } if(index_mode){ rifflen = muxer->file_end - vsi->riffofs[vsi->riffofspos] - 8; if (vsi->riffofspos == 0) { rifflen += 8+muxer->idx_pos*sizeof(AVIINDEXENTRY); } if (rifflen + paddedlen > ODML_CHUNKLEN && write_odml == 1) { if (vsi->riffofspos == 0) { avifile_write_standard_index(muxer); } avifile_odml_new_riff(muxer); } if (vsi->riffofspos == 0) { // add to the traditional index: if(muxer->idx_pos>=muxer->idx_size){ muxer->idx_size+=256; // 4kB muxer->idx=realloc_struct(muxer->idx,muxer->idx_size,16); } muxer->idx[muxer->idx_pos].ckid=s->ckid; muxer->idx[muxer->idx_pos].dwFlags=flags; // keyframe? muxer->idx[muxer->idx_pos].dwChunkOffset=muxer->file_end-(muxer->movi_start-4); muxer->idx[muxer->idx_pos].dwChunkLength=len; ++muxer->idx_pos; } // add to odml index if(si->idxpos>=si->idxsize){ si->idxsize+=256; si->idx=realloc_struct(si->idx,si->idxsize,sizeof(*si->idx)); } si->idx[si->idxpos].flags=(flags&AVIIF_KEYFRAME)?0:ODML_NOTKEYFRAME; si->idx[si->idxpos].ofs=muxer->file_end; si->idx[si->idxpos].len=len; ++si->idxpos; } // write out the chunk: write_avi_chunk(muxer->stream,s->ckid,len,s->buffer); /* unsigned char */ if (len > s->h.dwSuggestedBufferSize){ s->h.dwSuggestedBufferSize = len; } if((unsigned int)len>s->h.dwSuggestedBufferSize) s->h.dwSuggestedBufferSize=len; muxer->file_end += 8 + paddedlen; }
static int demux_aac_adif_fill_buffer(demuxer_t *demuxer, demux_stream_t *ds) { aac_adif_priv_t *priv = (aac_adif_priv_t *) demuxer->priv; demux_packet_t *dp; int c1, c2, len, srate, num; float tm = 0; if(demuxer->stream->eof || (demuxer->movi_end && stream_tell(demuxer->stream) >= demuxer->movi_end)) return 0; len = READLEN; dp = new_demux_packet(len); if(! dp) { fprintf(stderr,"fill_buffer,NEW ADIF PACKET(%d)FAILED\n", len); mp_msg(MSGT_DEMUX, MSGL_ERR, "fill_buffer, NEW ADIF PACKET(%d)FAILED\n", len); return 0; } len = stream_read(demuxer->stream, dp->buffer, READLEN); if (len != READLEN) len = len; if(priv->bitrate) { tm = (len * 8); tm /= (priv->bitrate); // FIXME assumes CBR } priv->last_pts += tm; dp->len = len; dp->pts = priv->last_pts; // fprintf(stderr, "\nPTS: %.3f\n", dp->pts); ds_add_packet(demuxer->audio, dp); priv->size += len; priv->time += tm; demuxer->filepos = stream_tell(demuxer->stream); return len; }
static const struct pl_format *probe_pl(struct pl_parser *p, bool force) { int64_t start = stream_tell(p->s); for (int n = 0; n < MP_ARRAY_SIZE(formats); n++) { const struct pl_format *fmt = &formats[n]; stream_seek(p->s, start); if (fmt->parse(p) >= 0) return fmt; } return NULL; }
static int mp_read(void *opaque, uint8_t *buf, int size) { demuxer_t *demuxer = opaque; stream_t *stream = demuxer->stream; int ret; ret=stream_read(stream, buf, size); mp_msg(MSGT_HEADER,MSGL_DBG2,"%d=mp_read(%p, %p, %d), pos: %"PRId64", eof:%d\n", ret, stream, buf, size, stream_tell(stream), stream->eof); return ret; }
static int load_image(Image *p, Stream *st) { GIF_info *g_info; int c; g_info = GIFReadSignature(st, &c); if (c != 0) { if (c == NOENOUGHMEM) err_message("gif loader: No enough memory for g_info.\n"); return (c == NOTGIFFILE) ? LOAD_NOT : LOAD_ERROR; } if (g_info->revision != 87 && g_info->revision != 89) { err_message("gif loader: GIF87a or GIF89a only...sorry\n"); return LOAD_ERROR; } if (GIFReadScreenDescriptor(st, g_info) != SUCCESS) { err_message("No enough memory for sd.\n"); return LOAD_ERROR; } if (g_info->sd->aspect_ratio) { double ratio = (double)((g_info->sd->aspect_ratio + 15) / 64); if ((int)ratio != 1) warning("Aspect ratio = %f ... ignored\n", ratio); } do { c = GIFParseNextBlock(st, g_info); if (g_info->npics > 1) { GIFDestroyData(g_info); return LOAD_NOT; } } while (c == PARSE_OK); if (g_info->comment != NULL) p->comment = strdup(g_info->comment); if (c == PARSE_ERROR) err_message("gif loader: Parse error: %s at 0x%lX.\n", g_info->err, stream_tell(st)); gif_convert(p, g_info, g_info->top); /* TODO: Use Screen g_info->sd->width, g_info->sd->height */ GIFDestroyData(g_info); return LOAD_OK; }
// Runs in the cache thread static void cache_execute_control(struct priv *s) { uint64_t old_pos = stream_tell(s->stream); s->control_res = stream_control(s->stream, s->control, s->control_arg); s->control_flush = false; bool pos_changed = old_pos != stream_tell(s->stream); bool ok = s->control_res == STREAM_OK; if (pos_changed && !ok) { mp_msg(MSGT_STREAM, MSGL_ERR, "STREAM_CTRL changed stream pos but " "returned error, this is not allowed!\n"); } else if (pos_changed || (ok && control_needs_flush(s->control))) { mp_msg(MSGT_CACHE, MSGL_V, "Dropping cache due to control()\n"); s->read_filepos = stream_tell(s->stream); s->control_flush = true; cache_drop_contents(s); } s->control = CACHE_CTRL_NONE; pthread_cond_signal(&s->wakeup); }