|
|
|
|
/*
|
|
|
|
|
** <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;
|
|
|
|
|
}
|