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

📄 pnm.c

📁 君正早期ucos系统(只有早期的才不没有打包成库),MPLAYER,文件系统,图片解码,浏览,电子书,录音,想学ucos,识货的人就下吧 russblock fmradio explore set
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Copyright (C) 2000-2002 the xine project * * This file is part of xine, a free video player. * * xine 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. * * xine 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * $Id: pnm.c,v 1.3 2008/04/12 07:14:45 dsqiu Exp $ * * pnm protocol implementation  * based upon code from joschka */#include "config.h"#include <mplaylib.h>#include <mplaylib.h>#include <assert.h>#include <mplaylib.h>#include <sys/stat.h>#include <fcntl.h>#include <errno.h>#include <mplaylib.h>#include <sys/time.h>#include <inttypes.h>#ifndef HAVE_WINSOCK2#define closesocket close#include <sys/socket.h>//#include <netinet/in.h>//#include <netdb.h>#else#include <winsock2.h>#endif#include "stream.h"#include "libmpdemux/demuxer.h"#include "help_mp.h"#include "osdep/timer.h"#include "pnm.h"#include "tcp.h"//#include "libreal/rmff.h"#undef memcpy#define memcpy uc_memcpyextern int network_bandwidth;#define FOURCC_TAG( ch0, ch1, ch2, ch3 ) \        (((long)(unsigned char)(ch3)       ) | \        ( (long)(unsigned char)(ch2) << 8  ) | \        ( (long)(unsigned char)(ch1) << 16 ) | \        ( (long)(unsigned char)(ch0) << 24 ) )#define RMF_TAG   FOURCC_TAG('.', 'R', 'M', 'F')#define PROP_TAG  FOURCC_TAG('P', 'R', 'O', 'P')#define MDPR_TAG  FOURCC_TAG('M', 'D', 'P', 'R')#define CONT_TAG  FOURCC_TAG('C', 'O', 'N', 'T')#define DATA_TAG  FOURCC_TAG('D', 'A', 'T', 'A')#define INDX_TAG  FOURCC_TAG('I', 'N', 'D', 'X')#define PNA_TAG   FOURCC_TAG('P', 'N', 'A',  0 )/*#define LOG*/#define BUF_SIZE 4096#define HEADER_SIZE 4096struct pnm_s {  int           s;//  char         *host;//  int           port;  char         *path;//  char         *url;  char          buffer[BUF_SIZE]; /* scratch buffer */  /* receive buffer */  uint8_t       recv[BUF_SIZE];  int           recv_size;  int           recv_read;  uint8_t       header[HEADER_SIZE];  int           header_len;  int           header_read;  unsigned int  seq_num[4];     /* two streams with two indices   */  unsigned int  seq_current[2]; /* seqs of last stream chunk read */  uint32_t      ts_current;     /* timestamp of current chunk     */  uint32_t      ts_last[2];     /* timestamps of last chunks      */  unsigned int  packet;         /* number of last recieved packet */};/* * utility macros */#define BE_16(x)  ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])#define BE_32(x)  ((((uint8_t*)(x))[0] << 24) | \                   (((uint8_t*)(x))[1] << 16) | \                   (((uint8_t*)(x))[2] << 8) | \                    ((uint8_t*)(x))[3])/* D means direct (no pointer) */#define BE_16D(x) ((x & 0xff00) >> 8)|((x & 0x00ff) << 8)/* sizes */#define PREAMBLE_SIZE 8#define CHECKSUM_SIZE 3/* header of rm files */#define RM_HEADER_SIZE 0x12static const unsigned char rm_header[]={        0x2e, 0x52, 0x4d, 0x46, /* object_id      ".RMF" */        0x00, 0x00, 0x00, 0x12, /* header_size    0x12   */        0x00, 0x00,             /* object_version 0x00   */        0x00, 0x00, 0x00, 0x00, /* file_version   0x00   */        0x00, 0x00, 0x00, 0x06  /* num_headers    0x06   */};/* data chunk header */#define PNM_DATA_HEADER_SIZE 18static const unsigned char pnm_data_header[]={        'D','A','T','A',         0,0,0,0,       /* data chunk size  */         0,0,           /* object version   */         0,0,0,0,       /* num packets      */         0,0,0,0};      /* next data header *//* pnm request chunk ids */#define PNA_CLIENT_CAPS      0x03#define PNA_CLIENT_CHALLANGE 0x04#define PNA_BANDWIDTH        0x05#define PNA_GUID             0x13#define PNA_TIMESTAMP        0x17#define PNA_TWENTYFOUR       0x18#define PNA_CLIENT_STRING    0x63#define PNA_PATH_REQUEST     0x52static const unsigned char pnm_challenge[] = "0990f6b4508b51e801bd6da011ad7b56";static const unsigned char pnm_timestamp[] = "[15/06/1999:22:22:49 00:00]";static const unsigned char pnm_guid[]      = "3eac2411-83d5-11d2-f3ea-d7c3a51aa8b0";static const unsigned char pnm_response[]  = "97715a899cbe41cee00dd434851535bf";static const unsigned char client_string[] = "WinNT_9.0_6.0.6.45_plus32_MP60_en-US_686l";#define PNM_HEADER_SIZE 11static const unsigned char pnm_header[] = {        'P','N','A',        0x00, 0x0a,        0x00, 0x14,        0x00, 0x02,        0x00, 0x01 };#define PNM_CLIENT_CAPS_SIZE 126static const unsigned char pnm_client_caps[] = {    0x07, 0x8a, 'p','n','r','v',        0, 0x90, 'p','n','r','v',        0, 0x64, 'd','n','e','t',        0, 0x46, 'p','n','r','v',        0, 0x32, 'd','n','e','t',        0, 0x2b, 'p','n','r','v',        0, 0x28, 'd','n','e','t',        0, 0x24, 'p','n','r','v',        0, 0x19, 'd','n','e','t',        0, 0x18, 'p','n','r','v',        0, 0x14, 's','i','p','r',        0, 0x14, 'd','n','e','t',        0, 0x24, '2','8','_','8',        0, 0x12, 'p','n','r','v',        0, 0x0f, 'd','n','e','t',        0, 0x0a, 's','i','p','r',        0, 0x0a, 'd','n','e','t',        0, 0x08, 's','i','p','r',        0, 0x06, 's','i','p','r',        0, 0x12, 'l','p','c','J',        0, 0x07, '0','5','_','6' };static const uint32_t pnm_default_bandwidth=10485800;static const uint32_t pnm_available_bandwidths[]={14400,19200,28800,33600,34430,57600,                                  115200,262200,393216,524300,1544000,10485800};#define PNM_TWENTYFOUR_SIZE 16static unsigned char pnm_twentyfour[]={    0xd5, 0x42, 0xa3, 0x1b, 0xef, 0x1f, 0x70, 0x24,    0x85, 0x29, 0xb3, 0x8d, 0xba, 0x11, 0xf3, 0xd6 };/* now other data follows. marked with 0x0000 at the beginning */static int after_chunks_length=6;static unsigned char after_chunks[]={    0x00, 0x00, /* mark */        0x50, 0x84, /* seems to be fixated */    0x1f, 0x3a  /* varies on each request (checksum ?)*/    };static void hexdump (char *buf, int length);static int rm_write(int s, const char *buf, int len) {  int total, timeout;  total = 0; timeout = 30;  while (total < len){     int n;    n = send (s, &buf[total], len - total, 0);    if (n > 0)      total += n;    else if (n < 0) {#ifndef HAVE_WINSOCK2      if ((timeout>0) && ((errno == EAGAIN) || (errno == EINPROGRESS))) {#else      if ((timeout>0) && ((errno == EAGAIN) || (WSAGetLastError() == WSAEINPROGRESS))) {#endif        usec_sleep (1000000); timeout--;      } else        return -1;    }  }  return total;}static ssize_t rm_read(int fd, void *buf, size_t count) {    ssize_t ret, total;  total = 0;  while (total < count) {      fd_set rset;    struct timeval timeout;    FD_ZERO (&rset);    FD_SET  (fd, &rset);        timeout.tv_sec  = 3;    timeout.tv_usec = 0;        if (select (fd+1, &rset, NULL, NULL, &timeout) <= 0) {      return -1;    }        ret=recv (fd, ((uint8_t*)buf)+total, count-total, 0);    if (ret<=0) {      mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: read error.\n");      return ret;    } else      total += ret;  }  return total;}/* * debugging utilities */ static void hexdump (char *buf, int length) {  int i;  mp_msg(MSGT_OPEN, MSGL_INFO, "input_pnm: ascii>");  for (i = 0; i < length; i++) {    unsigned char c = buf[i];    if ((c >= 32) && (c <= 128))      mp_msg(MSGT_OPEN, MSGL_INFO, "%c", c);    else      mp_msg(MSGT_OPEN, MSGL_INFO, ".");  }  mp_msg(MSGT_OPEN, MSGL_INFO, "\n");  mp_msg(MSGT_OPEN, MSGL_INFO, "input_pnm: hexdump> ");  for (i = 0; i < length; i++) {    unsigned char c = buf[i];    mp_msg(MSGT_OPEN, MSGL_INFO, "%02x", c);    if ((i % 16) == 15)      mp_msg(MSGT_OPEN, MSGL_INFO, "\npnm:         ");    if ((i % 2) == 1)      mp_msg(MSGT_OPEN, MSGL_INFO, " ");  }  mp_msg(MSGT_OPEN, MSGL_INFO, "\n");}/* * pnm_get_chunk gets a chunk from stream * and returns number of bytes read  */static int pnm_get_chunk(pnm_t *p,                          unsigned int max,                         unsigned int *chunk_type,                         char *data, int *need_response) {  unsigned int chunk_size;  unsigned int n;  char *ptr;   if (max < PREAMBLE_SIZE)    return -1;  /* get first PREAMBLE_SIZE bytes and ignore checksum */  rm_read (p->s, data, CHECKSUM_SIZE);  if (data[0] == 0x72)    rm_read (p->s, data, PREAMBLE_SIZE);  else    rm_read (p->s, data+CHECKSUM_SIZE, PREAMBLE_SIZE-CHECKSUM_SIZE);    max -= PREAMBLE_SIZE;  *chunk_type = BE_32(data);  chunk_size = BE_32(data+4);  switch (*chunk_type) {    case PNA_TAG:      *need_response=0;      ptr=data+PREAMBLE_SIZE;      if (max < 1)	return -1;      rm_read (p->s, ptr++, 1);      max -= 1;      while(1) {	/* expecting following chunk format: 0x4f <chunk size> <data...> */        if (max < 2)          return -1;        rm_read (p->s, ptr, 2);        max -= 2;	if (*ptr == 'X') /* checking for server message */	{	  mp_msg(MSGT_OPEN, MSGL_WARN, "input_pnm: got a message from server:\n");	  if (max < 1)	    return -1;	  rm_read (p->s, ptr+2, 1);	  max = -1;	  n=BE_16(ptr+1);	  if (max < n)	    return -1;	  rm_read (p->s, ptr+3, n);	  max -= n;	  ptr[3+n]=0;	  mp_msg(MSGT_OPEN, MSGL_WARN, "%s\n",ptr+3);	  return -1;	}		if (*ptr == 'F') /* checking for server error */	{	  mp_msg(MSGT_OPEN, MSGL_ERR, "input_pnm: server error.\n");	  return -1;	}	if (*ptr == 'i')	{	  ptr+=2;	  *need_response=1;	  continue;	}	if (*ptr != 0x4f) break;	n=ptr[1];	if (max < n)	  return -1;	rm_read (p->s, ptr+2, n);	max -= n;	ptr+=(n+2);      }      /* the checksum of the next chunk is ignored here */      if (max < 1)        return -1;      rm_read (p->s, ptr+2, 1);      ptr+=3;      chunk_size=ptr-data;      break;    case RMF_TAG:    case DATA_TAG:    case PROP_TAG:    case MDPR_TAG:    case CONT_TAG:      if (chunk_size > max || chunk_size < PREAMBLE_SIZE) {        mp_msg(MSGT_OPEN, MSGL_ERR, "error: max chunk size exceded (max was 0x%04x)\n", max);#ifdef LOG        n=rm_read (p->s, &data[PREAMBLE_SIZE], 0x100 - PREAMBLE_SIZE);        hexdump(data,n+PREAMBLE_SIZE);#endif        return -1;      }      rm_read (p->s, &data[PREAMBLE_SIZE], chunk_size-PREAMBLE_SIZE);      break;    default:      *chunk_type = 0;      chunk_size  = PREAMBLE_SIZE;       break;  }  return chunk_size;}/* * writes a chunk to a buffer, returns number of bytes written */static int pnm_write_chunk(uint16_t chunk_id, uint16_t length,     const char *chunk, char *data) {  data[0]=(chunk_id>>8)%0xff;  data[1]=chunk_id%0xff;  data[2]=(length>>8)%0xff;  data[3]=length%0xff;  memcpy(&data[4],chunk,length);    return length+4;}/* * constructs a request and sends it */static void pnm_send_request(pnm_t *p, uint32_t bandwidth) {  uint16_t i16;  int c=PNM_HEADER_SIZE;  char fixme[]={0,1};  memcpy(p->buffer,pnm_header,PNM_HEADER_SIZE);  c+=pnm_write_chunk(PNA_CLIENT_CHALLANGE,strlen(pnm_challenge),          pnm_challenge,&p->buffer[c]);  c+=pnm_write_chunk(PNA_CLIENT_CAPS,PNM_CLIENT_CAPS_SIZE,          pnm_client_caps,&p->buffer[c]);  c+=pnm_write_chunk(0x0a,0,NULL,&p->buffer[c]);  c+=pnm_write_chunk(0x0c,0,NULL,&p->buffer[c]);  c+=pnm_write_chunk(0x0d,0,NULL,&p->buffer[c]);  c+=pnm_write_chunk(0x16,2,fixme,&p->buffer[c]);  c+=pnm_write_chunk(PNA_TIMESTAMP,strlen(pnm_timestamp),          pnm_timestamp,&p->buffer[c]);  c+=pnm_write_chunk(PNA_BANDWIDTH,4,          (const char *)&pnm_default_bandwidth,&p->buffer[c]);  c+=pnm_write_chunk(0x08,0,NULL,&p->buffer[c]);  c+=pnm_write_chunk(0x0e,0,NULL,&p->buffer[c]);  c+=pnm_write_chunk(0x0f,0,NULL,&p->buffer[c]);  c+=pnm_write_chunk(0x11,0,NULL,&p->buffer[c]);

⌨️ 快捷键说明

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