diff options
Diffstat (limited to 'stream')
-rw-r--r-- | stream/stream.c | 2 | ||||
-rw-r--r-- | stream/stream_netstream.c | 304 | ||||
-rw-r--r-- | stream/stream_netstream.h | 166 |
3 files changed, 0 insertions, 472 deletions
diff --git a/stream/stream.c b/stream/stream.c index d7ab7a751a..76cf453740 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -65,7 +65,6 @@ static struct input_ctx *stream_check_interrupt_ctx; extern const stream_info_t stream_info_vcd; extern const stream_info_t stream_info_cdda; -extern const stream_info_t stream_info_netstream; extern const stream_info_t stream_info_asf; extern const stream_info_t stream_info_udp; extern const stream_info_t stream_info_http1; @@ -97,7 +96,6 @@ static const stream_info_t* const auto_open_streams[] = { &stream_info_ffmpeg, // use for rstp:// before http fallback &stream_info_avdevice, #ifdef CONFIG_NETWORKING - &stream_info_netstream, &stream_info_http1, &stream_info_asf, &stream_info_udp, diff --git a/stream/stream_netstream.c b/stream/stream_netstream.c deleted file mode 100644 index 2abc0e48f9..0000000000 --- a/stream/stream_netstream.c +++ /dev/null @@ -1,304 +0,0 @@ -/* - * Copyright (C) Alban Bedel - 04/2003 - * - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * MPlayer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -/* - * Net stream allow you to access MPlayer stream accross a tcp - * connection. - * Note that at least mf and tv use a dummy stream (they are - * implemented at the demuxer level) so you won't be able to - * access those :(( but dvd, vcd and so on should work perfectly - * (if you have the bandwidth ;) - * A simple server is in TOOLS/netstream. - * - */ - - -#include "config.h" - -#include <sys/types.h> -#include <sys/stat.h> -#include <fcntl.h> -#include <unistd.h> - -#include <stdlib.h> -#include <stdio.h> -#include <inttypes.h> -#include <errno.h> - -#if !HAVE_WINSOCK2_H -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#else -#include <winsock2.h> -#endif - -#include "core/mp_msg.h" -#include "stream.h" -#include "core/m_option.h" -#include "core/m_struct.h" -#include "libavutil/common.h" -#include "compat/mpbswap.h" - -#include "network.h" -#include "stream_netstream.h" -#include "tcp.h" - -static struct stream_priv_s { - char* host; - int port; - char* url; -} stream_priv_dflts = { - NULL, - 10000, - NULL -}; - -#define ST_OFF(f) M_ST_OFF(struct stream_priv_s,f) -/// URL definition -static const m_option_t stream_opts_fields[] = { - {"hostname", ST_OFF(host), CONF_TYPE_STRING, 0, 0 ,0, NULL}, - {"port", ST_OFF(port), CONF_TYPE_INT, M_OPT_MIN, 1 ,0, NULL}, - {"filename", ST_OFF(url), CONF_TYPE_STRING, 0, 0 ,0, NULL}, - { NULL, NULL, 0, 0, 0, 0, NULL } -}; -static const struct m_struct_st stream_opts = { - "netstream", - sizeof(struct stream_priv_s), - &stream_priv_dflts, - stream_opts_fields -}; - -//// When the cache is running we need a lock as -//// fill_buffer is called from another proccess -static int lock_fd(int fd) { -#if !HAVE_WINSOCK2_H - struct flock lock; - - memset(&lock,0,sizeof(struct flock)); - lock.l_type = F_WRLCK; - - mp_msg(MSGT_STREAM,MSGL_DBG2, "Lock (%d)\n",getpid()); - do { - if(fcntl(fd,F_SETLKW,&lock)) { - if(errno == EAGAIN) continue; - mp_msg(MSGT_STREAM,MSGL_ERR, "Failed to get the lock: %s\n", - strerror(errno)); - return 0; - } - } while(0); - mp_msg(MSGT_STREAM,MSGL_DBG2, "Locked (%d)\n",getpid()); -#else -printf("FIXME? should lock here\n"); -#endif - return 1; -} - -static int unlock_fd(int fd) { -#if !HAVE_WINSOCK2_H - struct flock lock; - - memset(&lock,0,sizeof(struct flock)); - lock.l_type = F_UNLCK; - - mp_msg(MSGT_STREAM,MSGL_DBG2, "Unlock (%d)\n",getpid()); - if(fcntl(fd,F_SETLK,&lock)) { - mp_msg(MSGT_STREAM,MSGL_ERR, "Failed to release the lock: %s\n", - strerror(errno)); - return 0; - } -#else -printf("FIXME? should unlock here\n"); -#endif - return 1; -} - -static mp_net_stream_packet_t* send_net_stream_cmd(stream_t *s,uint16_t cmd,char* data,int len) { - mp_net_stream_packet_t* pack; - - // Cache is enabled : lock - if(s->cache_data && !lock_fd(s->fd)) - return NULL; - // Send a command - if(!write_packet(s->fd,cmd,data,len)) { - if(s->cache_data) unlock_fd(s->fd); - return 0; - } - // Read the response - pack = read_packet(s->fd); - // Now we can unlock - if(s->cache_data) unlock_fd(s->fd); - - if(!pack) - return NULL; - - switch(pack->cmd) { - case NET_STREAM_OK: - return pack; - case NET_STREAM_ERROR: - if(pack->len > sizeof(mp_net_stream_packet_t)) - mp_msg(MSGT_STREAM,MSGL_ERR, "Fill buffer failed: %s\n",pack->data); - else - mp_msg(MSGT_STREAM,MSGL_ERR, "Fill buffer failed\n"); - free(pack); - return NULL; - } - - mp_msg(MSGT_STREAM,MSGL_ERR, "Unknown response to %d: %d\n",cmd,pack->cmd); - free(pack); - return NULL; -} - -static int fill_buffer(stream_t *s, char* buffer, int max_len){ - uint16_t len = le2me_16(max_len); - mp_net_stream_packet_t* pack; - - pack = send_net_stream_cmd(s,NET_STREAM_FILL_BUFFER,(char*)&len,2); - if(!pack) { - return -1; - } - len = pack->len - sizeof(mp_net_stream_packet_t); - if(len > max_len) { - mp_msg(MSGT_STREAM,MSGL_ERR, "Got a too big a packet %d / %d\n",len,max_len); - free(pack); - return 0; - } - if(len > 0) - memcpy(buffer,pack->data,len); - free(pack); - return len; -} - - -static int seek(stream_t *s,int64_t newpos) { - uint64_t pos = le2me_64((uint64_t)newpos); - mp_net_stream_packet_t* pack; - - pack = send_net_stream_cmd(s,NET_STREAM_SEEK,(char*)&pos,8); - if(!pack) { - return 0; - } - s->pos = newpos; - free(pack); - return 1; -} - -static int net_stream_reset(struct stream *s) { - mp_net_stream_packet_t* pack; - - pack = send_net_stream_cmd(s,NET_STREAM_RESET,NULL,0); - if(!pack) { - return 0; - } - free(pack); - return 1; -} - -static int control(struct stream *s,int cmd,void* arg) { - switch(cmd) { - case STREAM_CTRL_RESET: - return net_stream_reset(s); - } - return STREAM_UNSUPPORTED; -} - -static void close_s(struct stream *s) { - mp_net_stream_packet_t* pack; - - pack = send_net_stream_cmd(s,NET_STREAM_CLOSE,NULL,0); - free(pack); -} - -static int open_s(stream_t *stream,int mode, void* opts, int* file_format) { - int f; - struct stream_priv_s* p = (struct stream_priv_s*)opts; - mp_net_stream_packet_t* pack; - mp_net_stream_opened_t* opened; - - if(mode != STREAM_READ) - return STREAM_UNSUPPORTED; - - if(!p->host) { - mp_msg(MSGT_OPEN,MSGL_ERR, "We need an host name (ex: mpst://server.net/cdda://5)\n"); - m_struct_free(&stream_opts,opts); - return STREAM_ERROR; - } - if(!p->url || strlen(p->url) == 0) { - mp_msg(MSGT_OPEN,MSGL_ERR, "We need a remote url (ex: mpst://server.net/cdda://5)\n"); - m_struct_free(&stream_opts,opts); - return STREAM_ERROR; - } - - f = connect2Server(p->host,p->port,1); - if(f < 0) { - mp_msg(MSGT_OPEN,MSGL_ERR, "Connection to %s:%d failed\n",p->host,p->port); - m_struct_free(&stream_opts,opts); - return STREAM_ERROR; - } - stream->fd = f; - /// Now send an open command - pack = send_net_stream_cmd(stream,NET_STREAM_OPEN,p->url,strlen(p->url) + 1); - if(!pack) { - goto error; - } - - if(pack->len != sizeof(mp_net_stream_packet_t) + - sizeof(mp_net_stream_opened_t)) { - mp_msg(MSGT_OPEN,MSGL_ERR, "Invalid open response packet len (%d bytes)\n",pack->len); - free(pack); - goto error; - } - - opened = (mp_net_stream_opened_t*)pack->data; - net_stream_opened_2_me(opened); - - *file_format = opened->file_format; - stream->flags = opened->flags; - stream->sector_size = opened->sector_size; - stream->start_pos = opened->start_pos; - stream->end_pos = opened->end_pos; - - stream->fill_buffer = fill_buffer; - stream->control = control; - if(stream->flags & MP_STREAM_SEEK) - stream->seek = seek; - stream->close = close_s; - - free(pack); - m_struct_free(&stream_opts,opts); - - return STREAM_OK; - - error: - closesocket(f); - m_struct_free(&stream_opts,opts); - return STREAM_ERROR; -} - -const stream_info_t stream_info_netstream = { - "Net stream", - "netstream", - "Albeu", - "", - open_s, - { "mpst",NULL }, - &stream_opts, - 1 // Url is an option string -}; diff --git a/stream/stream_netstream.h b/stream/stream_netstream.h deleted file mode 100644 index 5d219e3a7e..0000000000 --- a/stream/stream_netstream.h +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Common stuff for netstream - * Packets and so on are defined here along with a few helpers - * wich are used by both the client and the server - * - * Data is always low endian - * - * This file is part of MPlayer. - * - * MPlayer is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * MPlayer is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with MPlayer; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#ifndef MPLAYER_NETSTREAM_H -#define MPLAYER_NETSTREAM_H - -#include "config.h" -#include <stdint.h> -#include <stdlib.h> -#include <string.h> -#include <errno.h> -#if !HAVE_WINSOCK2_H -#include <sys/socket.h> -#endif -#include "core/mp_msg.h" -#include "compat/mpbswap.h" - -typedef struct mp_net_stream_packet_st { - uint16_t len; - uint8_t cmd; - char data[0]; -} __attribute__ ((packed)) mp_net_stream_packet_t; - -#define PACKET_MAX_SIZE 4096 - -// Commands sent by the client -#define NET_STREAM_OPEN 0 -// data is the url -#define NET_STREAM_FILL_BUFFER 1 -// data is an uint16 wich is the max len of the data to return -#define NET_STREAM_SEEK 3 -// data is an uint64 wich the pos where to seek -#define NET_STREAM_CLOSE 4 -// no data -#define NET_STREAM_RESET 5 -// no data - -// Server response -#define NET_STREAM_OK 128 -// Data returned if open is successful -typedef struct mp_net_stream_opened_st { - uint32_t file_format; - uint32_t flags; - uint32_t sector_size; - uint64_t start_pos; - uint64_t end_pos; -} __attribute__ ((packed)) mp_net_stream_opened_t; -// FILL_BUFFER return the data -// CLOSE return nothing -#define NET_STREAM_ERROR 129 -// Data is the error message (if any ;) - -static int net_read(int fd, char* buf, int len) { - int r = 0; - while(len) { - r = recv(fd,buf,len,0); - if(r <= 0) { - if(errno == EINTR) continue; - if(r < 0) - mp_msg(MSGT_NETST,MSGL_ERR,"Read failed: %s\n",strerror(errno)); - return 0; - } - len -= r; - buf += r; - } - return 1; -} - -static mp_net_stream_packet_t* read_packet(int fd) { - uint16_t len; - mp_net_stream_packet_t* pack = malloc(sizeof(mp_net_stream_packet_t)); - - if(!net_read(fd,(char*)pack,sizeof(mp_net_stream_packet_t))) { - free(pack); - return NULL; - } - pack->len = le2me_16(pack->len); - - if(pack->len < sizeof(mp_net_stream_packet_t)) { - mp_msg(MSGT_NETST,MSGL_WARN,"Got invalid packet (too small: %d)\n",pack->len); - free(pack); - return NULL; - } - if(pack->len > PACKET_MAX_SIZE) { - mp_msg(MSGT_NETST,MSGL_WARN,"Got invalid packet (too big: %d)\n",pack->len); - free(pack); - return NULL; - } - len = pack->len; - if(len > sizeof(mp_net_stream_packet_t)) { - pack = realloc(pack,len); - if(!pack) { - mp_msg(MSGT_NETST,MSGL_ERR,"Failed to get memory for the packet (%d bytes)\n",len); - return NULL; - } - if(!net_read(fd,pack->data,len - sizeof(mp_net_stream_packet_t))) - return NULL; - } - // printf ("Read packet %d %d %d\n",fd,pack->cmd,pack->len); - return pack; -} - -static int net_write(int fd, char* buf, int len) { - int w; - while(len) { - w = send(fd,buf,len,DEFAULT_SEND_FLAGS); - if(w <= 0) { - if(errno == EINTR) continue; - if(w < 0) - mp_msg(MSGT_NETST,MSGL_ERR,"Write failed: %s\n",strerror(errno)); - return 0; - } - len -= w; - buf += w; - } - return 1; -} - -static int write_packet(int fd, uint8_t cmd,char* data,int len) { - mp_net_stream_packet_t* pack = malloc(len + sizeof(mp_net_stream_packet_t)); - - if(len > 0 && data) - memcpy(pack->data,data,len); - pack->len = len + sizeof(mp_net_stream_packet_t); - pack->cmd = cmd; - - // printf("Write packet %d %d (%p) %d\n",fd,cmd,data,len); - pack->len = le2me_16(pack->len); - if(net_write(fd,(char*)pack,pack->len)) { - free(pack); - return 1; - } - free(pack); - return 0; -} - -static void net_stream_opened_2_me(mp_net_stream_opened_t* o) { - o->file_format = le2me_32(o->file_format); - o->flags = le2me_32(o->flags); - o->sector_size = le2me_32(o->sector_size); - o->start_pos = le2me_64(o->start_pos); - o->end_pos = le2me_64(o->end_pos); -} - -#endif /* MPLAYER_NETSTREAM_H */ |