void audio_decode_example(AVCodecContext *c ,uint8_t *adpcm_buf,int in_size,uint8_t *pcm_buf,int *pcm_size) { int size, len,out_size; uint8_t *inbuf_ptr=adpcm_buf; uint8_t *outbuf=pcm_buf; *pcm_size=0; size=in_size; while (size > 0) { len = avcodec_decode_audio(c, (short *)outbuf, &out_size, inbuf_ptr, size); if (len < 0) { printf("Error while decoding\n"); return ; } if (out_size > 0) { /* if a frame has been decoded, output it */ *pcm_size+=out_size; outbuf+=out_size; } size -= len; inbuf_ptr += len; } }
// decode data in d->packetData and fill d->outputBuffer int K3bFFMpegFile::fillOutputBuffer() { // decode if the output buffer is empty if( d->outputBufferSize <= 0 ) { // make sure we have data to decode if( readPacket() == 0 ) { return 0; } d->outputBufferPos = d->outputBuffer; #ifdef FFMPEG_BUILD_PRE_4629 int len = avcodec_decode_audio( &d->formatContext->streams[0]->codec, #else int len = avcodec_decode_audio( d->formatContext->streams[0]->codec, #endif (short*)d->outputBuffer, &d->outputBufferSize, d->packetData, d->packetSize ); d->packetSize -= len; d->packetData += len; if( d->packetSize <= 0 ) av_free_packet( &d->packet ); } // if it is still empty try again if( d->outputBufferSize <= 0 ) return fillOutputBuffer(); else return d->outputBufferSize; }
uint8_t ADM_AudiocodecWMA::run( uint8_t * ptr, uint32_t nbIn, uint8_t * outptr, uint32_t * nbOut,ADM_ChannelMatrix *matrix) { int out=0; int max=0,pout=0; printf("[lavAudio]Incoming %d\n",nbIn); *nbOut=0; // Shrink if(_head && (_tail+nbIn)*3>ADMWA_BUF*2) { memmove(_buffer,_buffer+_head,_tail-_head); _tail-=_head; _head=0; } // ADM_assert(nbIn+_tail<ADMWA_BUF); memcpy(_buffer+_tail,ptr,nbIn); _tail+=nbIn; while(_tail-_head>_blockalign) { out=avcodec_decode_audio(_context,(int16_t *)outptr,&pout,_buffer+_head,_tail-_head); if(out<0) { printf( " *** [lavAudio] decoding error ***\n"); return 1; } //printf("This round %d Consumed %d produced %d\n",_tail-_head,out,pout); _head+=out; // consumed bytes //_head+=_blockalign; *nbOut+=pout; outptr+=pout; } return 1; }
uint8_t ADM_AudiocodecAMR::run( uint8_t * ptr, uint32_t nbIn, uint8_t * outptr, uint32_t * nbOut,ADM_ChannelMatrix *matrix) { int out; int max=0,pout=0,toread; *nbOut=0; // Shrink if(_head && (_tail+nbIn)*3>ADM_AMR_BUFFER*2) { memmove(_buffer,_buffer+_head,_tail-_head); _tail-=_head; _head=0; } // ADM_assert(nbIn+_tail<ADM_AMR_BUFFER); memcpy(_buffer+_tail,ptr,nbIn); _tail+=nbIn; while(_tail-_head>AMR_PACKET) { out=avcodec_decode_audio(_context,(int16_t *)outptr,&pout,_buffer+_head,_tail-_head); if(out<0) { printf( " *** WMA decoding error ***\n"); _head+=1; // Try skipping some bytes continue; } _head+=out; // consumed bytes *nbOut+=pout; outptr+=pout; } return 1; }
static void* AudioDecodeThreadProc(void *param) { PLAYER *player = (PLAYER*)param; AVPacket *packet = NULL; AVFrame *aframe = NULL; aframe = av_frame_alloc(); if (!aframe) return NULL; while (!(player->nPlayerStatus & PS_CLOSE)) { //++ when audio decoding pause ++// if (player->nPlayerStatus & PS_A_PAUSE) { Sleep(20); continue; } //-- when audio decoding pause --// // read packet pktqueue_read_request_a(&(player->PacketQueue), &packet); //++ play completed ++// if (packet->pts == -1) { renderwriteaudio(player->hCoreRender, (AVFrame*)-1); pktqueue_read_done_a(&(player->PacketQueue)); continue; } //-- play completed --// //++ decode audio packet ++// if (player->iAudioStreamIndex != -1) { while (packet->size > 0) { int consumed = 0; int gotaudio = 0; consumed = avcodec_decode_audio(player->pAudioCodecContext, aframe, &gotaudio, packet); if (consumed < 0) { log_printf(TEXT("an error occurred during decoding audio.\n")); break; } if (gotaudio) { aframe->pts = (int64_t)(av_frame_get_best_effort_timestamp(aframe) * player->dAudioTimeBase); renderwriteaudio(player->hCoreRender, aframe); } packet->data += consumed; packet->size -= consumed; } } //-- decode audio packet --// // free packet av_packet_unref(packet); pktqueue_read_done_a(&(player->PacketQueue)); } av_frame_free(&aframe); return NULL; }
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; }
/* decode one audio frame and returns its uncompressed size */ static int audio_decode_frame(FFMovie *movie, uint8_t *audio_buf, double *pts_ptr) { /*SDL AUDIO THREAD*/ AVPacket *pkt = &movie->audio_pkt; int len1, data_size; double pts; for(;;) { if (movie->paused || movie->audioq.abort_request || Global_abort_all) { return -1; } while (movie->audio_pkt_size > 0) { len1 = avcodec_decode_audio(&movie->audio_st->codec, (int16_t *)audio_buf, &data_size, movie->audio_pkt_data, movie->audio_pkt_size); if (len1 < 0) break; movie->audio_pkt_data += len1; movie->audio_pkt_size -= len1; if (data_size > 0) { pts = 0; if (movie->audio_pkt_ipts != AV_NOPTS_VALUE) pts = (double)movie->audio_pkt_ipts * movie->context->pts_num / movie->context->pts_den; /* if no pts, then compute it */ if (pts != 0) { movie->audio_clock = pts; } else { int n; n = 2 * movie->audio_st->codec.channels; movie->audio_clock += (double)data_size / (double)(n * movie->audio_st->codec.sample_rate); } *pts_ptr = movie->audio_clock; movie->audio_pkt_ipts = AV_NOPTS_VALUE; /* we got samples : we can exit now */ return data_size; } } /* free previous packet if any */ if (pkt->destruct) av_free_packet(pkt); /* read next packet */ if (packet_queue_get(&movie->audioq, pkt, 1) < 0) return -1; movie->audio_pkt_data = pkt->data; movie->audio_pkt_size = pkt->size; movie->audio_pkt_ipts = pkt->pts; } }
/* * internal function to only read one paquet */ bool SoundSourceFFmpeg::readInput(){ char * dst; unsigned char * src; int ret = 0; int readsize = 0; int inputsize = 0; int tries = 0; //DEBUG bufferSize = 0; bufferOffset = 0; memset(buffer, 0, AVCODEC_MAX_AUDIO_FRAME_SIZE); while (av_read_packet(pFormatCtx, &packet)>0) { if (packet.stream_index==audioStream){ dst = (char *)buffer; src = packet.data; inputsize = 0; readsize = 0; //qDebug() << "ffmpeg: before avcodec_decode_audio packet.size(" << packet.size << ")"; tries = 0; do { ret = avcodec_decode_audio(pCodecCtx, (int16_t *)dst, &readsize, src, packet.size - inputsize); if (readsize == 0) { tries++; //qDebug() << "ffmpeg: skip frame, decoded readsize = 0"; break; } if (ret <= 0) { tries++; //qDebug() << "ffmpeg: skip frame, decoded ret = 0"; if (tries > 3) break; continue; } dst += readsize; bufferSize += readsize; src += ret; inputsize += ret; //qDebug() << "ffmpeg: loop buffersize(" << bufferSize << "), readsize(" << readsize << ") ret(" << ret << ") psize(" << packet.size << ")"; } while (inputsize < packet.size); //qDebug() << "ffmpeg: after avcodec_decode_audio outsize(" << bufferSize << ") - ret(" << ret << ")"; if (bufferSize != 0) return true; } //debug av_free_packet(&packet); } return false; }
static void avdec_init() { static unsigned char inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; static short outbuf[AVCODEC_MAX_AUDIO_FRAME_SIZE]; int read, written; memset(&inbuf[INBUF_SIZE], 0, FF_INPUT_BUFFER_PADDING_SIZE); if (!(read = fread(inbuf, 1, INBUF_SIZE, fp))) return; avcodec_decode_audio(ctx, outbuf, &written, inbuf, read); sample_rate = ctx->sample_rate; channels = ctx->channels; }
// it is running in sound mixer thread bool as_netstream::decode_audio(const AVPacket& pkt, Sint16** data, int* size) { bool ok = false; int frame_size; Uint8* decoder_buf = (Uint8*) malloc((AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2); if (avcodec_decode_audio(m_ACodecCtx, (Sint16*) decoder_buf, &frame_size, pkt.data, pkt.size) >= 0) { sound_handler* sh = get_sound_handler(); if (sh) { sh->cvt(data, size, decoder_buf, frame_size, m_ACodecCtx->channels, m_ACodecCtx->sample_rate); ok = true; } } free(decoder_buf); return ok; }
uint8_t ADM_AudiocodecAMR::run(uint8_t *inptr, uint32_t nbIn, float *outptr, uint32_t *nbOut) { int out; int pout=0; int16_t *run16; *nbOut=0; // Shrink if(_head && (_tail+nbIn)*3>ADM_AMR_BUFFER*2) { memmove(_buffer,_buffer+_head,_tail-_head); _tail-=_head; _head=0; } // ADM_assert(nbIn+_tail<ADM_AMR_BUFFER); memcpy(_buffer+_tail,inptr,nbIn); _tail+=nbIn; while(_tail-_head>AMR_PACKET) { out=avcodec_decode_audio(_context,(int16_t *)scratchPad, &pout,_buffer+_head,_tail-_head); if(out<0) { printf( " *** AMR decoding error ***\n"); _head+=1; // Try skipping some bytes continue; } _head+=out; // consumed bytes pout>>=1; *nbOut+=pout; run16=(int16_t *)scratchPad; for(int i=0;i<pout;i++) { *outptr++=((float)run16[i])/32767.; } } return 1; }
uint8_t ADM_AudiocodecWMA::run(uint8_t *inptr, uint32_t nbIn, float *outptr, uint32_t *nbOut) { int out=0; int max=0,pout=0; int16_t *run16; *nbOut=0; // Shrink if(_head && (_tail+nbIn)*3>ADMWA_BUF*2) { memmove(_buffer,_buffer+_head,_tail-_head); _tail-=_head; _head=0; } // ADM_assert(nbIn+_tail<ADMWA_BUF); memcpy(_buffer+_tail,inptr,nbIn); _tail+=nbIn; while(_tail-_head>=_blockalign) { out=avcodec_decode_audio(_context,(int16_t *)scratchPad, &pout,_buffer+_head,_tail-_head); if(out<0) { printf( " *** WMA decoding error (%u)***\n",_blockalign); _head+=1; // Try skipping some bytes continue; } ADM_assert(pout<SCRATCH_PAD_SIZE); _head+=out; // consumed bytes pout>>=1; *nbOut+=pout; run16=(int16_t *)scratchPad; for(int i=0;i<pout;i++) { *outptr++=((float)run16[i])/32767.; } } return 1; }
int Encoder::getNextFrame(void) { int bytesDecoded; int isFrameFinished; int returnCode; if (avFrame) av_free(avFrame); avFrame = avcodec_alloc_frame(); if (avFrame == NULL) { systemLog->sysLog(ERROR, "cannot allocate a YUV frame. cannot decode frame"); return false; } if (audioSamples) delete audioSamples; while (av_read_frame(avFormatContext, &avPacket) >= 0) { // Is this packet a packet from this video stream ? if (videoPacket.stream_index == videoStream) { // Decode video frame systemLog->sysLog(NOTICE, "decoding a video frame"); returnCode = avcodec_decode_video(videoCodecContext, avFrame, &isFrameFinished, videoPacket.data, videoPacket.size); if (returnCode < 0) systemLog->sysLog(ERROR, "problem while decoding a video frame"); if (isFrameFinished) return true; } if (audioPacket.stream_index == audioStream) { // Decode audio frame systemLog->sysLog(NOTICE, "decoding an audio frame"); returnCode = avcodec_decode_audio(audioCodecContext, audioSamples, &isFrameFinished, audioPacket.data, audioPacket.size); if (returnCode < 0) systemLog->sysLog(ERROR, "problem while decoding an audio frame"); if (isFrameFinished) return true; } } return false; }
void LAVCAudioProvider::GetAudio(void *buf, __int64 start, __int64 count) { int16_t *_buf = (int16_t *)buf; __int64 _count = num_samples - start; if (count < _count) _count = count; if (_count < 0) _count = 0; memset(_buf + _count, 0, (count - _count) << 1); AVPacket packet; while (_count > 0 && av_read_frame(lavcfile->fctx, &packet) >= 0) { while (packet.stream_index == audStream) { int bytesout = 0, samples; if (avcodec_decode_audio(codecContext, buffer, &bytesout, packet.data, packet.size) < 0) throw _T("Failed to decode audio"); if (bytesout == 0) break; samples = bytesout >> 1; if (rsct) { if ((__int64)(samples * resample_ratio / codecContext->channels) > _count) samples = (__int64)(_count / resample_ratio * codecContext->channels); samples = audio_resample(rsct, _buf, buffer, samples / codecContext->channels); assert(samples <= _count); } else { /* currently dead code, rsct != NULL because we're resampling for mono */ if (samples > _count) samples = _count; memcpy(_buf, buffer, samples << 1); } _buf += samples; _count -= samples; break; } av_free_packet(&packet); } }
EmErrorCode WmaDecoder::DecodeUnit(char* data, uint32_t& used, uint32_t& unitCount) { used = 0; unitCount = 0; m_BitRate = m_CodecCtx->bit_rate / 1000; if (m_UnitIndex < m_UnitCount) { AVPacket packet; if (av_read_frame(m_FormatCtx, &packet) < 0) { m_UnitIndex = m_UnitCount; unitCount = m_UnitCount; return ErrorCode::DecoderOutOfRange; } unitCount = packet.duration; m_UnitIndex += unitCount; int insize = packet.size; uint8_t* inbuf = packet.data; while (insize > 0) { int outsize = 0; int len = avcodec_decode_audio(m_CodecCtx, (short*)data, &outsize, inbuf, insize); if (len < 0) break; if (outsize <= 0) continue; insize -= len; inbuf += len; data += outsize; used += outsize; if (packet.data != nullptr) av_free_packet(&packet); } return ErrorCode::Ok; } else { m_UnitIndex = m_UnitCount; unitCount = m_UnitCount; return ErrorCode::DecoderOutOfRange; } }
int avdec_read(unsigned char **buf) { #define OUTBUF_SIZE 65536 static unsigned char inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; static unsigned char outbuf[OUTBUF_SIZE]; static short tmp[AVCODEC_MAX_AUDIO_FRAME_SIZE]; unsigned char *ptr = inbuf; int read = 0, decoded, written, total = 0; *buf = outbuf; memset(&inbuf[INBUF_SIZE], 0, FF_INPUT_BUFFER_PADDING_SIZE); if (!(read = fread(inbuf, 1, INBUF_SIZE, fp))) return EOF; while (read > 0) { written = 0; decoded = avcodec_decode_audio(ctx, tmp, &written, ptr, read); if (decoded < 0) { fprintf(stderr, "AVCODEC: Error while decoding\n"); return EOF; } if (written) { /* make sure we don't overflow the output buffer */ assert(total + written <= OUTBUF_SIZE); memcpy(&outbuf[total], tmp, written); total += written; } read -= decoded; ptr += decoded; } return total; }
int IoAVCodec_decodeAudioPacket(IoAVCodec *self, AVCodecContext *c, uint8_t *inbuf, size_t size) { UArray *outba = IoSeq_rawUArray(DATA(self)->outputBuffer); uint8_t *outbuf = DATA(self)->audioOutBuffer; //UArray_setItemType_(outba, CTYPE_float32_t); while (size > 0) { int outSize; int len = avcodec_decode_audio(c, (int16_t *)outbuf, &outSize, inbuf, size); if (len < 0) { printf("Error while decoding audio packet\n"); return -1; } if (outSize > 0) { // if a frame has been decoded, output it // convert short ints to floats size_t sampleCount = outSize / c->channels; size_t oldSize = UArray_size(outba); //UArray_setSize_(outba, oldSize + sampleCount); // knows it's a float32 array UArray_setSize_(outba, oldSize + sampleCount * sizeof(float)); // knows it's a float32 array IoAVCodec_ConvertShortToFloat((short *)outbuf, (float *)(UArray_bytes(outba) + oldSize), sampleCount); } size -= len; inbuf += len; } return 0; }
static int ffmpeg_decode (void *prv_data, char *buf, int buf_len, struct sound_params *sound_params) { struct ffmpeg_data *data = (struct ffmpeg_data *)prv_data; int ret; int data_size; AVPacket pkt, pkt_tmp; uint8_t *pkt_data; int pkt_size = 0; int filled = 0; /* The sample buffer should be 16 byte aligned (because SSE), a segmentation * fault may occur otherwise. * * See: avcodec.h in ffmpeg */ char avbuf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2] __attribute__((aligned(16))); decoder_error_clear (&data->error); sound_params->channels = data->enc->channels; sound_params->rate = data->enc->sample_rate; sound_params->fmt = SFMT_S16 | SFMT_NE; if (data->remain_buf) { int to_copy = MIN (buf_len, data->remain_buf_len); debug ("Copying %d bytes from the remain buf", to_copy); memcpy (buf, data->remain_buf, to_copy); if (to_copy < data->remain_buf_len) { memmove (data->remain_buf, data->remain_buf + to_copy, data->remain_buf_len - to_copy); data->remain_buf_len -= to_copy; } else { debug ("Remain buf is now empty"); free (data->remain_buf); data->remain_buf = NULL; data->remain_buf_len = 0; } return to_copy; } do { ret = av_read_frame (data->ic, &pkt); if (ret < 0) return 0; memcpy(&pkt_tmp, &pkt, sizeof(pkt)); pkt_data = pkt.data; pkt_size = pkt.size; debug ("Got %dB packet", pkt_size); while (pkt_size) { int len; #if LIBAVCODEC_VERSION_INT >= ((52<<16)+(26<<8)+0) data_size = sizeof (avbuf); len = avcodec_decode_audio3 (data->enc, (int16_t *)avbuf, &data_size, &pkt); #elif LIBAVCODEC_VERSION_INT >= ((51<<16)+(50<<8)+0) data_size = sizeof (avbuf); len = avcodec_decode_audio2 (data->enc, (int16_t *)avbuf, &data_size, pkt_data, pkt_size); #else len = avcodec_decode_audio (data->enc, (int16_t *)avbuf, &data_size, pkt_data, pkt_size); #endif debug ("Decoded %dB", data_size); if (len < 0) { /* skip frame */ decoder_error (&data->error, ERROR_STREAM, 0, "Error in the stream!"); break; } pkt_data += len; pkt_size -= len; if (buf_len) { int to_copy = MIN (data_size, buf_len); memcpy (buf, avbuf, to_copy); buf += to_copy; filled += to_copy; buf_len -= to_copy; debug ("Copying %dB (%dB filled)", to_copy, filled); if (to_copy < data_size) put_in_remain_buf (data, avbuf + to_copy, data_size - to_copy); } else if (data_size) add_to_remain_buf (data, avbuf, data_size); } } while (!filled); /* 2.0 - 16bit/sample*/ data->bitrate = pkt.size * 8 / ((filled + data->remain_buf_len) / 2.0 / sound_params->channels / sound_params->rate) / 1000; av_free_packet (&pkt_tmp); return filled; }
int AudioLoader::decode_audio_frame(AVCodecContext* audioCtx, int16_t* output, int* outputSize, AVPacket* packet) { #if LIBAVCODEC_VERSION_INT < AVCODEC_51_28_0 int len = avcodec_decode_audio(audioCtx, output, outputSize, packet->data, packet->size); #elif LIBAVCODEC_VERSION_INT < AVCODEC_52_47_0 int len = avcodec_decode_audio2(audioCtx, output, outputSize, packet->data, packet->size); #elif LIBAVCODEC_VERSION_INT < AVCODEC_AUDIO_DECODE4 int len = avcodec_decode_audio3(audioCtx, output, outputSize, packet); #else int gotFrame = 0; avcodec_get_frame_defaults(_decodedFrame); int len = avcodec_decode_audio4(audioCtx, _decodedFrame, &gotFrame, packet); if (len < 0) return len; // error handling should be done outside if (gotFrame) { int nsamples = _decodedFrame->nb_samples; int inputDataSize = av_samples_get_buffer_size(NULL, audioCtx->channels, nsamples, audioCtx->sample_fmt, 1); # if HAVE_SWRESAMPLE if (_convertCtx) { int outputSamples = *outputSize / (2 /*sizeof(S16)*/ * _nChannels); //if (outputSamples < nsamples) { cout << "OOPS!!" << endl; } if (swr_convert(_convertCtx, (uint8_t**) &output, outputSamples, (const uint8_t**)_decodedFrame->data, nsamples) < 0) { ostringstream msg; msg << "AudioLoader: Error converting" << " from " << av_get_sample_fmt_name(_audioCtx->sample_fmt) << " to " << av_get_sample_fmt_name(AV_SAMPLE_FMT_S16); throw EssentiaException(msg); } *outputSize = nsamples * (2 /*sizeof(S16)*/ * _nChannels); } else { // no conversion needed, make a direct copy // copy and convert data from our frame to our output audio buffer //E_WARNING("Should use swresample always!"); memcpy(output, _decodedFrame->data[0], inputDataSize); *outputSize = inputDataSize; } # else // direct copy, we do the sample format conversion later if needed memcpy(output, _decodedFrame->data[0], inputDataSize); *outputSize = inputDataSize; # endif } else { E_DEBUG(EAlgorithm, "AudioLoader: tried to decode packet but didn't get any frame..."); *outputSize = 0; } #endif return len; }
int FileFFMPEG::read_samples(double *buffer, int64_t len) { const int debug = 0; int error = 0; ffmpeg_lock->lock("FileFFMPEG::read_samples"); if(debug) printf("FileFFMPEG::read_samples %d\n", __LINE__); // Compute stream & stream channel from global channel int audio_channel = file->current_channel; int audio_index = -1; FileFFMPEGStream *stream = 0; for(int i = 0; i < audio_streams.size(); i++) { if(audio_channel < audio_streams.get(i)->channels) { stream = audio_streams.get(i); audio_index = stream->index; break; } audio_channel -= audio_streams.get(i)->channels; } if(debug) printf("FileFFMPEG::read_samples %d\n", __LINE__); AVStream *ffmpeg_stream = ((AVFormatContext*)stream->ffmpeg_file_context)->streams[stream->index]; AVCodecContext *decoder_context = ffmpeg_stream->codec; stream->update_pcm_history(file->current_sample, len); if(debug) printf("FileFFMPEG::read_samples %d len=%d\n", __LINE__, (int)len); if(debug) printf("FileFFMPEG::read_samples %d decode_start=%lld decode_end=%lld\n", __LINE__, (long long)stream->decode_start, (long long)stream->decode_end); // Seek occurred if(stream->decode_start != stream->decode_end) { int64_t timestamp = (int64_t)((double)file->current_sample * ffmpeg_stream->time_base.den / ffmpeg_stream->time_base.num / asset->sample_rate); // Want to seek to the nearest keyframe and read up to the current frame // but ffmpeg doesn't support that kind of precision. // Also, basing all the seeking on the same stream seems to be required for synchronization. if(debug) printf("FileFFMPEG::read_samples %d\n", __LINE__); av_seek_frame((AVFormatContext*)stream->ffmpeg_file_context, /* stream->index */ 0, timestamp, AVSEEK_FLAG_ANY); if(debug) printf("FileFFMPEG::read_samples %d\n", __LINE__); stream->current_sample = file->current_sample; stream->decode_end = stream->decode_start; } if(debug) printf("FileFFMPEG::read_samples %d stream->decode_len=%d\n", __LINE__, (int)stream->decode_len); int got_it = 0; int accumulation = 0; // Read frames until the requested range is decoded. while(accumulation < stream->decode_len && !error) { //printf("FileFFMPEG::read_samples %d accumulation=%d\n", __LINE__, accumulation); AVPacket packet; error = av_read_frame((AVFormatContext*)stream->ffmpeg_file_context, &packet); unsigned char *packet_ptr = packet.data; int packet_len = packet.size; if(debug) printf("FileFFMPEG::read_samples %d error=%d packet_len=%d\n", __LINE__, error, packet_len); if(packet.stream_index == stream->index) { while(packet_len > 0 && !error) { int data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; if(!ffmpeg_samples) ffmpeg_samples = (short*)realloc(ffmpeg_samples, data_size); if(debug) printf("FileFFMPEG::read_samples %d decoder_context=%p ffmpeg_samples=%p data_size=%d packet.size=%d packet.data=%p codec_id=%d\n", __LINE__, decoder_context, ffmpeg_samples, data_size, packet_len, packet_ptr, decoder_context->codec_id); //av_log_set_level(AV_LOG_DEBUG); #if 1 int bytes_decoded = avcodec_decode_audio2(decoder_context, ffmpeg_samples, &data_size, packet_ptr, packet_len); #else int bytes_decoded = avcodec_decode_audio(decoder_context, ffmpeg_samples, &data_size, packet_ptr, packet_len); #endif if(debug) PRINT_TRACE // if(bytes_decoded < 0) error = 1; if(bytes_decoded == -1) error = 1; packet_ptr += bytes_decoded; packet_len -= bytes_decoded; if(debug) printf("FileFFMPEG::read_samples %d bytes_decoded=%d data_size=%d\n", __LINE__, bytes_decoded, data_size); // if(data_size <= 0) // break; int samples_decoded = data_size / stream->channels / sizeof(short); // Transfer decoded samples to ring buffer stream->append_history(ffmpeg_samples, samples_decoded); // static FILE *fd = 0; // if(!fd) fd = fopen("/tmp/test.pcm", "w"); // fwrite(ffmpeg_samples, data_size, 1, fd); accumulation += samples_decoded; } } if(debug) PRINT_TRACE av_free_packet(&packet); } if(debug) printf("FileFFMPEG::read_samples %d\n", __LINE__); stream->read_history(buffer, file->current_sample, audio_channel, len); if(debug) printf("FileFFMPEG::read_samples %d\n", __LINE__); if(debug) printf("FileFFMPEG::read_samples %d %d\n", __LINE__, error); stream->current_sample += len; ffmpeg_lock->unlock(); return error; }
/* * Audio decoding. */ void audio_decode_example(const char *outfilename, const char *filename) { AVCodec *codec; AVCodecContext *c= NULL; int out_size, size, len; FILE *f, *outfile; uint8_t *outbuf; uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE], *inbuf_ptr; printf("Audio decoding\n"); /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */ memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE); /* find the mpeg audio decoder */ codec = avcodec_find_decoder(CODEC_ID_MP2); if (!codec) { fprintf(stderr, "codec not found\n"); exit(1); } c= avcodec_alloc_context(); /* open it */ if (avcodec_open(c, codec) < 0) { fprintf(stderr, "could not open codec\n"); exit(1); } outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE); f = fopen(filename, "rb"); if (!f) { fprintf(stderr, "could not open %s\n", filename); exit(1); } outfile = fopen(outfilename, "wb"); if (!outfile) { av_free(c); exit(1); } /* decode until eof */ inbuf_ptr = inbuf; for(;;) { size = fread(inbuf, 1, INBUF_SIZE, f); if (size == 0) break; inbuf_ptr = inbuf; while (size > 0) { len = avcodec_decode_audio(c, (short *)outbuf, &out_size, inbuf_ptr, size); if (len < 0) { fprintf(stderr, "Error while decoding\n"); exit(1); } if (out_size > 0) { /* if a frame has been decoded, output it */ fwrite(outbuf, 1, out_size, outfile); } size -= len; inbuf_ptr += len; } } fclose(outfile); fclose(f); free(outbuf); avcodec_close(c); av_free(c); }
int scan_audio_stream_0(unsigned char *mbuf, int count) { /* StreamReader asr; asr.addBytes(sr.curBuffPos(),packetSize); int ID = 0; int layer = 0; int protection_bit = 0; int bitrate_index = 0; int sampling_frequency = 0; int padding_bit = 0; int private_bit = 0; int mode = 0; int mode_extension = 0; int copyright = 0; int original_home = 0; int emphasis = 0; */ int16_t chan1 = 0; int16_t chan2 = 0; // int16_t chan1t = 0; // int16_t chan2t = 0; long size = count; inbuf_ptr = mbuf; while (size > 0) { len = avcodec_decode_audio(c, (short *)outbuf, &out_size, inbuf_ptr, size); if (len < 0) { fprintf(stderr, "Error while decoding\n"); break; } // SDL_PauseAudio(0); if (out_size > 0) { audiosamples += out_size/4; //fprintf(stdout,"decode audio out_size=%d\n",out_size); chan1 = 0; chan2 = 0; //lowvalcount = 0; uint8_t *src=outbuf; for( int i = 0; i < out_size && !havesilence; i+=4) { //if(*src == 0 || *src == 0xFF ) { chan1 = bswap_16(*((int16_t *)src)); chan2 = bswap_16(*((int16_t *)(src+2))); //chan1 = *((int16_t *)&outbuf[i]); //chan2 = *((int16_t *)&outbuf[i+2]); /* chan1 = (outbuf[i]<<8)|outbuf[i+1]; chan2 = (outbuf[i+2]<<8)|outbuf[i+3]; chan1t = bswap_16(*((int16_t *)&outbuf[i])); chan2t = bswap_16(*((int16_t *)&outbuf[i+2])); if( chan1 != chan1t ) fprintf(stdout,"ungleich %d %d %d %d\n",chan1,chan1t,chan2,chan2t); */ if( (abs(chan1)+abs(chan2)) < CUT_VAL ) { lowvalcount++; if( lowvalcount > MIN_LOWVALS ) havesilence = true; } else { if( lowvalcount > MIN_LOWVALS ) havesilence = true; lowvalcount = 0; } } src += 4; //fprintf(stdout,"%.2X %.2X %.2X %.2X\n",outbuf[i],outbuf[i+1],outbuf[i+2],outbuf[i+3]); } /* if( havesilince || (lowvalcount > 3) ) { double videooffset; videooffset = audiopts-audiobasepts; videooffset /= 90000.0; double sampleoffset; sampleoffset = audiosamples; sampleoffset /=48000.0; int min = sampleoffset/60; int sec=sampleoffset; sec%=60; int min2 = (sampleoffset-lastsampleoffset)/60; int sec2 = (sampleoffset-lastsampleoffset); sec2%=60; lastsampleoffset = sampleoffset; fprintf(stdout,"found %d low values within %d total values at %5.2f sampleofset %8.2f (%0.2d:%0.2d) diff %0.2d:%0.2d\n",lowvalcount,out_size/4,videooffset,sampleoffset,min,sec,min2,sec2); } */ /* if a frame has been decoded, output it */ //fwrite(outbuf, 1, out_size, outfile); #ifdef PLAY_AUDIO audioRingBuffer->Put(outbuf,out_size); // SDL_PauseAudio(0); while( audioRingBuffer->Available() > 12000 ) SDL_Delay(10); #endif /* if( (audio_len+out_size) > AUDIO_BUF_SIZE ) { // play audio audio_offset = 0; SDL_PauseAudio(0); while( audio_len > 0 ) SDL_Delay(10); SDL_PauseAudio(1); } // move data to audio_buffer memmove(audio_buff+audio_len,outbuf,out_size); audio_len += out_size; //SDL_Delay(100); */ } size -= len; inbuf_ptr += len; }
/** buffer management callback function for AMR decoding in new standard * of FFmpeg library */ void omx_amr_audiodec_component_BufferMgmtCallback(OMX_COMPONENTTYPE *openmaxStandComp, OMX_BUFFERHEADERTYPE* pInputBuffer, OMX_BUFFERHEADERTYPE* pOutputBuffer) { omx_amr_audiodec_component_PrivateType* omx_amr_audiodec_component_Private = openmaxStandComp->pComponentPrivate; int output_length, len; OMX_ERRORTYPE err; DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n",__func__); if(omx_amr_audiodec_component_Private->isFirstBuffer == OMX_TRUE) { omx_amr_audiodec_component_Private->isFirstBuffer = OMX_FALSE; if((pInputBuffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) == OMX_BUFFERFLAG_CODECCONFIG) { omx_amr_audiodec_component_Private->extradata_size = pInputBuffer->nFilledLen; if(omx_amr_audiodec_component_Private->extradata_size > 0) { if(omx_amr_audiodec_component_Private->extradata) { free(omx_amr_audiodec_component_Private->extradata); } omx_amr_audiodec_component_Private->extradata = malloc(pInputBuffer->nFilledLen); memcpy(omx_amr_audiodec_component_Private->extradata, pInputBuffer->pBuffer,pInputBuffer->nFilledLen); } DEBUG(DEB_ALL_MESS, "In %s Received First Buffer Extra Data Size=%d\n",__func__,(int)pInputBuffer->nFilledLen); pInputBuffer->nFlags = 0x0; pInputBuffer->nFilledLen = 0; } if (!omx_amr_audiodec_component_Private->avcodecReady) { err = omx_amr_audiodec_component_ffmpegLibInit(omx_amr_audiodec_component_Private); if (err != OMX_ErrorNone) { DEBUG(DEB_LEV_ERR, "In %s omx_amr_audiodec_component_ffmpegLibInit Failed\n",__func__); return; } omx_amr_audiodec_component_Private->avcodecReady = OMX_TRUE; } if(pInputBuffer->nFilledLen == 0) { return; } } if(omx_amr_audiodec_component_Private->avcodecReady == OMX_FALSE) { DEBUG(DEB_LEV_ERR, "In %s avcodec Not Ready \n",__func__); return; } if(omx_amr_audiodec_component_Private->isNewBuffer) { omx_amr_audiodec_component_Private->isNewBuffer = 0; } pOutputBuffer->nFilledLen = 0; pOutputBuffer->nOffset=0; /** resetting output length to a predefined value */ output_length = OUTPUT_LEN_STANDARD_FFMPEG; #if FFMPEG_DECODER_VERSION >= 2 len = avcodec_decode_audio2(omx_amr_audiodec_component_Private->avCodecContext, (short*)(pOutputBuffer->pBuffer), &output_length, pInputBuffer->pBuffer, pInputBuffer->nFilledLen); #else len = avcodec_decode_audio(omx_amr_audiodec_component_Private->avCodecContext, (short*)(pOutputBuffer->pBuffer), &output_length, pInputBuffer->pBuffer, pInputBuffer->nFilledLen); #endif if((omx_amr_audiodec_component_Private->pAudioPcmMode.nSamplingRate != omx_amr_audiodec_component_Private->avCodecContext->sample_rate) || ( omx_amr_audiodec_component_Private->pAudioPcmMode.nChannels!=omx_amr_audiodec_component_Private->avCodecContext->channels)) { DEBUG(DEB_LEV_FULL_SEQ, "---->Sending Port Settings Change Event\n"); //switch for different audio formats---parameter settings accordingly switch(omx_amr_audiodec_component_Private->audio_coding_type) { /*Update Parameter which has changed from avCodecContext*/ case OMX_AUDIO_CodingAMR : /*pAudioAMR is for input port AMR data*/ omx_amr_audiodec_component_Private->pAudioAmr.nChannels = omx_amr_audiodec_component_Private->avCodecContext->channels; omx_amr_audiodec_component_Private->pAudioAmr.nBitRate = omx_amr_audiodec_component_Private->avCodecContext->bit_rate; break; default : DEBUG(DEB_LEV_ERR, "Audio format other than AMR not supported\nCodec type %lu not found\n",omx_amr_audiodec_component_Private->audio_coding_type); break; }//end of switch /*pAudioPcmMode is for output port PCM data*/ omx_amr_audiodec_component_Private->pAudioPcmMode.nChannels = omx_amr_audiodec_component_Private->avCodecContext->channels; if(omx_amr_audiodec_component_Private->avCodecContext->sample_fmt==SAMPLE_FMT_S16) omx_amr_audiodec_component_Private->pAudioPcmMode.nBitPerSample = 16; else if(omx_amr_audiodec_component_Private->avCodecContext->sample_fmt==SAMPLE_FMT_S32) omx_amr_audiodec_component_Private->pAudioPcmMode.nBitPerSample = 32; omx_amr_audiodec_component_Private->pAudioPcmMode.nSamplingRate = omx_amr_audiodec_component_Private->avCodecContext->sample_rate; /*Send Port Settings changed call back*/ (*(omx_amr_audiodec_component_Private->callbacks->EventHandler)) (openmaxStandComp, omx_amr_audiodec_component_Private->callbackData, OMX_EventPortSettingsChanged, /* The command was completed */ 0, 1, /* This is the output port index */ NULL); } if(len < 0) { DEBUG(DEB_LEV_ERR,"error in packet decoding in audio dcoder \n"); } else { /*If output is max length it might be an error, so Don't send output buffer*/ if((output_length != OUTPUT_LEN_STANDARD_FFMPEG) || (output_length <= pOutputBuffer->nAllocLen)) { pOutputBuffer->nFilledLen += output_length; } pInputBuffer->nFilledLen = 0; omx_amr_audiodec_component_Private->isNewBuffer = 1; } /** return output buffer */ }
/***************************************************************************** * DecodeAudio: Called to decode one frame *****************************************************************************/ aout_buffer_t * DecodeAudio ( decoder_t *p_dec, block_t **pp_block ) { decoder_sys_t *p_sys = p_dec->p_sys; int i_used, i_output; aout_buffer_t *p_buffer; block_t *p_block; if( !pp_block || !*pp_block ) return NULL; p_block = *pp_block; if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) { block_Release( p_block ); avcodec_flush_buffers( p_sys->p_context ); p_sys->i_samples = 0; date_Set( &p_sys->end_date, 0 ); if( p_sys->i_codec_id == CODEC_ID_MP2 || p_sys->i_codec_id == CODEC_ID_MP3 ) p_sys->i_reject_count = 3; return NULL; } if( p_sys->i_samples > 0 ) { /* More data */ p_buffer = SplitBuffer( p_dec ); if( !p_buffer ) block_Release( p_block ); return p_buffer; } if( !date_Get( &p_sys->end_date ) && !p_block->i_pts ) { /* We've just started the stream, wait for the first PTS. */ block_Release( p_block ); return NULL; } if( p_block->i_buffer <= 0 ) { block_Release( p_block ); return NULL; } if( (p_block->i_flags & BLOCK_FLAG_PRIVATE_REALLOCATED) == 0 ) { *pp_block = p_block = block_Realloc( p_block, 0, p_block->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE ); if( !p_block ) return NULL; p_block->i_buffer -= FF_INPUT_BUFFER_PADDING_SIZE; memset( &p_block->p_buffer[p_block->i_buffer], 0, FF_INPUT_BUFFER_PADDING_SIZE ); p_block->i_flags |= BLOCK_FLAG_PRIVATE_REALLOCATED; } do { i_output = __MAX( p_block->i_buffer, p_sys->i_output_max ); if( i_output > p_sys->i_output_max ) { /* Grow output buffer if necessary (eg. for PCM data) */ p_sys->p_output = av_realloc( p_sys->p_output, i_output ); } #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 52, 0, 0 ) i_used = avcodec_decode_audio2( p_sys->p_context, (int16_t*)p_sys->p_output, &i_output, p_block->p_buffer, p_block->i_buffer ); #else i_used = avcodec_decode_audio( p_sys->p_context, (int16_t*)p_sys->p_output, &i_output, p_block->p_buffer, p_block->i_buffer ); #endif if( i_used < 0 || i_output < 0 ) { if( i_used < 0 ) msg_Warn( p_dec, "cannot decode one frame (%zu bytes)", p_block->i_buffer ); block_Release( p_block ); return NULL; } else if( (size_t)i_used > p_block->i_buffer ) { i_used = p_block->i_buffer; } p_block->i_buffer -= i_used; p_block->p_buffer += i_used; } while( p_block->i_buffer > 0 && i_output <= 0 ); if( p_sys->p_context->channels <= 0 || p_sys->p_context->channels > 8 || p_sys->p_context->sample_rate <= 0 ) { msg_Warn( p_dec, "invalid audio properties channels count %d, sample rate %d", p_sys->p_context->channels, p_sys->p_context->sample_rate ); block_Release( p_block ); return NULL; } if( p_dec->fmt_out.audio.i_rate != (unsigned int)p_sys->p_context->sample_rate ) { date_Init( &p_sys->end_date, p_sys->p_context->sample_rate, 1 ); date_Set( &p_sys->end_date, p_block->i_pts ); } /* **** Set audio output parameters **** */ SetupOutputFormat( p_dec, true ); if( p_block->i_pts != 0 && p_block->i_pts != date_Get( &p_sys->end_date ) ) { date_Set( &p_sys->end_date, p_block->i_pts ); } p_block->i_pts = 0; /* **** Now we can output these samples **** */ p_sys->i_samples = i_output / (p_dec->fmt_out.audio.i_bitspersample / 8) / p_sys->p_context->channels; p_sys->p_samples = p_sys->p_output; /* Silent unwanted samples */ if( p_sys->i_reject_count > 0 ) { memset( p_sys->p_output, 0, i_output ); p_sys->i_reject_count--; } p_buffer = SplitBuffer( p_dec ); if( !p_buffer ) block_Release( p_block ); return p_buffer; }