You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

325 lines
7.6 KiB

/*
** <EFBFBD>л<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĺ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD> ByteIOContext <EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
** ByteIOContext<EFBFBD><EFBFBD>URLContext<EFBFBD>IJ<EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>ByteIOContext<EFBFBD>Ǵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD>ByteIOContext<EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǻ<EFBFBD><EFBFBD>ڻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
** <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>URLContext<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݽ<EFBFBD><EFBFBD><EFBFBD>ByteIOContext<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>URLContext<EFBFBD><EFBFBD>ByteIOContext<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ByteIOContext<EFBFBD>ĵײ<EFBFBD>
*/
#include "../berrno.h"
#include "avformat.h"
#include "avio.h"
#include <stdarg.h>
/* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
#define IO_BUFFER_SIZE 32768
/*
** <EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD> ByteIOContext <EFBFBD>
*/
int init_put_byte(ByteIOContext *s,
unsigned char *buffer,
int buffer_size,
int write_flag,
void *opaque,
int(*read_buf)(void *opaque, uint8_t *buf, int buf_size),
int(*write_buf)(void *opaque, uint8_t *buf, int buf_size),
offset_t(*seek)(void *opaque, offset_t offset, int whence))
{
s->buffer = buffer;
s->buffer_size = buffer_size;
s->buf_ptr = buffer;
s->write_flag = write_flag;
if (!s->write_flag)
s->buf_end = buffer;
else
s->buf_end = buffer + buffer_size;
s->opaque = opaque;
s->write_buf = write_buf;
s->read_buf = read_buf;
s->seek = seek;
s->pos = 0;
s->must_flush = 0;
s->eof_reached = 0;
s->error = 0;
s->max_packet_size = 0;
return 0;
}
/*
** <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD> ByteIOContext <EFBFBD><EFBFBD> seek <EFBFBD><EFBFBD><EFBFBD><EFBFBD>
*/
offset_t url_fseek(ByteIOContext *s, offset_t offset, int whence)
{
offset_t offset1;
if (whence != SEEK_CUR && whence != SEEK_SET)
return - EINVAL;
if (whence == SEEK_CUR)
{
offset1 = s->pos - (s->buf_end - s->buffer) + (s->buf_ptr - s->buffer);
if (offset == 0)
return offset1;
offset += offset1;
}
offset1 = offset - (s->pos - (s->buf_end - s->buffer));
if (offset1 >= 0 && offset1 <= (s->buf_end - s->buffer))
{
s->buf_ptr = s->buffer + offset1; // can do the seek inside the buffer
}
else
{
if (!s->seek)
return - EPIPE;
s->buf_ptr = s->buffer;
s->buf_end = s->buffer;
if (s->seek(s->opaque, offset, SEEK_SET) == (offset_t) - EPIPE)
return - EPIPE;
s->pos = offset;
}
s->eof_reached = 0;
return offset;
}
/* <EFBFBD><EFBFBD>ת */
void url_fskip(ByteIOContext *s, offset_t offset)
{
url_fseek(s, offset, SEEK_CUR);
}
/* <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
offset_t url_ftell(ByteIOContext *s)
{
return url_fseek(s, 0, SEEK_CUR);
}
/* <EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>С */
offset_t url_fsize(ByteIOContext *s)
{
offset_t size;
if (!s->seek)
return - EPIPE;
size = s->seek(s->opaque, - 1, SEEK_END) + 1;
s->seek(s->opaque, s->pos, SEEK_SET);
return size;
}
/* <EFBFBD>Ƿ񵽴<EFBFBD><EFBFBD>ļ<EFBFBD>β */
int url_feof(ByteIOContext *s)
{
return s->eof_reached;
}
/* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
int url_ferror(ByteIOContext *s)
{
return s->error;
}
// Input stream
/* <EFBFBD><EFBFBD><EFBFBD><EFBFBD>buffer<EFBFBD><EFBFBD>Ҳ<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD>ļ<EFBFBD><EFBFBD>IJ<EFBFBD><EFBFBD><EFBFBD> */
static void fill_buffer(ByteIOContext *s)
{
int len;
if (s->eof_reached)
return ;
len = s->read_buf(s->opaque, s->buffer, s->buffer_size);
if (len <= 0)
{ // do not modify buffer if EOF reached so that a seek back can be done without rereading data
s->eof_reached = 1;
if (len < 0)
s->error = len;
}
else
{
s->pos += len;
s->buf_ptr = s->buffer;
s->buf_end = s->buffer + len;
}
}
/* <EFBFBD><EFBFBD>ȡһ<EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD> */
int get_byte(ByteIOContext *s) // NOTE: return 0 if EOF, so you cannot use it if EOF handling is necessary
{
if (s->buf_ptr < s->buf_end)
{
return *s->buf_ptr++;
}
else
{
// <EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
fill_buffer(s);
if (s->buf_ptr < s->buf_end)
return *s->buf_ptr++;
else
return 0;
}
}
/* <EFBFBD>ӹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD> ByteIOContext <EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>˷<EFBFBD>ʽ<EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD> get_byte()<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
unsigned int get_le16(ByteIOContext *s)
{
unsigned int val;
val = get_byte(s);
val |= get_byte(s) << 8;
return val;
}
/* <EFBFBD>ӹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD> ByteIOContext <EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>˷<EFBFBD>ʽ<EFBFBD><EFBFBD>ȡ<EFBFBD>ĸ<EFBFBD><EFBFBD>ֽ<EFBFBD><EFBFBD>ִ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD> get_le16()<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
unsigned int get_le32(ByteIOContext *s)
{
unsigned int val;
val = get_le16(s);
val |= get_le16(s) << 16;
return val;
}
#define url_write_buf NULL
/* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
static int url_read_buf(void *opaque, uint8_t *buf, int buf_size)
{
URLContext *h = opaque;
return url_read(h, buf, buf_size);
}
/* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ת seek <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
static offset_t url_seek_buf(void *opaque, offset_t offset, int whence)
{
URLContext *h = opaque;
return url_seek(h, offset, whence);
}
/* <EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD> ByteIOContext <EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĵ<EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
int url_setbufsize(ByteIOContext *s, int buf_size) // must be called before any I/O
{
uint8_t *buffer;
buffer = av_malloc(buf_size);
if (!buffer)
return - ENOMEM;
av_free(s->buffer);
s->buffer = buffer;
s->buffer_size = buf_size;
s->buf_ptr = buffer;
if (!s->write_flag)
s->buf_end = buffer;
else
s->buf_end = buffer + buf_size;
return 0;
}
/* <EFBFBD>򿪹<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD> ByteIOContext */
int url_fopen(ByteIOContext *s, const char *filename, int flags)
{
URLContext *h;
uint8_t *buffer;
int buffer_size, max_packet_size;
int err;
err = url_open(&h, filename, flags);
if (err < 0)
return err;
max_packet_size = url_get_max_packet_size(h);
if (max_packet_size)
{
buffer_size = max_packet_size; // no need to bufferize more than one packet
}
else
{
buffer_size = IO_BUFFER_SIZE;
}
buffer = av_malloc(buffer_size);
if (!buffer)
{
url_close(h);
return - ENOMEM;
}
if (init_put_byte(s,
buffer,
buffer_size,
(h->flags & URL_WRONLY || h->flags & URL_RDWR),
h,
url_read_buf,
url_write_buf,
url_seek_buf) < 0)
{
url_close(h);
av_free(buffer);
return AVERROR_IO;
}
s->max_packet_size = max_packet_size;
return 0;
}
/* <EFBFBD>رչ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD> ByteIOContext */
int url_fclose(ByteIOContext *s)
{
URLContext *h = s->opaque;
av_free(s->buffer);
memset(s, 0, sizeof(ByteIOContext));
return url_close(h);
}
/* <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD> ByteIOContext <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
int url_fread(ByteIOContext *s, unsigned char *buf, int size) // get_buffer
{
int len, size1;
size1 = size;
while (size > 0)
{
len = s->buf_end - s->buf_ptr;
if (len > size)
len = size;
if (len == 0)
{
if (size > s->buffer_size)
{
len = s->read_buf(s->opaque, buf, size);
if (len <= 0)
{
s->eof_reached = 1;
if (len < 0)
s->error = len;
break;
}
else
{
s->pos += len;
size -= len;
buf += len;
s->buf_ptr = s->buffer;
s->buf_end = s->buffer /* + len*/;
}
}
else
{
fill_buffer(s);
len = s->buf_end - s->buf_ptr;
if (len == 0)
break;
}
}
else
{
memcpy(buf, s->buf_ptr, len);
buf += len;
s->buf_ptr += len;
size -= len;
}
}
return size1 - size;
}