static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen) { unsigned char *start=NULL; int y,len=-1; while(len<minlen){ int len2=0; double pts; int x=ds_get_packet_pts(sh_audio->ds,&start, &pts); if(x<=0) break; // error if (pts != MP_NOPTS_VALUE) { sh_audio->pts = pts; sh_audio->pts_bytes = 0; } y=avcodec_decode_audio(sh_audio->context,(int16_t*)buf,&len2,start,x); //printf("return:%d samples_out:%d bitstream_in:%d sample_sum:%d\n", y, len2, x, len); fflush(stdout); if(y<0){ mp_msg(MSGT_DECAUDIO,MSGL_V,"lavc_audio: error\n");break; } if(y<x) sh_audio->ds->buffer_pos+=y-x; // put back data (HACK!) if(len2>0){ //len=len2;break; if(len<0) len=len2; else len+=len2; buf+=len2; sh_audio->pts_bytes += len2; } mp_dbg(MSGT_DECAUDIO,MSGL_DBG2,"Decoded %d -> %d \n",y,len2); } return len; }
static int decode_audio(sh_audio_t *sh, unsigned char *buf, int minlen, int maxlen) { double pts; context_t *ctx = sh->context; int len, framelen, framesamples; char *packet; int i, err; speex_decoder_ctl(ctx->dec_context, SPEEX_GET_FRAME_SIZE, &framesamples); framelen = framesamples * ctx->hdr->nb_channels * sizeof(short); if (maxlen < ctx->hdr->frames_per_packet * framelen) { mp_msg(MSGT_DECAUDIO, MSGL_V, "maxlen too small in decode_audio\n"); return -1; } len = ds_get_packet_pts(sh->ds, (unsigned char **)&packet, &pts); if (len <= 0) return -1; if (sh->pts == MP_NOPTS_VALUE) sh->pts = 0; if (pts != MP_NOPTS_VALUE) { sh->pts = pts; sh->pts_bytes = 0; } speex_bits_read_from(&ctx->bits, packet, len); i = ctx->hdr->frames_per_packet; do { err = speex_decode_int(ctx->dec_context, &ctx->bits, (short *)buf); if (err == -2) mp_msg(MSGT_DECAUDIO, MSGL_ERR, "Error decoding file.\n"); if (ctx->hdr->nb_channels == 2) speex_decode_stereo_int((short *)buf, framesamples, &ctx->stereo); buf = &buf[framelen]; } while (--i > 0); sh->pts_bytes += ctx->hdr->frames_per_packet * framelen; return ctx->hdr->frames_per_packet * framelen; }
static int decode_audio(sh_audio_t *sh_audio,unsigned char *buf,int minlen,int maxlen) { unsigned char *start=NULL; int y,len=-1; while(len<minlen){ AVPacket pkt; int len2=maxlen; double pts; int x=ds_get_packet_pts(sh_audio->ds,&start, &pts); if(x<=0) { start = NULL; x = 0; ds_parse(sh_audio->ds, &start, &x, MP_NOPTS_VALUE, 0); if (x <= 0) break; // error } else { int in_size = x; int consumed = ds_parse(sh_audio->ds, &start, &x, pts, 0); sh_audio->ds->buffer_pos -= in_size - consumed; } av_init_packet(&pkt); pkt.data = start; pkt.size = x; if (pts != MP_NOPTS_VALUE) { sh_audio->pts = pts; sh_audio->pts_bytes = 0; } y=avcodec_decode_audio3(sh_audio->context,(int16_t*)buf,&len2,&pkt); //printf("return:%d samples_out:%d bitstream_in:%d sample_sum:%d\n", y, len2, x, len); fflush(stdout); // LATM may need many packets to find mux info if (y == AVERROR(EAGAIN)) continue; if(y<0){ mp_msg(MSGT_DECAUDIO,MSGL_V,"lavc_audio: error\n");break; } if(!sh_audio->parser && y<x) sh_audio->ds->buffer_pos+=y-x; // put back data (HACK!) if(len2>0){ if (((AVCodecContext *)sh_audio->context)->channels >= 5) { int samplesize = av_get_bytes_per_sample(((AVCodecContext *) sh_audio->context)->sample_fmt); reorder_channel_nch(buf, AF_CHANNEL_LAYOUT_LAVC_DEFAULT, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, ((AVCodecContext *)sh_audio->context)->channels, len2 / samplesize, samplesize); } //len=len2;break; if(len<0) len=len2; else len+=len2; buf+=len2; maxlen -= len2; sh_audio->pts_bytes += len2; } mp_dbg(MSGT_DECAUDIO,MSGL_DBG2,"Decoded %d -> %d \n",y,len2); if (setup_format(sh_audio, sh_audio->context)) break; } return len; }
static int decode_audio(sh_audio_t *sh, unsigned char *buf, int minlen, int maxlen) { struct spdifContext *spdif_ctx = sh->context; AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx; AVPacket pkt; double pts; int ret, in_size, consumed, x; unsigned char *start = NULL; consumed = spdif_ctx->out_buffer_len = 0; spdif_ctx->out_buffer_size = maxlen; spdif_ctx->out_buffer = buf; while (spdif_ctx->out_buffer_len + spdif_ctx->iec61937_packet_size < maxlen && spdif_ctx->out_buffer_len < minlen) { if (sh->ds->eof) break; x = ds_get_packet_pts(sh->ds, &start, &pts); if (x <= 0) { x = 0; ds_parse(sh->ds, &start, &x, MP_NOPTS_VALUE, 0); if (x == 0) continue; // END_NOT_FOUND in_size = x; } else { in_size = x; consumed = ds_parse(sh->ds, &start, &x, pts, 0); if (x == 0) { mp_msg(MSGT_DECAUDIO,MSGL_V, "start[%p] in_size[%d] consumed[%d] x[%d].\n", start, in_size, consumed, x); continue; // END_NOT_FOUND } sh->ds->buffer_pos -= in_size - consumed; } av_init_packet(&pkt); pkt.data = start; pkt.size = x; mp_msg(MSGT_DECAUDIO,MSGL_V, "start[%p] pkt.size[%d] in_size[%d] consumed[%d] x[%d].\n", start, pkt.size, in_size, consumed, x); if (pts != MP_NOPTS_VALUE) { sh->pts = pts; sh->pts_bytes = 0; } ret = lavf_ctx->oformat->write_packet(lavf_ctx, &pkt); if (ret < 0) break; } sh->pts_bytes += spdif_ctx->out_buffer_len; return spdif_ctx->out_buffer_len; }
static int control(sh_audio_t *sh, int cmd, void *arg) { unsigned char *start; double pts; switch (cmd) { case ADCTRL_RESYNC_STREAM: case ADCTRL_SKIP_FRAME: ds_get_packet_pts(sh->ds, &start, &pts); return CONTROL_TRUE; } return CONTROL_UNKNOWN; }
static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen) { int len = 0; int samples; #ifdef CONFIG_TREMOR ogg_int32_t **pcm; #else float scale; float **pcm; #endif struct ov_struct_st *ov = sh->context; while(len < minlen) { while((samples=vorbis_synthesis_pcmout(&ov->vd,&pcm))<=0){ ogg_packet op; double pts; memset(&op,0,sizeof(op)); //op.b_o_s = op.e_o_s = 0; op.bytes = ds_get_packet_pts(sh->ds,&op.packet, &pts); if(op.bytes<=0) break; if (pts != MP_NOPTS_VALUE) { sh->pts = pts; sh->pts_bytes = 0; } if(vorbis_synthesis(&ov->vb,&op)==0) /* test for success! */ vorbis_synthesis_blockin(&ov->vd,&ov->vb); } if(samples<=0) break; // error/EOF while(samples>0){ int i,j; int clipflag=0; int convsize=(maxlen-len)/(2*ov->vi.channels); // max size! int bout=((samples<convsize)?samples:convsize); if(bout<=0) break; // no buffer space /* convert floats to 16 bit signed ints (host order) and interleave */ #ifdef CONFIG_TREMOR if (ov->rg_scale_int == 64) { for(i=0;i<ov->vi.channels;i++){ ogg_int16_t *convbuffer=(ogg_int16_t *)(&buf[len]); ogg_int16_t *ptr=convbuffer+i; ogg_int32_t *mono=pcm[i]; for(j=0;j<bout;j++){ int val=mono[j]>>9; /* might as well guard against clipping */ if(val>32767){ val=32767; clipflag=1; } if(val<-32768){ val=-32768; clipflag=1; } *ptr=val; ptr+=ov->vi.channels; } } } else #endif /* CONFIG_TREMOR */ { #ifndef CONFIG_TREMOR scale = 32767.f * ov->rg_scale; #endif for(i=0;i<ov->vi.channels;i++){ ogg_int16_t *convbuffer=(ogg_int16_t *)(&buf[len]); ogg_int16_t *ptr=convbuffer+i; #ifdef CONFIG_TREMOR ogg_int32_t *mono=pcm[i]; for(j=0;j<bout;j++){ int val=(mono[j]*ov->rg_scale_int)>>(9+6); #else float *mono=pcm[i]; for(j=0;j<bout;j++){ int val=mono[j]*scale; /* might as well guard against clipping */ if(val>32767){ val=32767; clipflag=1; } if(val<-32768){ val=-32768; clipflag=1; } #endif /* CONFIG_TREMOR */ *ptr=val; ptr+=ov->vi.channels; } } } if(clipflag) mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"Clipping in frame %ld\n",(long)(ov->vd.sequence)); len+=2*ov->vi.channels*bout; sh->pts_bytes += 2*ov->vi.channels*bout; mp_msg(MSGT_DECAUDIO,MSGL_DBG2,"\n[decoded: %d / %d ]\n",bout,samples); samples-=bout; vorbis_synthesis_read(&ov->vd,bout); /* tell libvorbis how many samples we actually consumed */ } //while(samples>0) // if (!samples) break; // why? how? } if (len > 0 && ov->vi.channels >= 5) { reorder_channel_nch(buf, AF_CHANNEL_LAYOUT_VORBIS_DEFAULT, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, ov->vi.channels, len / sh->samplesize, sh->samplesize); } return len; }
static int init(sh_audio_t *sh, const char *decoder) { int x, in_size, srate, bps, *dtshd_rate; unsigned char *start; double pts; AVFormatContext *lavf_ctx = NULL; AVStream *stream = NULL; const AVOption *opt = NULL; struct spdifContext *spdif_ctx = NULL; spdif_ctx = av_mallocz(sizeof(*spdif_ctx)); if (!spdif_ctx) goto fail; spdif_ctx->lavf_ctx = avformat_alloc_context(); if (!spdif_ctx->lavf_ctx) goto fail; sh->context = spdif_ctx; lavf_ctx = spdif_ctx->lavf_ctx; lavf_ctx->oformat = av_guess_format(FILENAME_SPDIFENC, NULL, NULL); if (!lavf_ctx->oformat) goto fail; lavf_ctx->priv_data = av_mallocz(lavf_ctx->oformat->priv_data_size); if (!lavf_ctx->priv_data) goto fail; lavf_ctx->pb = avio_alloc_context(spdif_ctx->pb_buffer, OUTBUF_SIZE, 1, spdif_ctx, read_packet, write_packet, seek); if (!lavf_ctx->pb) goto fail; stream = avformat_new_stream(lavf_ctx, 0); if (!stream) goto fail; lavf_ctx->duration = AV_NOPTS_VALUE; lavf_ctx->start_time = AV_NOPTS_VALUE; lavf_ctx->streams[0]->codec->codec_id = mp_codec_to_av_codec_id(decoder); lavf_ctx->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; if (AVERROR_PATCHWELCOME == lavf_ctx->oformat->write_header(lavf_ctx)) { mp_msg(MSGT_DECAUDIO,MSGL_INFO, "This codec is not supported by spdifenc.\n"); goto fail; } // get sample_rate & bitrate from parser x = ds_get_packet_pts(sh->ds, &start, &pts); in_size = x; if (x <= 0) { pts = MP_NOPTS_VALUE; x = 0; } ds_parse(sh->ds, &start, &x, pts, 0); srate = 48000; //fake value bps = 768000/8; //fake value if (x && sh->avctx) { // we have parser and large enough buffer if (sh->avctx->sample_rate < 44100) { mp_msg(MSGT_DECAUDIO,MSGL_INFO, "This stream sample_rate[%d Hz] may be broken. " "Force reset 48000Hz.\n", sh->avctx->sample_rate); srate = 48000; //fake value } else srate = sh->avctx->sample_rate; bps = sh->avctx->bit_rate/8; } sh->ds->buffer_pos -= in_size; switch (lavf_ctx->streams[0]->codec->codec_id) { case AV_CODEC_ID_AAC: spdif_ctx->iec61937_packet_size = 16384; sh->sample_format = AF_FORMAT_IEC61937_LE; sh->samplerate = srate; sh->channels = 2; sh->i_bps = bps; break; case AV_CODEC_ID_AC3: spdif_ctx->iec61937_packet_size = 6144; sh->sample_format = AF_FORMAT_AC3_LE; sh->samplerate = srate; sh->channels = 2; sh->i_bps = bps; break; case AV_CODEC_ID_DTS: if(sh->opts->dtshd) { opt = av_opt_find(&lavf_ctx->oformat->priv_class, "dtshd_rate", NULL, 0, 0); if (!opt) goto fail; dtshd_rate = (int*)(((uint8_t*)lavf_ctx->priv_data) + opt->offset); *dtshd_rate = 192000*4; spdif_ctx->iec61937_packet_size = 32768; sh->sample_format = AF_FORMAT_IEC61937_LE; sh->samplerate = 192000; // DTS core require 48000 sh->channels = 2*4; sh->i_bps = bps; } else { spdif_ctx->iec61937_packet_size = 32768; sh->sample_format = AF_FORMAT_AC3_LE; sh->samplerate = srate; sh->channels = 2; sh->i_bps = bps; } break; case AV_CODEC_ID_EAC3: spdif_ctx->iec61937_packet_size = 24576; sh->sample_format = AF_FORMAT_IEC61937_LE; sh->samplerate = 192000; sh->channels = 2; sh->i_bps = bps; break; case AV_CODEC_ID_MP3: spdif_ctx->iec61937_packet_size = 4608; sh->sample_format = AF_FORMAT_MPEG2; sh->samplerate = srate; sh->channels = 2; sh->i_bps = bps; break; case AV_CODEC_ID_TRUEHD: spdif_ctx->iec61937_packet_size = 61440; sh->sample_format = AF_FORMAT_IEC61937_LE; sh->samplerate = 192000; sh->channels = 8; sh->i_bps = bps; break; default: break; } return 1; fail: uninit(sh); return 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; }
/* This tries to extract a requested amount of decoded data. * Even when you request 0 bytes, it will feed enough input so that * the decoder _could_ have delivered something. * Returns byte count >= 0, -1 on error. * * Thoughts on exact pts keeping: * We have to assume that MPEG frames are cut in pieces by packet boundaries. * Also, it might be possible that the first packet does not contain enough * data to ensure initial stream sync... or re-sync on erroneous streams. * So we need something robust to relate the decoded byte count to the correct * time stamp. This is tricky, though. From the outside, you cannot tell if, * after having fed two packets until the first output arrives, one should * start counting from the first packet's pts or the second packet's. * So, let's just count from the last fed package's pts. If the packets are * exactly cut to MPEG frames, this will cause one frame mismatch in the * beginning (when mpg123 peeks ahead for the following header), but will * be corrected with the third frame already. One might add special code to * not increment the base pts past the first packet's after a resync before * the first decoded bytes arrived. */ static int decode_a_bit(sh_audio_t *sh, unsigned char *buf, int count) { int ret = MPG123_OK; int got = 0; struct ad_mpg123_context *con = sh->context; /* There will be one MPG123_NEW_FORMAT message on first open. * This will be handled in init(). */ do { size_t got_now = 0; /* Feed the decoder. This will only fire from the second round on. */ if (ret == MPG123_NEED_MORE) { int incount; double pts; unsigned char *inbuf; /* Feed more input data. */ incount = ds_get_packet_pts(sh->ds, &inbuf, &pts); if (incount <= 0) break; /* Apparently that's it. EOF. */ /* Next bytes from that presentation time. */ if (pts != MP_NOPTS_VALUE) { sh->pts = pts; sh->pts_bytes = 0; } #ifdef AD_MPG123_FRAMEWISE /* Have to use mpg123_feed() to avoid decoding here. */ ret = mpg123_feed(con->handle, inbuf, incount); #else /* Do not use mpg123_feed(), added in later libmpg123 versions. */ ret = mpg123_decode(con->handle, inbuf, incount, NULL, 0, NULL); #endif if (ret == MPG123_ERR) break; } /* Theoretically, mpg123 could return MPG123_DONE, so be prepared. * Should not happen in our usage, but it is a valid return code. */ else if (ret == MPG123_ERR || ret == MPG123_DONE) break; /* Try to decode a bit. This is the return value that counts * for the loop condition. */ #ifdef AD_MPG123_FRAMEWISE if (!buf) { /* fake call just for feeding to get format */ ret = mpg123_getformat(con->handle, NULL, NULL, NULL); } else { /* This is the decoding. One frame at a time. */ ret = mpg123_replace_buffer(con->handle, buf, count); if (ret == MPG123_OK) ret = mpg123_decode_frame(con->handle, NULL, NULL, &got_now); } #else ret = mpg123_decode(con->handle, NULL, 0, buf + got, count - got, &got_now); #endif got += got_now; sh->pts_bytes += got_now; #ifdef AD_MPG123_FRAMEWISE } while (ret == MPG123_NEED_MORE || (got == 0 && count != 0)); #else } while (ret == MPG123_NEED_MORE || got < count);
static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen) { int len = 0; union smc *sc = (union smc *)sm_com; // shared memory int temp ; int buflen = sh->a_in_buffer_len; int force = 0; while(len < minlen ) { int y; int len2=0; unsigned char* bufptr=NULL; double pts; int ret; if (buflen<=0){ buflen=ds_get_packet_pts(sh->ds, &bufptr, &pts); // printf("\nbuflen=%d\n",buflen); if(buflen<=0){ sh->a_in_buffer_len = 0; return -1; //EOF } // if (buflen>0){ //fill buffer // |............csd...................| // phead buflen ptail csd_avail_num = 0; //total available csd num phead = bufptr; ptail = phead + buflen ; force = 1; if (pts != MP_NOPTS_VALUE) { sh->pts = pts; sh->pts_bytes = 0; } // } } if (phead<=ptail ){ //fill buffer [csd_buf_size] pfillin_comin = sm_in ; csd_avail_num = 0 ; while ( csd_avail_num < csd_buf_size && phead<ptail){ *pfillin_comin++ = *phead++; csd_avail_num++; //get sm_in[csd_avail_num] } } //force flag :inform decoder to start subframe sc->pdecod.paremeter1 = force; //send to server ret = ipc_decode(sc, APE_ID, csd_avail_num, id); if (!ret) return 0 ; //IPC Error else if(ret < 0) return -1; if (sc->sctrl.codec_id == APE_ID) //decode success! len2 = sc->sctrl.data_len; //copy res data y = sc->sctrl.paremeter1 ;//y: consume byetes res_num = csd_avail_num - (sc->sctrl.paremeter2 &0xfffffffc) ; phead -= res_num ; //shift phead abide by residue if(len2>0) memcpy( buf, sm_out , len2); // sm_out -->wav out force = 0; if(y<0) { mp_msg(MSGT_DECAUDIO,MSGL_V,"APE: error code %d\n", y); buflen = 0; break; } //buflen -= y; //total-consumed temp = buflen ; temp-=y; if(0<temp<=-3)//because of res allignment,it maybe minus { temp=0; // if(temp<0) printf("\n%d\n",temp); } else if (temp <=-4) //X { printf("error decode"); break ; } buflen = temp ; len+=len2; buf+=len2; sh->pts_bytes += len2; } sh->a_in_buffer_len = buflen; return len; }
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; }
static int decode_audio(sh_audio_t *sh,unsigned char *buf,int minlen,int maxlen) { int j = 0, len = -1; union smc *sc = (union smc *)sm_com; // shared memory while(len < minlen ) { int y; int len2=0; unsigned char* bufptr=NULL; double pts; int buflen=ds_get_packet_pts(sh->ds, &bufptr, &pts); if(buflen<=0) break; //EOF if (pts != MP_NOPTS_VALUE) { sh->pts = pts; sh->pts_bytes = 0; } memcpy(sm_in,bufptr, buflen); #if 1 int ret; ret = ipc_decode(sc, AMRNB_ID, buflen, id); if(!ret) return 0; else if(ret < 0) return -1; #else if (!ipc_decode(sc, AMRNB_ID, buflen, id)) return 0 ; //IPC Error #endif if (sc->sctrl.codec_id == AMRNB_ID) //decode success! len2 = sc->sctrl.data_len; y = sc->sctrl.paremeter1 ; // sh->channels = sc->sctrl.paremeter2; // sh->samplerate = sc->sctrl.paremeter3; memcpy( buf, sm_out , len2); // sm_out -->16 bit wav if(y<0) { mp_msg(MSGT_DECAUDIO,MSGL_V,"AMR_audio: error\n"); break; } if(y<buflen) sh->ds->buffer_pos+=y-buflen; // put back data (HACK!) if(len2>0){ // first decoding if(len<0) len=len2; else len+=len2; buf+=len2; sh->pts_bytes += len2; } mp_dbg(MSGT_DECAUDIO,MSGL_DBG2,"Decoded %d -> %d \n",y,len2); } return len; }