Esempio n. 1
0
void
extract_tags(struct fidinfo *fidinfo, char *buf, size_t len)
{
	int		i;
	char		*cp;
	uint16_t	num_tags;
	uint16_t	tag_size;
	uint16_t	value_size;
	uint16_t	unknown;
	char		*tagname;

	cp = buf;
	num_tags = *(uint16_t *)cp;
	le2me_16(num_tags);
	cp += sizeof(uint16_t);

	for (i=0; i<num_tags; i++)
	{
		tag_size = *(uint16_t *)cp;
		le2me_16(tag_size);
		cp += sizeof(uint16_t);

		tagname = utf16tointernal(cp, tag_size);
		cp += tag_size;

		unknown = *(uint16_t *)cp;
		cp += sizeof(uint16_t);

		value_size = *(uint16_t *)cp;
		cp += sizeof(uint16_t);

		parsewmatag(fidinfo, tagname, cp, value_size);
		cp += value_size;
	}
}
Esempio n. 2
0
static int net_stream_fill_buffer(client_t* cl,uint16_t max_len) {
  int r;
  mp_net_stream_packet_t *pack;
  
  if(!cl->stream) {
    if(!write_error(cl->fd,"No stream is currently opened\n"))
      return 0;
    return 1;
  }
  if(max_len == 0) {
    if(!write_error(cl->fd,"Fill buffer called with 0 lenght\n"))
      return 0;
    return 1;
  }
  pack = malloc(max_len + sizeof(mp_net_stream_packet_t));
  pack->cmd = NET_STREAM_OK;
  r = stream_read(cl->stream,pack->data,max_len);
  pack->len = le2me_16(r + sizeof(mp_net_stream_packet_t));
  if(!net_write(cl->fd,(char*)pack,le2me_16(pack->len))) {
    free(pack);
    return 0;
  }
  free(pack);
  return 1;
}
Esempio n. 3
0
static int pci_get_vendor(
          unsigned char bus,
          unsigned char dev,
          int func)
{
    int retval;
    char path[100];
    int fd;
    short vendor, device;
    sprintf(path,"/proc/bus/pci/%02d/%02x.0", bus, dev);
    fd = open(path,O_RDONLY|O_SYNC);
    if (fd == -1) {
	    retval=0xFFFF;
    }
    else if (pread(fd, &vendor, 2, PCI_VENDOR_ID) == 2 &&
             pread(fd, &device, 2, PCI_DEVICE_ID) == 2) {
	    vendor = le2me_16(vendor);
	    device = le2me_16(device);
	    retval = vendor + (device<<16); /*no worries about byte order, 
	    				      all ppc are bigendian*/
    } else {
	    retval = 0xFFFF;
    }   
    if (fd > 0) {
	    close(fd);
    }
    return retval;
}
Esempio n. 4
0
void _x_waveformatex_le2me( xine_waveformatex *wavex ) {

  wavex->wFormatTag = le2me_16(wavex->wFormatTag);
  wavex->nChannels = le2me_16(wavex->nChannels);
  wavex->nSamplesPerSec = le2me_32(wavex->nSamplesPerSec);
  wavex->nAvgBytesPerSec = le2me_32(wavex->nAvgBytesPerSec);
  wavex->nBlockAlign = le2me_16(wavex->nBlockAlign);
  wavex->wBitsPerSample = le2me_16(wavex->wBitsPerSample);
  wavex->cbSize = le2me_16(wavex->cbSize);
}
Esempio n. 5
0
static int fill_buffer(stream_t *s, char *buffer, int max_len)
{
    cdda_priv *p = (cdda_priv *)s->priv;
    int16_t *buf;
    int i;

    if (max_len < CDIO_CD_FRAMESIZE_RAW)
        return -1;

    if ((p->sector < p->start_sector) || (p->sector > p->end_sector)) {
        return 0;
    }

    buf = paranoia_read(p->cdp, cdparanoia_callback);
    if (!buf)
        return 0;

#if BYTE_ORDER == BIG_ENDIAN
    for (i = 0; i < CDIO_CD_FRAMESIZE_RAW / 2; i++)
        buf[i] = le2me_16(buf[i]);
#endif

    p->sector++;
    memcpy(buffer, buf, CDIO_CD_FRAMESIZE_RAW);

    for (i = 0; i < p->cd->tracks; i++) {
        if (p->cd->disc_toc[i].dwStartSector == p->sector - 1) {
            print_track_info(s, i + 1);
            break;
        }
    }

    return CDIO_CD_FRAMESIZE_RAW;
}
Esempio n. 6
0
void _x_bmiheader_le2me( xine_bmiheader *bih ) {
  /* OBS: fourcc must be read using machine endianness
   *      so don't play with biCompression here!
   */

  bih->biSize = le2me_32(bih->biSize);
  bih->biWidth = le2me_32(bih->biWidth);
  bih->biHeight = le2me_32(bih->biHeight);
  bih->biPlanes = le2me_16(bih->biPlanes);
  bih->biBitCount = le2me_16(bih->biBitCount);
  bih->biSizeImage = le2me_32(bih->biSizeImage);
  bih->biXPelsPerMeter = le2me_32(bih->biXPelsPerMeter);
  bih->biYPelsPerMeter = le2me_32(bih->biYPelsPerMeter);
  bih->biClrUsed = le2me_32(bih->biClrUsed);
  bih->biClrImportant = le2me_32(bih->biClrImportant);
}
Esempio n. 7
0
static int sol_probe(AVProbeData *p)
{
    /* check file header */
    uint16_t magic;
    magic=le2me_16(*((uint16_t*)p->buf));
    if ((magic == 0x0B8D || magic == 0x0C0D || magic == 0x0C8D) &&
        p->buf[2] == 'S' && p->buf[3] == 'O' &&
        p->buf[4] == 'L' && p->buf[5] == 0)
        return AVPROBE_SCORE_MAX;
    else
        return 0;
}
Esempio n. 8
0
static void cdparanoia_callback(long inpos, int function) {
#else
static void cdparanoia_callback(long int inpos, paranoia_cb_mode_t function) {
#endif
}

static int fill_buffer(stream_t* s, char* buffer, int max_len) {
  cdda_priv* p = (cdda_priv*)s->priv;
  cd_track_t *cd_track;
  int16_t * buf;
  int i;
  
  buf = paranoia_read(p->cdp,cdparanoia_callback);
  if (!buf)
    return 0;

#ifdef WORDS_BIGENDIAN 
  for(i=0;i<CD_FRAMESIZE_RAW/2;i++)
          buf[i]=le2me_16(buf[i]);
#endif

  p->sector++;
  s->pos = p->sector*CD_FRAMESIZE_RAW;
  memcpy(buffer,buf,CD_FRAMESIZE_RAW);

  if((p->sector < p->start_sector) || (p->sector >= p->end_sector)) {
    s->eof = 1;
    return 0;
  }

  for(i=0;i<p->cd->tracks;i++){
	  if(p->cd->disc_toc[i].dwStartSector==p->sector-1) {
		  cd_track = cd_info_get_track(p->cd_info, i+1);
//printf("Track %d, sector=%d\n", i, p->sector-1);
		  if( cd_track!=NULL ) {
			mp_msg(MSGT_SEEK, MSGL_INFO, "\n%s\n", cd_track->name); 
			mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_CDDA_TRACK=%d\n", cd_track->track_nb);
		  }
		  break;
	  }
  }

  
  return CD_FRAMESIZE_RAW;
}
Esempio n. 9
0
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;
}
Esempio n. 10
0
// plays 'len' bytes of 'data'
// it should round it down to outburst*n
// return: number of bytes played
static int play(void* data,int len,int flags){

// let libaf to do the conversion...
#if 0
//#ifdef WORDS_BIGENDIAN
	if (ao_data.format == AFMT_S16_LE) {
	  unsigned short *buffer = (unsigned short *) data;
	  register int i;
	  for(i = 0; i < len/2; ++i) {
	    buffer[i] = le2me_16(buffer[i]);
	  }
	}
#endif 

	//printf("PCM: Writing chunk!\n");
	fwrite(data,len,1,fp);

	if(ao_pcm_waveheader)
		wavhdr.data_length += len;
	
	return len;
}
Esempio n. 11
0
int handle_client(client_t* cl,mp_net_stream_packet_t* pack) {

  if(!pack)
    return 0;
 
  switch(pack->cmd) {
  case NET_STREAM_OPEN:
    if(((char*)pack)[pack->len-1] != '\0') {
      mp_msg(MSGT_NETST,MSGL_WARN,"Got invalid open packet\n");
      return 0;
    }
    return net_stream_open(cl,pack->data);
  case NET_STREAM_FILL_BUFFER:
    if(pack->len != sizeof(mp_net_stream_packet_t) + 2) {
      mp_msg(MSGT_NETST,MSGL_WARN,"Got invalid fill buffer packet\n");
      return 0;
    }
    return net_stream_fill_buffer(cl,le2me_16(*((uint16_t*)pack->data)));
  case NET_STREAM_SEEK:
    if(pack->len != sizeof(mp_net_stream_packet_t) + 8) {
      mp_msg(MSGT_NETST,MSGL_WARN,"Got invalid fill buffer packet\n");
      return 0;
    }
    return net_stream_seek(cl,le2me_64(*((uint64_t*)pack->data)));
  case NET_STREAM_RESET:
    return net_stream_reset(cl);
  case NET_STREAM_CLOSE:
    if(pack->len != sizeof(mp_net_stream_packet_t)){
      mp_msg(MSGT_NETST,MSGL_WARN,"Got invalid fill buffer packet\n");
      return 0;
    }
    return net_stream_close(cl);
  default:
    mp_msg(MSGT_NETST,MSGL_WARN,"Got unknown command %d\n",pack->cmd);
    if(!write_error(cl->fd,"Unknown command\n"))
      return 0;
  }
  return 0;
}
Esempio n. 12
0
// open & setup audio device
// return: 1=success 0=fail
static int init(int rate,int channels,int format,int flags){
	int bits;
	opt_t subopts[] = {
	  {"waveheader", OPT_ARG_BOOL, &ao_pcm_waveheader, NULL},
	  {"file",       OPT_ARG_MSTRZ, &ao_outputfilename, NULL},
	  {"fast",       OPT_ARG_BOOL, &fast, NULL},
	  {NULL}
	};
	// set defaults
	ao_pcm_waveheader = 1;

	if (subopt_parse(ao_subdevice, subopts) != 0) {
	  return 0;
	}
	if (!ao_outputfilename){
	  ao_outputfilename =
	    strdup(ao_pcm_waveheader?"audiodump.wav":"audiodump.pcm");
	}

	/* bits is only equal to format if (format == 8) or (format == 16);
	   this means that the following "if" is a kludge and should
	   really be a switch to be correct in all cases */

	bits=8;
	switch(format){
	case AF_FORMAT_S8:
	    format=AF_FORMAT_U8;
	case AF_FORMAT_U8:
	    break;
	default:
	    format=AF_FORMAT_S16_LE;
	    bits=16;
	    break;
	}

	ao_data.outburst = 65536;
	ao_data.buffersize= 2*65536;
	ao_data.channels=channels;
	ao_data.samplerate=rate;
	ao_data.format=format;
	ao_data.bps=channels*rate*(bits/8);

	wavhdr.riff = le2me_32(WAV_ID_RIFF);
	wavhdr.wave = le2me_32(WAV_ID_WAVE);
	wavhdr.fmt = le2me_32(WAV_ID_FMT);
	wavhdr.fmt_length = le2me_32(16);
	wavhdr.fmt_tag = le2me_16(WAV_ID_PCM);
	wavhdr.channels = le2me_16(ao_data.channels);
	wavhdr.sample_rate = le2me_32(ao_data.samplerate);
	wavhdr.bytes_per_second = le2me_32(ao_data.bps);
	wavhdr.bits = le2me_16(bits);
	wavhdr.block_align = le2me_16(ao_data.channels * (bits / 8));
	
	wavhdr.data = le2me_32(WAV_ID_DATA);
	wavhdr.data_length=le2me_32(0x7ffff000);
	wavhdr.file_length = wavhdr.data_length + sizeof(wavhdr) - 8;

	mp_msg(MSGT_AO, MSGL_INFO, MSGTR_AO_PCM_FileInfo, ao_outputfilename, 
	       (ao_pcm_waveheader?"WAVE":"RAW PCM"), rate, 
	       (channels > 1) ? "Stereo" : "Mono", af_fmt2str_short(format));
	mp_msg(MSGT_AO, MSGL_INFO, MSGTR_AO_PCM_HintInfo);

	fp = fopen(ao_outputfilename, "wb");
	if(fp) {
		if(ao_pcm_waveheader){ /* Reserve space for wave header */
			fwrite(&wavhdr,sizeof(wavhdr),1,fp);
			wavhdr.file_length=wavhdr.data_length=0;
		}
		return 1;
	}
	mp_msg(MSGT_AO, MSGL_ERR, MSGTR_AO_PCM_CantOpenOutputFile, 
               ao_outputfilename);
	return 0;
}
Esempio n. 13
0
/*
 * choose best audio and video streams, below bw.
 * 'header' is an asf header, and 'asf_header_size' is its size.
 * the result will be in 'streams'
 *             return value:   1  ... success
 *                            -1  ... failed
 */
int asf_choose_best_streams(const uint8_t *header, int asf_header_size,
			    int bw, struct asf_streams_t *streams)
{

    int i = 0,pos = 0,start = 0;
    int *v_rates = NULL, *a_rates = NULL;
    int v_rate = 0, a_rate = 0, v_idx = -1, a_idx = -1;
  
    /*
      header is entire ASF header, including very first asf_header_t.
    */
    pos = sizeof(struct asf_header_t);
    start = pos;
  
    /*
      choose best (fastest) streams
    */
  
    while((pos = find_asf_guid(header,pos,asf_stream_header_guid,asf_header_size)) >= 0) {
	struct asf_stream_header_t *streamh = 
	    (struct asf_stream_header_t *)(header + pos);

	pos += sizeof(struct asf_stream_header_t);
	if(pos > asf_header_size)  /* error */
	    return -1;
    
    
	/* get ASF GUID PREFIX (first 4 byte of GUID) */
	switch(get32_le(streamh->type)) {
	    
	case ASF_AUDIO_STREAM: /* audio stream */
	    display(MSDL_VER,"audio stream detected!!!!\n");
	    if(streams->audio_streams == NULL) { /* no audio stream registerd yet */
		streams->audio_streams = (int *)xmalloc(sizeof(int));
		streams->n_audio = 1;
	    }
	    else { /* more audio streams.!! */
		streams->n_audio++;
		streams->audio_streams = 
		    (int *)xrealloc(streams->audio_streams,
				    streams->n_audio * sizeof(int));
	    }
	    streams->audio_streams[streams->n_audio - 1] =
		le2me_16(streamh->stream_no);
	    break;
      
	case ASF_VIDEO_STREAM: /* video streams */
	    display(MSDL_VER,"video stream detected!!!!\n");
	    if(streams->video_streams == NULL) { /* no video stream registerd yet */
		streams->video_streams = (int *)xmalloc(sizeof(int));
		streams->n_video = 1;
	    }
	    else { /* more video streams.!! */
		streams->n_video++;
		streams->video_streams = 
		    (int *)xrealloc(streams->video_streams,
				    streams->n_video * sizeof(int));
	    }
	    streams->video_streams[streams->n_video - 1] =
		le2me_16(streamh->stream_no);
	    break;
      
	case ASF_COMMAND_MEDIA_STREAM: /* Command media stream... whatever*/
	    display(MSDL_VER,"Command media stream detected, but ignore this.\n");
	    break;
      
	case ASF_FILE_TRANSFER_MEDIA_STREAM: /* File transfer media stream... 
						I don't know what the heck this is.*/
	    display(MSDL_VER,"File transfer stream detected, but ignore this.\n");
	    break;
      
	}
    }

    a_rates = (int *)xmalloc(streams->n_audio * sizeof(int));
    v_rates = (int *)xmalloc(streams->n_video * sizeof(int));

  
    pos = find_asf_guid(header,start,asf_stream_group_guid,asf_header_size);
    if(pos >= 0) {
	/* stream bitrate proterties object */

	int stream_count = 0;
	uint8_t *ptr = (uint8_t *)header + pos;
	
	display(MSDL_VER,"stream bitrate properties object\n");
    
	stream_count = get16_le(ptr); /* little endian. */
	ptr += sizeof(uint16_t);
	if(ptr > header + asf_header_size) goto failed;
	display(MSDL_VER,"stream count = [0x%x] [%u]\n",stream_count,stream_count);
	display(MSDL_VER,"audio streams: %d, video streams: %d\n",
		streams->n_audio,streams->n_video);

	for(i = 0; i < stream_count; i++) {
	    uint32_t rate = 0;
	    int id = 0;
	    int j = 0;
      
	    id = get16_le(ptr);
	    ptr += sizeof(uint16_t);
	    if(ptr > header + asf_header_size) goto failed;
	    rate = get32_le(ptr);
	    ptr += sizeof(uint32_t);
	    if(ptr > header + asf_header_size) goto failed;
      
	    display(MSDL_VER,
		    "stream_id   = [0x%x] [%u]\n"
		    "max bitrate = [0x%x] [%u]\n",
		    id,id,rate,rate);
      
	    for(j = 0; j < streams->n_audio; j++) {
		if(id == streams->audio_streams[j]) {
		    display(MSDL_VER,"is audio stream\n");
		    a_rates[j] = rate;
		    break;
		}
	    }
	    for(j = 0; j < streams->n_video; j++) {
		if(id == streams->video_streams[j]) {
		    display(MSDL_VER,"is video stream\n");
		    v_rates[j] = rate;
		    break;
		}
	    }
	}
    }

    /* just to make sure bw is not Zero! */
    if(bw == 0) {
	bw = INT_MAX_BANDWIDTH;
    }

    if(streams->n_audio) {
	/* find lowest-bitrate audio stream */
	a_rate = a_rates[0];
	a_idx = 0;
	for(i = 0; i < streams->n_audio; i++) {
	    if(a_rates[i] < a_rate) {
		a_rate = a_rates[i];
		a_idx = i;
	    }
	}
	if(max_idx(streams->n_video,v_rates,bw - a_rate) < 0) {
	    /* both audio and video are not possible, try video only next */
	    a_idx = -1;
	    a_rate = 0;
	}
    }
  
    /* find best video stream */
    v_idx = max_idx(streams->n_video,v_rates,bw - a_rate);
    if(v_idx >= 0) {
	v_rate = v_rates[v_idx];
    }
  
    /* find best auido stream */
    a_idx = max_idx(streams->n_audio,a_rates,bw - v_rate);

    free(v_rates);
    v_rates = NULL;
    free(a_rates);
    a_rates = NULL;

    if(a_idx < 0 && v_idx < 0) {
	display(MSDL_ERR,"bandwidth too low ... cannot get streams.");
	return -1;
    }
  
  
    if(a_idx >= 0) {
	streams->audio_id = streams->audio_streams[a_idx];
    }
    else if(streams->n_audio) {
	display(MSDL_ERR,"Bandwidth too too small so deselected audio....sad.\n");
    }
  
    if(v_idx >= 0) {
	streams->video_id = streams->video_streams[v_idx];
    }
    else if(streams->n_video) {
	display(MSDL_ERR,"Bandwidth too too small so deselected video....sad.\n");
    }
  
  
    return 1;

  failed:
    free(v_rates);
    free(a_rates);
    return -1;

}
Esempio n. 14
0
int main(int argc, char *argv[])
{
    if( argc != 4 )
    {
        io::cerr << "Usage: \t lpcm2wav sample_rate:channels:bps file.lpcm out_file.wav" << io::endl;
        io::cerr << "\t lpcm2wav makes wav from dvd lpcm stream."                        << io::endl;

        return 1;
    }

    PCMWaveHeader hdr;
    if( !ParsePcmTriple(argv[1], hdr) )
    {
        io::cerr << "Can't get correct sample_rate:channels:bps triple!" << io::endl;
        return 2;
    }
    uint32_t samplerate = hdr.sampleRate;
    uint16_t channels   = hdr.channels;
    uint16_t bits       = hdr.bits;

    io::cerr << "Sample rate (Hz):\t " << samplerate  << io::endl;
    io::cerr << "Number of channels:\t "  << channels << io::endl;
    io::cerr << "Sample size (bit):\t "   << bits     << io::endl;

    io::stream strm(argv[2], iof::in);
    if( !strm )
    {
        io::cerr << "Can't open file: " << argv[2] << io::endl;
        return 3;
    }

    io::pos file_big_sz = StreamSize(strm);
    if( file_big_sz > UINT32_MAX-100 ) // ограничение размера wav-файла 32битами
    {
        io::cerr << "Can't do wav-file because " << argv[2] << " is too big, > 3,9Gb." << io::endl;
        return 4;
    }
    uint32_t file_sz = file_big_sz;

    // заполняем оставшееся, c учетом little endian
    hdr.riff    = le2me_32(WAV_ID_RIFF);
    hdr.fileLen = le2me_32(file_sz + PCM_WAVE_HEADER_SIZE - 8);
    hdr.wave    = le2me_32(WAV_ID_WAVE);

    hdr.frmt     = le2me_32(WAV_ID_FMT);
    hdr.frmtLen  = le2me_32(16);
    hdr.frmtTag  = le2me_16(WAV_ID_PCM);
    hdr.channels = le2me_16(channels);
    hdr.sampleRate     = le2me_32(samplerate);
    hdr.bytesPerSecond = le2me_32(channels * samplerate * bits / 8);
    hdr.blockAlign     = le2me_16(channels * bits / 8);
    hdr.bits     = le2me_16(bits);

    hdr.data     = le2me_32(WAV_ID_DATA);
    hdr.dataLen  = le2me_32(file_sz);
    
    // запись
    io::stream wav_strm(argv[3], iof::out);
    if( !wav_strm )
    {
        io::cerr << "Can't write to file: " << argv[3] << io::endl;
        return 5;
    }

    wav_strm.raw_write((const char*)&hdr, PCM_WAVE_HEADER_SIZE);
    const char* incomplete_samples = "Error: Number of PCM samples is incomplete.";
    switch( bits )
    {
    case 16:
        {
            if( file_sz%2 )
                io::cerr << incomplete_samples << io::endl;
            TBReadFunctor fnr = bl::bind(&Swap16AndWrite, bl::_1, boost::ref(wav_strm));
            ReadStreamThroughTB(fnr, strm, file_sz);
        }
        break;
    case 20:
        {
            if( file_sz%(5*channels) )
                io::cerr << incomplete_samples << io::endl;
            TBReadFunctor fnr = bl::bind(&Reconstruct20bitLPCM, bl::_1, channels, boost::ref(wav_strm));
            ReadStreamThroughTB(fnr, strm, file_sz);
        }
        break;
    case 24:
        {
            if( file_sz%(6*channels) )
                io::cerr << incomplete_samples << io::endl;
            TBReadFunctor fnr = bl::bind(&Reconstruct24bitLPCM, bl::_1, channels, boost::ref(wav_strm));
            ReadStreamThroughTB(fnr, strm, file_sz);
        }
        break;
    default:
        ASSERT(0);
    }
    return 0;
}
static int
demux_mkv_open_audio (FileInfo *finfo, mkv_track_t *track)
{
  WAVEFORMATEX *finfowf = &finfo->wf;

  if (track->ms_compat && (track->private_size >= sizeof(WAVEFORMATEX)))
    {
      WAVEFORMATEX *wf = (WAVEFORMATEX *)track->private_data;
      finfowf->wFormatTag = le2me_16 (wf->wFormatTag);
      finfowf->nChannels = le2me_16 (wf->nChannels);
      finfowf->nSamplesPerSec = le2me_32 (wf->nSamplesPerSec);
      finfowf->nAvgBytesPerSec = le2me_32 (wf->nAvgBytesPerSec);
      finfowf->nBlockAlign = le2me_16 (wf->nBlockAlign);
      finfowf->wBitsPerSample = le2me_16 (wf->wBitsPerSample);
      if (track->a_sfreq == 0.0)
        track->a_sfreq = finfowf->nSamplesPerSec;
      if (track->a_channels == 0)
        track->a_channels = finfowf->nChannels;
      if (track->a_bps == 0)
        track->a_bps = finfowf->wBitsPerSample;
      track->a_formattag = finfowf->wFormatTag;
    }
  else
    {
      memset(finfowf, 0, sizeof (WAVEFORMATEX));
      if (!strcmp(track->codec_id, MKV_A_MP3) ||
          !strcmp(track->codec_id, MKV_A_MP2))
        track->a_formattag = 0x0055;
      else if (!strncmp(track->codec_id, MKV_A_AC3, strlen(MKV_A_AC3)))
        track->a_formattag = 0x2000;
      else if (!strncmp(track->codec_id, MKV_A_EAC3, strlen(MKV_A_EAC3)))
        track->a_formattag = AUDIO_EAC3;
      else if (!strcmp(track->codec_id, MKV_A_DTS))
	  {
        track->a_formattag = 0x2001;
        //dts_packet = 1;
	  }
      else if (!strcmp(track->codec_id, MKV_A_PCM) ||
               !strcmp(track->codec_id, MKV_A_PCM_BE))
        track->a_formattag = 0x0001;
      else if (!strcmp(track->codec_id, MKV_A_AAC_2MAIN) ||
               !strncmp(track->codec_id, MKV_A_AAC_2LC,
                        strlen(MKV_A_AAC_2LC)) ||
               !strcmp(track->codec_id, MKV_A_AAC_2SSR) ||
               !strcmp(track->codec_id, MKV_A_AAC_4MAIN) ||
               !strncmp(track->codec_id, MKV_A_AAC_4LC,
                        strlen(MKV_A_AAC_4LC)) ||
               !strcmp(track->codec_id, MKV_A_AAC_4SSR) ||
               !strcmp(track->codec_id, MKV_A_AAC_4LTP) ||
               !strcmp(track->codec_id, MKV_A_AAC))
        track->a_formattag = mmioFOURCC('M', 'P', '4', 'A');
      else if (!strcmp(track->codec_id, MKV_A_VORBIS))
        {
          if (track->private_data == NULL)
            return 1;
          track->a_formattag = mmioFOURCC('v', 'r', 'b', 's');
        }
      else if (!strcmp(track->codec_id, MKV_A_QDMC))
        track->a_formattag = mmioFOURCC('Q', 'D', 'M', 'C');
      else if (!strcmp(track->codec_id, MKV_A_QDMC2))
        track->a_formattag = mmioFOURCC('Q', 'D', 'M', '2');
      else if (!strcmp(track->codec_id, MKV_A_WAVPACK))
        track->a_formattag = mmioFOURCC('W', 'V', 'P', 'K');
      else if (!strcmp(track->codec_id, MKV_A_TRUEHD))
        track->a_formattag = mmioFOURCC('T', 'R', 'H', 'D');
      else if (!strcmp(track->codec_id, MKV_A_FLAC))
        {
          if (track->private_data == NULL || track->private_size == 0)
            {
              mp_msg (MSGT_DEMUX, MSGL_WARN,
                      MSGTR_MPDEMUX_MKV_FlacTrackDoesNotContainValidHeaders);
              return 1;
            }
          track->a_formattag = mmioFOURCC ('f', 'L', 'a', 'C');
        }
      else if (track->private_size >= RAPROPERTIES4_SIZE)
        {
          if (!strcmp(track->codec_id, MKV_A_REAL28))
            track->a_formattag = mmioFOURCC('2', '8', '_', '8');
          else if (!strcmp(track->codec_id, MKV_A_REALATRC))
            track->a_formattag = mmioFOURCC('a', 't', 'r', 'c');
          else if (!strcmp(track->codec_id, MKV_A_REALCOOK))
            track->a_formattag = mmioFOURCC('c', 'o', 'o', 'k');
          else if (!strcmp(track->codec_id, MKV_A_REALDNET))
            track->a_formattag = mmioFOURCC('d', 'n', 'e', 't');
          else if (!strcmp(track->codec_id, MKV_A_REALSIPR))
            track->a_formattag = mmioFOURCC('s', 'i', 'p', 'r');
        }
      else
        {
          mp_msg (MSGT_DEMUX, MSGL_WARN, MSGTR_MPDEMUX_MKV_UnknownAudioCodec,
                  track->codec_id, track->tnum);
          return 1;
        }
    }

  finfowf->wFormatTag = track->a_formattag;
  finfowf->nChannels = track->a_channels;
  finfowf->nSamplesPerSec = (uint32_t) track->a_sfreq;
  if (track->a_bps == 0)
    {
      finfowf->wBitsPerSample = 16;
    }
  else
    {
      finfowf->wBitsPerSample = track->a_bps;
    }
  if (track->a_formattag == 0x0055)  /* MP3 || MP2 */
    {
      finfowf->nAvgBytesPerSec = 16000;
      finfowf->nBlockAlign = 1152;
    }
  else if (track->a_formattag == 0x2000 )/* AC3 */
    {
    }
  else if (track->a_formattag == AUDIO_EAC3 )/* EAC3 */
    {
    }
  else if (track->a_formattag == 0x2001) /* DTS */
    {
      //dts_packet = 1;
    }
  else if (track->a_formattag == 0x0001)  /* PCM || PCM_BE */
    {
      finfowf->nAvgBytesPerSec = track->a_channels * track->a_sfreq * 2;
      finfowf->nBlockAlign = finfowf->nAvgBytesPerSec;
	  /*
      if (!strcmp(track->codec_id, MKV_A_PCM_BE))
        sh_a->format = mmioFOURCC('t', 'w', 'o', 's');
		*/
    }
  else if (!strcmp(track->codec_id, MKV_A_QDMC) ||
           !strcmp(track->codec_id, MKV_A_QDMC2))
    {
      finfowf->nAvgBytesPerSec = 16000;
      finfowf->nBlockAlign = 1486;
      track->fix_i_bps = 1;
      track->qt_last_a_pts = 0.0;
    }
  else if (track->a_formattag == mmioFOURCC('M', 'P', '4', 'A'))
    {
      int profile, srate_idx;

      finfowf->nAvgBytesPerSec = 16000;
      finfowf->nBlockAlign = 1024;

      if (!strcmp (track->codec_id, MKV_A_AAC) &&
          (NULL != track->private_data))
        {
          return 0;
        }

      /* Recreate the 'private data' */
      /* which faad2 uses in its initialization */
      srate_idx = aac_get_sample_rate_index (track->a_sfreq);
      if (!strncmp (&track->codec_id[12], "MAIN", 4))
        profile = 0;
      else if (!strncmp (&track->codec_id[12], "LC", 2))
        profile = 1;
      else if (!strncmp (&track->codec_id[12], "SSR", 3))
        profile = 2;
      else
        profile = 3;

      if (strstr(track->codec_id, "SBR") != NULL)
        {
          /* HE-AAC (aka SBR AAC) */
          track->default_duration = 1024.0 / finfowf->nSamplesPerSec;
          finfowf->nSamplesPerSec *= 2;
        }
      else
        {
          track->default_duration = 1024.0 / (float)finfowf->nSamplesPerSec;
        }
    }
  else if (track->a_formattag == mmioFOURCC('v', 'r', 'b', 's'))  /* VORBIS */
    {
      //finfowf->cbSize = track->private_size;
    }
  else if (track->private_size >= RAPROPERTIES4_SIZE
           && !strncmp (track->codec_id, MKV_A_REALATRC, 7))
    {
      /* Common initialization for all RealAudio codecs */
      unsigned char *src = (unsigned char *)track->private_data;
      int codecdata_length, version;
      int flavor;

      finfowf->nAvgBytesPerSec = 0;  /* FIXME !? */

      version = AV_RB16(src + 4);
      flavor = AV_RB16(src + 22);
      track->coded_framesize = AV_RB32(src + 24);
      track->sub_packet_h = AV_RB16(src + 40);
      finfowf->nBlockAlign =
      track->audiopk_size = AV_RB16(src + 42);
      track->sub_packet_size = AV_RB16(src + 44);
      if (version == 4)
        {
          src += RAPROPERTIES4_SIZE;
          src += src[0] + 1;
          src += src[0] + 1;
        }
      else
        src += RAPROPERTIES5_SIZE;

      src += 3;
      if (version == 5)
        src++;
      codecdata_length = AV_RB32(src);
      src += 4;

      switch (track->a_formattag) {
        case mmioFOURCC('a', 't', 'r', 'c'):
          finfowf->nAvgBytesPerSec = atrc_fl2bps[flavor];
          finfowf->nBlockAlign = track->sub_packet_size;
          break;
        case mmioFOURCC('c', 'o', 'o', 'k'):
          finfowf->nAvgBytesPerSec = cook_fl2bps[flavor];
          finfowf->nBlockAlign = track->sub_packet_size;
          break;
        case mmioFOURCC('s', 'i', 'p', 'r'):
          finfowf->nAvgBytesPerSec = sipr_fl2bps[flavor];
          finfowf->nBlockAlign = track->coded_framesize;
          break;
        case mmioFOURCC('2', '8', '_', '8'):
          finfowf->nAvgBytesPerSec = 3600;
          finfowf->nBlockAlign = track->coded_framesize;
          break;
      }

      track->realmedia = 1;
    }
  else if (!strcmp(track->codec_id, MKV_A_FLAC) ||
           (track->a_formattag == 0xf1ac))
    {
      unsigned char *ptr;
      int size;
#if 1	//Fuchun 2010.06.23
	if(track->a_formattag == mmioFOURCC('f', 'L', 'a', 'C'))
	{
		ptr = (unsigned char *)track->private_data;
		size = track->private_size;
	}
	else
	{
		//sh_a->format = mmioFOURCC('f', 'L', 'a', 'C');
		ptr = (unsigned char *) track->private_data + sizeof (WAVEFORMATEX);
		size = track->private_size - sizeof (WAVEFORMATEX);
	}
	if(size < 4 || ptr[0] != 'f' || ptr[1] != 'L' ||ptr[2] != 'a' || ptr[3] != 'C')
	{
		//finfowf->cbSize = 4;
	}
	else
	{
		//finfowf->cbSize = size;
	}
#else
      free(finfowf);
      finfowf = NULL;

      if (track->a_formattag == mmioFOURCC('f', 'L', 'a', 'C'))
        {
          ptr = (unsigned char *)track->private_data;
          size = track->private_size;
        }
      else
        {
          sh_a->format = mmioFOURCC('f', 'L', 'a', 'C');
          ptr = (unsigned char *) track->private_data
            + sizeof (WAVEFORMATEX);
          size = track->private_size - sizeof (WAVEFORMATEX);
        }
      if (size < 4 || ptr[0] != 'f' || ptr[1] != 'L' ||
          ptr[2] != 'a' || ptr[3] != 'C')
        {
          dp = new_demux_packet (4);
          memcpy (dp->buffer, "fLaC", 4);
        }
      else
        {
          dp = new_demux_packet (size);
          memcpy (dp->buffer, ptr, size);
        }
      dp->pts = 0;
      dp->flags = 0;
      ds_add_packet (demuxer->audio, dp);
#endif
    }
  else if (track->a_formattag == mmioFOURCC('W', 'V', 'P', 'K') ||
           track->a_formattag == mmioFOURCC('T', 'R', 'H', 'D'))
    {  /* do nothing, still works */  }
  else if (!track->ms_compat || (track->private_size < sizeof(WAVEFORMATEX)))
    {
      return 1;
    }

  return 0;
}
static int
demux_mkv_open_video (FileInfo *finfo, mkv_track_t *track)
{
  BITMAP_INFO_HEADER *bih = &finfo->bih;
#ifdef CONFIG_QTX_CODECS
  void *ImageDesc = NULL;
#endif

  if (track->ms_compat)  /* MS compatibility mode */
    {
      BITMAP_INFO_HEADER *src;

      if (track->private_data == NULL
          || track->private_size < sizeof (BITMAP_INFO_HEADER))
        return 1;

      src = (BITMAP_INFO_HEADER *) track->private_data;
      bih->biSize = le2me_32 (src->biSize);
      bih->biWidth = le2me_32 (src->biWidth);
      bih->biHeight = le2me_32 (src->biHeight);
      bih->biPlanes = le2me_16 (src->biPlanes);
      bih->biBitCount = le2me_16 (src->biBitCount);
      bih->biCompression = le2me_32 (src->biCompression);
      bih->biSizeImage = le2me_32 (src->biSizeImage);
      bih->biXPelsPerMeter = le2me_32 (src->biXPelsPerMeter);
      bih->biYPelsPerMeter = le2me_32 (src->biYPelsPerMeter);
      bih->biClrUsed = le2me_32 (src->biClrUsed);
      bih->biClrImportant = le2me_32 (src->biClrImportant);

      if (track->v_width == 0)
        track->v_width = bih->biWidth;
      if (track->v_height == 0)
        track->v_height = bih->biHeight;
    }
  else
    {
      bih->biSize = sizeof (BITMAP_INFO_HEADER);
      bih->biWidth = track->v_width;
      bih->biHeight = track->v_height;
      bih->biBitCount = 24;
      bih->biSizeImage = bih->biWidth * bih->biHeight * bih->biBitCount/8;

      if (track->private_size >= RVPROPERTIES_SIZE
          && (!strcmp (track->codec_id, MKV_V_REALV10)
              || !strcmp (track->codec_id, MKV_V_REALV20)
              || !strcmp (track->codec_id, MKV_V_REALV30)
              || !strcmp (track->codec_id, MKV_V_REALV40)))
        {
          unsigned char *src;
          uint32_t type2;
          unsigned int cnt;

          src = (uint8_t *)track->private_data + RVPROPERTIES_SIZE;

          cnt = track->private_size - RVPROPERTIES_SIZE;
          bih->biPlanes = 1;
          type2 = AV_RB32(src - 4);
          if (type2 == 0x10003000 || type2 == 0x10003001)
            bih->biCompression=mmioFOURCC('R','V','1','3');
          else
            bih->biCompression=mmioFOURCC('R','V',track->codec_id[9],'0');
          track->realmedia = 1;

#ifdef CONFIG_QTX_CODECS
        }
      else if (track->private_size >= sizeof (ImageDescription)
               && !strcmp(track->codec_id, MKV_V_QUICKTIME))
        {
          ImageDescriptionPtr idesc;

          idesc = (ImageDescriptionPtr) track->private_data;
          idesc->idSize = be2me_32 (idesc->idSize);
          idesc->cType = be2me_32 (idesc->cType);
          idesc->version = be2me_16 (idesc->version);
          idesc->revisionLevel = be2me_16 (idesc->revisionLevel);
          idesc->vendor = be2me_32 (idesc->vendor);
          idesc->temporalQuality = be2me_32 (idesc->temporalQuality);
          idesc->spatialQuality = be2me_32 (idesc->spatialQuality);
          idesc->width = be2me_16 (idesc->width);
          idesc->height = be2me_16 (idesc->height);
          idesc->hRes = be2me_32 (idesc->hRes);
          idesc->vRes = be2me_32 (idesc->vRes);
          idesc->dataSize = be2me_32 (idesc->dataSize);
          idesc->frameCount = be2me_16 (idesc->frameCount);
          idesc->depth = be2me_16 (idesc->depth);
          idesc->clutID = be2me_16 (idesc->clutID);
          bih->biPlanes = 1;
          bih->biCompression = idesc->cType;
          ImageDesc = idesc;
#endif /* CONFIG_QTX_CODECS */

        }
      else
        {
          const videocodec_info_t *vi = vinfo;
          while (vi->id && strcmp(vi->id, track->codec_id)) vi++;
          bih->biCompression = vi->fourcc;
          track->reorder_timecodes = 1;
          if (!vi->id) {
              mp_msg (MSGT_DEMUX,MSGL_WARN, MSGTR_MPDEMUX_MKV_UnknownCodecID,
                      track->codec_id, track->tnum);
              return 1;
          }
        }
    }

  if (track->v_frate == 0.0)
    track->v_frate = 25.0;
  finfo->FPS = track->v_frate;

  return 0;
}