mirror of https://github.com/mpv-player/mpv
stream: uncrustify stream.c/.h
The formatting almost made me break out in tears.
This commit is contained in:
parent
42b47624f8
commit
47cec75291
384
stream/stream.c
384
stream/stream.c
|
@ -54,10 +54,10 @@
|
||||||
#include "cache2.h"
|
#include "cache2.h"
|
||||||
|
|
||||||
/// We keep these 2 for the gui atm, but they will be removed.
|
/// We keep these 2 for the gui atm, but they will be removed.
|
||||||
int vcd_track=0;
|
int vcd_track = 0;
|
||||||
char* cdrom_device=NULL;
|
char *cdrom_device = NULL;
|
||||||
char* dvd_device=NULL;
|
char *dvd_device = NULL;
|
||||||
int dvd_title=0;
|
int dvd_title = 0;
|
||||||
|
|
||||||
struct input_ctx;
|
struct input_ctx;
|
||||||
static int (*stream_check_interrupt_cb)(struct input_ctx *ctx, int time);
|
static int (*stream_check_interrupt_cb)(struct input_ctx *ctx, int time);
|
||||||
|
@ -86,7 +86,7 @@ extern const stream_info_t stream_info_ifo;
|
||||||
extern const stream_info_t stream_info_dvd;
|
extern const stream_info_t stream_info_dvd;
|
||||||
extern const stream_info_t stream_info_bluray;
|
extern const stream_info_t stream_info_bluray;
|
||||||
|
|
||||||
static const stream_info_t* const auto_open_streams[] = {
|
static const stream_info_t *const auto_open_streams[] = {
|
||||||
#ifdef CONFIG_VCD
|
#ifdef CONFIG_VCD
|
||||||
&stream_info_vcd,
|
&stream_info_vcd,
|
||||||
#endif
|
#endif
|
||||||
|
@ -142,30 +142,33 @@ static stream_t *open_stream_plugin(const stream_info_t *sinfo,
|
||||||
int *file_format, int *ret,
|
int *file_format, int *ret,
|
||||||
char **redirected_url)
|
char **redirected_url)
|
||||||
{
|
{
|
||||||
void* arg = NULL;
|
void *arg = NULL;
|
||||||
stream_t* s;
|
stream_t *s;
|
||||||
m_struct_t* desc = (m_struct_t*)sinfo->opts;
|
m_struct_t *desc = (m_struct_t *)sinfo->opts;
|
||||||
|
|
||||||
// Parse options
|
// Parse options
|
||||||
if(desc) {
|
if (desc) {
|
||||||
arg = m_struct_alloc(desc);
|
arg = m_struct_alloc(desc);
|
||||||
if(sinfo->opts_url) {
|
if (sinfo->opts_url) {
|
||||||
m_option_t url_opt =
|
m_option_t url_opt = { "stream url", arg, CONF_TYPE_CUSTOM_URL, 0,
|
||||||
{ "stream url", arg , CONF_TYPE_CUSTOM_URL, 0, 0 ,0, (void *)sinfo->opts };
|
0, 0, (void *)sinfo->opts };
|
||||||
if (m_option_parse(&url_opt, bstr0("stream url"), bstr0(filename), arg) < 0) {
|
if (m_option_parse(&url_opt, bstr0("stream url"), bstr0(filename),
|
||||||
mp_tmsg(MSGT_OPEN,MSGL_ERR, "URL parsing failed on url %s\n",filename);
|
arg) < 0)
|
||||||
m_struct_free(desc,arg);
|
{
|
||||||
|
mp_tmsg(MSGT_OPEN, MSGL_ERR, "URL parsing failed on url %s\n",
|
||||||
|
filename);
|
||||||
|
m_struct_free(desc, arg);
|
||||||
*ret = STREAM_ERROR;
|
*ret = STREAM_ERROR;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
s = new_stream(-2,-2);
|
s = new_stream(-2, -2);
|
||||||
s->opts = options;
|
s->opts = options;
|
||||||
s->url=strdup(filename);
|
s->url = strdup(filename);
|
||||||
s->flags |= mode;
|
s->flags |= mode;
|
||||||
*ret = sinfo->open(s,mode,arg,file_format);
|
*ret = sinfo->open(s, mode, arg, file_format);
|
||||||
if((*ret) != STREAM_OK) {
|
if ((*ret) != STREAM_OK) {
|
||||||
#ifdef CONFIG_NETWORKING
|
#ifdef CONFIG_NETWORKING
|
||||||
if (*ret == STREAM_REDIRECTED && redirected_url) {
|
if (*ret == STREAM_REDIRECTED && redirected_url) {
|
||||||
if (s->streaming_ctrl && s->streaming_ctrl->url
|
if (s->streaming_ctrl && s->streaming_ctrl->url
|
||||||
|
@ -186,19 +189,19 @@ static stream_t *open_stream_plugin(const stream_info_t *sinfo,
|
||||||
s->cache_size = 320;
|
s->cache_size = 320;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(s->type <= -2)
|
if (s->type <= -2)
|
||||||
mp_msg(MSGT_OPEN,MSGL_WARN, "Warning streams need a type !!!!\n");
|
mp_msg(MSGT_OPEN, MSGL_WARN, "Warning streams need a type !!!!\n");
|
||||||
if(s->flags & MP_STREAM_SEEK && !s->seek)
|
if (s->flags & MP_STREAM_SEEK && !s->seek)
|
||||||
s->flags &= ~MP_STREAM_SEEK;
|
s->flags &= ~MP_STREAM_SEEK;
|
||||||
if(s->seek && !(s->flags & MP_STREAM_SEEK))
|
if (s->seek && !(s->flags & MP_STREAM_SEEK))
|
||||||
s->flags |= MP_STREAM_SEEK;
|
s->flags |= MP_STREAM_SEEK;
|
||||||
|
|
||||||
s->mode = mode;
|
s->mode = mode;
|
||||||
|
|
||||||
mp_msg(MSGT_OPEN,MSGL_V, "STREAM: [%s] %s\n",sinfo->name,filename);
|
mp_msg(MSGT_OPEN, MSGL_V, "STREAM: [%s] %s\n", sinfo->name, filename);
|
||||||
mp_msg(MSGT_OPEN,MSGL_V, "STREAM: Description: %s\n",sinfo->info);
|
mp_msg(MSGT_OPEN, MSGL_V, "STREAM: Description: %s\n", sinfo->info);
|
||||||
mp_msg(MSGT_OPEN,MSGL_V, "STREAM: Author: %s\n", sinfo->author);
|
mp_msg(MSGT_OPEN, MSGL_V, "STREAM: Author: %s\n", sinfo->author);
|
||||||
mp_msg(MSGT_OPEN,MSGL_V, "STREAM: Comment: %s\n", sinfo->comment);
|
mp_msg(MSGT_OPEN, MSGL_V, "STREAM: Comment: %s\n", sinfo->comment);
|
||||||
|
|
||||||
if (s->mime_type)
|
if (s->mime_type)
|
||||||
mp_msg(MSGT_OPEN, MSGL_V, "Mime-type: '%s'\n", s->mime_type);
|
mp_msg(MSGT_OPEN, MSGL_V, "Mime-type: '%s'\n", s->mime_type);
|
||||||
|
@ -210,9 +213,9 @@ static stream_t *open_stream_plugin(const stream_info_t *sinfo,
|
||||||
static stream_t *open_stream_full(const char *filename, int mode,
|
static stream_t *open_stream_full(const char *filename, int mode,
|
||||||
struct MPOpts *options, int *file_format)
|
struct MPOpts *options, int *file_format)
|
||||||
{
|
{
|
||||||
int i,j,l,r;
|
int i, j, l, r;
|
||||||
const stream_info_t* sinfo;
|
const stream_info_t *sinfo;
|
||||||
stream_t* s;
|
stream_t *s;
|
||||||
char *redirected_url = NULL;
|
char *redirected_url = NULL;
|
||||||
|
|
||||||
assert(filename);
|
assert(filename);
|
||||||
|
@ -223,31 +226,38 @@ static stream_t *open_stream_full(const char *filename, int mode,
|
||||||
|
|
||||||
*file_format = DEMUXER_TYPE_UNKNOWN;
|
*file_format = DEMUXER_TYPE_UNKNOWN;
|
||||||
|
|
||||||
for(i = 0 ; auto_open_streams[i] ; i++) {
|
for (i = 0; auto_open_streams[i]; i++) {
|
||||||
sinfo = auto_open_streams[i];
|
sinfo = auto_open_streams[i];
|
||||||
if(!sinfo->protocols) {
|
if (!sinfo->protocols) {
|
||||||
mp_msg(MSGT_OPEN,MSGL_WARN, "Stream type %s has protocols == NULL, it's a bug\n", sinfo->name);
|
mp_msg(MSGT_OPEN, MSGL_WARN,
|
||||||
|
"Stream type %s has protocols == NULL, it's a bug\n",
|
||||||
|
sinfo->name);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
for(j = 0 ; sinfo->protocols[j] ; j++) {
|
for (j = 0; sinfo->protocols[j]; j++) {
|
||||||
l = strlen(sinfo->protocols[j]);
|
l = strlen(sinfo->protocols[j]);
|
||||||
// l == 0 => Don't do protocol matching (ie network and filenames)
|
// l == 0 => Don't do protocol matching (ie network and filenames)
|
||||||
if((l == 0 && !strstr(filename, "://")) ||
|
if ((l == 0 && !strstr(filename, "://")) ||
|
||||||
((strncasecmp(sinfo->protocols[j],filename,l) == 0) &&
|
((strncasecmp(sinfo->protocols[j], filename, l) == 0) &&
|
||||||
(strncmp("://",filename+l,3) == 0))) {
|
(strncmp("://", filename + l, 3) == 0))) {
|
||||||
*file_format = DEMUXER_TYPE_UNKNOWN;
|
*file_format = DEMUXER_TYPE_UNKNOWN;
|
||||||
s = open_stream_plugin(sinfo,filename,mode,options,file_format,&r,
|
s =
|
||||||
|
open_stream_plugin(sinfo, filename, mode, options,
|
||||||
|
file_format,
|
||||||
|
&r,
|
||||||
&redirected_url);
|
&redirected_url);
|
||||||
if(s) return s;
|
if (s)
|
||||||
if(r == STREAM_REDIRECTED && redirected_url) {
|
return s;
|
||||||
mp_msg(MSGT_OPEN,MSGL_V, "[%s] open %s redirected to %s\n",
|
if (r == STREAM_REDIRECTED && redirected_url) {
|
||||||
|
mp_msg(MSGT_OPEN, MSGL_V, "[%s] open %s redirected to %s\n",
|
||||||
sinfo->info, filename, redirected_url);
|
sinfo->info, filename, redirected_url);
|
||||||
s = open_stream_full(redirected_url, mode, options, file_format);
|
s = open_stream_full(redirected_url, mode, options,
|
||||||
|
file_format);
|
||||||
free(redirected_url);
|
free(redirected_url);
|
||||||
return s;
|
return s;
|
||||||
}
|
} else if (r != STREAM_UNSUPPORTED) {
|
||||||
else if(r != STREAM_UNSUPPORTED) {
|
mp_tmsg(MSGT_OPEN, MSGL_ERR, "Failed to open %s.\n",
|
||||||
mp_tmsg(MSGT_OPEN,MSGL_ERR, "Failed to open %s.\n",filename);
|
filename);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -255,19 +265,19 @@ static stream_t *open_stream_full(const char *filename, int mode,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
mp_tmsg(MSGT_OPEN,MSGL_ERR, "No stream found to handle url %s\n", filename);
|
mp_tmsg(MSGT_OPEN, MSGL_ERR, "No stream found to handle url %s\n", filename);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream_t* open_stream(const char *filename, struct MPOpts *options,
|
stream_t *open_stream(const char *filename, struct MPOpts *options,
|
||||||
int *file_format)
|
int *file_format)
|
||||||
{
|
{
|
||||||
return open_stream_full(filename,STREAM_READ,options,file_format);
|
return open_stream_full(filename, STREAM_READ, options, file_format);
|
||||||
}
|
}
|
||||||
|
|
||||||
stream_t *open_output_stream(const char *filename, struct MPOpts *options)
|
stream_t *open_output_stream(const char *filename, struct MPOpts *options)
|
||||||
{
|
{
|
||||||
return open_stream_full(filename,STREAM_WRITE,options,NULL);
|
return open_stream_full(filename, STREAM_WRITE, options, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
//=================== STREAMER =========================
|
//=================== STREAMER =========================
|
||||||
|
@ -284,9 +294,10 @@ static int stream_reconnect(stream_t *s)
|
||||||
do {
|
do {
|
||||||
if (retry >= MAX_RECONNECT_RETRIES)
|
if (retry >= MAX_RECONNECT_RETRIES)
|
||||||
return 0;
|
return 0;
|
||||||
if (retry) usec_sleep(RECONNECT_SLEEP_MS * 1000);
|
if (retry)
|
||||||
|
usec_sleep(RECONNECT_SLEEP_MS * 1000);
|
||||||
retry++;
|
retry++;
|
||||||
s->eof=1;
|
s->eof = 1;
|
||||||
stream_reset(s);
|
stream_reset(s);
|
||||||
} while (stream_seek_internal(s, pos) >= 0 || s->pos != pos); // seek failed
|
} while (stream_seek_internal(s, pos) >= 0 || s->pos != pos); // seek failed
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -296,30 +307,30 @@ int stream_read_internal(stream_t *s, void *buf, int len)
|
||||||
{
|
{
|
||||||
int orig_len = len;
|
int orig_len = len;
|
||||||
// we will retry even if we already reached EOF previously.
|
// we will retry even if we already reached EOF previously.
|
||||||
switch(s->type){
|
switch (s->type) {
|
||||||
case STREAMTYPE_STREAM:
|
case STREAMTYPE_STREAM:
|
||||||
#ifdef CONFIG_NETWORKING
|
if (s->streaming_ctrl != NULL && s->streaming_ctrl->streaming_read) {
|
||||||
if( s->streaming_ctrl!=NULL && s->streaming_ctrl->streaming_read ) {
|
len = s->streaming_ctrl->streaming_read(s->fd, buf, len,
|
||||||
len=s->streaming_ctrl->streaming_read(s->fd, buf, len, s->streaming_ctrl);
|
s->streaming_ctrl);
|
||||||
if (s->streaming_ctrl->status == streaming_stopped_e &&
|
if (s->streaming_ctrl->status == streaming_stopped_e &&
|
||||||
(!s->end_pos || s->pos == s->end_pos))
|
(!s->end_pos || s->pos == s->end_pos))
|
||||||
s->eof = 1;
|
s->eof = 1;
|
||||||
} else
|
} else {
|
||||||
#endif
|
|
||||||
if (s->fill_buffer)
|
if (s->fill_buffer)
|
||||||
len = s->fill_buffer(s, buf, len);
|
len = s->fill_buffer(s, buf, len);
|
||||||
else
|
else
|
||||||
len = read(s->fd, buf, len);
|
len = read(s->fd, buf, len);
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case STREAMTYPE_DS:
|
case STREAMTYPE_DS:
|
||||||
len = demux_read_data((demux_stream_t*)s->priv, buf, len);
|
len = demux_read_data((demux_stream_t *)s->priv, buf, len);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
len= s->fill_buffer ? s->fill_buffer(s, buf, len) : 0;
|
len = s->fill_buffer ? s->fill_buffer(s, buf, len) : 0;
|
||||||
}
|
}
|
||||||
if(len<=0){
|
if (len <= 0) {
|
||||||
// do not retry if this looks like proper eof
|
// do not retry if this looks like proper eof
|
||||||
if (s->eof || (s->end_pos && s->pos == s->end_pos))
|
if (s->eof || (s->end_pos && s->pos == s->end_pos))
|
||||||
goto eof_out;
|
goto eof_out;
|
||||||
|
@ -329,36 +340,38 @@ int stream_read_internal(stream_t *s, void *buf, int len)
|
||||||
if (!stream_reconnect(s))
|
if (!stream_reconnect(s))
|
||||||
goto eof_out;
|
goto eof_out;
|
||||||
// make sure EOF is set to ensure no endless loops
|
// make sure EOF is set to ensure no endless loops
|
||||||
s->eof=1;
|
s->eof = 1;
|
||||||
return stream_read_internal(s, buf, orig_len);
|
return stream_read_internal(s, buf, orig_len);
|
||||||
|
|
||||||
eof_out:
|
eof_out:
|
||||||
s->eof=1;
|
s->eof = 1;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
// When reading succeeded we are obviously not at eof.
|
// When reading succeeded we are obviously not at eof.
|
||||||
// This e.g. avoids issues with eof getting stuck when lavf seeks in MPEG-TS
|
// This e.g. avoids issues with eof getting stuck when lavf seeks in MPEG-TS
|
||||||
s->eof=0;
|
s->eof = 0;
|
||||||
s->pos+=len;
|
s->pos += len;
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int stream_fill_buffer(stream_t *s){
|
int stream_fill_buffer(stream_t *s)
|
||||||
|
{
|
||||||
int len = stream_read_internal(s, s->buffer, STREAM_BUFFER_SIZE);
|
int len = stream_read_internal(s, s->buffer, STREAM_BUFFER_SIZE);
|
||||||
if (len <= 0)
|
if (len <= 0)
|
||||||
return 0;
|
return 0;
|
||||||
s->buf_pos=0;
|
s->buf_pos = 0;
|
||||||
s->buf_len=len;
|
s->buf_len = len;
|
||||||
// printf("[%d]",len);fflush(stdout);
|
// printf("[%d]",len);fflush(stdout);
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
int stream_write_buffer(stream_t *s, unsigned char *buf, int len) {
|
int stream_write_buffer(stream_t *s, unsigned char *buf, int len)
|
||||||
|
{
|
||||||
int rd;
|
int rd;
|
||||||
if(!s->write_buffer)
|
if (!s->write_buffer)
|
||||||
return -1;
|
return -1;
|
||||||
rd = s->write_buffer(s, buf, len);
|
rd = s->write_buffer(s, buf, len);
|
||||||
if(rd < 0)
|
if (rd < 0)
|
||||||
return -1;
|
return -1;
|
||||||
s->pos += rd;
|
s->pos += rd;
|
||||||
assert(rd == len && "stream_write_buffer(): unexpected short write");
|
assert(rd == len && "stream_write_buffer(): unexpected short write");
|
||||||
|
@ -367,31 +380,33 @@ int stream_write_buffer(stream_t *s, unsigned char *buf, int len) {
|
||||||
|
|
||||||
int stream_seek_internal(stream_t *s, int64_t newpos)
|
int stream_seek_internal(stream_t *s, int64_t newpos)
|
||||||
{
|
{
|
||||||
if(newpos==0 || newpos!=s->pos){
|
if (newpos == 0 || newpos != s->pos) {
|
||||||
switch(s->type){
|
switch (s->type) {
|
||||||
case STREAMTYPE_STREAM:
|
case STREAMTYPE_STREAM:
|
||||||
//s->pos=newpos; // real seek
|
//s->pos=newpos; // real seek
|
||||||
// Some streaming protocol allow to seek backward and forward
|
// Some streaming protocol allow to seek backward and forward
|
||||||
// A function call that return -1 can tell that the protocol
|
// A function call that return -1 can tell that the protocol
|
||||||
// doesn't support seeking.
|
// doesn't support seeking.
|
||||||
#ifdef CONFIG_NETWORKING
|
#ifdef CONFIG_NETWORKING
|
||||||
if(s->seek) { // new stream seek is much cleaner than streaming_ctrl one
|
if (s->seek) { // new stream seek is much cleaner than streaming_ctrl one
|
||||||
if(!s->seek(s,newpos)) {
|
if (!s->seek(s, newpos)) {
|
||||||
mp_tmsg(MSGT_STREAM,MSGL_ERR, "Seek failed\n");
|
mp_tmsg(MSGT_STREAM, MSGL_ERR, "Seek failed\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( s->streaming_ctrl!=NULL && s->streaming_ctrl->streaming_seek ) {
|
if (s->streaming_ctrl != NULL &&
|
||||||
if( s->streaming_ctrl->streaming_seek( s->fd, newpos, s->streaming_ctrl )<0 ) {
|
s->streaming_ctrl->streaming_seek) {
|
||||||
mp_tmsg(MSGT_STREAM,MSGL_INFO,"Stream not seekable!\n");
|
if (s->streaming_ctrl->streaming_seek(s->fd, newpos,
|
||||||
|
s->streaming_ctrl) < 0) {
|
||||||
|
mp_tmsg(MSGT_STREAM, MSGL_INFO, "Stream not seekable!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if(newpos<s->pos){
|
if (newpos < s->pos) {
|
||||||
mp_tmsg(MSGT_STREAM, MSGL_INFO,
|
mp_tmsg(MSGT_STREAM, MSGL_INFO,
|
||||||
"Cannot seek backward in linear streams!\n");
|
"Cannot seek backward in linear streams!\n");
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -399,89 +414,98 @@ if(newpos==0 || newpos!=s->pos){
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// This should at the beginning as soon as all streams are converted
|
// This should at the beginning as soon as all streams are converted
|
||||||
if(!s->seek)
|
if (!s->seek)
|
||||||
return 0;
|
return 0;
|
||||||
// Now seek
|
// Now seek
|
||||||
if(!s->seek(s,newpos)) {
|
if (!s->seek(s, newpos)) {
|
||||||
mp_tmsg(MSGT_STREAM,MSGL_ERR, "Seek failed\n");
|
mp_tmsg(MSGT_STREAM, MSGL_ERR, "Seek failed\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// putchar('.');fflush(stdout);
|
// putchar('.');fflush(stdout);
|
||||||
//} else {
|
//} else {
|
||||||
// putchar('%');fflush(stdout);
|
// putchar('%');fflush(stdout);
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int stream_seek_long(stream_t *s,int64_t pos){
|
int stream_seek_long(stream_t *s, int64_t pos)
|
||||||
|
{
|
||||||
int res;
|
int res;
|
||||||
int64_t newpos=0;
|
int64_t newpos = 0;
|
||||||
|
|
||||||
// if( mp_msg_test(MSGT_STREAM,MSGL_DBG3) ) printf("seek_long to 0x%X\n",(unsigned int)pos);
|
// if( mp_msg_test(MSGT_STREAM,MSGL_DBG3) ) printf("seek_long to 0x%X\n",(unsigned int)pos);
|
||||||
|
|
||||||
s->buf_pos=s->buf_len=0;
|
s->buf_pos = s->buf_len = 0;
|
||||||
|
|
||||||
if(s->mode == STREAM_WRITE) {
|
if (s->mode == STREAM_WRITE) {
|
||||||
if(!s->seek || !s->seek(s,pos))
|
if (!s->seek || !s->seek(s, pos))
|
||||||
return 0;
|
return 0;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(s->sector_size)
|
if (s->sector_size)
|
||||||
newpos = (pos/s->sector_size)*s->sector_size;
|
newpos = (pos / s->sector_size) * s->sector_size;
|
||||||
else
|
else
|
||||||
newpos = pos&(~((int64_t)STREAM_BUFFER_SIZE-1));
|
newpos = pos & (~((int64_t)STREAM_BUFFER_SIZE - 1));
|
||||||
|
|
||||||
if( mp_msg_test(MSGT_STREAM,MSGL_DBG3) ){
|
if (mp_msg_test(MSGT_STREAM, MSGL_DBG3)) {
|
||||||
mp_msg(MSGT_STREAM,MSGL_DBG3, "s->pos=%"PRIX64" newpos=%"PRIX64" new_bufpos=%"PRIX64" buflen=%X \n",
|
mp_msg(
|
||||||
(int64_t)s->pos,(int64_t)newpos,(int64_t)pos,s->buf_len);
|
MSGT_STREAM, MSGL_DBG3,
|
||||||
}
|
"s->pos=%" PRIX64 " newpos=%" PRIX64 " new_bufpos=%" PRIX64
|
||||||
pos-=newpos;
|
" buflen=%X \n",
|
||||||
|
(int64_t)s->pos, (int64_t)newpos, (int64_t)pos, s->buf_len);
|
||||||
|
}
|
||||||
|
pos -= newpos;
|
||||||
|
|
||||||
res = stream_seek_internal(s, newpos);
|
res = stream_seek_internal(s, newpos);
|
||||||
if (res >= 0)
|
if (res >= 0)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
while(s->pos<newpos){
|
while (s->pos < newpos) {
|
||||||
if(stream_fill_buffer(s)<=0) break; // EOF
|
if (stream_fill_buffer(s) <= 0)
|
||||||
|
break; // EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
s->eof = 0; // EOF reset when seek succeeds.
|
s->eof = 0; // EOF reset when seek succeeds.
|
||||||
while (stream_fill_buffer(s) > 0) {
|
while (stream_fill_buffer(s) > 0) {
|
||||||
if(pos<=s->buf_len){
|
if (pos <= s->buf_len) {
|
||||||
s->buf_pos=pos; // byte position in sector
|
s->buf_pos = pos; // byte position in sector
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
pos -= s->buf_len;
|
pos -= s->buf_len;
|
||||||
}
|
|
||||||
// Fill failed, but seek still is a success.
|
|
||||||
s->pos += pos;
|
|
||||||
s->buf_pos = 0;
|
|
||||||
s->buf_len = 0;
|
|
||||||
|
|
||||||
mp_msg(MSGT_STREAM,MSGL_V,
|
|
||||||
"stream_seek: Seek to/past EOF: no buffer preloaded.\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void stream_reset(stream_t *s){
|
|
||||||
if(s->eof){
|
|
||||||
s->pos=0;
|
|
||||||
s->buf_pos=s->buf_len=0;
|
|
||||||
s->eof=0;
|
|
||||||
}
|
}
|
||||||
if(s->control) s->control(s,STREAM_CTRL_RESET,NULL);
|
// Fill failed, but seek still is a success.
|
||||||
|
s->pos += pos;
|
||||||
|
s->buf_pos = 0;
|
||||||
|
s->buf_len = 0;
|
||||||
|
|
||||||
|
mp_msg(MSGT_STREAM, MSGL_V,
|
||||||
|
"stream_seek: Seek to/past EOF: no buffer preloaded.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void stream_reset(stream_t *s)
|
||||||
|
{
|
||||||
|
if (s->eof) {
|
||||||
|
s->pos = 0;
|
||||||
|
s->buf_pos = s->buf_len = 0;
|
||||||
|
s->eof = 0;
|
||||||
|
}
|
||||||
|
if (s->control)
|
||||||
|
s->control(s, STREAM_CTRL_RESET, NULL);
|
||||||
//stream_seek(s,0);
|
//stream_seek(s,0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int stream_control(stream_t *s, int cmd, void *arg){
|
int stream_control(stream_t *s, int cmd, void *arg)
|
||||||
|
{
|
||||||
#ifdef CONFIG_STREAM_CACHE
|
#ifdef CONFIG_STREAM_CACHE
|
||||||
if (s->cache_pid)
|
if (s->cache_pid)
|
||||||
return cache_do_control(s, cmd, arg);
|
return cache_do_control(s, cmd, arg);
|
||||||
#endif
|
#endif
|
||||||
if(!s->control) return STREAM_UNSUPPORTED;
|
if (!s->control)
|
||||||
|
return STREAM_UNSUPPORTED;
|
||||||
return s->control(s, cmd, arg);
|
return s->control(s, cmd, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -494,64 +518,72 @@ void stream_update_size(stream_t *s)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stream_t* new_memory_stream(unsigned char* data,int len){
|
stream_t *new_memory_stream(unsigned char *data, int len)
|
||||||
|
{
|
||||||
stream_t *s;
|
stream_t *s;
|
||||||
|
|
||||||
if(len < 0)
|
if (len < 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
s=calloc(1, sizeof(stream_t)+len);
|
s = calloc(1, sizeof(stream_t) + len);
|
||||||
s->fd=-1;
|
s->fd = -1;
|
||||||
s->type=STREAMTYPE_MEMORY;
|
s->type = STREAMTYPE_MEMORY;
|
||||||
s->buf_pos=0; s->buf_len=len;
|
s->buf_pos = 0;
|
||||||
s->start_pos=0; s->end_pos=len;
|
s->buf_len = len;
|
||||||
|
s->start_pos = 0;
|
||||||
|
s->end_pos = len;
|
||||||
stream_reset(s);
|
stream_reset(s);
|
||||||
s->pos=len;
|
s->pos = len;
|
||||||
memcpy(s->buffer,data,len);
|
memcpy(s->buffer, data, len);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream_t* new_stream(int fd,int type){
|
stream_t *new_stream(int fd, int type)
|
||||||
stream_t *s=talloc_zero(NULL, stream_t);
|
{
|
||||||
|
stream_t *s = talloc_zero(NULL, stream_t);
|
||||||
|
|
||||||
#if HAVE_WINSOCK2_H
|
#if HAVE_WINSOCK2_H
|
||||||
{
|
{
|
||||||
WSADATA wsdata;
|
WSADATA wsdata;
|
||||||
int temp = WSAStartup(0x0202, &wsdata); // there might be a better place for this (-> later)
|
int temp = WSAStartup(0x0202, &wsdata); // there might be a better place for this (-> later)
|
||||||
mp_msg(MSGT_STREAM,MSGL_V,"WINSOCK2 init: %i\n", temp);
|
mp_msg(MSGT_STREAM, MSGL_V, "WINSOCK2 init: %i\n", temp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
s->fd=fd;
|
s->fd = fd;
|
||||||
s->type=type;
|
s->type = type;
|
||||||
stream_reset(s);
|
stream_reset(s);
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void free_stream(stream_t *s){
|
void free_stream(stream_t *s)
|
||||||
|
{
|
||||||
// printf("\n*** free_stream() called ***\n");
|
// printf("\n*** free_stream() called ***\n");
|
||||||
#ifdef CONFIG_STREAM_CACHE
|
#ifdef CONFIG_STREAM_CACHE
|
||||||
cache_uninit(s);
|
cache_uninit(s);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(s->close) s->close(s);
|
if (s->close)
|
||||||
if(s->fd>0){
|
s->close(s);
|
||||||
|
if (s->fd > 0) {
|
||||||
/* on unix we define closesocket to close
|
/* on unix we define closesocket to close
|
||||||
on windows however we have to distinguish between
|
on windows however we have to distinguish between
|
||||||
network socket and file */
|
network socket and file */
|
||||||
if(s->url && strstr(s->url,"://"))
|
if (s->url && strstr(s->url, "://"))
|
||||||
closesocket(s->fd);
|
closesocket(s->fd);
|
||||||
else close(s->fd);
|
else
|
||||||
|
close(s->fd);
|
||||||
}
|
}
|
||||||
#if HAVE_WINSOCK2_H
|
#if HAVE_WINSOCK2_H
|
||||||
mp_msg(MSGT_STREAM,MSGL_V,"WINSOCK2 uninit\n");
|
mp_msg(MSGT_STREAM, MSGL_V, "WINSOCK2 uninit\n");
|
||||||
WSACleanup(); // there might be a better place for this (-> later)
|
WSACleanup(); // there might be a better place for this (-> later)
|
||||||
#endif
|
#endif
|
||||||
free(s->url);
|
free(s->url);
|
||||||
talloc_free(s);
|
talloc_free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
stream_t* new_ds_stream(demux_stream_t *ds) {
|
stream_t *new_ds_stream(demux_stream_t *ds)
|
||||||
stream_t* s = new_stream(-1,STREAMTYPE_DS);
|
{
|
||||||
|
stream_t *s = new_stream(-1, STREAMTYPE_DS);
|
||||||
s->priv = ds;
|
s->priv = ds;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
@ -563,8 +595,9 @@ void stream_set_interrupt_callback(int (*cb)(struct input_ctx *, int),
|
||||||
stream_check_interrupt_ctx = ctx;
|
stream_check_interrupt_ctx = ctx;
|
||||||
}
|
}
|
||||||
|
|
||||||
int stream_check_interrupt(int time) {
|
int stream_check_interrupt(int time)
|
||||||
if(!stream_check_interrupt_cb) {
|
{
|
||||||
|
if (!stream_check_interrupt_cb) {
|
||||||
usec_sleep(time * 1000);
|
usec_sleep(time * 1000);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -607,14 +640,16 @@ static const uint8_t *find_newline(const uint8_t *buf, int len, int utf16)
|
||||||
return (uint8_t *)memchr(buf, '\n', len);
|
return (uint8_t *)memchr(buf, '\n', len);
|
||||||
case 1:
|
case 1:
|
||||||
while (buf < end - 1) {
|
while (buf < end - 1) {
|
||||||
GET_UTF16(c, buf < end - 1 ? get_le16_inc(&buf) : 0, return NULL;)
|
GET_UTF16(c, buf < end - 1 ? get_le16_inc(&buf) : 0, return NULL;
|
||||||
|
)
|
||||||
if (buf <= end && c == '\n')
|
if (buf <= end && c == '\n')
|
||||||
return buf - 1;
|
return buf - 1;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
while (buf < end - 1) {
|
while (buf < end - 1) {
|
||||||
GET_UTF16(c, buf < end - 1 ? get_be16_inc(&buf) : 0, return NULL;)
|
GET_UTF16(c, buf < end - 1 ? get_be16_inc(&buf) : 0, return NULL;
|
||||||
|
)
|
||||||
if (buf <= end && c == '\n')
|
if (buf <= end && c == '\n')
|
||||||
return buf - 1;
|
return buf - 1;
|
||||||
}
|
}
|
||||||
|
@ -647,16 +682,20 @@ static int copy_characters(uint8_t *dst, int dstsize,
|
||||||
case 1:
|
case 1:
|
||||||
while (src < end - 1 && dst_end - dst > 8) {
|
while (src < end - 1 && dst_end - dst > 8) {
|
||||||
uint8_t tmp;
|
uint8_t tmp;
|
||||||
GET_UTF16(c, src < end - 1 ? get_le16_inc(&src) : 0, ;)
|
GET_UTF16(c, src < end - 1 ? get_le16_inc(&src) : 0,;
|
||||||
PUT_UTF8(c, tmp, *dst++ = tmp;)
|
)
|
||||||
|
PUT_UTF8(c, tmp, *dst++ = tmp;
|
||||||
|
)
|
||||||
}
|
}
|
||||||
*len -= end - src;
|
*len -= end - src;
|
||||||
return dstsize - (dst_end - dst);
|
return dstsize - (dst_end - dst);
|
||||||
case 2:
|
case 2:
|
||||||
while (src < end - 1 && dst_end - dst > 8) {
|
while (src < end - 1 && dst_end - dst > 8) {
|
||||||
uint8_t tmp;
|
uint8_t tmp;
|
||||||
GET_UTF16(c, src < end - 1 ? get_be16_inc(&src) : 0, ;)
|
GET_UTF16(c, src < end - 1 ? get_be16_inc(&src) : 0,;
|
||||||
PUT_UTF8(c, tmp, *dst++ = tmp;)
|
)
|
||||||
|
PUT_UTF8(c, tmp, *dst++ = tmp;
|
||||||
|
)
|
||||||
}
|
}
|
||||||
*len -= end - src;
|
*len -= end - src;
|
||||||
return dstsize - (dst_end - dst);
|
return dstsize - (dst_end - dst);
|
||||||
|
@ -664,31 +703,38 @@ static int copy_characters(uint8_t *dst, int dstsize,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* stream_read_line(stream_t *s,unsigned char* mem, int max, int utf16) {
|
unsigned char *stream_read_line(stream_t *s, unsigned char *mem, int max,
|
||||||
|
int utf16)
|
||||||
|
{
|
||||||
int len;
|
int len;
|
||||||
const unsigned char *end;
|
const unsigned char *end;
|
||||||
unsigned char *ptr = mem;
|
unsigned char *ptr = mem;
|
||||||
if (max < 1) return NULL;
|
if (max < 1)
|
||||||
|
return NULL;
|
||||||
max--; // reserve one for 0-termination
|
max--; // reserve one for 0-termination
|
||||||
do {
|
do {
|
||||||
len = s->buf_len-s->buf_pos;
|
len = s->buf_len - s->buf_pos;
|
||||||
// try to fill the buffer
|
// try to fill the buffer
|
||||||
if(len <= 0 &&
|
if (len <= 0 &&
|
||||||
(!cache_stream_fill_buffer(s) ||
|
(!cache_stream_fill_buffer(s) ||
|
||||||
(len = s->buf_len-s->buf_pos) <= 0)) break;
|
(len = s->buf_len - s->buf_pos) <= 0))
|
||||||
end = find_newline(s->buffer+s->buf_pos, len, utf16);
|
break;
|
||||||
if(end) len = end - (s->buffer+s->buf_pos) + 1;
|
end = find_newline(s->buffer + s->buf_pos, len, utf16);
|
||||||
if(len > 0 && max > 0) {
|
if (end)
|
||||||
int l = copy_characters(ptr, max, s->buffer+s->buf_pos, &len, utf16);
|
len = end - (s->buffer + s->buf_pos) + 1;
|
||||||
|
if (len > 0 && max > 0) {
|
||||||
|
int l = copy_characters(ptr, max, s->buffer + s->buf_pos, &len,
|
||||||
|
utf16);
|
||||||
max -= l;
|
max -= l;
|
||||||
ptr += l;
|
ptr += l;
|
||||||
if (!len)
|
if (!len)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
s->buf_pos += len;
|
s->buf_pos += len;
|
||||||
} while(!end);
|
} while (!end);
|
||||||
ptr[0] = 0;
|
ptr[0] = 0;
|
||||||
if(s->eof && ptr == mem) return NULL;
|
if (s->eof && ptr == mem)
|
||||||
|
return NULL;
|
||||||
return mem;
|
return mem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -703,7 +749,9 @@ struct bstr stream_read_complete(struct stream *s, void *talloc_ctx,
|
||||||
int padding = FFMAX(padding_bytes, 1);
|
int padding = FFMAX(padding_bytes, 1);
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
if (s->end_pos > max_size)
|
if (s->end_pos > max_size)
|
||||||
return (struct bstr){NULL, 0};
|
return (struct bstr){
|
||||||
|
NULL, 0
|
||||||
|
};
|
||||||
if (s->end_pos > 0)
|
if (s->end_pos > 0)
|
||||||
bufsize = s->end_pos + padding;
|
bufsize = s->end_pos + padding;
|
||||||
else
|
else
|
||||||
|
@ -716,10 +764,14 @@ struct bstr stream_read_complete(struct stream *s, void *talloc_ctx,
|
||||||
break;
|
break;
|
||||||
if (bufsize > max_size) {
|
if (bufsize > max_size) {
|
||||||
talloc_free(buf);
|
talloc_free(buf);
|
||||||
return (struct bstr){NULL, 0};
|
return (struct bstr){
|
||||||
|
NULL, 0
|
||||||
|
};
|
||||||
}
|
}
|
||||||
bufsize = FFMIN(bufsize + (bufsize >> 1), max_size + padding);
|
bufsize = FFMIN(bufsize + (bufsize >> 1), max_size + padding);
|
||||||
}
|
}
|
||||||
buf = talloc_realloc_size(talloc_ctx, buf, total_read + padding);
|
buf = talloc_realloc_size(talloc_ctx, buf, total_read + padding);
|
||||||
return (struct bstr){buf, total_read};
|
return (struct bstr){
|
||||||
|
buf, total_read
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
216
stream/stream.h
216
stream/stream.h
|
@ -57,7 +57,7 @@
|
||||||
#define STREAMTYPE_AVDEVICE 21
|
#define STREAMTYPE_AVDEVICE 21
|
||||||
|
|
||||||
#define STREAM_BUFFER_SIZE 2048
|
#define STREAM_BUFFER_SIZE 2048
|
||||||
#define STREAM_MAX_SECTOR_SIZE (8*1024)
|
#define STREAM_MAX_SECTOR_SIZE (8 * 1024)
|
||||||
|
|
||||||
#define VCD_SECTOR_SIZE 2352
|
#define VCD_SECTOR_SIZE 2352
|
||||||
#define VCD_SECTOR_OFFS 24
|
#define VCD_SECTOR_OFFS 24
|
||||||
|
@ -71,7 +71,7 @@
|
||||||
/// MP_STREAM_SEEK is automaticly set
|
/// MP_STREAM_SEEK is automaticly set
|
||||||
#define MP_STREAM_SEEK_BW 2
|
#define MP_STREAM_SEEK_BW 2
|
||||||
#define MP_STREAM_SEEK_FW 4
|
#define MP_STREAM_SEEK_FW 4
|
||||||
#define MP_STREAM_SEEK (MP_STREAM_SEEK_BW|MP_STREAM_SEEK_FW)
|
#define MP_STREAM_SEEK (MP_STREAM_SEEK_BW | MP_STREAM_SEEK_FW)
|
||||||
|
|
||||||
//////////// Open return code
|
//////////// Open return code
|
||||||
#define STREAM_REDIRECTED -2
|
#define STREAM_REDIRECTED -2
|
||||||
|
@ -120,8 +120,10 @@ typedef struct streaming_control {
|
||||||
unsigned int buffer_size;
|
unsigned int buffer_size;
|
||||||
unsigned int buffer_pos;
|
unsigned int buffer_pos;
|
||||||
unsigned int bandwidth; // The downstream available
|
unsigned int bandwidth; // The downstream available
|
||||||
int (*streaming_read)( int fd, char *buffer, int buffer_size, struct streaming_control *stream_ctrl );
|
int (*streaming_read)(int fd, char *buffer, int buffer_size,
|
||||||
int (*streaming_seek)( int fd, int64_t pos, struct streaming_control *stream_ctrl );
|
struct streaming_control *stream_ctrl);
|
||||||
|
int (*streaming_seek)(int fd, int64_t pos,
|
||||||
|
struct streaming_control *stream_ctrl);
|
||||||
void *data;
|
void *data;
|
||||||
// hacks for asf
|
// hacks for asf
|
||||||
int *audio_id_ptr;
|
int *audio_id_ptr;
|
||||||
|
@ -137,9 +139,9 @@ typedef struct stream_info_st {
|
||||||
/// mode isn't used atm (ie always READ) but it shouldn't be ignored
|
/// mode isn't used atm (ie always READ) but it shouldn't be ignored
|
||||||
/// opts is at least in it's defaults settings and may have been
|
/// opts is at least in it's defaults settings and may have been
|
||||||
/// altered by url parsing if enabled and the options string parsing.
|
/// altered by url parsing if enabled and the options string parsing.
|
||||||
int (*open)(struct stream* st, int mode, void* opts, int* file_format);
|
int (*open)(struct stream *st, int mode, void *opts, int *file_format);
|
||||||
const char* protocols[MAX_STREAM_PROTOCOLS];
|
const char *protocols[MAX_STREAM_PROTOCOLS];
|
||||||
const void* opts;
|
const void *opts;
|
||||||
int opts_url; /* If this is 1 we will parse the url as an option string
|
int opts_url; /* If this is 1 we will parse the url as an option string
|
||||||
* too. Otherwise options are only parsed from the
|
* too. Otherwise options are only parsed from the
|
||||||
* options string given to open_stream_plugin */
|
* options string given to open_stream_plugin */
|
||||||
|
@ -147,15 +149,15 @@ typedef struct stream_info_st {
|
||||||
|
|
||||||
typedef struct stream {
|
typedef struct stream {
|
||||||
// Read
|
// Read
|
||||||
int (*fill_buffer)(struct stream *s, char* buffer, int max_len);
|
int (*fill_buffer)(struct stream *s, char *buffer, int max_len);
|
||||||
// Write
|
// Write
|
||||||
int (*write_buffer)(struct stream *s, char* buffer, int len);
|
int (*write_buffer)(struct stream *s, char *buffer, int len);
|
||||||
// Seek
|
// Seek
|
||||||
int (*seek)(struct stream *s,int64_t pos);
|
int (*seek)(struct stream *s, int64_t pos);
|
||||||
// Control
|
// Control
|
||||||
// Will be later used to let streams like dvd and cdda report
|
// Will be later used to let streams like dvd and cdda report
|
||||||
// their structure (ie tracks, chapters, etc)
|
// their structure (ie tracks, chapters, etc)
|
||||||
int (*control)(struct stream *s,int cmd,void* arg);
|
int (*control)(struct stream *s, int cmd, void *arg);
|
||||||
// Close
|
// Close
|
||||||
void (*close)(struct stream *s);
|
void (*close)(struct stream *s);
|
||||||
|
|
||||||
|
@ -164,22 +166,24 @@ typedef struct stream {
|
||||||
int flags;
|
int flags;
|
||||||
int sector_size; // sector size (seek will be aligned on this size if non 0)
|
int sector_size; // sector size (seek will be aligned on this size if non 0)
|
||||||
int read_chunk; // maximum amount of data to read at once to limit latency (0 for default)
|
int read_chunk; // maximum amount of data to read at once to limit latency (0 for default)
|
||||||
unsigned int buf_pos,buf_len;
|
unsigned int buf_pos, buf_len;
|
||||||
int64_t pos,start_pos,end_pos;
|
int64_t pos, start_pos, end_pos;
|
||||||
int eof;
|
int eof;
|
||||||
int mode; //STREAM_READ or STREAM_WRITE
|
int mode; //STREAM_READ or STREAM_WRITE
|
||||||
bool streaming; // known to be a network stream if true
|
bool streaming; // known to be a network stream if true
|
||||||
int cache_size; // cache size in KB to use if enabled
|
int cache_size; // cache size in KB to use if enabled
|
||||||
bool cached; // cache active
|
bool cached; // cache active
|
||||||
unsigned int cache_pid;
|
unsigned int cache_pid;
|
||||||
void* cache_data;
|
void *cache_data;
|
||||||
void* priv; // used for DVD, TV, RTSP etc
|
void *priv; // used for DVD, TV, RTSP etc
|
||||||
char* url; // strdup() of filename/url
|
char *url; // strdup() of filename/url
|
||||||
char *mime_type; // when HTTP streaming is used
|
char *mime_type; // when HTTP streaming is used
|
||||||
char *lavf_type; // name of expected demuxer type for lavf
|
char *lavf_type; // name of expected demuxer type for lavf
|
||||||
struct MPOpts *opts;
|
struct MPOpts *opts;
|
||||||
streaming_ctrl_t *streaming_ctrl;
|
streaming_ctrl_t *streaming_ctrl;
|
||||||
unsigned char buffer[STREAM_BUFFER_SIZE>STREAM_MAX_SECTOR_SIZE?STREAM_BUFFER_SIZE:STREAM_MAX_SECTOR_SIZE];
|
unsigned char buffer[STREAM_BUFFER_SIZE >
|
||||||
|
STREAM_MAX_SECTOR_SIZE ? STREAM_BUFFER_SIZE :
|
||||||
|
STREAM_MAX_SECTOR_SIZE];
|
||||||
} stream_t;
|
} stream_t;
|
||||||
|
|
||||||
#ifdef CONFIG_NETWORKING
|
#ifdef CONFIG_NETWORKING
|
||||||
|
@ -191,154 +195,180 @@ int stream_seek_long(stream_t *s, int64_t pos);
|
||||||
|
|
||||||
#ifdef CONFIG_STREAM_CACHE
|
#ifdef CONFIG_STREAM_CACHE
|
||||||
int stream_enable_cache_percent(stream_t *stream, int64_t stream_cache_size,
|
int stream_enable_cache_percent(stream_t *stream, int64_t stream_cache_size,
|
||||||
float stream_cache_min_percent, float stream_cache_seek_min_percent);
|
float stream_cache_min_percent,
|
||||||
int stream_enable_cache(stream_t *stream,int64_t size,int64_t min,int64_t prefill);
|
float stream_cache_seek_min_percent);
|
||||||
|
int stream_enable_cache(stream_t *stream, int64_t size, int64_t min,
|
||||||
|
int64_t prefill);
|
||||||
int cache_stream_fill_buffer(stream_t *s);
|
int cache_stream_fill_buffer(stream_t *s);
|
||||||
int cache_stream_seek_long(stream_t *s,int64_t pos);
|
int cache_stream_seek_long(stream_t *s, int64_t pos);
|
||||||
#else
|
#else
|
||||||
// no cache, define wrappers:
|
// no cache, define wrappers:
|
||||||
#define cache_stream_fill_buffer(x) stream_fill_buffer(x)
|
#define cache_stream_fill_buffer(x) stream_fill_buffer(x)
|
||||||
#define cache_stream_seek_long(x,y) stream_seek_long(x,y)
|
#define cache_stream_seek_long(x, y) stream_seek_long(x, y)
|
||||||
#define stream_enable_cache(x,y,z,w) 1
|
#define stream_enable_cache(x, y, z, w) 1
|
||||||
#define stream_enable_cache_percent(x,y,z,w) 1
|
#define stream_enable_cache_percent(x, y, z, w) 1
|
||||||
#endif
|
#endif
|
||||||
int stream_write_buffer(stream_t *s, unsigned char *buf, int len);
|
int stream_write_buffer(stream_t *s, unsigned char *buf, int len);
|
||||||
|
|
||||||
inline static int stream_read_char(stream_t *s){
|
inline static int stream_read_char(stream_t *s)
|
||||||
return (s->buf_pos<s->buf_len)?s->buffer[s->buf_pos++]:
|
{
|
||||||
(cache_stream_fill_buffer(s)?s->buffer[s->buf_pos++]:-256);
|
return (s->buf_pos < s->buf_len) ? s->buffer[s->buf_pos++] :
|
||||||
|
(cache_stream_fill_buffer(s) ? s->buffer[s->buf_pos++] : -256);
|
||||||
// if(s->buf_pos<s->buf_len) return s->buffer[s->buf_pos++];
|
// if(s->buf_pos<s->buf_len) return s->buffer[s->buf_pos++];
|
||||||
// stream_fill_buffer(s);
|
// stream_fill_buffer(s);
|
||||||
// if(s->buf_pos<s->buf_len) return s->buffer[s->buf_pos++];
|
// if(s->buf_pos<s->buf_len) return s->buffer[s->buf_pos++];
|
||||||
// return 0; // EOF
|
// return 0; // EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static unsigned int stream_read_word(stream_t *s){
|
inline static unsigned int stream_read_word(stream_t *s)
|
||||||
int x,y;
|
{
|
||||||
x=stream_read_char(s);
|
int x, y;
|
||||||
y=stream_read_char(s);
|
x = stream_read_char(s);
|
||||||
return (x<<8)|y;
|
y = stream_read_char(s);
|
||||||
|
return (x << 8) | y;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static unsigned int stream_read_dword(stream_t *s){
|
inline static unsigned int stream_read_dword(stream_t *s)
|
||||||
|
{
|
||||||
unsigned int y;
|
unsigned int y;
|
||||||
y=stream_read_char(s);
|
y = stream_read_char(s);
|
||||||
y=(y<<8)|stream_read_char(s);
|
y = (y << 8) | stream_read_char(s);
|
||||||
y=(y<<8)|stream_read_char(s);
|
y = (y << 8) | stream_read_char(s);
|
||||||
y=(y<<8)|stream_read_char(s);
|
y = (y << 8) | stream_read_char(s);
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define stream_read_fourcc stream_read_dword_le
|
#define stream_read_fourcc stream_read_dword_le
|
||||||
|
|
||||||
inline static unsigned int stream_read_word_le(stream_t *s){
|
inline static unsigned int stream_read_word_le(stream_t *s)
|
||||||
int x,y;
|
{
|
||||||
x=stream_read_char(s);
|
int x, y;
|
||||||
y=stream_read_char(s);
|
x = stream_read_char(s);
|
||||||
return (y<<8)|x;
|
y = stream_read_char(s);
|
||||||
|
return (y << 8) | x;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static uint32_t stream_read_dword_le(stream_t *s)
|
inline static uint32_t stream_read_dword_le(stream_t *s)
|
||||||
{
|
{
|
||||||
unsigned int y;
|
unsigned int y;
|
||||||
y=stream_read_char(s);
|
y = stream_read_char(s);
|
||||||
y|=stream_read_char(s)<<8;
|
y |= stream_read_char(s) << 8;
|
||||||
y|=stream_read_char(s)<<16;
|
y |= stream_read_char(s) << 16;
|
||||||
y|=stream_read_char(s)<<24;
|
y |= stream_read_char(s) << 24;
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static uint64_t stream_read_qword(stream_t *s){
|
inline static uint64_t stream_read_qword(stream_t *s)
|
||||||
|
{
|
||||||
uint64_t y;
|
uint64_t y;
|
||||||
y = stream_read_char(s);
|
y = stream_read_char(s);
|
||||||
y=(y<<8)|stream_read_char(s);
|
y = (y << 8) | stream_read_char(s);
|
||||||
y=(y<<8)|stream_read_char(s);
|
y = (y << 8) | stream_read_char(s);
|
||||||
y=(y<<8)|stream_read_char(s);
|
y = (y << 8) | stream_read_char(s);
|
||||||
y=(y<<8)|stream_read_char(s);
|
y = (y << 8) | stream_read_char(s);
|
||||||
y=(y<<8)|stream_read_char(s);
|
y = (y << 8) | stream_read_char(s);
|
||||||
y=(y<<8)|stream_read_char(s);
|
y = (y << 8) | stream_read_char(s);
|
||||||
y=(y<<8)|stream_read_char(s);
|
y = (y << 8) | stream_read_char(s);
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static uint64_t stream_read_qword_le(stream_t *s){
|
inline static uint64_t stream_read_qword_le(stream_t *s)
|
||||||
|
{
|
||||||
uint64_t y;
|
uint64_t y;
|
||||||
y = stream_read_dword_le(s);
|
y = stream_read_dword_le(s);
|
||||||
y|=(uint64_t)stream_read_dword_le(s)<<32;
|
y |= (uint64_t)stream_read_dword_le(s) << 32;
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static unsigned int stream_read_int24(stream_t *s){
|
inline static unsigned int stream_read_int24(stream_t *s)
|
||||||
|
{
|
||||||
unsigned int y;
|
unsigned int y;
|
||||||
y = stream_read_char(s);
|
y = stream_read_char(s);
|
||||||
y=(y<<8)|stream_read_char(s);
|
y = (y << 8) | stream_read_char(s);
|
||||||
y=(y<<8)|stream_read_char(s);
|
y = (y << 8) | stream_read_char(s);
|
||||||
return y;
|
return y;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static int stream_read(stream_t *s,char* mem,int total){
|
inline static int stream_read(stream_t *s, char *mem, int total)
|
||||||
int len=total;
|
{
|
||||||
while(len>0){
|
int len = total;
|
||||||
|
while (len > 0) {
|
||||||
int x;
|
int x;
|
||||||
x=s->buf_len-s->buf_pos;
|
x = s->buf_len - s->buf_pos;
|
||||||
if(x==0){
|
if (x == 0) {
|
||||||
if(!cache_stream_fill_buffer(s)) return total-len; // EOF
|
if (!cache_stream_fill_buffer(s))
|
||||||
x=s->buf_len-s->buf_pos;
|
return total - len; // EOF
|
||||||
|
x = s->buf_len - s->buf_pos;
|
||||||
}
|
}
|
||||||
if(s->buf_pos>s->buf_len) mp_msg(MSGT_DEMUX, MSGL_WARN, "stream_read: WARNING! s->buf_pos>s->buf_len\n");
|
if (s->buf_pos > s->buf_len)
|
||||||
if(x>len) x=len;
|
mp_msg(MSGT_DEMUX, MSGL_WARN,
|
||||||
memcpy(mem,&s->buffer[s->buf_pos],x);
|
"stream_read: WARNING! s->buf_pos>s->buf_len\n");
|
||||||
s->buf_pos+=x; mem+=x; len-=x;
|
if (x > len)
|
||||||
|
x = len;
|
||||||
|
memcpy(mem, &s->buffer[s->buf_pos], x);
|
||||||
|
s->buf_pos += x;
|
||||||
|
mem += x;
|
||||||
|
len -= x;
|
||||||
}
|
}
|
||||||
return total;
|
return total;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char* stream_read_line(stream_t *s,unsigned char* mem, int max, int utf16);
|
unsigned char *stream_read_line(stream_t *s, unsigned char *mem, int max,
|
||||||
|
int utf16);
|
||||||
|
|
||||||
inline static int stream_eof(stream_t *s){
|
inline static int stream_eof(stream_t *s)
|
||||||
|
{
|
||||||
return s->eof;
|
return s->eof;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static int64_t stream_tell(stream_t *s){
|
inline static int64_t stream_tell(stream_t *s)
|
||||||
return s->pos+s->buf_pos-s->buf_len;
|
{
|
||||||
|
return s->pos + s->buf_pos - s->buf_len;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static int stream_seek(stream_t *s,int64_t pos){
|
inline static int stream_seek(stream_t *s, int64_t pos)
|
||||||
|
{
|
||||||
|
|
||||||
mp_dbg(MSGT_DEMUX, MSGL_DBG3, "seek to 0x%llX\n", (long long)pos);
|
mp_dbg(MSGT_DEMUX, MSGL_DBG3, "seek to 0x%llX\n", (long long)pos);
|
||||||
|
|
||||||
if (pos < 0) {
|
if (pos < 0) {
|
||||||
mp_msg(MSGT_DEMUX, MSGL_ERR, "Invalid seek to negative position %llx!\n",
|
mp_msg(MSGT_DEMUX, MSGL_ERR,
|
||||||
|
"Invalid seek to negative position %llx!\n",
|
||||||
(long long)pos);
|
(long long)pos);
|
||||||
pos = 0;
|
pos = 0;
|
||||||
}
|
}
|
||||||
if(pos<s->pos){
|
if (pos < s->pos) {
|
||||||
int64_t x=pos-(s->pos-s->buf_len);
|
int64_t x = pos - (s->pos - s->buf_len);
|
||||||
if(x>=0){
|
if (x >= 0) {
|
||||||
s->buf_pos=x;
|
s->buf_pos = x;
|
||||||
s->eof = 0;
|
s->eof = 0;
|
||||||
// putchar('*');fflush(stdout);
|
// putchar('*');fflush(stdout);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return cache_stream_seek_long(s,pos);
|
return cache_stream_seek_long(s, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline static int stream_skip(stream_t *s,int64_t len){
|
inline static int stream_skip(stream_t *s, int64_t len)
|
||||||
if( len<0 || (len>2*STREAM_BUFFER_SIZE && (s->flags & MP_STREAM_SEEK_FW)) ) {
|
{
|
||||||
|
if (len < 0 ||
|
||||||
|
(len > 2 * STREAM_BUFFER_SIZE && (s->flags & MP_STREAM_SEEK_FW))) {
|
||||||
// negative or big skip!
|
// negative or big skip!
|
||||||
return stream_seek(s,stream_tell(s)+len);
|
return stream_seek(s, stream_tell(s) + len);
|
||||||
}
|
}
|
||||||
while(len>0){
|
while (len > 0) {
|
||||||
int x=s->buf_len-s->buf_pos;
|
int x = s->buf_len - s->buf_pos;
|
||||||
if(x==0){
|
if (x == 0) {
|
||||||
if(!cache_stream_fill_buffer(s)) return 0; // EOF
|
if (!cache_stream_fill_buffer(s))
|
||||||
x=s->buf_len-s->buf_pos;
|
return 0; // EOF
|
||||||
|
x = s->buf_len - s->buf_pos;
|
||||||
}
|
}
|
||||||
if(x>len) x=len;
|
if (x > len)
|
||||||
|
x = len;
|
||||||
//memcpy(mem,&s->buf[s->buf_pos],x);
|
//memcpy(mem,&s->buf[s->buf_pos],x);
|
||||||
s->buf_pos+=x; len-=x;
|
s->buf_pos += x;
|
||||||
|
len -= x;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -355,9 +385,9 @@ struct bstr stream_read_complete(struct stream *s, void *talloc_ctx,
|
||||||
void stream_reset(stream_t *s);
|
void stream_reset(stream_t *s);
|
||||||
int stream_control(stream_t *s, int cmd, void *arg);
|
int stream_control(stream_t *s, int cmd, void *arg);
|
||||||
void stream_update_size(stream_t *s);
|
void stream_update_size(stream_t *s);
|
||||||
stream_t* new_stream(int fd,int type);
|
stream_t *new_stream(int fd, int type);
|
||||||
void free_stream(stream_t *s);
|
void free_stream(stream_t *s);
|
||||||
stream_t* new_memory_stream(unsigned char* data,int len);
|
stream_t *new_memory_stream(unsigned char *data, int len);
|
||||||
stream_t *open_stream(const char *filename, struct MPOpts *options,
|
stream_t *open_stream(const char *filename, struct MPOpts *options,
|
||||||
int *file_format);
|
int *file_format);
|
||||||
stream_t *open_output_stream(const char *filename, struct MPOpts *options);
|
stream_t *open_output_stream(const char *filename, struct MPOpts *options);
|
||||||
|
@ -367,7 +397,7 @@ struct stream *new_ds_stream(struct demux_stream *ds);
|
||||||
/// Set the callback to be used by libstream to check for user
|
/// Set the callback to be used by libstream to check for user
|
||||||
/// interruption during long blocking operations (cache filling, etc).
|
/// interruption during long blocking operations (cache filling, etc).
|
||||||
struct input_ctx;
|
struct input_ctx;
|
||||||
void stream_set_interrupt_callback(int (*cb)(struct input_ctx*, int),
|
void stream_set_interrupt_callback(int (*cb)(struct input_ctx *, int),
|
||||||
struct input_ctx *ctx);
|
struct input_ctx *ctx);
|
||||||
/// Call the interrupt checking callback if there is one and
|
/// Call the interrupt checking callback if there is one and
|
||||||
/// wait for time milliseconds
|
/// wait for time milliseconds
|
||||||
|
|
Loading…
Reference in New Issue