⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 plaympeg.c

📁 This code is based on mpeg_play, available from: http://bmrc.berkeley.edu/frame/research/mpeg/
💻 C
📖 第 1 页 / 共 2 页
字号:
/*   plaympeg - Sample MPEG player using the SMPEG library   Copyright (C) 1999 Loki Entertainment Software      This program 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.      This program 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 this program; if not, write to the Free Software   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.*/#include <stdio.h>#include <stdlib.h>#include <string.h>#include <signal.h>#ifdef unix#include <unistd.h>#include <errno.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/time.h>#define NET_SUPPORT  /* General network support */#define RAW_SUPPORT  /* Raw data transport support */#define HTTP_SUPPORT /* HTTP support */#define FTP_SUPPORT  /* FTP support */#ifdef linux#define VCD_SUPPORT  /* Video CD support */#endif#endif#ifdef NET_SUPPORT#include <netinet/in.h>#include <netdb.h>#include <sys/socket.h>#include <arpa/inet.h>#endif#ifdef VCD_SUPPORT#include <signal.h>#include <fcntl.h>#include <sys/stat.h>#include <linux/cdrom.h>#endif#include "smpeg.h"void usage(char *argv0){    printf("Usage: %s [options] file ...\n""Where the options are one of:\n""	--noaudio	     Don't play audio stream\n""	--novideo	     Don't play video stream\n""	--fullscreen	     Play MPEG in fullscreen mode\n""	--double or -2	     Play MPEG at double size\n""	--loop or -l	     Play MPEG over and over\n""	--bilinear	     Use software bilinear filtering\n""	--volume N or -v N   Set audio volume to N (0-100)\n""	--scale wxh or -s wxh  Play MPEG at given resolution\n""	--seek N or -S N     Skip N bytes\n"#ifdef USE_SYSTEM_TIMESTAMP"	--skip N or -k N     Skip N seconds\n"#endif"	--help or -h\n""	--version or -V\n""Specifying - as filename will use stdin for input\n", argv0);}#ifdef NET_SUPPORTint is_address_multicast(unsigned long address){  if((address & 255) >= 224 && (address & 255) <= 239) return(1);  return(0);}int 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);}int 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);}#ifdef RAW_SUPPORTint raw_open(char * arg){  char * host;  int port;  int sock;  /* Check for URL syntax */  if(strncmp(arg, "raw://", strlen("raw://"))) return(0);  /* Parse URL */  port = 0;  host = arg + strlen("raw://");  if(strchr(host, ':') != NULL) /* port is specified */  {    port = atoi(strchr(host, ':') + 1);    *strchr(host, ':') = 0;  }  /* Open a UDP socket */  if(!(sock = udp_open(host, port)))    perror("raw_open");    return(sock);}#endif#ifdef HTTP_SUPPORTint http_open(char * arg){  char * host;  int port;  char * request;  int tcp_sock;  char http_request[1024];  char c;  /* 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);  }  /* Send HTTP GET request */  sprintf(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",	  request, host);  send(tcp_sock, http_request, strlen(http_request), 0);    /* Parse server reply */  do read(tcp_sock, &c, sizeof(char)); while(c != ' ');  read(tcp_sock, http_request, 4*sizeof(char));  http_request[4] = 0;  if(strcmp(http_request, "200 "))  {    fprintf(stderr, "http_open: ");    do {       read(tcp_sock, &c, sizeof(char));      fprintf(stderr, "%c", c);     }    while(c != '\r');    fprintf(stderr, "\n");    return(0);  }    return(tcp_sock);}#endif#ifdef FTP_SUPPORTint ftp_get_reply(int tcp_sock){  int i;  char c;  char answer[1024];  do {    /* Read a line */    for(i = 0, c = 0; i < 1024 && c != '\n'; i++)    {      read(tcp_sock, &c, sizeof(char));      answer[i] = c;    }    answer[i] = 0;    fprintf(stderr, answer + 4);  }  while(answer[3] == '-');  answer[3] = 0;  return(atoi(answer));}int ftp_open(char * arg){  char * host;  int port;  char * dir;  char * file;  int tcp_sock;  int data_sock;  char ftp_request[1024];  struct sockaddr_in stLclAddr;  socklen_t namelen;  int i;  /* Check for URL syntax */  if(strncmp(arg, "ftp://", strlen("ftp://"))) return(0);  /* Parse URL */  port = 21;  host = arg + strlen("ftp://");  if((dir = strchr(host, '/')) == NULL) return(0);  *dir++ = 0;  if((file = strrchr(dir, '/')) == NULL) {    file = dir;    dir = NULL;  } else    *file++ = 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("ftp_open");    return(0);  }  /* Send FTP USER and PASS request */  ftp_get_reply(tcp_sock);  sprintf(ftp_request, "USER anonymous\r\n");  send(tcp_sock, ftp_request, strlen(ftp_request), 0);  if(ftp_get_reply(tcp_sock) != 331) return(0);  sprintf(ftp_request, "PASS smpeguser@\r\n");  send(tcp_sock, ftp_request, strlen(ftp_request), 0);  if(ftp_get_reply(tcp_sock) != 230) return(0);  sprintf(ftp_request, "TYPE I\r\n");  send(tcp_sock, ftp_request, strlen(ftp_request), 0);  if(ftp_get_reply(tcp_sock) != 200) return(0);  if(dir != NULL)  {    sprintf(ftp_request, "CWD %s\r\n", dir);    send(tcp_sock, ftp_request, strlen(ftp_request), 0);    if(ftp_get_reply(tcp_sock) != 250) return(0);  }      /* Get interface address */  namelen = sizeof(stLclAddr);  if(getsockname(tcp_sock, (struct sockaddr *) &stLclAddr, &namelen) < 0)    return(0);  /* Open data socket */  if ((data_sock = socket(PF_INET, SOCK_STREAM, 0)) < 0) return(0);  stLclAddr.sin_family = AF_INET;  /* Get the first free port */  for(i = 0; i < 0xC000; i++) {    stLclAddr.sin_port = htons(0x4000 + i);    if(bind(data_sock, (struct sockaddr *) &stLclAddr, sizeof(stLclAddr)) >= 0) break;  }  port = 0x4000 + i;  if(listen(data_sock, 1) < 0) return(0);  i = ntohl(stLclAddr.sin_addr.s_addr);  sprintf(ftp_request, "PORT %d,%d,%d,%d,%d,%d\r\n",	    (i >> 24) & 0xFF, (i >> 16) & 0xFF,	    (i >> 8) & 0xFF, i & 0xFF,	    (port >> 8) & 0xFF, port & 0xFF);  send(tcp_sock, ftp_request, strlen(ftp_request), 0);  if(ftp_get_reply(tcp_sock) != 200) return(0);  sprintf(ftp_request, "RETR %s\r\n", file);  send(tcp_sock, ftp_request, strlen(ftp_request), 0);  if(ftp_get_reply(tcp_sock) != 150) return(0);  return(accept(data_sock, NULL, NULL));}#endif#endif#ifdef VCD_SUPPORTint vcd_read(int fd, int lba, unsigned char *buf){    struct cdrom_msf *msf;    msf = (struct cdrom_msf*) buf;    msf->cdmsf_min0   = (lba + CD_MSF_OFFSET) / CD_FRAMES / CD_SECS;     msf->cdmsf_sec0   = (lba + CD_MSF_OFFSET) / CD_FRAMES % CD_SECS;    msf->cdmsf_frame0 = (lba + CD_MSF_OFFSET) % CD_FRAMES;    return(ioctl(fd, CDROMREADMODE2, buf));}int vcd_open(char * arg){  struct stat buf;  struct cdrom_tocentry toc;  char *pip;  int track;  int pipe_fd[2];  int fd;  int pid, parent;  unsigned char * buffer;    /* Track defaults to 02, unless requested otherwise */  track = 02;  pip = strrchr(arg, ':');  if ( pip ) {    *pip = '\0';    track = atoi(pip+1) + 1;  }  /* See if the CD-ROM device file exists */  if ( (stat(arg, &buf) < 0) || !S_ISBLK(buf.st_mode) ) {    if ( pip ) {      *pip = ':';    }    return(0);  }  fd = open(arg, O_RDONLY, 0);  if ( fd < 0 ) {    if ( pip ) {      *pip = ':';    }    return(0);  }  /* Track 02 (changed to 'track') contains MPEG data */  if ( track < 2 ) {    printf("Warning: VCD data normally starts on track 2\n");  }  toc.cdte_track  = track;   toc.cdte_format = CDROM_LBA;  if(ioctl(fd, CDROMREADTOCENTRY, &toc) < 0) return(0);  if(pipe(pipe_fd) < 0) return(0);  parent = getpid();  pid = fork();  if(pid < 0) return(0);  if(!pid)  {    /* Child process fills the pipe */    int pos;    struct timeval timeout;    fd_set fdset;    buffer = (unsigned char *) malloc(CD_FRAMESIZE_RAW0);    for(pos = toc.cdte_addr.lba; vcd_read(fd, pos, buffer) >= 0; pos ++)    {      if(kill(parent, 0) < 0) break;      FD_ZERO(&fdset);      FD_SET(pipe_fd[1], &fdset);      timeout.tv_sec = 10;      timeout.tv_usec = 0;      if(select(pipe_fd[1]+1, NULL, &fdset, NULL, &timeout) <= 0) break;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -