-rw-r--r-- | core/multimedia/opieplayer/libmad/libmadplugin.cpp | 72 | ||||
-rw-r--r-- | core/multimedia/opieplayer/libmad/libmadplugin.h | 2 |
2 files changed, 69 insertions, 5 deletions
diff --git a/core/multimedia/opieplayer/libmad/libmadplugin.cpp b/core/multimedia/opieplayer/libmad/libmadplugin.cpp index 7bb6541..6793773 100644 --- a/core/multimedia/opieplayer/libmad/libmadplugin.cpp +++ b/core/multimedia/opieplayer/libmad/libmadplugin.cpp @@ -70,207 +70,269 @@ public: #endif unsigned char *data; unsigned long length; int eof; }; class Output { public: mad_fixed_t attenuate; struct filter *filters; unsigned int channels_in; unsigned int channels_out; unsigned int speed_in; unsigned int speed_out; const char *path; }; # if defined(HAVE_MMAP) static void *map_file(int fd, unsigned long *length) { void *fdm; *length += MAD_BUFFER_GUARD; fdm = mmap(0, *length, PROT_READ, MAP_SHARED, fd, 0); if (fdm == MAP_FAILED) return 0; # if defined(HAVE_MADVISE) madvise(fdm, *length, MADV_SEQUENTIAL); # endif return fdm; } static int unmap_file(void *fdm, unsigned long length) { if (munmap(fdm, length) == -1) return -1; return 0; } # endif static inline QString tr( const char *str ) { // Apparently this is okay from a plugin as it runs in the process space of the owner of the plugin return qApp->translate( "OpiePlayer", str, "libmad strings for mp3 file info" ); } class LibMadPluginData { public: Input input; Output output; int bad_last_frame; struct mad_stream stream; struct mad_frame frame; struct mad_synth synth; bool flush; }; LibMadPlugin::LibMadPlugin() { d = new LibMadPluginData; d->input.fd = 0; #if defined(HAVE_MMAP) d->input.fdm = 0; #endif d->input.data = 0; d->flush = TRUE; info = tr( "No Song Open" ); } LibMadPlugin::~LibMadPlugin() { close(); delete d; } bool LibMadPlugin::isFileSupported( const QString& path ) { debugMsg( "LibMadPlugin::isFileSupported" ); // Mpeg file extensions // "mp2","mp3","m1v","m2v","m2s","mpg","vob","mpeg","ac3" // Other media extensions // "wav","mid","mod","s3m","ogg","avi","mov","sid" char *ext = strrchr( path.latin1(), '.' ); // Test file extension if ( ext ) { - if ( strncasecmp(ext, ".mp2", 4) == 0 ) - return TRUE; - if ( strncasecmp(ext, ".mp3", 4) == 0 ) - return TRUE; + if ( strncasecmp(ext, ".mp2", 4) == 0 ) + return TRUE; + if ( strncasecmp(ext, ".mp3", 4) == 0 ) + return TRUE; } + // UGLY - just for fast testing if ( path.left(4) == "http") { return TRUE; } + return FALSE; +} + - return FALSE; + +int LibMadPlugin::is_address_multicast(unsigned long address) { + if ((address & 255) >= 224 && (address & 255) <= 239) + return (1); + return (0); } +int LibMadPlugin::udp_open(char *address, int port) { + + int enable = 1L; + struct sockaddr_in stAddr; + struct sockaddr_in stLclAddr; + struct ip_mreq stMreq; + struct hostent *host; + int sock; + + stAddr.sin_family = AF_INET; + stAddr.sin_port = htons(port); + + if ((host = gethostbyname(address)) == NULL) + return (0); + + stAddr.sin_addr = *((struct in_addr *)host->h_addr_list[0]); + + /* Create a UDP socket */ + if ((sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) + return (0); + + /* Allow multiple instance of the client to share the same address and port */ + if (setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&enable, sizeof(unsigned long int)) < 0) + return (0); + + /* If the address is multicast, register to the multicast group */ + if (is_address_multicast(stAddr.sin_addr.s_addr)) + { + /* Bind the socket to port */ + stLclAddr.sin_family = AF_INET; + stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); + stLclAddr.sin_port = stAddr.sin_port; + if (bind(sock, (struct sockaddr *)&stLclAddr, sizeof(stLclAddr)) < 0) + return (0); + + /* Register to a multicast address */ + stMreq.imr_multiaddr.s_addr = stAddr.sin_addr.s_addr; + stMreq.imr_interface.s_addr = INADDR_ANY; + if (setsockopt(sock, IPPROTO_IP, IP_ADD_MEMBERSHIP, (char *)&stMreq, sizeof(stMreq)) < 0) + return (0); + } + else + { + /* Bind the socket to port */ + stLclAddr.sin_family = AF_INET; + stLclAddr.sin_addr.s_addr = htonl(INADDR_ANY); + stLclAddr.sin_port = htons(0); + if (bind(sock, (struct sockaddr *)&stLclAddr, sizeof(stLclAddr)) < 0) + return (0); + } + + return (sock); +} + int LibMadPlugin::tcp_open(char *address, int port) { struct sockaddr_in stAddr; struct hostent *host; int sock; struct linger l; memset(&stAddr, 0, sizeof(stAddr)); stAddr.sin_family = AF_INET; stAddr.sin_port = htons(port); if ((host = gethostbyname(address)) == NULL) return (0); stAddr.sin_addr = *((struct in_addr *)host->h_addr_list[0]); if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) return (0); l.l_onoff = 1; l.l_linger = 5; if (setsockopt(sock, SOL_SOCKET, SO_LINGER, (char *)&l, sizeof(l)) < 0) return (0); if (connect(sock, (struct sockaddr *)&stAddr, sizeof(stAddr)) < 0) return (0); return (sock); } /** * Read a http line header. * This function read character by character. * @param tcp_sock the socket use to read the stream * @param buf a buffer to receive the data * @param size size of the buffer * @return the size of the stream read or -1 if an error occured */ int LibMadPlugin::http_read_line(int tcp_sock, char *buf, int size) { int offset = 0; do { if (std::read(tcp_sock, buf + offset, 1) < 0) return -1; if (buf[offset] != '\r') /* Strip \r from answer */ offset++; } while (offset < size - 1 && buf[offset - 1] != '\n'); buf[offset] = 0; return offset; } int LibMadPlugin::http_open(const QString& path ) { char *host; int port; char *request; int tcp_sock; char http_request[PATH_MAX]; char filename[PATH_MAX]; char c; char *arg =strdup(path.latin1()); /* Check for URL syntax */ if (strncmp(arg, "http://", strlen("http://"))) return (0); /* Parse URL */ port = 80; host = arg + strlen("http://"); if ((request = strchr(host, '/')) == NULL) return (0); *request++ = 0; if (strchr(host, ':') != NULL) /* port is specified */ { port = atoi(strchr(host, ':') + 1); *strchr(host, ':') = 0; } /* Open a TCP socket */ if (!(tcp_sock = tcp_open(host, port))) { perror("http_open"); return (0); } snprintf(filename, sizeof(filename) - strlen(host) - 75, "%s", request); /* Send HTTP GET request */ /* Please don't use a Agent know by shoutcast (Lynx, Mozilla) seems to be reconized and print * a html page and not the stream */ snprintf(http_request, sizeof(http_request), "GET /%s HTTP/1.0\r\n" /* "User-Agent: Mozilla/2.0 (Win95; I)\r\n" */ "Pragma: no-cache\r\n" "Host: %s\r\n" "Accept: */*\r\n" "\r\n", filename, host); diff --git a/core/multimedia/opieplayer/libmad/libmadplugin.h b/core/multimedia/opieplayer/libmad/libmadplugin.h index ee1ca9d..6747712 100644 --- a/core/multimedia/opieplayer/libmad/libmadplugin.h +++ b/core/multimedia/opieplayer/libmad/libmadplugin.h @@ -9,107 +9,109 @@ ** packaging of this file. ** ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. ** ** See http://www.trolltech.com/gpl/ for GPL licensing information. ** ** Contact info@trolltech.com if any conditions of this licensing are ** not clear to you. ** **********************************************************************/ #ifndef LIBMAD_PLUGIN_H #define LIBMAD_PLUGIN_H #include <qstring.h> #include <qpe/mediaplayerplugininterface.h> /* #include "../mediaplayerplugininterface.h" */ // #define OLD_MEDIAPLAYER_API class LibMadPluginData; class LibMadPlugin : public MediaPlayerDecoder { public: LibMadPlugin(); ~LibMadPlugin(); const char *pluginName() { return "LibMadPlugin"; } const char *pluginComment() { return "This is the libmad library that has been wrapped as a plugin"; } double pluginVersion() { return 1.0; } bool isFileSupported( const QString& ); bool open( const QString& ); bool close(); bool isOpen(); const QString &fileInfo() { return info; } // If decoder doesn't support audio then return 0 here int audioStreams(); int audioChannels( int stream ); int audioFrequency( int stream ); int audioSamples( int stream ); bool audioSetSample( long sample, int stream ); /* int audioBitsPerSample(int) {return 0;} */ long audioGetSample( int stream ); #ifdef OLD_MEDIAPLAYER_API bool audioReadMonoSamples( short *output, long samples, long& samplesRead, int stream ); bool audioReadStereoSamples( short *output, long samples, long& samplesRead, int stream ); bool audioReadSamples( short *output, int channel, long samples, int stream ); bool audioReReadSamples( short *output, int channel, long samples, int stream ); #else bool audioReadSamples( short *output, int channels, long samples, long& samplesRead, int stream ); #endif bool read(); bool decode( short *output, long samples, long& samplesRead ); void printID3Tags(); // If decoder doesn't support video then return 0 here int videoStreams() { return 0; } int videoWidth( int ) { return 0; } int videoHeight( int ) { return 0; } double videoFrameRate( int ) { return 0.0; } int videoFrames( int ) { return 0; } bool videoSetFrame( long, int ) { return FALSE; } long videoGetFrame( int ) { return 0; } bool videoReadFrame( unsigned char **, int, int, int, int, ColorFormat, int ) { return FALSE; } bool videoReadScaledFrame( unsigned char **, int, int, int, int, int, int, ColorFormat, int ) { return FALSE; } bool videoReadYUVFrame( char *, char *, char *, int, int, int, int, int ) { return FALSE; } // Profiling double getTime(); // Ignore if these aren't supported bool setSMP( int ) { return FALSE; } bool setMMX( bool ) { return FALSE; } // Capabilities bool supportsAudio() { return TRUE; } bool supportsVideo() { return FALSE; } bool supportsYUV() { return FALSE; } bool supportsMMX() { return TRUE; } bool supportsSMP() { return FALSE; } bool supportsStereo() { return TRUE; } bool supportsScaling() { return FALSE; } long getPlayTime() { return -1; } private: + int is_address_multicast(unsigned long address); + int udp_open(char *address, int port); int tcp_open(char *address, int port); int http_read_line(int tcp_sock, char *buf, int size) ; int http_open(const QString& path ); LibMadPluginData *d; QString info; int bufferSize; }; #endif |