Пример #1
0
static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
{
  if(sh_audio->format==0x31 || sh_audio->format==0x32){
    unsigned char ibuf[65]; // 65 bytes / frame
    if(demux_read_data(sh_audio->ds,ibuf,65)!=65) return -1; // EOF
    XA_MSGSM_Decoder(ibuf,(unsigned short *) buf); // decodes 65 byte -> 320 short
    return 2*320;
  } else {
    unsigned char ibuf[33]; // 33 bytes / frame
    if(demux_read_data(sh_audio->ds,ibuf,33)!=33) return -1; // EOF
    XA_GSM_Decoder(ibuf,(unsigned short *) buf); // decodes 33 byte -> 160 short
    return 2*160;
  }
}
Пример #2
0
int stream_fill_buffer(stream_t *s){
  int len;
  if (/*s->fd == NULL ||*/ s->eof) { s->buf_pos = s->buf_len = 0; return 0; }
  switch(s->type){
  case STREAMTYPE_STREAM:
#ifdef MPLAYER_NETWORK
    if( s->streaming_ctrl!=NULL ) {
	    len=s->streaming_ctrl->streaming_read(s->fd,s->buffer,STREAM_BUFFER_SIZE, s->streaming_ctrl);break;
    } else {
      len=read(s->fd,s->buffer,STREAM_BUFFER_SIZE);break;
    }
#else
    len=read(s->fd,s->buffer,STREAM_BUFFER_SIZE);break;
#endif
  case STREAMTYPE_DS:
    len = demux_read_data((demux_stream_t*)s->priv,s->buffer,STREAM_BUFFER_SIZE);
    break;
  
    
  default: 
    len= s->fill_buffer ? s->fill_buffer(s,s->buffer,STREAM_BUFFER_SIZE) : 0;
  }
  if(len<=0){ s->eof=1; s->buf_pos=s->buf_len=0; return 0; }
  s->buf_pos=0;
  s->buf_len=len;
  s->pos+=len;
//  printf("[%d]",len);fflush(stdout);
  return len;
}
Пример #3
0
int a52_fillbuff(sh_audio_t *sh_audio){
int length=0;
int flags=0;
int sample_rate=0;
int bit_rate=0;

    sh_audio->a_in_buffer_len=0;
    /* sync frame:*/
while(1){
    while(sh_audio->a_in_buffer_len<8){
	int c=demux_getc(sh_audio->ds);
	if(c<0) return -1; /* EOF*/
        sh_audio->a_in_buffer[sh_audio->a_in_buffer_len++]=c;
    }
    if(sh_audio->format!=0x2000) swab(sh_audio->a_in_buffer,sh_audio->a_in_buffer,8);
    length = a52_syncinfo (sh_audio->a_in_buffer, &flags, &sample_rate, &bit_rate);
    if(length>=7 && length<=3840) break; /* we're done.*/
    /* bad file => resync*/
    if(sh_audio->format!=0x2000) swab(sh_audio->a_in_buffer,sh_audio->a_in_buffer,8);
    memmove(sh_audio->a_in_buffer,sh_audio->a_in_buffer+1,7);
    --sh_audio->a_in_buffer_len;
}
    mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"a52: len=%d  flags=0x%X  %d Hz %d bit/s\n",length,flags,sample_rate,bit_rate);
    sh_audio->samplerate=sample_rate;
    sh_audio->i_bps=bit_rate/8;
    sh_audio->samplesize=sh_audio->sample_format==AF_FORMAT_FLOAT_NE ? 4 : 2;
    demux_read_data(sh_audio->ds,sh_audio->a_in_buffer+8,length-8);
    if(sh_audio->format!=0x2000)
	swab(sh_audio->a_in_buffer+8,sh_audio->a_in_buffer+8,length-8);
    
    if(crc16_block(sh_audio->a_in_buffer+2,length-2)!=0)
	mp_msg(MSGT_DECAUDIO,MSGL_STATUS,"a52: CRC check failed!  \n");
    
    return length;
}
Пример #4
0
static int read_frame(sh_audio_t *sh){
  mad_decoder_t *this = sh->context;
  int len;

while((len=demux_read_data(sh->ds,&sh->a_in_buffer[sh->a_in_buffer_len],
          sh->a_in_buffer_size-sh->a_in_buffer_len))>0){
  sh->a_in_buffer_len+=len;
  while(1){
    int ret;
    mad_stream_buffer (&this->stream, sh->a_in_buffer, sh->a_in_buffer_len);
    ret=mad_frame_decode (&this->frame, &this->stream);
    if (this->stream.next_frame) {
	int num_bytes =
	    (char*)sh->a_in_buffer+sh->a_in_buffer_len - (char*)this->stream.next_frame;
	memmove(sh->a_in_buffer, this->stream.next_frame, num_bytes);
	mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"libmad: %d bytes processed\n",sh->a_in_buffer_len-num_bytes);
	sh->a_in_buffer_len = num_bytes;
    }
    if (ret == 0) return 1; // OK!!!
    // error! try to resync!
    if(this->stream.error==MAD_ERROR_BUFLEN) break;
  }
}
mp_msg(MSGT_DECAUDIO,MSGL_INFO,"Cannot sync MAD frame\n");
return 0;
}
Пример #5
0
/**
 * \brief read data until the given 3-byte pattern is encountered, up to maxlen
 * \param mem memory to read data into, may be NULL to discard data
 * \param maxlen maximum number of bytes to read
 * \param read number of bytes actually read
 * \param pattern pattern to search for (lowest 8 bits are ignored)
 * \return whether pattern was found
 */
int demux_pattern_3(demux_stream_t *ds, unsigned char *mem, int maxlen,
                    int *read, uint32_t pattern)
{
    register uint32_t head = 0xffffff00;
    register uint32_t pat = pattern & 0xffffff00;
    int total_len = 0;
    do {
        register unsigned char *ds_buf = &ds->buffer[ds->buffer_size];
        int len = ds->buffer_size - ds->buffer_pos;
        register long pos = -len;
        if (unlikely(pos >= 0)) { // buffer is empty
            ds_fill_buffer(ds);
            continue;
        }
        do {
            head |= ds_buf[pos];
            head <<= 8;
        } while (++pos && head != pat);
        len += pos;
        if (total_len + len > maxlen)
            len = maxlen - total_len;
        len = demux_read_data(ds, mem ? &mem[total_len] : NULL, len);
        total_len += len;
    } while ((head != pat || total_len < 3) && total_len < maxlen && !ds->eof);
    if (read)
        *read = total_len;
    return total_len >= 3 && head == pat;
}
Пример #6
0
int stream_fill_buffer(stream_t *s){
  int len;
  // we will retry even if we already reached EOF previously.
  switch(s->type){
  case STREAMTYPE_STREAM:
#ifdef CONFIG_NETWORKING
    if( s->streaming_ctrl!=NULL && s->streaming_ctrl->streaming_read ) {
	    len=s->streaming_ctrl->streaming_read(s->fd,s->buffer,STREAM_BUFFER_SIZE, s->streaming_ctrl);
    } else
#endif
    if (s->fill_buffer)
      len = s->fill_buffer(s, s->buffer, STREAM_BUFFER_SIZE);
    else
      len=read(s->fd,s->buffer,STREAM_BUFFER_SIZE);
    break;
  case STREAMTYPE_DS:
    len = demux_read_data((demux_stream_t*)s->priv,s->buffer,STREAM_BUFFER_SIZE);
    break;


  default:
    len= s->fill_buffer ? s->fill_buffer(s,s->buffer,STREAM_BUFFER_SIZE) : 0;
  }
  if(len<=0){ s->eof=1; return 0; }
  // When reading succeeded we are obviously not at eof.
  // This e.g. avoids issues with eof getting stuck when lavf seeks in MPEG-TS
  s->eof=0;
  s->buf_pos=0;
  s->buf_len=len;
  s->pos+=len;
//  printf("[%d]",len);fflush(stdout);
  if (s->capture_file)
    stream_capture_do(s);
  return len;
}
Пример #7
0
static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
{
	DMO_AudioDecoder* ds_adec = sh_audio->context;
//	int len=-1;
        int size_in=0;
        int size_out=0;
        int srcsize=DMO_AudioDecoder_GetSrcSize(ds_adec, maxlen);
        mp_msg(MSGT_DECAUDIO,MSGL_DBG3,"DMO says: srcsize=%d  (buffsize=%d)  out_size=%d\n",srcsize,sh_audio->a_in_buffer_size,maxlen);
        if(srcsize>sh_audio->a_in_buffer_size) srcsize=sh_audio->a_in_buffer_size; // !!!!!!
        if(sh_audio->a_in_buffer_len<srcsize){
          sh_audio->a_in_buffer_len+=
            demux_read_data(sh_audio->ds,&sh_audio->a_in_buffer[sh_audio->a_in_buffer_len],
            srcsize-sh_audio->a_in_buffer_len);
        }
        DMO_AudioDecoder_Convert(ds_adec, sh_audio->a_in_buffer,sh_audio->a_in_buffer_len,
            buf,maxlen, &size_in,&size_out);
        mp_dbg(MSGT_DECAUDIO,MSGL_DBG2,"DMO: audio %d -> %d converted  (in_buf_len=%d of %d)  %d\n",size_in,size_out,sh_audio->a_in_buffer_len,sh_audio->a_in_buffer_size,ds_tell_pts(sh_audio->ds));
        if(size_in>=sh_audio->a_in_buffer_len){
          sh_audio->a_in_buffer_len=0;
        } else {
          sh_audio->a_in_buffer_len-=size_in;
          memmove(sh_audio->a_in_buffer,&sh_audio->a_in_buffer[size_in],sh_audio->a_in_buffer_len);
        }
//        len=size_out;
  return size_out;
}
Пример #8
0
static int mpa_sync(sh_audio_t *sh, int no_frames, int *n, int *chans, int *srate, int *spf, int *mpa_layer, int *br)
{
	int cnt = 0, x = 0, len, frames_count;

	frames_count = 0;
	do
	{
		while(cnt + 4 < sh->a_in_buffer_len)
		{
			x = mp_get_mp3_header(&(sh->a_in_buffer[cnt]), chans, srate, spf, mpa_layer, br);
			if(x > 0)
			{
				frames_count++;
				if(frames_count == no_frames)
				{
					*n = x;
					return cnt;
				}
			}
			cnt++;
		}
		len = demux_read_data(sh->ds,&sh->a_in_buffer[sh->a_in_buffer_len],sh->a_in_buffer_size-sh->a_in_buffer_len);
		if(len > 0)
			sh->a_in_buffer_len += len;
	} while(len > 0);
	mp_msg(MSGT_DECAUDIO,MSGL_INFO,"Cannot sync MPA frame: %d\r\n", len);
	return -1;
}
Пример #9
0
int stream_read_internal(stream_t *s, void *buf, int len)
{
  int orig_len = len;
  // we will retry even if we already reached EOF previously.
  switch(s->type){
  case STREAMTYPE_STREAM:
#ifdef CONFIG_NETWORKING
    if( s->streaming_ctrl!=NULL && s->streaming_ctrl->streaming_read ) {
      len=s->streaming_ctrl->streaming_read(s->fd, buf, len, s->streaming_ctrl);
      if (s->streaming_ctrl->status == streaming_stopped_e)
        s->eof = 1;
    } else
#endif
    if (s->fill_buffer)
      len = s->fill_buffer(s, buf, len);
    else
      len = read(s->fd, buf, len);
    break;
  case STREAMTYPE_DS:
    len = demux_read_data((demux_stream_t*)s->priv, buf, len);
    break;


  default:
    len= s->fill_buffer ? s->fill_buffer(s, buf, len) : 0;
  }
  if(len<=0){
    off_t pos = s->pos;
    // do not retry if this looks like proper eof
    if (s->eof || (s->end_pos && pos == s->end_pos))
      goto eof_out;
    // dvdnav has some horrible hacks to "suspend" reads,
    // we need to skip this code or seeks will hang.
    if (s->type == STREAMTYPE_DVDNAV)
      goto eof_out;

    // just in case this is an error e.g. due to network
    // timeout reset and retry
    // Seeking is used as a hack to make network streams
    // reopen the connection, ideally they would implement
    // e.g. a STREAM_CTRL_RECONNECT to do this
    s->eof=1;
    stream_reset(s);
    if (stream_seek_internal(s, pos) >= 0 || s->pos != pos) // seek failed
      goto eof_out;
    // make sure EOF is set to ensure no endless loops
    s->eof=1;
    return stream_read_internal(s, buf, orig_len);

eof_out:
    s->eof=1;
    return 0;
  }
  // When reading succeeded we are obviously not at eof.
  // This e.g. avoids issues with eof getting stuck when lavf seeks in MPEG-TS
  s->eof=0;
  s->pos+=len;
  return len;
}
Пример #10
0
static int control(sh_audio_t *sh_audio,int cmd,void* arg, ...)
{
  if(cmd==ADCTRL_SKIP_FRAME){
    demux_read_data(sh_audio->ds, sh_audio->a_in_buffer,sh_audio->ds->ss_mul);
    return CONTROL_TRUE;
  }
  return CONTROL_UNKNOWN;
}
Пример #11
0
static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
{
  unsigned len = sh_audio->channels*sh_audio->samplesize;
  len = (minlen + len - 1) / len * len;
  if (len > maxlen)
      // if someone needs hundreds of channels adjust audio_out_minsize
      // based on channels in preinit()
      return -1;
  len=demux_read_data(sh_audio->ds,buf,len);
  return len;
}
Пример #12
0
static int control(sh_audio_t *sh,int cmd,void* arg, ...)
{
  int skip;
    switch(cmd)
    {
      case ADCTRL_SKIP_FRAME:
	skip=sh->i_bps/16;
	skip=skip&(~3);
	demux_read_data(sh->ds,NULL,skip);
	return CONTROL_TRUE;
    }
  return CONTROL_UNKNOWN;
}
Пример #13
0
int stream_read_internal(stream_t *s, void *buf, int len)
{
  int orig_len = len;
  // we will retry even if we already reached EOF previously.
  switch(s->type){
  case STREAMTYPE_STREAM:
#ifdef CONFIG_NETWORKING
    if( s->streaming_ctrl!=NULL && s->streaming_ctrl->streaming_read ) {
      len=s->streaming_ctrl->streaming_read(s->fd, buf, len, s->streaming_ctrl);
      if (s->streaming_ctrl->status == streaming_stopped_e &&
          (!s->end_pos || s->pos == s->end_pos))
        s->eof = 1;
    } else
#endif
    if (s->fill_buffer)
      len = s->fill_buffer(s, buf, len);
    else
      len = read(s->fd, buf, len);
    break;
  case STREAMTYPE_DS:
    len = demux_read_data((demux_stream_t*)s->priv, buf, len);
    break;


  default:
    len= s->fill_buffer ? s->fill_buffer(s, buf, len) : 0;
  }
  if(len<=0){
    // do not retry if this looks like proper eof
    if (s->eof || (s->end_pos && s->pos == s->end_pos))
      goto eof_out;

    // just in case this is an error e.g. due to network
    // timeout reset and retry
    if (!stream_reconnect(s))
      goto eof_out;
    // make sure EOF is set to ensure no endless loops
    s->eof=1;
    return stream_read_internal(s, buf, orig_len);

eof_out:
    s->eof=1;
    return 0;
  }
  // When reading succeeded we are obviously not at eof.
  // This e.g. avoids issues with eof getting stuck when lavf seeks in MPEG-TS
  s->eof=0;
  s->pos+=len;
  return len;
}
Пример #14
0
static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
{
  if (demux_read_data(sh_audio->ds, sh_audio->a_in_buffer,
    sh_audio->ds->ss_mul) != 
    sh_audio->ds->ss_mul) 
      return -1; /* EOF */

  if (maxlen < 2 * 4 * sh_audio->wf->nBlockAlign * 2 / 3) {
    mp_msg(MSGT_DECAUDIO, MSGL_V, "dk3adpcm: maxlen too small in decode_audio\n");
    return -1;
  }
  return 2 * dk3_adpcm_decode_block(
    (unsigned short*)buf, sh_audio->a_in_buffer,
    sh_audio->ds->ss_mul);
}
Пример #15
0
static int control(sh_audio_t *sh_audio,int cmd,void* arg, ...)
{
  int skip;
    switch(cmd)
    {
      case ADCTRL_SKIP_FRAME:
		    skip=sh_audio->wf->nBlockAlign;
		    if(skip<16){
		      skip=(sh_audio->wf->nAvgBytesPerSec/16)&(~7);
		      if(skip<16) skip=16;
		    }
		    demux_read_data(sh_audio->ds,NULL,skip);
	  return CONTROL_TRUE;
    }
  return CONTROL_UNKNOWN;
}
Пример #16
0
static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
{
 int len;
 int l=demux_read_data(sh_audio->ds,buf,minlen/2);
 unsigned short *d=(unsigned short *) buf;
 unsigned char *s=buf;
 len=2*l;
 if(sh_audio->format==6 || sh_audio->format==0x77616C61){
 /* aLaw */
   while(l>0){ --l; d[l]=alaw2short[s[l]]; }
 } else {
 /* uLaw */
    while(l>0){ --l; d[l]=ulaw2short[s[l]]; }
 }
 return len;
}
Пример #17
0
static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
{
  unsigned len = sh_audio->channels*sh_audio->samplesize;
  len = (minlen + len - 1) / len * len;
  if (len > maxlen)
      // if someone needs hundreds of channels adjust audio_out_minsize
      // based on channels in preinit()
      return -1;
  len=demux_read_data(sh_audio->ds,buf,len);
  if (len > 0 && sh_audio->channels >= 5) {
    reorder_channel_nch(buf, AF_CHANNEL_LAYOUT_WAVEEX_DEFAULT,
                        AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,
                        sh_audio->channels,
                        len / sh_audio->samplesize, sh_audio->samplesize);
  }
  return len;
}
Пример #18
0
static int aac_sync(sh_audio_t *sh)
{
  int pos = 0;
  if(!sh->codecdata_len) {
    if(sh->a_in_buffer_len < sh->a_in_buffer_size){
      sh->a_in_buffer_len +=
	demux_read_data(sh->ds,&sh->a_in_buffer[sh->a_in_buffer_len],
	sh->a_in_buffer_size - sh->a_in_buffer_len);
    }
    pos = aac_probe(sh->a_in_buffer, sh->a_in_buffer_len);
    if(pos) {
      sh->a_in_buffer_len -= pos;
      memmove(sh->a_in_buffer, &(sh->a_in_buffer[pos]), sh->a_in_buffer_len);
      mp_msg(MSGT_DECAUDIO,MSGL_V, "\nAAC SYNC AFTER %d bytes\n", pos);
    }
  }
  return pos;
}
static int aac_sync(sh_audio_t *sh)
{
  int pos = 0;
  // do not probe LATM, faad does that
  if(!sh->codecdata_len && sh->format != mmioFOURCC('M', 'P', '4', 'L')) {
    if(sh->a_in_buffer_len < sh->a_in_buffer_size){
      sh->a_in_buffer_len +=
	demux_read_data(sh->ds,&sh->a_in_buffer[sh->a_in_buffer_len],
	sh->a_in_buffer_size - sh->a_in_buffer_len);
    }
    pos = aac_probe(sh->a_in_buffer, sh->a_in_buffer_len);
    if(pos) {
      sh->a_in_buffer_len -= pos;
      memmove(sh->a_in_buffer, &(sh->a_in_buffer[pos]), sh->a_in_buffer_len);
      mp_msg(MSGT_DECAUDIO,MSGL_V, "\nAAC SYNC AFTER %d bytes\n", pos);
    }
  }
  return pos;
}
Пример #20
0
static int bread(char   *data,    /* Output: Output data array */
          int   size,     /* Input:  Length of each data */
          int   nbits,    /* Input:  Number of bits to write */
          sh_audio_t *sh)  /* Input:  File pointer */
{
    /*--- Variables ---*/
    int  ibits, iptr, idata, ibufadr, ibufbit, icl;
    unsigned char mask, tmpdat;
    int  retval;
    vqf_priv_t *priv=sh->context;

    /*--- Main operation ---*/
    retval = 0;
    mask = 0x1;
    for ( ibits=0; ibits<nbits; ibits++ ){
        if ( priv->readable == 0 ){  /* when the file data buffer is empty */
            priv->nbuf = demux_read_data(sh->ds, priv->buf, BBUFSIZ);
            priv->nbuf *= 8;
            priv->readable = 1;
        }
        iptr = priv->ptr;           /* current file data buffer pointer */
        if ( iptr >= priv->nbuf )   /* If data file is empty then return */
            return retval;
        ibufadr = iptr/BYTE_BIT;      /* current file data buffer address */
        ibufbit = iptr%BYTE_BIT;      /* current file data buffer bit */
        /*  tmpdat = stream->buf[ibufadr] >> (BYTE_BIT-ibufbit-1); */
        tmpdat = (unsigned char)priv->buf[ibufadr];
        tmpdat >>= (BYTE_BIT-ibufbit-1);
        /* current data bit */

        idata = ibits*size;                   /* output data address */
        data[idata] = (char)(tmpdat & mask);  /* set output data */
        for (icl=1; icl<size; icl++)
            data[idata+icl] = 0; /* clear the rest output data buffer */
        priv->ptr += 1;       /* update data buffer pointer */
        if (priv->ptr == BBUFLEN){
            priv->ptr = 0;
            priv->readable = 0;
        }
        ++retval;
    }
    return retval;
}
Пример #21
0
static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen)
{
	int len, start, tot;
	int chans, srate, spf, mpa_layer, br;
	int tot2;

	tot = tot2 = 0;

	while(tot2 < maxlen)
	{
		start = mpa_sync(sh, 1, &len, &chans, &srate, &spf, &mpa_layer, &br);
		if(start < 0 || tot2 + spf * 2 * chans > maxlen)
			break;

		if(start + len > sh->a_in_buffer_len)
		{
			int l;
			l = FFMIN(sh->a_in_buffer_size - sh->a_in_buffer_len, start + len);
			l = demux_read_data(sh->ds,&sh->a_in_buffer[sh->a_in_buffer_len], l);
			if(! l)
				break;
			sh->a_in_buffer_len += l;
			continue;
		}

		memcpy(&buf[tot], &(sh->a_in_buffer[start]), len);
		tot += len;

		sh->a_in_buffer_len -= start + len;
		memmove(sh->a_in_buffer, &(sh->a_in_buffer[start + len]), sh->a_in_buffer_len);
		tot2 += spf * 2 * chans;

                /* HACK: seems to fix most A/V sync issues */
                break;
	}

	memset(&buf[tot], 0, tot2-tot);
	return tot2;
}
Пример #22
0
static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen)
{
    ACMSTREAMHEADER ash;
    HRESULT hr;
    DWORD srcsize=0;
    DWORD len=minlen;
    acm_context_t *priv = sh_audio->context;

    acmStreamSize(priv->handle, len, &srcsize, ACM_STREAMSIZEF_DESTINATION);
    mp_msg(MSGT_WIN32,MSGL_DBG3,"acm says: srcsize=%ld  (buffsize=%d)  out_size=%ld\n",srcsize,sh_audio->a_in_buffer_size,len);

    if(srcsize<sh_audio->wf->nBlockAlign){
       srcsize=sh_audio->wf->nBlockAlign;
       acmStreamSize(priv->handle, srcsize, &len, ACM_STREAMSIZEF_SOURCE);
       if(len>maxlen) len=maxlen;
    }

//    if(srcsize==0) srcsize=((WAVEFORMATEX *)&sh_audio->o_wf_ext)->nBlockAlign;
    if(srcsize>sh_audio->a_in_buffer_size) srcsize=sh_audio->a_in_buffer_size; // !!!!!!
    if(sh_audio->a_in_buffer_len<srcsize){
      sh_audio->a_in_buffer_len+=
        demux_read_data(sh_audio->ds,&sh_audio->a_in_buffer[sh_audio->a_in_buffer_len],
        srcsize-sh_audio->a_in_buffer_len);
    }
    mp_msg(MSGT_WIN32,MSGL_DBG3,"acm convert %d -> %ld bytes\n",sh_audio->a_in_buffer_len,len);
    memset(&ash, 0, sizeof(ash));
    ash.cbStruct=sizeof(ash);
    ash.fdwStatus=0;
    ash.dwUser=0;
    ash.pbSrc=sh_audio->a_in_buffer;
    ash.cbSrcLength=sh_audio->a_in_buffer_len;
    ash.pbDst=buf;
    ash.cbDstLength=len;
    hr=acmStreamPrepareHeader(priv->handle,&ash,0);
    if(hr){
      mp_msg(MSGT_WIN32,MSGL_V,"ACM_Decoder: acmStreamPrepareHeader error %d\n",(int)hr);
      return -1;
    }
    hr=acmStreamConvert(priv->handle,&ash,0);
    if(hr){
      mp_msg(MSGT_WIN32,MSGL_DBG2,"ACM_Decoder: acmStreamConvert error %d\n",(int)hr);
      switch(hr)
      {
	case ACMERR_NOTPOSSIBLE:
	case ACMERR_UNPREPARED:
	    mp_msg(MSGT_WIN32, MSGL_DBG2, "ACM_Decoder: acmStreamConvert error: probarly not initialized!\n");
      }
//      return -1;
    }
    mp_msg(MSGT_WIN32,MSGL_DBG2,"acm converted %ld -> %ld\n",ash.cbSrcLengthUsed,ash.cbDstLengthUsed);
    if(ash.cbSrcLengthUsed>=sh_audio->a_in_buffer_len){
      sh_audio->a_in_buffer_len=0;
    } else {
      sh_audio->a_in_buffer_len-=ash.cbSrcLengthUsed;
      memcpy(sh_audio->a_in_buffer,&sh_audio->a_in_buffer[ash.cbSrcLengthUsed],sh_audio->a_in_buffer_len);
    }
    len=ash.cbDstLengthUsed;
    hr=acmStreamUnprepareHeader(priv->handle,&ash,0);
    if(hr){
      mp_msg(MSGT_WIN32,MSGL_V,"ACM_Decoder: acmStreamUnprepareHeader error %d\n",(int)hr);
    }
    return len;
}
Пример #23
0
static void demux_seek_avi(demuxer_t *demuxer, float rel_seek_secs,
                           float audio_delay, int flags)
{
    avi_priv_t *priv=demuxer->priv;
    demux_stream_t *d_audio=demuxer->audio;
    demux_stream_t *d_video=demuxer->video;
    sh_audio_t *sh_audio=d_audio->sh;
    sh_video_t *sh_video=d_video->sh;
    float skip_audio_secs=0;

  //FIXME: OFF_T - Didn't check AVI case yet (avi files can't be >2G anyway?)
  //================= seek in AVI ==========================
    int rel_seek_frames=rel_seek_secs*sh_video->fps;
    int video_chunk_pos=d_video->pos;
    int i;

      if(flags&SEEK_ABSOLUTE){
	// seek absolute
	video_chunk_pos=0;
      }

      if(flags&SEEK_FACTOR){
	rel_seek_frames=rel_seek_secs*priv->numberofframes;
      }

      priv->skip_video_frames=0;
      priv->avi_audio_pts=0;

// ------------ STEP 1: find nearest video keyframe chunk ------------
      // find nearest video keyframe chunk pos:
      if(rel_seek_frames>0){
        // seek forward
        while(video_chunk_pos<priv->idx_size-1){
          int id=((AVIINDEXENTRY *)priv->idx)[video_chunk_pos].ckid;
          if(avi_stream_id(id)==d_video->id){  // video frame
            if((--rel_seek_frames)<0 && ((AVIINDEXENTRY *)priv->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break;
          }
          ++video_chunk_pos;
        }
      } else {
        // seek backward
        while(video_chunk_pos>0){
          int id=((AVIINDEXENTRY *)priv->idx)[video_chunk_pos].ckid;
          if(avi_stream_id(id)==d_video->id){  // video frame
            if((++rel_seek_frames)>0 && ((AVIINDEXENTRY *)priv->idx)[video_chunk_pos].dwFlags&AVIIF_KEYFRAME) break;
          }
          --video_chunk_pos;
        }
      }
      priv->idx_pos_a=priv->idx_pos_v=priv->idx_pos=video_chunk_pos;

      // re-calc video pts:
      d_video->pack_no=0;
      for(i=0;i<video_chunk_pos;i++){
          int id=((AVIINDEXENTRY *)priv->idx)[i].ckid;
          if(avi_stream_id(id)==d_video->id) ++d_video->pack_no;
      }
      priv->video_pack_no=
      sh_video->num_frames=sh_video->num_frames_decoded=d_video->pack_no;
      priv->avi_video_pts=d_video->pack_no*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
      d_video->pos=video_chunk_pos;

      mp_msg(MSGT_SEEK,MSGL_DBG2,"V_SEEK:  pack=%d  pts=%5.3f  chunk=%d  \n",d_video->pack_no,priv->avi_video_pts,video_chunk_pos);

// ------------ STEP 2: seek audio, find the right chunk & pos ------------

      d_audio->pack_no=0;
      priv->audio_block_no=0;
      d_audio->dpos=0;

      if(sh_audio){
        int i;
        int len=0;
	int skip_audio_bytes=0;
	int curr_audio_pos=-1;
	int audio_chunk_pos=-1;
	int chunk_max=(demuxer->type==DEMUXER_TYPE_AVI)?video_chunk_pos:priv->idx_size;

	if(sh_audio->audio.dwSampleSize){
	    // constant rate audio stream
	    /* immediate seeking to audio position, including when streams are delayed */
	    curr_audio_pos=(priv->avi_video_pts + audio_delay)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale;
	    curr_audio_pos*=sh_audio->audio.dwSampleSize;

        // find audio chunk pos:
          for(i=0;i<chunk_max;i++){
            int id=((AVIINDEXENTRY *)priv->idx)[i].ckid;
            if(avi_stream_id(id)==d_audio->id){
                len=((AVIINDEXENTRY *)priv->idx)[i].dwChunkLength;
                if(d_audio->dpos<=curr_audio_pos && curr_audio_pos<(d_audio->dpos+len)){
                  break;
                }
                ++d_audio->pack_no;
                priv->audio_block_no+=priv->audio_block_size ?
		    ((len+priv->audio_block_size-1)/priv->audio_block_size) : 1;
                d_audio->dpos+=len;
            }
          }
	  audio_chunk_pos=i;
	  skip_audio_bytes=curr_audio_pos-d_audio->dpos;

          mp_msg(MSGT_SEEK,MSGL_V,"SEEK: i=%d (max:%d) dpos=%d (wanted:%d)  \n",
	      i,chunk_max,(int)d_audio->dpos,curr_audio_pos);

	} else {
	    // VBR audio
	    /* immediate seeking to audio position, including when streams are delayed */
	    int chunks=(priv->avi_video_pts + audio_delay)*(float)sh_audio->audio.dwRate/(float)sh_audio->audio.dwScale;
	    audio_chunk_pos=0;

        // find audio chunk pos:
          for(i=0;i<priv->idx_size && chunks>0;i++){
            int id=((AVIINDEXENTRY *)priv->idx)[i].ckid;
            if(avi_stream_id(id)==d_audio->id){
                len=((AVIINDEXENTRY *)priv->idx)[i].dwChunkLength;
		if(i>chunk_max){
		  skip_audio_bytes+=len;
		} else {
		  ++d_audio->pack_no;
                  priv->audio_block_no+=priv->audio_block_size ?
		    ((len+priv->audio_block_size-1)/priv->audio_block_size) : 1;
                  d_audio->dpos+=len;
		  audio_chunk_pos=i;
		}
		if(priv->audio_block_size)
		    chunks-=(len+priv->audio_block_size-1)/priv->audio_block_size;
            }
          }
	}

	// Now we have:
	//      audio_chunk_pos = chunk no in index table (it's <=chunk_max)
	//      skip_audio_bytes = bytes to be skipped after chunk seek
	//      d-audio->pack_no = chunk_no in stream at audio_chunk_pos
	//      d_audio->dpos = bytepos in stream at audio_chunk_pos
	// let's seek!

          // update stream position:
          d_audio->pos=audio_chunk_pos;

	if(demuxer->type==DEMUXER_TYPE_AVI){
	  // interleaved stream:
	  if(audio_chunk_pos<video_chunk_pos){
            // calc priv->skip_video_frames & adjust video pts counter:
	    for(i=audio_chunk_pos;i<video_chunk_pos;i++){
              int id=((AVIINDEXENTRY *)priv->idx)[i].ckid;
              if(avi_stream_id(id)==d_video->id) ++priv->skip_video_frames;
            }
            // requires for correct audio pts calculation (demuxer):
            priv->avi_video_pts-=priv->skip_video_frames*(float)sh_video->video.dwScale/(float)sh_video->video.dwRate;
	    priv->avi_audio_pts=priv->avi_video_pts;
	    // set index position:
	    priv->idx_pos_a=priv->idx_pos_v=priv->idx_pos=audio_chunk_pos;
	  }
	} else {
	    // non-interleaved stream:
	    priv->idx_pos_a=audio_chunk_pos;
	    priv->idx_pos_v=video_chunk_pos;
	    priv->idx_pos=(audio_chunk_pos<video_chunk_pos)?audio_chunk_pos:video_chunk_pos;
	}

          mp_msg(MSGT_SEEK,MSGL_V,"SEEK: idx=%d  (a:%d v:%d)  v.skip=%d  a.skip=%d/%4.3f  \n",
            (int)priv->idx_pos,audio_chunk_pos,video_chunk_pos,
            (int)priv->skip_video_frames,skip_audio_bytes,skip_audio_secs);

          if(skip_audio_bytes){
            demux_read_data(d_audio,NULL,skip_audio_bytes);
          }

      }
	d_video->pts=priv->avi_video_pts; // OSD

}
static int init(sh_audio_t *sh)
{
  unsigned long faac_samplerate;
  unsigned char faac_channels;
  int faac_init, pos = 0;
  faac_hdec = faacDecOpen();

  // If we don't get the ES descriptor, try manual config
  if(!sh->codecdata_len && sh->wf) {
    sh->codecdata_len = sh->wf->cbSize;
    sh->codecdata = malloc(sh->codecdata_len);
    memcpy(sh->codecdata, sh->wf+1, sh->codecdata_len);
    mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"FAAD: codecdata extracted from WAVEFORMATEX\n");
  }
  if(!sh->codecdata_len) {
    faacDecConfigurationPtr faac_conf;
    /* Set the default object type and samplerate */
    /* This is useful for RAW AAC files */
    faac_conf = faacDecGetCurrentConfiguration(faac_hdec);
    if(sh->samplerate)
      faac_conf->defSampleRate = sh->samplerate;
    /* XXX: FAAD support FLOAT output, how do we handle
      * that (FAAD_FMT_FLOAT)? ::atmos
      */
    if (audio_output_channels <= 2) faac_conf->downMatrix = 1;
      switch(sh->samplesize){
	case 1: // 8Bit
	  mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: 8Bit samplesize not supported by FAAD, assuming 16Bit!\n");
	default:
	  sh->samplesize=2;
	case 2: // 16Bit
	  faac_conf->outputFormat = FAAD_FMT_16BIT;
	  break;
	case 3: // 24Bit
	  faac_conf->outputFormat = FAAD_FMT_24BIT;
	  break;
	case 4: // 32Bit
	  faac_conf->outputFormat = FAAD_FMT_32BIT;
	  break;
      }
    //faac_conf->defObjectType = LTP; // => MAIN, LC, SSR, LTP available.

    faacDecSetConfiguration(faac_hdec, faac_conf);

    sh->a_in_buffer_len = demux_read_data(sh->ds, sh->a_in_buffer, sh->a_in_buffer_size);
#if CONFIG_FAAD_INTERNAL
    /* init the codec, look for LATM */
    faac_init = faacDecInit(faac_hdec, sh->a_in_buffer,
                            sh->a_in_buffer_len, &faac_samplerate, &faac_channels,1);
    if (faac_init < 0 && sh->a_in_buffer_len >= 3 && sh->format == mmioFOURCC('M', 'P', '4', 'L')) {
        // working LATM not found at first try, look further on in stream
        int i;

        for (i = 0; i < 5; i++) {
            pos = sh->a_in_buffer_len-3;
            memmove(sh->a_in_buffer, &(sh->a_in_buffer[pos]), 3);
            sh->a_in_buffer_len  = 3;
            sh->a_in_buffer_len += demux_read_data(sh->ds,&sh->a_in_buffer[sh->a_in_buffer_len],
                                                   sh->a_in_buffer_size - sh->a_in_buffer_len);
            faac_init = faacDecInit(faac_hdec, sh->a_in_buffer,
                                    sh->a_in_buffer_len, &faac_samplerate, &faac_channels,1);
            if (faac_init >= 0) break;
        }
    }
#else
    /* external faad does not have latm lookup support */
    faac_init = faacDecInit(faac_hdec, sh->a_in_buffer,
                            sh->a_in_buffer_len, &faac_samplerate, &faac_channels);
#endif

    if (faac_init < 0) {
    pos = aac_probe(sh->a_in_buffer, sh->a_in_buffer_len);
    if(pos) {
      sh->a_in_buffer_len -= pos;
      memmove(sh->a_in_buffer, &(sh->a_in_buffer[pos]), sh->a_in_buffer_len);
      sh->a_in_buffer_len +=
	demux_read_data(sh->ds,&(sh->a_in_buffer[sh->a_in_buffer_len]),
	sh->a_in_buffer_size - sh->a_in_buffer_len);
      pos = 0;
    }

    /* init the codec */
#if CONFIG_FAAD_INTERNAL
    faac_init = faacDecInit(faac_hdec, sh->a_in_buffer,
          sh->a_in_buffer_len, &faac_samplerate, &faac_channels,0);
#else
    faac_init = faacDecInit(faac_hdec, sh->a_in_buffer,
          sh->a_in_buffer_len, &faac_samplerate, &faac_channels);
#endif
    }

    sh->a_in_buffer_len -= (faac_init > 0)?faac_init:0; // how many bytes init consumed
    // XXX FIXME: shouldn't we memcpy() here in a_in_buffer ?? --A'rpi

  } else { // We have ES DS in codecdata
    faacDecConfigurationPtr faac_conf = faacDecGetCurrentConfiguration(faac_hdec);
    if (audio_output_channels <= 2) {
        faac_conf->downMatrix = 1;
        faacDecSetConfiguration(faac_hdec, faac_conf);
    }

    /*int i;
    for(i = 0; i < sh_audio->codecdata_len; i++)
      printf("codecdata_dump %d: 0x%02X\n", i, sh_audio->codecdata[i]);*/

    faac_init = faacDecInit2(faac_hdec, sh->codecdata,
       sh->codecdata_len,	&faac_samplerate, &faac_channels);
  }
  if(faac_init < 0) {
    mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: Failed to initialize the decoder!\n"); // XXX: deal with cleanup!
    faacDecClose(faac_hdec);
    // XXX: free a_in_buffer here or in uninit?
    return 0;
  } else {
    mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Decoder init done (%dBytes)!\n", sh->a_in_buffer_len); // XXX: remove or move to debug!
    mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Negotiated samplerate: %ldHz  channels: %d\n", faac_samplerate, faac_channels);
    // 8 channels is aac channel order #7.
    sh->channels = faac_channels == 7 ? 8 : faac_channels;
    if (audio_output_channels <= 2) sh->channels = faac_channels > 1 ? 2 : 1;
    sh->samplerate = faac_samplerate;
    sh->samplesize=2;
    //sh->o_bps = sh->samplesize*faac_channels*faac_samplerate;
    if(!sh->i_bps) {
      mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: compressed input bitrate missing, assuming 128kbit/s!\n");
      sh->i_bps = 128*1000/8; // XXX: HACK!!! ::atmos
    } else
      mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: got %dkbit/s bitrate from MP4 header!\n",sh->i_bps*8/1000);
  }
  return 1;
}
Пример #25
0
static int init(sh_audio_t *sh)
{
  unsigned long faac_samplerate;
  unsigned char faac_channels;
  int faac_init, pos = 0;
  faac_hdec = faacDecOpen();

  // If we don't get the ES descriptor, try manual config
  if(!sh->codecdata_len && sh->wf) {
    sh->codecdata_len = sh->wf->cbSize;
    sh->codecdata = (char*)(sh->wf+1);
    mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"FAAD: codecdata extracted from WAVEFORMATEX\n");
  }
  if(!sh->codecdata_len) {
#if 1
    faacDecConfigurationPtr faac_conf;
    /* Set the default object type and samplerate */
    /* This is useful for RAW AAC files */
    faac_conf = faacDecGetCurrentConfiguration(faac_hdec);
    if(sh->samplerate)
      faac_conf->defSampleRate = sh->samplerate;
    /* XXX: FAAD support FLOAT output, how do we handle
      * that (FAAD_FMT_FLOAT)? ::atmos
      */
    if (audio_output_channels <= 2) faac_conf->downMatrix = 1;
      switch(sh->samplesize){
	case 1: // 8Bit
	  mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: 8Bit samplesize not supported by FAAD, assuming 16Bit!\n");
	default:
	  sh->samplesize=2;
	case 2: // 16Bit
	  faac_conf->outputFormat = FAAD_FMT_16BIT;
	  break;
	case 3: // 24Bit
	  faac_conf->outputFormat = FAAD_FMT_24BIT;
	  break;
	case 4: // 32Bit
	  faac_conf->outputFormat = FAAD_FMT_32BIT;
	  break;
      }
    //faac_conf->defObjectType = LTP; // => MAIN, LC, SSR, LTP available.

    faacDecSetConfiguration(faac_hdec, faac_conf);
#endif

    sh->a_in_buffer_len = demux_read_data(sh->ds, sh->a_in_buffer, sh->a_in_buffer_size);
    pos = aac_probe(sh->a_in_buffer, sh->a_in_buffer_len);
    if(pos) {
      sh->a_in_buffer_len -= pos;
      memmove(sh->a_in_buffer, &(sh->a_in_buffer[pos]), sh->a_in_buffer_len);
      sh->a_in_buffer_len +=
	demux_read_data(sh->ds,&(sh->a_in_buffer[sh->a_in_buffer_len]),
	sh->a_in_buffer_size - sh->a_in_buffer_len);
      pos = 0;
    }

    /* init the codec */
    faac_init = faacDecInit(faac_hdec, sh->a_in_buffer,
       sh->a_in_buffer_len, &faac_samplerate, &faac_channels);

    sh->a_in_buffer_len -= (faac_init > 0)?faac_init:0; // how many bytes init consumed
    // XXX FIXME: shouldn't we memcpy() here in a_in_buffer ?? --A'rpi

  } else { // We have ES DS in codecdata
    faacDecConfigurationPtr faac_conf = faacDecGetCurrentConfiguration(faac_hdec);
    if (audio_output_channels <= 2) {
        faac_conf->downMatrix = 1;
        faacDecSetConfiguration(faac_hdec, faac_conf);
    }
    
    /*int i;
    for(i = 0; i < sh_audio->codecdata_len; i++)
      printf("codecdata_dump %d: 0x%02X\n", i, sh_audio->codecdata[i]);*/

    faac_init = faacDecInit2(faac_hdec, sh->codecdata,
       sh->codecdata_len,	&faac_samplerate, &faac_channels);
  }
  if(faac_init < 0) {
    mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: Failed to initialize the decoder!\n"); // XXX: deal with cleanup!
    faacDecClose(faac_hdec);
    // XXX: free a_in_buffer here or in uninit?
    return 0;
  } else {
    mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Decoder init done (%dBytes)!\n", sh->a_in_buffer_len); // XXX: remove or move to debug!
    mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: Negotiated samplerate: %ldHz  channels: %d\n", faac_samplerate, faac_channels);
    sh->channels = faac_channels;
    if (audio_output_channels <= 2) sh->channels = faac_channels > 1 ? 2 : 1;
    
    /* re-map channels */
    switch (sh->channels) {
      default:
      case 1: /* no action needed */
      case 2: /* no action needed */
      case 3: /* no suitable default behavior? */
      case 4: /* no suitable default behavior? */
        break;
      case 5: /* mplayer treats this like 6-channel */
      case 6:
        sh->chan_map = af_set_channel_map(6, "04" "10" "21" "32" "43" "55");
        break;
      case 7: /* not supported by mplayer? */
        break;
    }
    
    sh->samplerate = faac_samplerate;
    sh->samplesize=2;
    //sh->o_bps = sh->samplesize*faac_channels*faac_samplerate;
    if(!sh->i_bps) {
      mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: compressed input bitrate missing, assuming 128kbit/s!\n");
      sh->i_bps = 128*1000/8; // XXX: HACK!!! ::atmos
    } else 
      mp_msg(MSGT_DECAUDIO,MSGL_V,"FAAD: got %dkbit/s bitrate from MP4 header!\n",sh->i_bps*8/1000);
  }  
  return 1;
}
Пример #26
0
static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen)
{
  int j = 0, len = 0, last_dec_len = 1, errors = 0;	      
  void *faac_sample_buffer;

  while(len < minlen && last_dec_len > 0 && errors < MAX_FAAD_ERRORS) {

    /* update buffer for raw aac streams: */
  if(!sh->codecdata_len)
    if(sh->a_in_buffer_len < sh->a_in_buffer_size){
      sh->a_in_buffer_len +=
	demux_read_data(sh->ds,&sh->a_in_buffer[sh->a_in_buffer_len],
	sh->a_in_buffer_size - sh->a_in_buffer_len);
    }
	  
#ifdef DUMP_AAC_COMPRESSED
    {int i;
    for (i = 0; i < 16; i++)
      printf ("%02X ", sh->a_in_buffer[i]);
    printf ("\n");}
#endif

  if(!sh->codecdata_len){
   // raw aac stream:
   do {
    faac_sample_buffer = faacDecDecode(faac_hdec, &faac_finfo, sh->a_in_buffer, sh->a_in_buffer_len);
	
    /* update buffer index after faacDecDecode */
    if(faac_finfo.bytesconsumed >= sh->a_in_buffer_len) {
      sh->a_in_buffer_len=0;
    } else {
      sh->a_in_buffer_len-=faac_finfo.bytesconsumed;
      memmove(sh->a_in_buffer,&sh->a_in_buffer[faac_finfo.bytesconsumed],sh->a_in_buffer_len);
    }

    if(faac_finfo.error > 0) {
      mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: error: %s, trying to resync!\n",
              faacDecGetErrorMessage(faac_finfo.error));
      if (sh->a_in_buffer_len <= 0) {
        errors = MAX_FAAD_ERRORS;
        break;
      }
      sh->a_in_buffer_len--;
      memmove(sh->a_in_buffer,&sh->a_in_buffer[1],sh->a_in_buffer_len);
      aac_sync(sh);
      errors++;
    } else
      break;
   } while(errors < MAX_FAAD_ERRORS);	  
  } else {
   // packetized (.mp4) aac stream:
    unsigned char* bufptr=NULL;
    double pts;
    int buflen=ds_get_packet_pts(sh->ds, &bufptr, &pts);
    if(buflen<=0) break;
    if (pts != MP_NOPTS_VALUE) {
	sh->pts = pts;
	sh->pts_bytes = 0;
    }
    faac_sample_buffer = faacDecDecode(faac_hdec, &faac_finfo, bufptr, buflen);
  }
  //for (j=0;j<faac_finfo.channels;j++) printf("%d:%d\n", j, faac_finfo.channel_position[j]);
  
    if(faac_finfo.error > 0) {
      mp_msg(MSGT_DECAUDIO,MSGL_WARN,"FAAD: Failed to decode frame: %s \n",
      faacDecGetErrorMessage(faac_finfo.error));
    } else if (faac_finfo.samples == 0) {
      mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"FAAD: Decoded zero samples!\n");
    } else {
      /* XXX: samples already multiplied by channels! */
      mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"FAAD: Successfully decoded frame (%ld Bytes)!\n",
      sh->samplesize*faac_finfo.samples);
      memcpy(buf+len,faac_sample_buffer, sh->samplesize*faac_finfo.samples);
      last_dec_len = sh->samplesize*faac_finfo.samples;
      len += last_dec_len;
      sh->pts_bytes += last_dec_len;
    //printf("FAAD: buffer: %d bytes  consumed: %d \n", k, faac_finfo.bytesconsumed);
    }
  }
  return len;
}
Пример #27
0
static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen){
  int len = 0, last_dec_len = 1, err = 0, in_len;
  int outOfData = 0, errors=0;;
  uint8_t *inBuf;

  while(len < minlen && last_dec_len > 0 ) {
    /* update buffer for raw aac streams: */
  if(!sh->codecdata_len){
    if(sh->a_in_buffer_len < sh->a_in_buffer_size){
      sh->a_in_buffer_len +=
        demux_read_data(sh->ds,&sh->a_in_buffer[sh->a_in_buffer_len],
        sh->a_in_buffer_size - sh->a_in_buffer_len);
    }
//#define DUMP_AAC_COMPRESSED
#ifdef DUMP_AAC_COMPRESSED
    {int i;
     inBuf = sh->a_in_buffer;
    for (i = 0; i < 16; i++)
      printf ("%02x ", inBuf[i]);
    printf ("\n");}
#endif
    inBuf  = sh->a_in_buffer;
    in_len = sh->a_in_buffer_len;
    // raw aac stream:
    err = AACDecode(hAACDecoder,  &(inBuf), &(in_len), buf+len);
    if(in_len > 0) {
      memmove(sh->a_in_buffer,inBuf,in_len);
    }
    sh->a_in_buffer_len = in_len;

    if (err  == ERR_AAC_NONE)
    {
        AACGetLastFrameInfo(hAACDecoder, frameInfo);
        reorder_ch_pcm(buf+len, frameInfo->outputSamps, frameInfo->nChans);
        last_dec_len = sh->samplesize*frameInfo->outputSamps*sh->channels/frameInfo->nChans;
        len += last_dec_len;
        sh->pts_bytes += last_dec_len;
        if(errors)
          errors=0;
    }else if(err  == ERR_AAC_INDATA_UNDERFLOW){
      errors++;
    }else if(sh->a_in_buffer_len > 0){
      sh->a_in_buffer_len--;
      memmove(sh->a_in_buffer,&sh->a_in_buffer[1],sh->a_in_buffer_len);
      aac_sync(sh);
      errors++;
    }
    if(errors > 10){
        break;
    }
   }else{
    /* update buffer for raw aac streams: */
    // packetized (.mp4) aac stream:
    unsigned char* bufptr=NULL;
    double pts;
    int buflen=ds_get_packet_pts(sh->ds, &bufptr, &pts);
    if(buflen<=0) break;
    if (pts != MP_NOPTS_VALUE) {
	sh->pts = pts;
	sh->pts_bytes = 0;
    }
    err = AACDecode(hAACDecoder, &bufptr, &buflen, buf+len);
    if (err  == ERR_AAC_NONE)
    {
        AACGetLastFrameInfo(hAACDecoder, frameInfo);
        reorder_ch_pcm(buf+len, frameInfo->outputSamps, frameInfo->nChans);
        last_dec_len = sh->samplesize*frameInfo->outputSamps*sh->channels/frameInfo->nChans;
        len += last_dec_len;
        sh->pts_bytes += last_dec_len;
    }
   }
  }
  return len;
}
Пример #28
0
static int init(sh_audio_t *sh){
  int pos = 0;
  int32_t result = HXR_OK;
  uint16_t *temp;
  uint8_t *inBuf;
  int in_len;
  int32_t NumChannels, SampleRate;
  hAACDecoder = (HAACDecoder *)AACInitDecoder();
  ga_config_data configData;
  int i;

  if (!hAACDecoder) {
          printf(" *** Error initializing decoder ***\n");
          return 0;
  }


  if(!sh->codecdata_len && sh->wf) {
    sh->codecdata_len = sh->wf->cbSize;
    sh->codecdata = (char*)(sh->wf+1);

    mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"realaac: codecdata extracted from WAVEFORMATEX\n");
  }

  if(!sh->codecdata_len){
    //return 0;
    sh->a_in_buffer_len = demux_read_data(sh->ds, sh->a_in_buffer, sh->a_in_buffer_size);

     inBuf  = sh->a_in_buffer;
     in_len = sh->a_in_buffer_len;
     temp = (uint16_t *)malloc(sizeof(uint16_t) * sh->audio_out_minsize);
     /* decode ADTS frame from opaque data to get config data */
     result = AACDecode(hAACDecoder,  &inBuf, &in_len, temp);
     free(temp);
     if (result != HXR_OK)
     {
        return 0;
     }

         /* get the config data struct from the decoder */
     AACGetLastFrameInfo(hAACDecoder, frameInfo);

     NumChannels = frameInfo->nChans;
     SampleRate = frameInfo->sampRateCore;
  }else{
    struct BITSTREAM *pBitstream ;

    pBitstream = (struct BITSTREAM *)malloc(sizeof(struct BITSTREAM)) ;
    if (!pBitstream)
        return 0 ;

    pBitstream->cacheBitsLeft = 0 ;
    pBitstream->buffer = sh->codecdata ;
    pBitstream->nBits  = sh->codecdata_len*8 ;
    pBitstream->pkptr = pBitstream->buffer + (0>>3) ;
    pBitstream->cacheBitsLeft = 0 ;
    pBitstream->cache = 0 ;
    pBitstream->inc = 1 ;

     result = ga_config_get_data(pBitstream, &configData);
    if(pBitstream){
      free(pBitstream);
    }

     if (result != HXR_OK) /* config data error */
     {
         return 0;
     }
      NumChannels = frameInfo->nChans=configData.numChannels;
      SampleRate = frameInfo->sampRateCore=configData.samplingFrequency;
     /* see MPEG4 spec for index of each object type */
     if (configData.audioObjectType == 2)
         frameInfo->profile = AAC_PROFILE_LC;
     else if (configData.audioObjectType == 1)
         frameInfo->profile = AAC_PROFILE_MP;
     else if (configData.audioObjectType == 3)
         frameInfo->profile = AAC_PROFILE_SSR;
     else
         return 0; /* don't know - assume LC */

    /* set decoder to handle raw data blocks */
    AACSetRawBlockParams(hAACDecoder, 0, frameInfo);
  }
    mp_msg(MSGT_DECAUDIO,MSGL_V,"realaac: Decoder init done (%dBytes)!\n", sh->a_in_buffer_len); // XXX: remove or move to debug!
    mp_msg(MSGT_DECAUDIO,MSGL_V,"realaac: Negotiated samplerate: %ldHz  channels: %d\n", SampleRate, NumChannels);

    sh->channels = NumChannels;
    if (audio_output_channels <= 2) sh->channels = NumChannels > 1 ? 2 : 1;
    sh->samplerate = SampleRate;
    sh->samplesize=2;

   if(!sh->i_bps) {
      mp_msg(MSGT_DECAUDIO,MSGL_WARN,"realaac: compressed input bitrate missing, assuming 128kbit/s!\n");
      sh->i_bps = 128*1000/8; // XXX: HACK!!! ::atmos
    } else
      mp_msg(MSGT_DECAUDIO,MSGL_V,"realaac: got %dkbit/s bitrate from MP4 header!\n",sh->i_bps*8/1000);

  return 1; // return values: 1=OK 0=ERROR
}
Пример #29
0
// MP3 decoder buffer callback:
int mplayer_audio_read(char *buf,int size){
  return demux_read_data(dec_audio_sh->ds,buf,size);
}
static int preinit(sh_audio_t *sh){
  // let's check if the driver is available, return 0 if not.
  // (you should do that if you use external lib(s) which is optional)
  unsigned int result;
  char *path;

  path = malloc(strlen(codec_path) + strlen(sh->codec->dll) + 2);
  if (!path) return 0;
  sprintf(path, "%s/%s", codec_path, sh->codec->dll);

    /* first try to load linux dlls, if failed and we're supporting win32 dlls,
       then try to load the windows ones */

#ifdef HAVE_LIBDL
    if (strstr(sh->codec->dll,".dll") || !load_syms_linux(path))
#endif
#ifdef CONFIG_WIN32DLL
	if (!load_syms_windows(sh->codec->dll))
#endif
    {
	mp_msg(MSGT_DECVIDEO, MSGL_ERR, MSGTR_MissingDLLcodec, sh->codec->dll);
	mp_msg(MSGT_DECVIDEO, MSGL_HINT, "Read the RealAudio section of the DOCS!\n");
	free(path);
	return 0;
    }

#ifdef CONFIG_WIN32DLL
  if((raSetDLLAccessPath && dll_type == 0) || (wraSetDLLAccessPath && dll_type == 1)){
#else
  if(raSetDLLAccessPath){
#endif
      // used by 'SIPR'
      path = realloc(path, strlen(codec_path) + 13);
      sprintf(path, "DT_Codecs=%s", codec_path);
      if(path[strlen(path)-1]!='/'){
        path[strlen(path)+1]=0;
        path[strlen(path)]='/';
      }
      path[strlen(path)+1]=0;
#ifdef CONFIG_WIN32DLL
    if (dll_type == 1)
    {
      int i;
      for (i=0; i < strlen(path); i++)
        if (path[i] == '/') path[i] = '\\';
      wraSetDLLAccessPath(path);
    }
    else
#endif
      raSetDLLAccessPath(path);
  }

#ifdef CONFIG_WIN32DLL
    if (dll_type == 1){
      if (wraOpenCodec2) {
        sprintf(path, "%s\\", codec_path);
        result = wraOpenCodec2(&sh->context, path);
      } else
	result=wraOpenCodec(&sh->context);
    } else
#endif
    if (raOpenCodec2) {
      sprintf(path, "%s/", codec_path);
      result = raOpenCodec2(&sh->context, path);
    } else
      result=raOpenCodec(&sh->context);
    if(result){
      mp_msg(MSGT_DECAUDIO,MSGL_WARN,"Decoder open failed, error code: 0x%X\n",result);
      return 0;
    }
//    printf("opencodec ok (result: %x)\n", result);
  free(path); /* after this it isn't used anymore */

  sh->samplerate=sh->wf->nSamplesPerSec;
  sh->samplesize=sh->wf->wBitsPerSample/8;
  sh->channels=sh->wf->nChannels;

  {
    ra_init_t init_data={
	sh->wf->nSamplesPerSec,
	sh->wf->wBitsPerSample,
	sh->wf->nChannels,
	100, // quality
	sh->wf->nBlockAlign, // subpacket size
	sh->wf->nBlockAlign, // coded frame size
	sh->wf->cbSize, // codec data length
	(char*)(sh->wf+1) // extras
    };
#ifdef CONFIG_WIN32DLL
    wra_init_t winit_data={
	sh->wf->nSamplesPerSec,
	sh->wf->wBitsPerSample,
	sh->wf->nChannels,
	100, // quality
	sh->wf->nBlockAlign, // subpacket size
	sh->wf->nBlockAlign, // coded frame size
	sh->wf->cbSize, // codec data length
	(char*)(sh->wf+1) // extras
    };
#endif
#ifdef CONFIG_WIN32DLL
    if (dll_type == 1)
	result=wraInitDecoder(sh->context,&winit_data);
    else
#endif
    result=raInitDecoder(sh->context,&init_data);

    if(result){
      mp_msg(MSGT_DECAUDIO,MSGL_WARN,"Decoder init failed, error code: 0x%X\n",result);
      return 0;
    }
//    printf("initdecoder ok (result: %x)\n", result);
  }

#ifdef CONFIG_WIN32DLL
    if((raSetPwd && dll_type == 0) || (wraSetPwd && dll_type == 1)){
#else
    if(raSetPwd){
#endif
	// used by 'SIPR'
#ifdef CONFIG_WIN32DLL
	if (dll_type == 1)
	    wraSetPwd(sh->context,"Ardubancel Quazanga");
	else
#endif
	raSetPwd(sh->context,"Ardubancel Quazanga"); // set password... lol.
    }

  if (sh->format == mmioFOURCC('s','i','p','r')) {
    short flavor;

    if (sh->wf->nAvgBytesPerSec > 1531)
        flavor = 3;
    else if (sh->wf->nAvgBytesPerSec > 937)
        flavor = 1;
    else if (sh->wf->nAvgBytesPerSec > 719)
        flavor = 0;
    else
        flavor = 2;
    mp_msg(MSGT_DECAUDIO,MSGL_V,"Got sipr flavor %d from bitrate %d\n",flavor, sh->wf->nAvgBytesPerSec);

#ifdef CONFIG_WIN32DLL
    if (dll_type == 1)
	result=wraSetFlavor(sh->context,flavor);
    else
#endif
    result=raSetFlavor(sh->context,flavor);
    if(result){
      mp_msg(MSGT_DECAUDIO,MSGL_WARN,"Decoder flavor setup failed, error code: 0x%X\n",result);
      return 0;
    }
  } // sipr flavor

    sh->i_bps=sh->wf->nAvgBytesPerSec;

  sh->audio_out_minsize=128000; // no idea how to get... :(
  sh->audio_in_minsize = sh->wf->nBlockAlign;

  return 1; // return values: 1=OK 0=ERROR
}

static int init(sh_audio_t *sh_audio){
  // initialize the decoder, set tables etc...

  // you can store HANDLE or private struct pointer at sh->context
  // you can access WAVEFORMATEX header at sh->wf

  // set sample format/rate parameters if you didn't do it in preinit() yet.

  return 1; // return values: 1=OK 0=ERROR
}

static void uninit(sh_audio_t *sh){
  // uninit the decoder etc...
  // again: you don't have to free() a_in_buffer here! it's done by the core.
#ifdef CONFIG_WIN32DLL
    if (dll_type == 1)
    {
	if (wraFreeDecoder) wraFreeDecoder(sh->context);
	if (wraCloseCodec) wraCloseCodec(sh->context);
    }
#endif

    if (raFreeDecoder) raFreeDecoder(sh->context);
    if (raCloseCodec) raCloseCodec(sh->context);


#ifdef CONFIG_WIN32DLL
    if (dll_type == 1)
    {
	if (rv_handle) FreeLibrary(rv_handle);
    } else
#endif
// this dlclose() causes some memory corruption, and crashes soon (in caller):
//    if (rv_handle) dlclose(rv_handle);
    rv_handle = NULL;
}

static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen){
  int result;
  int len=-1;

  if(sh->a_in_buffer_len<=0){
      // fill the buffer!
      if (sh->ds->eof)
          return 0;
      demux_read_data(sh->ds, sh->a_in_buffer, sh->wf->nBlockAlign);
      sh->a_in_buffer_size=
      sh->a_in_buffer_len=sh->wf->nBlockAlign;
  }

#ifdef CONFIG_WIN32DLL
    if (dll_type == 1)
      result=wraDecode(sh->context, sh->a_in_buffer+sh->a_in_buffer_size-sh->a_in_buffer_len, sh->wf->nBlockAlign,
       buf, &len, -1);
    else
#endif
  result=raDecode(sh->context, sh->a_in_buffer+sh->a_in_buffer_size-sh->a_in_buffer_len, sh->wf->nBlockAlign,
       buf, &len, -1);
  sh->a_in_buffer_len-=sh->wf->nBlockAlign;

//  printf("radecode: %d bytes, res=0x%X  \n",len,result);

  return len; // return value: number of _bytes_ written to output buffer,
              // or -1 for EOF (or uncorrectable error)
}

static int control(sh_audio_t *sh,int cmd,void* arg, ...){
    // various optional functions you MAY implement:
    switch(cmd){
      case ADCTRL_RESYNC_STREAM:
        // it is called once after seeking, to resync.
	// Note: sh_audio->a_in_buffer_len=0; is done _before_ this call!
	return CONTROL_TRUE;
      case ADCTRL_SKIP_FRAME:
        // it is called to skip (jump over) small amount (1/10 sec or 1 frame)
	// of audio data - used to sync audio to video after seeking
	// if you don't return CONTROL_TRUE, it will defaults to:
	//      ds_fill_buffer(sh_audio->ds);  // skip 1 demux packet
	return CONTROL_TRUE;
    }
  return CONTROL_UNKNOWN;
}