int static decodeFrame(AVCodecContext* codecCtx, uint8_t* buffer, int bufferSize, packetQueue* queue) { static AVPacket* packet = NULL; static int packetSize = 0; static uint8_t* packetData = NULL; //Get a packet. if(packetSize == 0) { packet = queue->get(); if(!packet) return -1; packetSize = packet->size; packetData = packet->data; } int dataSize = bufferSize; int framesRead = avcodec_decode_audio2(codecCtx, (int16_t*)buffer, &dataSize, packetData, packetSize); if(framesRead < 0) { //Skip this frame if we have an error. packetSize = 0; return 0; } packetSize -= framesRead; packetData -= framesRead; return dataSize; }
/* Decode one audio frame and returns its uncompressed size */ static int audio_decode_frame(priv_t * ffmpeg, uint8_t *audio_buf, int buf_size) { AVPacket *pkt = &ffmpeg->audio_pkt; int len1, data_size; for (;;) { /* NOTE: the audio packet can contain several frames */ while (ffmpeg->audio_pkt_size > 0) { data_size = buf_size; len1 = avcodec_decode_audio2(ffmpeg->audio_st->codec, (int16_t *)audio_buf, &data_size, ffmpeg->audio_pkt_data, ffmpeg->audio_pkt_size); if (len1 < 0) { /* if error, we skip the frame */ ffmpeg->audio_pkt_size = 0; break; } ffmpeg->audio_pkt_data += len1; ffmpeg->audio_pkt_size -= len1; if (data_size <= 0) continue; return data_size; } ffmpeg->audio_pkt_data = pkt->data; ffmpeg->audio_pkt_size = pkt->size; } }
int audio_decode_frame(AVCodecContext *aCodecCtx, uint8_t *audio_buf, int buf_size) { static AVPacket pkt; static uint8_t *audio_pkt_data = NULL; static int audio_pkt_size = 0; int len1, data_size; for(;;) { if(packet_queue_get(audioq, &pkt, 1) < 0) { return -1; } audio_pkt_data = pkt.data; audio_pkt_size = pkt.size; while(audio_pkt_size > 0) { data_size = buf_size; len1 = avcodec_decode_audio2(aCodecCtx, (int16_t *)audio_buf, &data_size,audio_pkt_data, audio_pkt_size); if(len1 < 0) { audio_pkt_size = 0; break; } audio_pkt_data += len1; audio_pkt_size -= len1; if(data_size <= 0) { continue; } return data_size; } if(pkt.data) av_free_packet(&pkt); } }
Omm::AvStream::Frame* FFmpegStreamInfo::decodeAudioFrame(Omm::AvStream::Frame* pFrame) { _pDecodedAudioFrame->_size = _maxDecodedAudioFrameSize; uint8_t* inBuffer = (uint8_t*)pFrame->data(); int inBufferSize = pFrame->size(); // TODO: does this while loop work for uncompressed packets ? // (it's only needed for e.g. .wav, where on packet contains multiple uncompressed frames while(inBufferSize > 0) { LOG(ffmpeg, trace, "ffmpeg::avcodec_decode_audio2() ..."); int bytesConsumed = avcodec_decode_audio2(_pAvCodecContext, (int16_t*)_pDecodedAudioFrame->_data, &_pDecodedAudioFrame->_size, inBuffer, inBufferSize); LOG(ffmpeg, debug, "ffmpeg::avcodec_decode_audio2() frame size: " + Poco::NumberFormatter::format(inBufferSize) + ", bytes consumed: " + Poco::NumberFormatter::format(bytesConsumed) + ", decoded size: " +\ Poco::NumberFormatter::format(_pDecodedAudioFrame->size()) ); if (bytesConsumed < 0 || _pDecodedAudioFrame->size() == 0) { LOGNS(Omm::AvStream, avstream, warning, "decoding audio frame in stream " + getName() + " failed, discarding frame."); delete pFrame; return 0; } inBuffer += bytesConsumed; inBufferSize -= bytesConsumed; } return _pDecodedAudioFrame; }
int audio_decode_frame(VideoState *is, uint8_t *audio_buf, int buf_size, double *pts_ptr) { int len1, data_size, n; AVPacket *pkt = &is->audio_pkt; double pts; for(;;) { while(is->audio_pkt_size > 0) { data_size = buf_size; len1 = avcodec_decode_audio2(is->audio_st->codec, (int16_t *)audio_buf, &data_size, is->audio_pkt_data, is->audio_pkt_size); if(len1 < 0) { /* if error, skip frame */ is->audio_pkt_size = 0; break; } is->audio_pkt_data += len1; is->audio_pkt_size -= len1; if(data_size <= 0) { /* No data yet, get more frames */ continue; } pts = is->audio_clock; *pts_ptr = pts; n = 2 * is->audio_st->codec->channels; is->audio_clock += (double)data_size / (double)(n * is->audio_st->codec->sample_rate); /* We have data, return it and come back for more later */ return data_size; } if(pkt->data) av_free_packet(pkt); if(is->quit) { return -1; } /* next packet */ if(packet_queue_get(&is->audioq, pkt, 1) < 0) { return -1; } if(pkt->data == flush_pkt.data) { avcodec_flush_buffers(is->audio_st->codec); continue; } is->audio_pkt_data = pkt->data; is->audio_pkt_size = pkt->size; /* if update, update the audio clock w/pts */ if(pkt->pts != AV_NOPTS_VALUE) { is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts; } } }
void decodeFrame() throw(PacketDecodeException) { if (!hasPacket()) throw PacketDecodeException(); int dataSize = sampleBufferAlloc; int used = #if (LIBAVCODEC_VERSION_MAJOR >= 53) avcodec_decode_audio3( pCodecCtx, (int16_t*)sampleBufferAligned, &dataSize, &packet); #else avcodec_decode_audio2( pCodecCtx, (int16_t*)sampleBufferAligned, &dataSize, packetBuffer, packetBufferSize); #endif if (used < 0) throw PacketDecodeException(); #if (LIBAVCODEC_VERSION_MAJOR >= 53) if ((size_t)used > packet.size) used = packet.size; (char*&)(packet.data) += used; packet.size -= used; #else if ((size_t)used > packetBufferSize) used = packetBufferSize; (char*&)packetBuffer += used; packetBufferSize -= used; #endif if (dataSize < 0) dataSize = 0; sampleBuffer = sampleBufferAligned; sampleBufferStart += sampleBufferSize; sampleBufferSize = dataSize / sampleSize; if (sampleBufferStart + sampleBufferSize > streamSize) streamSize = sampleBufferStart + sampleBufferSize; }
int CFFMPEGLoader::ReadAudioData(unsigned char *buf, const UINT &buf_size) { int len1, data_size; for(; iPKTAudioLength>0;) { while(audio_pkt_size > 0 && audio_pkt_data) { data_size = buf_size; bLock=true; len1 = avcodec_decode_audio2(pACodecCon, (int16_t *)buf, &data_size, audio_pkt_data, audio_pkt_size); bLock=false; if(len1 < 0) { /* if error, skip frame */ audio_pkt_size = 0; break; } audio_pkt_data += len1; audio_pkt_size -= len1; if(data_size <= 0) { /* No data yet, get more frames */ continue; } /* We have data, return it and come back for more later */ return data_size; } bLock=true; if(pktLastAudio[0].data) av_free_packet(&pktLastAudio[0]); iPKTAudioLength--; for(UINT i=0; i<iPKTAudioLength; i++) pktLastAudio[i]=pktLastAudio[i+1]; pktLastAudio[iPKTAudioLength].data=NULL; bLock=false; if(iPKTAudioLength<1) { return -1; } audio_pkt_data = pktLastAudio[0].data; audio_pkt_size = pktLastAudio[0].size; } return -1; }
int audio_decode_frame(AVCodecContext *aCodecCtx, uint8_t *audio_buf, int buf_size) { static AVPacket pkt; static uint8_t *audio_pkt_data = NULL; static int audio_pkt_size = 0; int len1, data_size; AVFrame *pFrame = 0; pFrame = avcodec_alloc_frame(); int got; for(;;) { while(audio_pkt_size > 0) { data_size = buf_size; avcodec_decode_audio4(aCodecCtx, pFrame, &got, &packet); len1 = avcodec_decode_audio2(aCodecCtx, (int16_t *)audio_buf, &data_size, audio_pkt_data, audio_pkt_size); if(len1 < 0) { /* if error, skip frame */ audio_pkt_size = 0; break; } audio_pkt_data += len1; audio_pkt_size -= len1; if(data_size <= 0) { /* No data yet, get more frames */ continue; } /* We have data, return it and come back for more later */ return data_size; } if(pkt.data) av_free_packet(&pkt); if(quit) { return -1; } if(packet_queue_get(&audioq, &pkt, 1) < 0) { return -1; } audio_pkt_data = pkt.data; audio_pkt_size = pkt.size; } }
static int decode_audio(AVCodecContext *avctx, int16_t *samples, int *frame_size_ptr, const uint8_t *buf, int buf_size) { #if LIBAVCODEC_VERSION_MAJOR >= 53 || (LIBAVCODEC_VERSION_MAJOR==52 && LIBAVCODEC_VERSION_MINOR>=32) // following code segment copied from ffmpeg's avcodec_decode_audio2() // implementation to avoid warnings about deprecated function usage. AVPacket avpkt; av_init_packet(&avpkt); avpkt.data = const_cast<uint8_t *>(buf); avpkt.size = buf_size; return avcodec_decode_audio3(avctx, samples, frame_size_ptr, &avpkt); #else // fallback for older versions of ffmpeg that don't have avcodec_decode_audio3. return avcodec_decode_audio2(avctx, samples, frame_size_ptr, buf, buf_size); #endif }
quint8 *DataSource::decodeAudio(AVCodecContext *codecCtx, AVPacket *packet, int *size) { uint8_t *sampleBuf = NULL; int decodeSize = 0; *size = AVCODEC_MAX_AUDIO_FRAME_SIZE; sampleBuf = (uint8_t *)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE * sizeof(uint8_t)); decodeSize = avcodec_decode_audio2(codecCtx, (int16_t *)sampleBuf, size, packet->data, packet->size); if (*size < 0) { free(sampleBuf); DPRINT("can ont decode data."); return NULL; } return sampleBuf; }
int audio_decode_frame(AVCodecContext *aCodecCtx, uint8_t *audio_buf, int buf_size) { static AVPacket pkt; static uint8_t *audio_pkt_data = NULL; static int audio_pkt_size = 0; // len1: number of bytes used to decompress // data_size: out put buffer size int len1, data_size; for(;;) { while(audio_pkt_size > 0) { data_size = buf_size; // @see http://dranger.com/ffmpeg/functions.html#avcodec_decode_audio2 len1 = avcodec_decode_audio2(aCodecCtx, (int16_t *)audio_buf, &data_size, audio_pkt_data, audio_pkt_size); if(len1 < 0) { /* if error, skip frame */ audio_pkt_size = 0; break; } audio_pkt_data += len1; audio_pkt_size -= len1; if(data_size <= 0) { /* No data yet, get more frames */ continue; } /* We have data, return it and come back for more later */ return data_size; } if(pkt.data) av_free_packet(&pkt); if(quit) { return -1; } if(packet_queue_get(&audioq, &pkt, 1) < 0) { return -1; } audio_pkt_data = pkt.data; audio_pkt_size = pkt.size; } }
int VideoLayer::decode_audio_packet(int *data_size) { int datasize, res; datasize = AVCODEC_MAX_AUDIO_FRAME_SIZE; //+ FF_INPUT_BUFFER_PADDING_SIZE; #if LIBAVCODEC_VERSION_MAJOR < 53 res = avcodec_decode_audio2(audio_codec_ctx, (int16_t *)audio_buf, &datasize, pkt.data, pkt.size); #else res = avcodec_decode_audio3(audio_codec_ctx, (int16_t *)audio_buf, &datasize, &pkt); #endif if (data_size) *data_size = datasize; if(res < 0) { /* if error, skip frame */ pkt.size = 0; return 0; } /* We have data, return it and come back for more later */ return res; }
int audio_decode_frame(VideoState *is, uint8_t *audio_buf, int buf_size) { int len1, data_size; AVPacket *pkt = &is->audio_pkt; for(;;) { while(is->audio_pkt_size > 0) { data_size = buf_size; len1 = avcodec_decode_audio2(is->audio_st->codec, (int16_t *)audio_buf, &data_size, is->audio_pkt_data, is->audio_pkt_size); if(len1 < 0) { /* if error, skip frame */ is->audio_pkt_size = 0; break; } is->audio_pkt_data += len1; is->audio_pkt_size -= len1; if(data_size <= 0) { /* No data yet, get more frames */ continue; } /* We have data, return it and come back for more later */ return data_size; } if(pkt->data) av_free_packet(pkt); if(is->quit) { return -1; } /* next packet */ if(packet_queue_get(&is->audioq, pkt, 1) < 0) { return -1; } is->audio_pkt_data = pkt->data; is->audio_pkt_size = pkt->size; } }
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_audio2(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 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; }
int main(int argc, char **argv) { AVFormatContext *formatCtx = NULL; AVCodecContext *codecCtx = NULL; AVCodec *codec = NULL; AVPacket packet; uint8_t sample_buf[AVCODEC_MAX_AUDIO_FRAME_SIZE] = {0}; int buf_size = sizeof(sample_buf); int decodec_size = 0; int len = 0; char **input_files = NULL; int opt = 0; int count = 0; int i = 0; int error = 0; pa_simple *ps = NULL; pa_sample_spec pss= {0}; while ((opt = getopt(argc, argv, "d:i:")) != -1) { switch (opt) { case 'd': count = iter_dir(&input_files, optarg); chdir(optarg); break; case 'i': input_files = (char **)malloc(sizeof(char **)); input_files[0] = (char *)malloc(strlen(optarg) + 1); memset(input_files[0], 0, strlen(optarg + 1)); strcpy(input_files[0], optarg); count = 1; break; default: printf("mp3player usage:\n" "\t-d [directory] set input directory\n" "\t-i [file] set input file\n"); return -1; } } av_register_all(); for (i = 0; i < count; i++) { printf("play audio file: %s\n", input_files[i]); if (av_open_input_file(&formatCtx, input_files[i], NULL, 0, NULL) != 0) { fprintf(stderr, "can not open input file.\n"); return -1; } if (av_find_stream_info(formatCtx) < 0) { fprintf(stderr, "can not find stream info.\n"); return -1; } dump_format(formatCtx, 0, input_files[i], 0); printf("streams: %d\n", formatCtx->nb_streams); codecCtx = formatCtx->streams[0]->codec; switch (codecCtx->sample_fmt) { case SAMPLE_FMT_S16: pss.format = PA_SAMPLE_S16LE; break; case SAMPLE_FMT_U8: pss.format = PA_SAMPLE_U8; break; default: fprintf(stderr, "can not support this format for dsp.\n"); return -1; } pss.channels = codecCtx->channels; pss.rate = codecCtx->sample_rate; printf("channels: %d\n", pss.channels); printf("rate: %d\n", pss.rate); printf("format: %d\n", pss.format); ps = pa_simple_new(NULL, input_files[i], PA_STREAM_PLAYBACK, NULL, "Music", &pss, NULL, NULL, &error); if (ps == NULL) { fprintf(stderr, "can not get new pulase stream: %s\n", pa_strerror(error)); return -1; } codec = avcodec_find_decoder(codecCtx->codec_id); if (codec == NULL) { fprintf(stderr, "can not find codec.\n"); return -1; } if (avcodec_open(codecCtx, codec) < 0) { fprintf(stderr, "can not open codec.\n"); return -1; } while (av_read_frame(formatCtx, &packet) >= 0) { buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; decodec_size = avcodec_decode_audio2(codecCtx, (int16_t *)sample_buf, &buf_size, packet.data, packet.size); if (decodec_size < 0) { fprintf(stderr, "can not decode\n"); return -1; } len = pa_simple_write(ps, sample_buf, buf_size, &error); if (len < 0) { fprintf(stderr, "pa_sample_write() failed: %s\n", pa_strerror(error)); return -1; } av_free_packet(&packet); } avcodec_close(codecCtx); av_close_input_file(formatCtx); pa_simple_free(ps); } for (i = 0; i < count; i++) { free(input_files[count]); } free(input_files); return 0; }
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; int nbChunk; *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) { nbChunk=(_tail-_head)/_blockalign; pout=SCRATCH_PAD_SIZE; out=avcodec_decode_audio2(_context,(int16_t *)scratchPad, &pout,_buffer+_head,nbChunk*_blockalign); if(out<0) { printf( " *** WMA decoding error (%u)***\n",_blockalign); _head+=1; // Try skipping some bytes continue; } if(pout>=SCRATCH_PAD_SIZE) { printf("Produced : %u, buffer %u,in%u\n",pout,SCRATCH_PAD_SIZE,_tail-_head); ADM_assert(0); } if(_context->codec_id == CODEC_ID_NELLYMOSER) { // Hack, it returns inconsistent size out=nbChunk*_blockalign; } _head+=out; // consumed bytes pout>>=1; *nbOut+=pout; run16=(int16_t *)scratchPad; for(int i=0;i<pout;i++) { *outptr++=((float)run16[i])/32767.; } if(_channels>=5 ) { CHANNEL_TYPE *p_ch_type = channelMapping; #define DOIT(x,y) if(_context->channel_layout & CH_##x) *(p_ch_type++)=CHTYP_##y; if(_context->codec_id == CODEC_ID_DTS) { DOIT(FRONT_LEFT,FRONT_LEFT); DOIT(FRONT_RIGHT,FRONT_RIGHT); DOIT(FRONT_CENTER,FRONT_CENTER); DOIT(SIDE_LEFT,REAR_LEFT); DOIT(SIDE_RIGHT,REAR_RIGHT); DOIT(LOW_FREQUENCY,LFE); }else { DOIT(LOW_FREQUENCY,LFE); DOIT(FRONT_LEFT,FRONT_LEFT); DOIT(FRONT_CENTER,FRONT_CENTER); DOIT(FRONT_RIGHT,FRONT_RIGHT); DOIT(SIDE_LEFT,REAR_LEFT); DOIT(SIDE_RIGHT,REAR_RIGHT); } } } return 1; }
static BOOL tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const BYTE *data, UINT32 data_size, UINT32 extensions) { TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; int len; int frame_size; UINT32 src_size; const BYTE *src; BYTE *dst; int dst_offset; #if 0 WLog_DBG(TAG, ("tsmf_ffmpeg_decode_audio: data_size %d", data_size)); int i; for(i = 0; i < data_size; i++) { WLog_DBG(TAG, ("%02X ", data[i])); if (i % 16 == 15) WLog_DBG(TAG, ("\n")); } #endif if (mdecoder->decoded_size_max == 0) mdecoder->decoded_size_max = MAX_AUDIO_FRAME_SIZE + 16; mdecoder->decoded_data = calloc(1, mdecoder->decoded_size_max); if (!mdecoder->decoded_data) return FALSE; /* align the memory for SSE2 needs */ dst = (BYTE *)(((uintptr_t) mdecoder->decoded_data + 15) & ~ 0x0F); dst_offset = dst - mdecoder->decoded_data; src = data; src_size = data_size; while(src_size > 0) { /* Ensure enough space for decoding */ if (mdecoder->decoded_size_max - mdecoder->decoded_size < MAX_AUDIO_FRAME_SIZE) { BYTE *tmp_data; tmp_data = realloc(mdecoder->decoded_data, mdecoder->decoded_size_max * 2 + 16); if (!tmp_data) return FALSE; mdecoder->decoded_size_max = mdecoder->decoded_size_max * 2 + 16; mdecoder->decoded_data = tmp_data; dst = (BYTE *)(((uintptr_t)mdecoder->decoded_data + 15) & ~ 0x0F); if (dst - mdecoder->decoded_data != dst_offset) { /* re-align the memory if the alignment has changed after realloc */ memmove(dst, mdecoder->decoded_data + dst_offset, mdecoder->decoded_size); dst_offset = dst - mdecoder->decoded_data; } dst += mdecoder->decoded_size; } frame_size = mdecoder->decoded_size_max - mdecoder->decoded_size; #if LIBAVCODEC_VERSION_MAJOR < 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR <= 20) len = avcodec_decode_audio2(mdecoder->codec_context, (int16_t *) dst, &frame_size, src, src_size); #else { #if LIBAVCODEC_VERSION_MAJOR < 55 AVFrame *decoded_frame = avcodec_alloc_frame(); #else AVFrame *decoded_frame = av_frame_alloc(); #endif int got_frame = 0; AVPacket pkt; av_init_packet(&pkt); pkt.data = (BYTE *) src; pkt.size = src_size; len = avcodec_decode_audio4(mdecoder->codec_context, decoded_frame, &got_frame, &pkt); if (len >= 0 && got_frame) { frame_size = av_samples_get_buffer_size(NULL, mdecoder->codec_context->channels, decoded_frame->nb_samples, mdecoder->codec_context->sample_fmt, 1); memcpy(dst, decoded_frame->data[0], frame_size); } av_free(decoded_frame); } #endif if (len <= 0 || frame_size <= 0) { WLog_ERR(TAG, "error decoding"); break; } src += len; src_size -= len; mdecoder->decoded_size += frame_size; dst += frame_size; } if (mdecoder->decoded_size == 0) { free(mdecoder->decoded_data); mdecoder->decoded_data = NULL; } else if (dst_offset) { /* move the aligned decoded data to original place */ memmove(mdecoder->decoded_data, mdecoder->decoded_data + dst_offset, mdecoder->decoded_size); } DEBUG_TSMF("data_size %d decoded_size %d", data_size, mdecoder->decoded_size); return TRUE; }
int decode_audio_file(ChromaprintContext *chromaprint_ctx, int16_t *buffer1, int16_t *buffer2, const char *file_name, int max_length, int *duration) { int i, ok = 0, remaining, length, consumed, buffer_size, codec_ctx_opened = 0; AVFormatContext *format_ctx = NULL; AVCodecContext *codec_ctx = NULL; AVCodec *codec = NULL; AVStream *stream = NULL; AVPacket packet, packet_temp; #ifdef HAVE_AV_AUDIO_CONVERT AVAudioConvert *convert_ctx = NULL; #endif int16_t *buffer; if (!strcmp(file_name, "-")) { file_name = "pipe:0"; } #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 2, 0) if (av_open_input_file(&format_ctx, file_name, NULL, 0, NULL) != 0) { #else if (avformat_open_input(&format_ctx, file_name, NULL, NULL) != 0) { #endif fprintf(stderr, "ERROR: couldn't open the file\n"); goto done; } if (av_find_stream_info(format_ctx) < 0) { fprintf(stderr, "ERROR: couldn't find stream information in the file\n"); goto done; } for (i = 0; i < format_ctx->nb_streams; i++) { codec_ctx = format_ctx->streams[i]->codec; if (codec_ctx && codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) { stream = format_ctx->streams[i]; break; } } if (!stream) { fprintf(stderr, "ERROR: couldn't find any audio stream in the file\n"); goto done; } codec = avcodec_find_decoder(codec_ctx->codec_id); if (!codec) { fprintf(stderr, "ERROR: unknown codec\n"); goto done; } if (avcodec_open(codec_ctx, codec) < 0) { fprintf(stderr, "ERROR: couldn't open the codec\n"); goto done; } codec_ctx_opened = 1; if (codec_ctx->channels <= 0) { fprintf(stderr, "ERROR: no channels found in the audio stream\n"); goto done; } if (codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16) { #ifdef HAVE_AV_AUDIO_CONVERT convert_ctx = av_audio_convert_alloc(AV_SAMPLE_FMT_S16, codec_ctx->channels, codec_ctx->sample_fmt, codec_ctx->channels, NULL, 0); if (!convert_ctx) { fprintf(stderr, "ERROR: couldn't create sample format converter\n"); goto done; } #else fprintf(stderr, "ERROR: unsupported sample format\n"); goto done; #endif } *duration = stream->time_base.num * stream->duration / stream->time_base.den; av_init_packet(&packet); av_init_packet(&packet_temp); remaining = max_length * codec_ctx->channels * codec_ctx->sample_rate; chromaprint_start(chromaprint_ctx, codec_ctx->sample_rate, codec_ctx->channels); while (1) { if (av_read_frame(format_ctx, &packet) < 0) { break; } packet_temp.data = packet.data; packet_temp.size = packet.size; while (packet_temp.size > 0) { buffer_size = BUFFER_SIZE; #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52, 23, 0) consumed = avcodec_decode_audio2(codec_ctx, buffer1, &buffer_size, packet_temp.data, packet_temp.size); #else consumed = avcodec_decode_audio3(codec_ctx, buffer1, &buffer_size, &packet_temp); #endif if (consumed < 0) { break; } packet_temp.data += consumed; packet_temp.size -= consumed; if (buffer_size <= 0) { if (buffer_size < 0) { fprintf(stderr, "WARNING: size returned from avcodec_decode_audioX is too small\n"); } continue; } if (buffer_size > BUFFER_SIZE) { fprintf(stderr, "WARNING: size returned from avcodec_decode_audioX is too large\n"); continue; } #ifdef HAVE_AV_AUDIO_CONVERT if (convert_ctx) { const void *ibuf[6] = { buffer1 }; void *obuf[6] = { buffer2 }; #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51, 8, 0) int istride[6] = { av_get_bits_per_sample_format(codec_ctx->sample_fmt) / 8 }; #else int istride[6] = { av_get_bytes_per_sample(codec_ctx->sample_fmt) }; #endif int ostride[6] = { 2 }; int len = buffer_size / istride[0]; if (av_audio_convert(convert_ctx, obuf, ostride, ibuf, istride, len) < 0) { break; } buffer = buffer2; buffer_size = len * ostride[0]; } else { buffer = buffer1; } #else buffer = buffer1; #endif length = MIN(remaining, buffer_size / 2); if (!chromaprint_feed(chromaprint_ctx, buffer, length)) { fprintf(stderr, "ERROR: fingerprint calculation failed\n"); goto done; } if (max_length) { remaining -= length; if (remaining <= 0) { goto finish; } } } if (packet.data) { av_free_packet(&packet); } } finish: if (!chromaprint_finish(chromaprint_ctx)) { fprintf(stderr, "ERROR: fingerprint calculation failed\n"); goto done; } ok = 1; done: if (codec_ctx_opened) { avcodec_close(codec_ctx); } if (format_ctx) { av_close_input_file(format_ctx); } #ifdef HAVE_AV_AUDIO_CONVERT if (convert_ctx) { av_audio_convert_free(convert_ctx); } #endif return ok; } int fpcalc_main(int argc, char **argv) { int i, j, max_length = 120, num_file_names = 0, raw = 0, raw_fingerprint_size, duration; int16_t *buffer1, *buffer2; int32_t *raw_fingerprint; char *file_name, *fingerprint, **file_names; ChromaprintContext *chromaprint_ctx; int algo = CHROMAPRINT_ALGORITHM_DEFAULT; file_names = malloc(argc * sizeof(char *)); for (i = 1; i < argc; i++) { char *arg = argv[i]; if (!strcmp(arg, "-length") && i + 1 < argc) { max_length = atoi(argv[++i]); } else if (!strcmp(arg, "-version") || !strcmp(arg, "-v")) { printf("fpcalc version %s\n", chromaprint_get_version()); return 0; } else if (!strcmp(arg, "-raw")) { raw = 1; } else if (!strcmp(arg, "-algo") && i + 1 < argc) { const char *v = argv[++i]; if (!strcmp(v, "test1")) { algo = CHROMAPRINT_ALGORITHM_TEST1; } else if (!strcmp(v, "test2")) { algo = CHROMAPRINT_ALGORITHM_TEST2; } else if (!strcmp(v, "test3")) { algo = CHROMAPRINT_ALGORITHM_TEST3; } else if (!strcmp(v, "test4")) { algo = CHROMAPRINT_ALGORITHM_TEST4; } else { fprintf(stderr, "WARNING: unknown algorithm, using the default\n"); } } else if (!strcmp(arg, "-set") && i + 1 < argc) { i += 1; } else { file_names[num_file_names++] = argv[i]; } } if (!num_file_names) { printf("usage: %s [OPTIONS] FILE...\n\n", argv[0]); printf("Options:\n"); printf(" -version print version information\n"); printf(" -length SECS length of the audio data used for fingerprint calculation (default 120)\n"); printf(" -raw output the raw uncompressed fingerprint\n"); printf(" -algo NAME version of the fingerprint algorithm\n"); return 2; } av_register_all(); av_log_set_level(AV_LOG_ERROR); buffer1 = av_malloc(BUFFER_SIZE + 16); buffer2 = av_malloc(BUFFER_SIZE + 16); chromaprint_ctx = chromaprint_new(algo); for (i = 1; i < argc; i++) { char *arg = argv[i]; if (!strcmp(arg, "-set") && i + 1 < argc) { char *name = argv[++i]; char *value = strchr(name, '='); if (value) { *value++ = '\0'; chromaprint_set_option(chromaprint_ctx, name, atoi(value)); } } } for (i = 0; i < num_file_names; i++) { file_name = file_names[i]; if (!decode_audio_file(chromaprint_ctx, buffer1, buffer2, file_name, max_length, &duration)) { fprintf(stderr, "ERROR: unable to calculate fingerprint for file %s, skipping\n", file_name); continue; } if (i > 0) { printf("\n"); } printf("FILE=%s\n", file_name); printf("DURATION=%d\n", duration); if (raw) { if (!chromaprint_get_raw_fingerprint(chromaprint_ctx, (void **)&raw_fingerprint, &raw_fingerprint_size)) { fprintf(stderr, "ERROR: unable to calculate fingerprint for file %s, skipping\n", file_name); continue; } printf("FINGERPRINT="); for (j = 0; j < raw_fingerprint_size; j++) { printf("%d%s", raw_fingerprint[j], j + 1 < raw_fingerprint_size ? "," : ""); } printf("\n"); chromaprint_dealloc(raw_fingerprint); } else { if (!chromaprint_get_fingerprint(chromaprint_ctx, &fingerprint)) { fprintf(stderr, "ERROR: unable to calculate fingerprint for file %s, skipping\n", file_name); continue; } printf("FINGERPRINT=%s\n", fingerprint); chromaprint_dealloc(fingerprint); } } chromaprint_free(chromaprint_ctx); av_free(buffer1); av_free(buffer2); free(file_names); return 0; }
int Libav::decodeNextAudio(void) throw (AVException*) { int bytes; int numSamples; // int bytesPerSample = (this->getSampleSize() * this->getSampleChannels()); //NSLog(@"> [libav decodeNextAudio] sample counter: %d",sampleCounter); // there must be another way to initialise the audio decoder than this sampleCounter test. if (!this->isOpen) this->open(); if (sampleCounter == 0) { //pFrame=avcodec_alloc_frame(); pFrame=av_frame_alloc(); if (!pFrame) throw new AVException ("Unable to allocate AUDIO buffer",MEMORY_ALLOCATION_ERROR); //avcodec_get_frame_defaults(pFrame); av_frame_unref(pFrame); } // we don't know SPS until we decode the first frame. // we cannot calculate SamplesOut without SPS. // what can we do here. Assume that once the sampleCounter is above 0 the SPS will be set. // NSLog (@"sampleCounter: %d samplesOut: %d", sampleCounter, [self getSamplesOut]); if (sampleCounter > 0) if (this->compareSamplesRange(sampleCounter) > 0) return -1; // loop until we are passed the frame in marker do { // NSLog(@"[libav decodeNextAudio] before IN loop"); #if LIBAVFORMAT_VERSION_MAJOR < 54 ; #else AVFrame *iFrame; #endif int gotFrame = 1; // loop until "gotFrame" do { // NSLog(@"[libav decodeNextAudio] gotFrame"); // Find our specified stream do { // NSLog(@"[libav decodeNextAudio] != avStream: %d",avStream); bytes = av_read_frame(pFormatCtx, &packet); if (bytes < 0) return bytes; } while (packet.stream_index != avStream) ; // int len; #if LIBAVFORMAT_VERSION_MAJOR < 50 avcodec_decode_audio2(pCodecCtx, aBuffer, &numBytes, packet.data, packet.size); #elseif LIBAVFORMAT_VERSION_MAJOR < 54 avcodec_decode_audio3(pCodecCtx, aBuffer, &numBytes, &packet); #else gotFrame = 0; //iFrame=avcodec_alloc_frame(); iFrame=av_frame_alloc(); //avcodec_get_frame_defaults(iFrame); av_frame_unref(iFrame); avcodec_decode_audio4(pCodecCtx, iFrame, &gotFrame, &packet); // NSLog (@"avcodec_decode_audio4 len: %d gotFrame: %d",len,gotFrame); if (gotFrame) { /* if a frame has been decoded, output it */ bytes = av_samples_get_buffer_size(NULL, pCodecCtx->channels, iFrame->nb_samples, pCodecCtx->sample_fmt, 1); // NSLog (@"decode Audio sps: %d",iFrame->sample_rate); // NSLog (@"audio samples decoded: %d",iFrame->nb_samples); if (sampleCounter == 0) this->setSamplesPerSecond(iFrame->sample_rate); } #endif //NSLog(@"decoded: %d finished: %d",len,gotFrame); } while (!gotFrame); int bytesPerSample = (this->getSampleSize() * this->getSampleChannels()); numSamples = bytes / bytesPerSample; int64_t endCounter = sampleCounter + numSamples; pFrame->nb_samples =numSamples; // NSLog(@"bytesPerSample: %d, numSamples: %d",bytesPerSample,numSamples); if (this->compareSamplesRange(endCounter) >=0) { if ((this->compareSamplesRange(sampleCounter)<0) && (this->compareSamplesRange(endCounter) >0)) { // send partial frame //NSLog(@"partial case 1"); if ((this->getSamplesOut() - this->getSamplesIn()) > INT_MAX) { throw new AVException(std::string("Sample Range Too Large"),SAMPLE_RANGE_ERROR); } pFrame->nb_samples =(this->getSamplesOut() - this->getSamplesIn()) ; avcodec_fill_audio_frame(pFrame, this->getSampleChannels(), this->getSampleFormat(), iFrame->data[0] + (this->getSamplesIn() - sampleCounter) * bytesPerSample, pFrame->nb_samples* bytesPerSample , 1); } else if ((this->compareSamplesRange(sampleCounter)<0) && (this->compareSamplesRange(endCounter) ==0)) { // send partial frame //NSLog(@"partial case 2"); if ((sampleCounter + numSamples - this->getSamplesIn() + 1) > INT_MAX) { throw new AVException(std::string("Sample Range Too Large"),SAMPLE_RANGE_ERROR); } pFrame->nb_samples =( sampleCounter + numSamples - this->getSamplesIn() + 1) ; avcodec_fill_audio_frame(pFrame, this->getSampleChannels(), this->getSampleFormat(), iFrame->data[0] + (this->getSamplesIn() - sampleCounter) * bytesPerSample, pFrame->nb_samples* bytesPerSample,1); } else if ((this->compareSamplesRange(sampleCounter)==0) && (this->compareSamplesRange(endCounter) >0)) { // send partial frame //NSLog(@"partial case 3"); if ((this->getSamplesOut() - sampleCounter) > INT_MAX) { throw new AVException(std::string("Sample Range Too Large"),SAMPLE_RANGE_ERROR); } pFrame->nb_samples =( this->getSamplesOut() - sampleCounter); avcodec_fill_audio_frame(pFrame, this->getSampleChannels(), this->getSampleFormat(), iFrame->data[0], pFrame->nb_samples * bytesPerSample,1); } else { // send entire frame. //NSLog(@"full case: %d",numSamples); // NSLog(@"pic buffer: %x pframe->data[0]: %x",pictureBuffer,pFrame->data[0]); pFrame->nb_samples =numSamples; avcodec_fill_audio_frame(pFrame, this->getSampleChannels(), this->getSampleFormat(), iFrame->data[0],bytes,1); // memset(pFrame->data[0],127,bytes); } } //avcodec_free_frame(&iFrame); av_frame_free(&iFrame); av_free(iFrame); #if LIBAVFORMAT_VERSION_MAJOR < 57 av_free_packet(&packet); #else av_packet_unref(&packet); #endif sampleCounter += pFrame->nb_samples; // NSLog(@"sample counter: %d",sampleCounter); } while (this->compareSamplesRange(sampleCounter) < 0); // NSLog(@"< [libav decodeNextAudio] %d %d ",pFrame->nb_samples , bytes) ; return pFrame->nb_samples; }
static gint player_av_get_audio_frame (PlayerAV *self, short *dest, int64_t *pts) { static AVPacket *packet = NULL; static uint8_t *pkt_data = NULL; static int pkt_size = 0; int len1, data_size; for (;;) { while (pkt_size > 0) { data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * self->priv->actx->channels; len1 = avcodec_decode_audio2 (self->priv->actx, dest, &data_size, pkt_data, pkt_size); if (len1 < 0) { pkt_size = 0; break; } *pts = packet->pts; pkt_data += len1; pkt_size -= len1; if (data_size <= 0) continue; return data_size; } for (;;) { // Free old packet if (packet) { if (packet->data != NULL) av_free_packet (packet); av_free (packet); packet = NULL; } if (g_async_queue_length (self->priv->apq) > 0) { packet = (AVPacket*) g_async_queue_pop (self->priv->apq); break; } else { packet = (AVPacket*) av_mallocz (sizeof (AVPacket)); // Read new packet g_mutex_lock (self->priv->rp_mutex); if(av_read_frame (self->priv->fctx, packet) < 0) { g_mutex_unlock (self->priv->rp_mutex); return -1; } if (packet->stream_index == self->priv->astream) { g_mutex_unlock (self->priv->rp_mutex); break; } else if (packet->stream_index == self->priv->vstream) { g_async_queue_push (self->priv->vpq, packet); packet = NULL; } g_mutex_unlock (self->priv->rp_mutex); } } pkt_data = packet->data; pkt_size = packet->size; } }
/***************************************************************************** * 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; }
/** 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 */ }
ByteArray DefaultReader::readFrame( double & duration, bool & stop ) { stop = false; // static just for speed static uint8_t audio_buf[AVCODEC_MAX_AUDIO_FRAME_SIZE*3/2]; int ret = 0; int dp_len, data_size; ByteArray data; ret = av_read_frame( this->pFormatContext_.get(), this->pPacket_.get() ); if( ret < 0 ) { stop = true; return data; } int64_t curPts = -1; int64_t decoded = 0; if( this->pPacket_->pts != static_cast< int64_t >( AV_NOPTS_VALUE ) ) { curPts = av_rescale( this->pPacket_->pts, AV_TIME_BASE * static_cast< int64_t >( this->pStream_->time_base.num ), this->pStream_->time_base.den ); } #if LIBAVCODEC_VERSION_MAJOR < 53 uint8_t * audio_pkt_data = this->pPacket_->data; int audio_pkt_size = this->pPacket_->size; while( audio_pkt_size > 0 ) { #else uint8_t * pktDataBackup = this->pPacket_->data; while( this->pPacket_->size > 0 ) { #endif if( this->afterEnd( toGeneral( curPts ) ) ) { stop = true; break; } data_size = sizeof( audio_buf ); #if LIBAVCODEC_VERSION_MAJOR < 53 dp_len = avcodec_decode_audio2( this->pCodecContext_.get(), static_cast< int16_t * >( static_cast< void * >( audio_buf ) ), &data_size, audio_pkt_data, audio_pkt_size ); #else dp_len = avcodec_decode_audio3( this->pCodecContext_.get(), static_cast< int16_t * >( static_cast< void * >( audio_buf ) ), &data_size, this->pPacket_.get() ); #endif if( dp_len < 0 ) { #if LIBAVCODEC_VERSION_MAJOR < 53 audio_pkt_size = 0; #endif break; } #if LIBAVCODEC_VERSION_MAJOR < 53 audio_pkt_data += dp_len; audio_pkt_size -= dp_len; #else this->pPacket_->data += dp_len; this->pPacket_->size -= dp_len; #endif if( data_size <= 0 ) { continue; } int64_t ptsDiff = (static_cast< int64_t >( AV_TIME_BASE )/2 * data_size) / (this->pCodecContext_->sample_rate * this->pCodecContext_->channels); if( this->afterBegin( toGeneral( curPts ) ) ) { data.insert( data.end(), audio_buf, audio_buf + data_size ); decoded += ptsDiff; } curPts += ptsDiff; } #if LIBAVCODEC_VERSION_MAJOR < 53 if( this->pPacket_->data ) { #else if( pktDataBackup ) { this->pPacket_->data = pktDataBackup; #endif av_free_packet( this->pPacket_.get() ); } duration = static_cast< double >( decoded ) / AV_TIME_BASE; return data; } bool DefaultReader::seekFrame( double timestamp ) { timestamp = av_rescale( timestamp, pStream_->time_base.den, pStream_->time_base.num ); int succeed = av_seek_frame( this->pFormatContext_.get(), pStream_->index, timestamp, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD ); if( succeed >= 0 ) { avcodec_flush_buffers( this->pCodecContext_.get() ); } return succeed >= 0; } }
static size_t ffmpeg_read_one_packet(struct input_handle* ih) { for (;;) { if (ih->need_new_frame && av_read_frame(ih->format_context, &ih->packet) < 0) { return 0; } ih->need_new_frame = FALSE; if (ih->packet.stream_index == ih->audio_stream) { int16_t* data_short = (int16_t*) &ih->audio_buf; int32_t* data_int = (int32_t*) &ih->audio_buf; float* data_float = (float*) &ih->audio_buf; double* data_double = (double*) &ih->audio_buf; if (!ih->old_data) { ih->old_data = ih->packet.data; } while (ih->packet.size > 0) { int data_size = sizeof(ih->audio_buf); #if LIBAVCODEC_VERSION_MAJOR >= 53 || \ (LIBAVCODEC_VERSION_MAJOR == 52 && \ LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 23, 0)) int len = avcodec_decode_audio3(ih->codec_context, (int16_t*) &ih->audio_buf, &data_size, &ih->packet); #else int len = avcodec_decode_audio2(ih->codec_context, (int16_t*) &ih->audio_buf, &data_size, ih->packet.data, ih->packet.size); #endif if (len < 0) { ih->packet.size = 0; break; } ih->packet.data += len; ih->packet.size -= len; if (!data_size) { continue; } if (ih->packet.size < 0) { fprintf(stderr, "Error in decoder!\n"); return 0; } size_t nr_frames_read, i; switch (ih->codec_context->sample_fmt) { case AV_SAMPLE_FMT_U8: fprintf(stderr, "8 bit audio not supported by libebur128!\n"); return 0; case AV_SAMPLE_FMT_S16: nr_frames_read = (size_t) data_size / sizeof(int16_t) / (size_t) ih->codec_context->channels; for (i = 0; i < (size_t) data_size / sizeof(int16_t); ++i) { ih->buffer[i] = ((float) data_short[i]) / MAX(-(float) SHRT_MIN, (float) SHRT_MAX); } break; case AV_SAMPLE_FMT_S32: nr_frames_read = (size_t) data_size / sizeof(int32_t) / (size_t) ih->codec_context->channels; for (i = 0; i < (size_t) data_size / sizeof(int32_t); ++i) { ih->buffer[i] = ((float) data_int[i]) / MAX(-(float) INT_MIN, (float) INT_MAX); } break; case AV_SAMPLE_FMT_FLT: nr_frames_read = (size_t) data_size / sizeof(float) / (size_t) ih->codec_context->channels; for (i = 0; i < (size_t) data_size / sizeof(float); ++i) { ih->buffer[i] = data_float[i]; } break; case AV_SAMPLE_FMT_DBL: nr_frames_read = (size_t) data_size / sizeof(double) / (size_t) ih->codec_context->channels; for (i = 0; i < (size_t) data_size / sizeof(double); ++i) { ih->buffer[i] = (float) data_double[i]; } break; case AV_SAMPLE_FMT_NONE: case AV_SAMPLE_FMT_NB: default: fprintf(stderr, "Unknown sample format!\n"); return 0; } return nr_frames_read; } ih->packet.data = ih->old_data; ih->old_data = NULL; } av_free_packet(&ih->packet); ih->need_new_frame = TRUE; } }
static int nextDataAudio( Vineo *v, void *data, int length ) { int dec = 0; while( dec < length ) { // If there's any pending decoded data, deal with it first if( v->dec_data_size > 0 ) { // Get the amount of bytes remaining to be written, and clamp to // the amount of decoded data we have size_t rem = length - dec; if( rem > v->dec_data_size ) { rem = v->dec_data_size; } // Copy the data to the app's buffer and increment memcpy( data, v->dec_data, rem ); data = (char*)data + rem; dec += rem; // If there's any decoded data left, move it to the front of the // buffer for next time if( rem < v->dec_data_size ) { memmove( v->dec_data, &v->dec_data[rem], v->dec_data_size - rem ); } v->dec_data_size -= rem; } // Check if we need to get more decoded data if( v->dec_data_size == 0 ) { size_t insize = v->data_size; int size, len; if( insize == 0 ) { nextPacketAudio( v ); // If there's no more input data, break and return what we have if( v->data_size == 0 ) { break; } insize = v->data_size; memset( &v->data[insize], 0, FF_INPUT_BUFFER_PADDING_SIZE ); } // Clear the input padding bits // Decode some data, and check for errors size = AVCODEC_MAX_AUDIO_FRAME_SIZE; while( ( len = avcodec_decode_audio2( v->aud_codec_ctx, (int16_t*)v->dec_data, &size, (unsigned char*)v->data, insize ) ) == 0 ) { if( size > 0 ) { break; } nextPacketAudio( v ); if( insize == v->data_size ) { break; } insize = v->data_size; memset( &v->data[insize], 0, FF_INPUT_BUFFER_PADDING_SIZE ); } // we got an error! return what we got. if( len < 0 ) { break; } if( len > 0 ) { // If any input data is left, move it to the start of the // buffer, and decrease the buffer size size_t rem = insize - len; if( rem ) { memmove( v->data, &v->data[len], rem ); } v->data_size = rem; } // Set the output buffer size v->dec_data_size = size; } } // Return the number of bytes we were able to get return dec; }
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; }
static boolean tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const uint8* data, uint32 data_size, uint32 extensions) { TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder; int len; int frame_size; uint32 src_size; const uint8* src; uint8* dst; int dst_offset; #if 0 LLOGLN(0, ("tsmf_ffmpeg_decode_audio: data_size %d", data_size)); int i; for (i = 0; i < data_size; i++) { LLOG(0, ("%02X ", data[i])); if (i % 16 == 15) LLOG(0, ("\n")); } LLOG(0, ("\n")); #endif if (mdecoder->decoded_size_max == 0) mdecoder->decoded_size_max = AVCODEC_MAX_AUDIO_FRAME_SIZE + 16; mdecoder->decoded_data = xzalloc(mdecoder->decoded_size_max); /* align the memory for SSE2 needs */ dst = (uint8*) (((uintptr_t)mdecoder->decoded_data + 15) & ~ 0x0F); dst_offset = dst - mdecoder->decoded_data; src = data; src_size = data_size; while (src_size > 0) { /* Ensure enough space for decoding */ if (mdecoder->decoded_size_max - mdecoder->decoded_size < AVCODEC_MAX_AUDIO_FRAME_SIZE) { mdecoder->decoded_size_max = mdecoder->decoded_size_max * 2 + 16; mdecoder->decoded_data = xrealloc(mdecoder->decoded_data, mdecoder->decoded_size_max); dst = (uint8*) (((uintptr_t)mdecoder->decoded_data + 15) & ~ 0x0F); if (dst - mdecoder->decoded_data != dst_offset) { /* re-align the memory if the alignment has changed after realloc */ memmove(dst, mdecoder->decoded_data + dst_offset, mdecoder->decoded_size); dst_offset = dst - mdecoder->decoded_data; } dst += mdecoder->decoded_size; } frame_size = mdecoder->decoded_size_max - mdecoder->decoded_size; #if LIBAVCODEC_VERSION_MAJOR < 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR <= 20) len = avcodec_decode_audio2(mdecoder->codec_context, (int16_t*) dst, &frame_size, src, src_size); #else { AVPacket pkt; av_init_packet(&pkt); pkt.data = (uint8*) src; pkt.size = src_size; len = avcodec_decode_audio3(mdecoder->codec_context, (int16_t*) dst, &frame_size, &pkt); } #endif if (len <= 0 || frame_size <= 0) { DEBUG_WARN("error decoding"); break; } src += len; src_size -= len; mdecoder->decoded_size += frame_size; dst += frame_size; } if (mdecoder->decoded_size == 0) { xfree(mdecoder->decoded_data); mdecoder->decoded_data = NULL; } else if (dst_offset) { /* move the aligned decoded data to original place */ memmove(mdecoder->decoded_data, mdecoder->decoded_data + dst_offset, mdecoder->decoded_size); } DEBUG_DVC("data_size %d decoded_size %d", data_size, mdecoder->decoded_size); return True; }
static int tsmf_ffmpeg_decode_audio(ITSMFDecoder * decoder, const uint8 * data, uint32 data_size, uint32 extensions) { TSMFFFmpegDecoder * mdecoder = (TSMFFFmpegDecoder *) decoder; int len; int frame_size; uint32 src_size; const uint8 * src; uint8 * dst; #if 0 LLOGLN(0, ("tsmf_ffmpeg_decode_audio: data_size %d", data_size)); int i; for (i = 0; i < data_size; i++) { LLOG(0, ("%02X ", data[i])); if (i % 16 == 15) LLOG(0, ("\n")); } LLOG(0, ("\n")); #endif if (mdecoder->decoded_size_max == 0) mdecoder->decoded_size_max = AVCODEC_MAX_AUDIO_FRAME_SIZE; mdecoder->decoded_data = malloc(mdecoder->decoded_size_max); dst = mdecoder->decoded_data; src = data; src_size = data_size; while (src_size > 0) { /* Ensure enough space for decoding */ if (mdecoder->decoded_size_max - mdecoder->decoded_size < AVCODEC_MAX_AUDIO_FRAME_SIZE) { mdecoder->decoded_size_max *= 2; mdecoder->decoded_data = realloc(mdecoder->decoded_data, mdecoder->decoded_size_max); dst = mdecoder->decoded_data + mdecoder->decoded_size; } frame_size = mdecoder->decoded_size_max - mdecoder->decoded_size; #if LIBAVCODEC_VERSION_MAJOR < 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR <= 20) len = avcodec_decode_audio2(mdecoder->codec_context, (int16_t *) dst, &frame_size, src, src_size); #else { AVPacket pkt; av_init_packet(&pkt); pkt.data = (uint8 *) src; pkt.size = src_size; len = avcodec_decode_audio3(mdecoder->codec_context, (int16_t *) dst, &frame_size, &pkt); } #endif if (len <= 0 || frame_size <= 0) { LLOGLN(0, ("tsmf_ffmpeg_decode_audio: erro decoding")); break; } src += len; src_size -= len; mdecoder->decoded_size += frame_size; dst += frame_size; } if (mdecoder->decoded_size == 0) { free(mdecoder->decoded_data); mdecoder->decoded_data = NULL; } LLOGLN(10, ("tsmf_ffmpeg_decode_audio: data_size %d decoded_size %d", data_size, mdecoder->decoded_size)); return 0; }