예제 #1
0
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;
}
예제 #2
0
파일: cache.c 프로젝트: ThreeGe/mpv
// 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);
}
예제 #3
0
파일: psion.cpp 프로젝트: bradhugh/mame
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;
}
예제 #4
0
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;
}
예제 #5
0
// 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;
}
예제 #6
0
// 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;
}
예제 #7
0
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;
}
예제 #9
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");
    }
}
예제 #10
0
파일: psion.cpp 프로젝트: bradhugh/mame
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;
}
예제 #11
0
파일: psion.cpp 프로젝트: bradhugh/mame
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;
}
예제 #12
0
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 ) );
}
예제 #13
0
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;
}
예제 #16
0
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 );
}
예제 #17
0
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;
}
예제 #18
0
// 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;
}
예제 #19
0
파일: ebml.c 프로젝트: ihling/mpv
/*
 * 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;
}
예제 #20
0
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;
}
예제 #21
0
/// 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;
}
예제 #22
0
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;
}
예제 #23
0
파일: stream.c 프로젝트: yamad/libabf
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);
}
예제 #24
0
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");
}
예제 #25
0
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;
}
예제 #26
0
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;
}
예제 #27
0
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;
}
예제 #28
0
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;
}
예제 #29
0
파일: gif.c 프로젝트: sina-ht/enfle
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;
}
예제 #30
0
파일: cache.c 프로젝트: CrimsonVoid/mpv
// 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);
}