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

📄 demux_viv.c

📁 自己移植的linux下的流媒体播放器原代码,支持mms协议,支持ftp和http协议.
💻 C
📖 第 1 页 / 共 2 页
字号:
//  VIVO file parser by A'rpi//  VIVO text header parser and audio support by alex#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h> /* strtok */#include "config.h"#include "mp_msg.h"#include "help_mp.h"#include "stream.h"#include "demuxer.h"#include "stheader.h"#include "bswap.h"/* parameters ! */int vivo_param_version = -1;char *vivo_param_acodec = NULL;int vivo_param_abitrate = -1;int vivo_param_samplerate = -1;int vivo_param_bytesperblock = -1;int vivo_param_width = -1;int vivo_param_height = -1;int vivo_param_vformat = -1;/* VIVO audio standards from vivog723.acm:    G.723:	FormatTag = 0x111	Channels = 1 - mono	SamplesPerSec = 8000 - 8khz	AvgBytesPerSec = 800	BlockAlign (bytes per block) = 24	BitsPerSample = 8    Siren:	FormatTag = 0x112	Channels = 1 - mono	SamplesPerSec = 16000 - 16khz	AvgBytesPerSec = 2000	BlockAlign (bytes per block) = 40	BitsPerSample = 8*///enum { VIVO_AUDIO_G723, VIVO_AUDIO_SIREN };#define VIVO_AUDIO_G723 1#define VIVO_AUDIO_SIREN 2typedef struct {    /* generic */    char	version;    int		supported;    /* info */    char	*title;    char	*author;    char	*copyright;    char	*producer;    /* video */    float	fps;    int		width;    int		height;    int		disp_width;    int		disp_height;    /* audio */    int		audio_codec;    int		audio_bitrate;    int		audio_samplerate;    int		audio_bytesperblock;} vivo_priv_t;/* parse all possible extra headers *//* (audio headers are seperate - mostly with recordtype=3 or 4) */#define TEXTPARSE_ALL 1static void vivo_parse_text_header(demuxer_t *demux, int header_len){    vivo_priv_t* priv = demux->priv;    char *buf;    int i;    char *token;    char *opt, *param;    int parser_in_audio_block = 0;    if (!demux->priv)    {	priv = malloc(sizeof(vivo_priv_t));	memset(priv, 0, sizeof(vivo_priv_t));	demux->priv = priv;	priv->supported = 0;    }    buf = malloc(header_len);    opt = malloc(header_len);    param = malloc(header_len);    stream_read(demux->stream, buf, header_len);    i=0;    while(i<header_len && buf[i]==0x0D && buf[i+1]==0x0A) i+=2; // skip empty lines        token = strtok(buf, (char *)&("\x0d\x0a"));    while (token && (header_len>2))    {	header_len -= strlen(token)+2;	if (sscanf(token, "%[^:]:%[^\n]", opt, param) != 2)	{	    mp_msg(MSGT_DEMUX, MSGL_V, "viv_text_header_parser: bad line: '%s' at ~%p\n",		token, stream_tell(demux->stream));	    break;	}	mp_dbg(MSGT_DEMUX, MSGL_DBG3, "token: '%s' (%d bytes/%d bytes left)\n",	    token, strlen(token), header_len);	mp_dbg(MSGT_DEMUX, MSGL_DBG3, "token => o: '%s', p: '%s'\n",	    opt, param);	/* checking versions: only v1 or v2 is suitable (or known?:) */	if (!strcmp(opt, "Version"))	{	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "Version: %s\n", param);	    if (!strncmp(param, "Vivo/1", 6) || !strncmp(param, "Vivo/2", 6))	    {		priv->supported = 1;		/* save major version for fourcc */		priv->version = param[5];	    }	}	/* video specific */		if (!strcmp(opt, "FPS"))	{	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "FPS: %f\n", atof(param));	    priv->fps = atof(param);	}	if (!strcmp(opt, "Width"))	{	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "Width: %d\n", atoi(param));	    priv->width = atoi(param);	}	if (!strcmp(opt, "Height"))	{	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "Height: %d\n", atoi(param));	    priv->height = atoi(param);	}	if (!strcmp(opt, "DisplayWidth"))	{	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "Display Width: %d\n", atoi(param));	    priv->disp_width = atoi(param);	}	if (!strcmp(opt, "DisplayHeight"))	{	    mp_msg(MSGT_DEMUX, MSGL_DBG2, "Display Height: %d\n", atoi(param));	    priv->disp_height = atoi(param);	}	/* audio specific */	if (!strcmp(opt, "RecordType"))	{	    /* no audio recordblock by Vivo/1.00, 3 and 4 by Vivo/2.00 */	    if ((atoi(param) == 3) || (atoi(param) == 4))		parser_in_audio_block = 1;	    else		parser_in_audio_block = 0;	}	if (!strcmp(opt, "NominalBitrate"))	{	    priv->audio_bitrate = atoi(param);	    if (priv->audio_bitrate == 2000)		priv->audio_codec = VIVO_AUDIO_SIREN;	    if (priv->audio_bitrate == 800)		priv->audio_codec = VIVO_AUDIO_G723;	}	if (!strcmp(opt, "SamplingFrequency"))	{	    priv->audio_samplerate = atoi(param);	    if (priv->audio_samplerate == 16000)		priv->audio_codec = VIVO_AUDIO_SIREN;	    if (priv->audio_samplerate == 8000)		priv->audio_codec = VIVO_AUDIO_G723;	}	if (!strcmp(opt, "Length") && (parser_in_audio_block == 1))	{	    priv->audio_bytesperblock = atoi(param); /* 24 or 40 kbps */	    if (priv->audio_bytesperblock == 40)		priv->audio_codec = VIVO_AUDIO_SIREN;	    if (priv->audio_bytesperblock == 24)		priv->audio_codec = VIVO_AUDIO_G723;	}		/* only for displaying some informations about movie*/	if (!strcmp(opt, "Title"))	{	    demux_info_add(demux, "name", param);	    priv->title = strdup(param);	}	if (!strcmp(opt, "Author"))	{	    demux_info_add(demux, "author", param);	    priv->author = strdup(param);	}	if (!strcmp(opt, "Copyright"))	{	    demux_info_add(demux, "copyright", param);	    priv->copyright = strdup(param);	}	if (!strcmp(opt, "Producer"))	{	    demux_info_add(demux, "encoder", param);	    priv->producer = strdup(param);	}	/* get next token */	token = strtok(NULL, (char *)&("\x0d\x0a"));    }        if (buf)	free(buf);    if (opt)	free(opt);    if (param)	free(param);}int vivo_check_file(demuxer_t* demuxer){    int i=0;    int len;    int c;    unsigned char buf[2048+256];    vivo_priv_t* priv;    int orig_pos = stream_tell(demuxer->stream);        mp_msg(MSGT_DEMUX,MSGL_V,"Checking for VIVO\n");        c=stream_read_char(demuxer->stream);    if(c==-256) return 0;    len=0;    while((c=stream_read_char(demuxer->stream))>=0x80){	len+=0x80*(c-0x80);	if(len>1024) return 0;    }    len+=c;    mp_msg(MSGT_DEMUX,MSGL_V,"header block 1 size: %d\n",len);    //stream_skip(demuxer->stream,len);    priv=malloc(sizeof(vivo_priv_t));    memset(priv,0,sizeof(vivo_priv_t));    demuxer->priv=priv;#if 0    vivo_parse_text_header(demuxer, len);    if (priv->supported == 0)	return 0;#else    /* this is enought for check (for now) */    stream_read(demuxer->stream,buf,len);    buf[len]=0;//    printf("VIVO header: '%s'\n",buf);    // parse header:    i=0;    while(i<len && buf[i]==0x0D && buf[i+1]==0x0A) i+=2; // skip empty lines    if(strncmp(buf+i,"Version:Vivo/",13)) return 0; // bad version/type!#endif#if 0    c=stream_read_char(demuxer->stream);    if(c) return 0;    len2=0;    while((c=stream_read_char(demuxer->stream))>=0x80){	len2+=0x80*(c-0x80);	if(len+len2>2048) return 0;    }    len2+=c;    mp_msg(MSGT_DEMUX,MSGL_V,"header block 2 size: %d\n",len2);    stream_skip(demuxer->stream,len2);//    stream_read(demuxer->stream,buf+len,len2);#endif    //    c=stream_read_char(demuxer->stream);//    printf("first packet: %02X\n",c);    stream_seek(demuxer->stream, orig_pos);return 1;}static int audio_pos=0;static int audio_rate=0;// return value://     0 = EOF or no stream found//     1 = successfully read a packetint demux_vivo_fill_buffer(demuxer_t *demux){  demux_stream_t *ds=NULL;  int c;  int len=0;  int seq;  int prefix=0;  demux->filepos=stream_tell(demux->stream);    c=stream_read_char(demux->stream);  if (c == -256) /* EOF */    return 0;//  printf("c=%x,%02X\n",c,c&0xf0);  if (c == 0x82)  {      /* ok, this works, but pts calculating from header is required! */#warning "Calculate PTS from picture header!"      prefix = 1;      c = stream_read_char(demux->stream);      printf("packet 0x82(pos=%u) chunk=%x\n",        (int)stream_tell(demux->stream), c);  }  switch(c&0xF0){  case 0x00: // header - skip it!  {      len=stream_read_char(demux->stream);      if(len>=0x80) len=0x80*(len-0x80)+stream_read_char(demux->stream);      printf("vivo extra header: %d bytes\n",len);#ifdef TEXTPARSE_ALL{      int pos;      /* also try to parse all headers */      pos = stream_tell(demux->stream);      vivo_parse_text_header(demux, len);      stream_seek(demux->stream, pos);}#endif      break;  }  case 0x10:  // video packet      if (prefix == 1)        len = stream_read_char(demux->stream);      else        len=128;      ds=demux->video;      break;  case 0x20:  // video packet      len=stream_read_char(demux->stream);      ds=demux->video;      break;  case 0x30:  // audio packet      if (prefix == 1)        len = stream_read_char(demux->stream);      else        len=40;	/* 40kbps */      ds=demux->audio;      audio_pos+=len;      break;  case 0x40:  // audio packet      if (prefix == 1)        len = stream_read_char(demux->stream);      else        len=24;	/* 24kbps */      ds=demux->audio;      audio_pos+=len;      break;  default:      mp_msg(MSGT_DEMUX,MSGL_WARN,"VIVO - unknown ID found: %02X at pos %lu contact author!\n",        c, stream_tell(demux->stream));      return 0;  }//  printf("chunk=%x, len=%d\n", c, len);    if(!ds || ds->id<-1){      if(len) stream_skip(demux->stream,len);      return 1;  }  

⌨️ 快捷键说明

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