/* * Class: com_spoledge_aacdecoder_Decoder * Method: nativeStart * Signature: (ILcom/spoledge/aacdecoder/BufferReader;Lcom/spoledge/aacdecoder/Decoder/Info;)I */ JNIEXPORT jlong JNICALL Java_com_spoledge_aacdecoder_Decoder_nativeStart (JNIEnv *env, jobject thiz, jlong decoder, jobject jreader, jobject aacInfo) { AACDDecoder *dec = decoder != 0 ? ((AACDDecoder*)decoder) : &aacd_opencore_decoder; AACDInfo *info = aacd_start( env, dec, jreader, aacInfo ); info->env = env; unsigned char* buffer = aacd_read_buffer( info ); unsigned long buffer_size = info->bytesleft; int pos = info->decoder->sync( info, buffer, buffer_size ); if (pos < 0) { AACD_ERROR( "start() failed - SYNC word not found" ); aacd_stop( info ); return 0; } AACD_DEBUG( "start() SYNC word found at offset=%d", pos ); buffer += pos; buffer_size -= pos; long err = info->decoder->start( info, buffer, buffer_size ); if (err < 0) { AACD_ERROR( "start() failed err=%ld", err ); aacd_stop( info ); return 0; } // remember pointers for first decode round: info->buffer = buffer + err; info->bytesleft = buffer_size - err; AACD_DEBUG( "start() bytesleft=%d", info->bytesleft ); aacd_start_info2java( info ); info->env = NULL; return (jlong) info; }
static void* aacd_opencore_init() { AACDOpenCore *oc = (AACDOpenCore*) calloc( 1, sizeof(struct AACDOpenCore)); oc->pExt = calloc( 1, sizeof( tPVMP4AudioDecoderExternal )); oc->pMem = malloc( PVMP4AudioDecoderGetMemRequirements()); tPVMP4AudioDecoderExternal *pExt = oc->pExt; pExt->desiredChannels = 2; pExt->outputFormat = OUTPUTFORMAT_16PCM_INTERLEAVED; pExt->repositionFlag = TRUE; pExt->aacPlusEnabled = TRUE; Int err = PVMP4AudioDecoderInitLibrary(pExt, oc->pMem); if (err) { AACD_ERROR( "PVMP4AudioDecoderInitLibrary failed err=%d", err ); free( pExt ); free( oc->pMem ); free( oc ); oc = NULL; } return oc; }
static int aacd_opencore_decode( AACDInfo *info, unsigned char *buffer, unsigned long buffer_size, jshort *jsamples, jint outLen ) { AACDOpenCore *oc = (AACDOpenCore*) info->ext; tPVMP4AudioDecoderExternal *pExt = oc->pExt; pExt->pInputBuffer = buffer; pExt->inputBufferMaxLength = buffer_size; pExt->inputBufferCurrentLength = buffer_size; pExt->inputBufferUsedLength = 0; pExt->pOutputBuffer = jsamples; pExt->pOutputBuffer_plus = jsamples+2048; int32_t status = PVMP4AudioDecodeFrame( pExt, oc->pMem ); if (status != MP4AUDEC_SUCCESS && status != SUCCESS) { AACD_ERROR( "decode() bytesleft=%lu, status=%d", buffer_size, status ); return -1; } info->frame_bytesconsumed = pExt->inputBufferUsedLength; info->frame_samples = pExt->frameLength * oc->frameSamplesFactor; return 0; }
/** * Initializes our context. */ static int aacd_ff_init( void **pext, AVInputFormat *fmt ) { AACD_TRACE( "init() start" ); av_log_set_level( AV_LOG_DEBUG ); AACDFFmpegInfo *ff = (AACDFFmpegInfo*) av_mallocz( sizeof(struct AACDFFmpegInfo)); if (!ff) return -1; ff->avpkt = aacd_ff_create_avpkt(); ff->pkt = aacd_ff_create_avpkt(); if (!ff->avpkt || !ff->pkt) { AACD_ERROR( "init() out of memory error !" ); aacd_ff_destroy( ff ); return -2; } ff->avifmt = fmt; ff->audio_stream_index = -1; av_log( ff->avfctx, AV_LOG_INFO, "Test of AV_LOG_INFO\n" ); av_log( ff->avfctx, AV_LOG_DEBUG, "Test of AV_LOG_DEBUG\n" ); av_log( ff->avfctx, AV_LOG_VERBOSE, "Test of AV_LOG_VERBOSE\n" ); (*pext) = ff; AACD_TRACE( "init() stop" ); return 0; }
static long aacd_opencoremp3_start( AACDInfo *info, unsigned char *buffer, unsigned long buffer_size) { AACD_TRACE( "start() buffer=%x size=%d", (*(unsigned long*)buffer), buffer_size ); AACDOpenCoreMP3 *oc = (AACDOpenCoreMP3*) info->ext; tPVMP3DecoderExternal *pExt = oc->pExt; // prepare the first samples buffer: pExt->pOutputBuffer = malloc(4096 * sizeof(int16_t)); pExt->outputFrameSize = 4096; pExt->pInputBuffer = buffer; pExt->inputBufferMaxLength = buffer_size; pExt->inputBufferCurrentLength = buffer_size; pExt->inputBufferUsedLength = 0; pExt->crcEnabled = 0; pExt->equalizerType = flat; pvmp3_InitDecoder( oc->pExt, oc->pMem ); int32_t status; int frameDecoded = 0; pExt->outputFrameSize = 0; /* pre-init search adts sync */ while (pExt->outputFrameSize == 0) { pExt->pInputBuffer = buffer; pExt->inputBufferMaxLength = buffer_size; pExt->inputBufferCurrentLength = buffer_size; pExt->inputBufferUsedLength = 0; pExt->outputFrameSize = 4096; status = pvmp3_framedecoder(pExt, oc->pMem); AACD_DEBUG( "start() Status[0]: %d - cosumed %d bytes", status, pExt->inputBufferUsedLength ); if (status != NO_DECODING_ERROR) { buffer -= pExt->inputBufferUsedLength; buffer_size -= pExt->inputBufferUsedLength; } else frameDecoded = 1; if (buffer_size <= 64) break; } free(pExt->pOutputBuffer); pExt->pOutputBuffer = NULL; if (status != NO_DECODING_ERROR) { AACD_ERROR( "start() init failed status=%d", status ); return -1; } AACD_DEBUG( "start() bytesconsumed=%d", pExt->inputBufferUsedLength ); info->samplerate = pExt->samplingRate; info->channels = pExt->num_channels; return pExt->inputBufferUsedLength; }
static int aacd_opencoremp3_decode( AACDInfo *info, unsigned char *buffer, unsigned long buffer_size, jshort *jsamples, jint outLen ) { AACDOpenCoreMP3 *oc = (AACDOpenCoreMP3*) info->ext; tPVMP3DecoderExternal *pExt = oc->pExt; pExt->pInputBuffer = buffer; pExt->inputBufferMaxLength = buffer_size; pExt->inputBufferCurrentLength = buffer_size; pExt->inputBufferUsedLength = 0; pExt->pOutputBuffer = jsamples; pExt->outputFrameSize = outLen; int32_t status = pvmp3_framedecoder( pExt, oc->pMem ); if (status != NO_DECODING_ERROR) { AACD_ERROR( "decode() bytesleft=%d, status=%d", buffer_size, status ); return -1; } info->frame_bytesconsumed = pExt->inputBufferUsedLength; info->frame_samples = pExt->outputFrameSize; return 0; }
static long aacd_faad_start( AACDCommonInfo *cinfo, void *ext, unsigned char *buffer, unsigned long buffer_size) { NeAACDecConfigurationPtr conf = NeAACDecGetCurrentConfiguration( ext ); conf->outputFormat = FAAD_FMT_16BIT; conf->downMatrix = 1; //conf->useOldADTSFormat = 1; NeAACDecSetConfiguration( ext, conf); AACD_DEBUG( "start() buffer=%d size=%d", (*(unsigned long*)buffer), buffer_size ); long ret = NeAACDecInit( ext, buffer, buffer_size, &cinfo->samplerate, &cinfo->channels ); if (ret < 0) AACD_ERROR( "NeAACDecInit failed err=%d", ret ); return ret; }
static int aacd_faad_decode( AACDCommonInfo *cinfo, void *ext, unsigned char *buffer, unsigned long buffer_size, jshort *jsamples, jint outLen ) { NeAACDecFrameInfo frame; jshort *ljsamples = jsamples; NeAACDecDecode2( ext, &frame, buffer, buffer_size, (void**)&jsamples, outLen*2 ); if (ljsamples != jsamples) { AACD_WARN( "NeAACDecDecode CHANGE jsamples !!!"); } cinfo->frame_bytesconsumed = frame.bytesconsumed; cinfo->frame_samples = frame.samples; if (frame.error != 0) { AACD_ERROR( "NeAACDecDecode bytesleft=%d, error: %s", buffer_size, NeAACDecGetErrorMessage(frame.error)); } return frame.error; }
static long aacd_opencore_start( AACDInfo *info, unsigned char *buffer, unsigned long buffer_size) { AACD_TRACE( "start() buffer=%x size=%d", (*(unsigned long*)buffer), buffer_size ); AACDOpenCore *oc = (AACDOpenCore*) info->ext; tPVMP4AudioDecoderExternal *pExt = oc->pExt; pExt->remainderBits = 0; pExt->frameLength = 0; // prepare the first samples buffer: //pExt->pOutputBuffer = malloc(4096 * sizeof(int16_t)); //pExt->pOutputBuffer_plus = pExt->pOutputBuffer + 2048; pExt->pOutputBuffer = aacd_prepare_samples( info, 4096 ); pExt->pOutputBuffer_plus = pExt->pOutputBuffer + 2048; int32_t status; int frameDecoded = 0; int attempts = 16; /* pre-init search adts sync */ while (pExt->frameLength == 0 && attempts--) { pExt->pInputBuffer = buffer; pExt->inputBufferMaxLength = buffer_size; pExt->inputBufferCurrentLength = buffer_size; pExt->inputBufferUsedLength = 0; status = PVMP4AudioDecoderConfig(pExt, oc->pMem); AACD_DEBUG( "start() Status[0]: %d", status ); if (status != MP4AUDEC_SUCCESS) { status = PVMP4AudioDecodeFrame(pExt, oc->pMem); AACD_DEBUG( "start() Status[1]: %d", status ); buffer -= pExt->inputBufferUsedLength; buffer_size -= pExt->inputBufferUsedLength; if (MP4AUDEC_SUCCESS == status) { AACD_DEBUG( "start() frameLength: %d\n", pExt->frameLength); frameDecoded = 1; continue; } } if (buffer_size <= PVMP4AUDIODECODER_INBUFSIZE) break; } if (!frameDecoded) { AACD_INFO( "start() No stream info available - trying to decode a frame" ); if (buffer_size >= PVMP4AUDIODECODER_INBUFSIZE) status = PVMP4AudioDecodeFrame(pExt, oc->pMem); else AACD_WARN( "start() Input buffer too small" ); } //free( pExt->pOutputBuffer ); if (status != MP4AUDEC_SUCCESS) { AACD_ERROR( "start() init failed status=%d", status ); return -1; } AACD_DEBUG( "start() bytesconsumed=%d", pExt->inputBufferUsedLength ); int streamType = -1; if ((pExt->extendedAudioObjectType == MP4AUDIO_AAC_LC) || (pExt->extendedAudioObjectType == MP4AUDIO_LTP)) { streamType = AAC; } else if (pExt->extendedAudioObjectType == MP4AUDIO_SBR) { streamType = AACPLUS; } else if (pExt->extendedAudioObjectType == MP4AUDIO_PS) { streamType = ENH_AACPLUS; } AACD_DEBUG( "start() streamType=%d", streamType ); if ((AAC == streamType) && (2 == pExt->aacPlusUpsamplingFactor)) { AACD_INFO( "start() DisableAacPlus" ); PVMP4AudioDecoderDisableAacPlus(pExt, oc->pMem); } info->samplerate = pExt->samplingRate; info->channels = pExt->desiredChannels; oc->frameSamplesFactor = pExt->desiredChannels; if (2 == pExt->aacPlusUpsamplingFactor) oc->frameSamplesFactor *= 2; info->frame_bytesconsumed = pExt->inputBufferUsedLength; info->frame_samples = pExt->frameLength * oc->frameSamplesFactor; return pExt->inputBufferUsedLength; }
static long aacd_opencoremp3_start( AACDInfo *info, unsigned char *buffer, unsigned long buffer_size) { AACD_TRACE( "start() buffer=%x size=%d", (*(unsigned long*)buffer), buffer_size ); AACDOpenCoreMP3 *oc = (AACDOpenCoreMP3*) info->ext; tPVMP3DecoderExternal *pExt = oc->pExt; // prepare the first samples buffer: //pExt->pOutputBuffer = malloc(4096 * sizeof(int16_t)); pExt->pOutputBuffer = aacd_prepare_samples( info, 4096 ); pExt->outputFrameSize = 4096; pExt->pInputBuffer = buffer; pExt->inputBufferMaxLength = buffer_size; pExt->inputBufferCurrentLength = buffer_size; pExt->inputBufferUsedLength = 0; pExt->crcEnabled = 0; pExt->equalizerType = flat; pvmp3_InitDecoder( oc->pExt, oc->pMem ); int32_t status; int frameDecoded = 0; int attempts = 16; int totalConsumed = 0; pExt->outputFrameSize = 0; /* pre-init search adts sync */ while (!frameDecoded && attempts--) { pExt->pInputBuffer = buffer; pExt->inputBufferMaxLength = buffer_size; pExt->inputBufferCurrentLength = buffer_size; pExt->inputBufferUsedLength = 0; pExt->outputFrameSize = 4096; status = pvmp3_framedecoder(pExt, oc->pMem); AACD_DEBUG( "start() Status[0]: %d - consumed %d bytes", status, pExt->inputBufferUsedLength ); totalConsumed += pExt->inputBufferUsedLength; if (status != NO_DECODING_ERROR) { AACD_ERROR( "start() frame decode error=%d", status ); if (!pExt->inputBufferUsedLength) { AACD_ERROR( "start() first frame cannot be decoded - trying to sync again" ); int move = buffer_size < 2048 ? (buffer_size >> 1) : 1024; buffer += move; buffer_size -= move; totalConsumed += move; pExt->pInputBuffer = buffer; pExt->inputBufferMaxLength = buffer_size; pExt->inputBufferCurrentLength = buffer_size; ERROR_CODE err = pvmp3_frame_synch( oc->pExt, oc->pMem ); if (err == SYNCH_LOST_ERROR) { AACD_ERROR( "start() cannot re-sync the stream after next %d bytes, status=%d", move, err ); } else if (err != NO_DECODING_ERROR) { AACD_ERROR( "start() cannot sync the stream status=%d", err ); break; } else { totalConsumed += pExt->inputBufferUsedLength; AACD_INFO( "start() sync was successful - used bytes=%d", totalConsumed ); } } buffer -= pExt->inputBufferUsedLength; buffer_size -= pExt->inputBufferUsedLength; }
/* * Class: com_biophysics_radioplayer_ArrayDecoder * Method: nativeStart * Signature: (ILcom/biophysics/radioplayer/ArrayBufferReader;Lcom/biophysics/radioplayer/Decoder/Info;)I */ JNIEXPORT jint JNICALL Java_com_biophysics_radioplayer_ArrayDecoder_nativeStart (JNIEnv *env, jobject thiz, jint decoder, jobject jreader, jobject aacInfo) { AACD_TRACE( "start() start" ); AACDDecoder *dec = aacda_decoder( decoder ); if (!dec) { AACD_ERROR( "start() decoder [%d] not supported", decoder ); return 0; } AACDArrayInfo *ainfo = aacda_start( env, dec, jreader, aacInfo ); if (!ainfo) { AACD_ERROR( "start() cannot initialize decoder - out-of-memory error ?" ); return 0; } ainfo->env = env; AACD_TRACE( "start() calling read_buffer" ); unsigned char* buffer = aacda_read_buffer( ainfo ); unsigned long buffer_size = ainfo->cinfo.bytesleft; AACD_TRACE( "start() got %d bytes from read_buffer", buffer_size ); int pos = ainfo->decoder->sync( buffer, buffer_size ); AACD_TRACE( "start() sync returned %d", pos ); if (pos < 0) { AACD_ERROR( "start() failed - ADTS sync word not found" ); aacda_stop( ainfo ); return 0; } buffer += pos; buffer_size -= pos; AACD_TRACE( "start() calling decoder->start()" ); long err = ainfo->decoder->start( &ainfo->cinfo, ainfo->ext, buffer, buffer_size ); if (err < 0) { AACD_ERROR( "start() failed err=%d", err ); aacda_stop( ainfo ); return 0; } // remember pointers for first decode round: if (!ainfo->cinfo.input_ctrl) { ainfo->cinfo.buffer = buffer + err; ainfo->cinfo.bytesleft = buffer_size - err; } AACD_DEBUG( "start() bytesleft=%d", ainfo->cinfo.bytesleft ); aacd_start_info2java( env, &ainfo->cinfo, aacInfo ); ainfo->env = NULL; AACD_TRACE( "nativeStart() stop" ); return (jint) ainfo; }
static int aacd_ffwma_decode( AACDCommonInfo *cinfo, void *ext, unsigned char *buffer, unsigned long buffer_size, jshort *jsamples, jint outLen ) { AACD_TRACE( "decode() start" ); AACDFFmpegInfo *ff = (AACDFFmpegInfo*) ext; AVFormatContext *ic = ff->avfctx; AVPacket *avpkt = ff->avpkt; AVPacket *pkt = ff->pkt; ff->bytesconsumed = 0; #ifdef AACD_LOGLEVEL_TRACE ic->debug = FF_FDEBUG_TS; #endif while (!pkt->size) { AACD_TRACE( "decode() calling av_read_frame..." ); int err = av_read_frame( ic, avpkt ); AACD_TRACE( "decode() av_read_frame returned: %d", err ); if (err < 0) { AACD_ERROR( "decode() cannot read av frame" ); return AACD_DECODE_EOF; } if (avpkt->stream_index == ff->audio_stream_index) { pkt->data = avpkt->data; pkt->size = avpkt->size; break; } // TODO: delete packet's buffer ? AACD_TRACE( "decode() : freeing packet's data" ); av_freep( &avpkt->data ); } AACD_TRACE( "decode() packet demuxed, will decode..." ); AVCodecContext *avctx = ic->streams[ff->audio_stream_index]->codec; AVCodec *codec = avctx->codec; AACD_DEBUG( "decode() frame_size=%d", avctx->frame_size ); // aac_decode_frame int outSize = outLen * 2; int consumed = (*codec->decode)( avctx, jsamples, &outSize, pkt ); if (consumed <= 0) { AACD_ERROR( "decode() cannot decode frame pkt->size=%d, outSize=%d, error: %d", pkt->size, outSize, consumed ); if ( cinfo->frame_samples < outLen * 3 / 2 ) { AACD_WARN( "decode() trying to obtain large output buffer" ); return AACD_DECODE_OUTPUT_NEEDED; } pkt->size = 0; return AACD_DECODE_OTHER; } pkt->data += consumed; pkt->size -= consumed; cinfo->frame_bytesconsumed = consumed; //cinfo->frame_samples = avctx->frame_size * avctx->channels; cinfo->frame_samples = (outSize >> 1); AACD_TRACE( "decode() stop - consumed %d, pkt->size=%d", consumed, pkt->size ); return AACD_DECODE_OK; }
static long aacd_ffwma_start( AACDCommonInfo *cinfo, void *ext, unsigned char *buffer, unsigned long buffer_size) { AACD_TRACE( "start() start" ); AACDFFmpegInfo *ff = (AACDFFmpegInfo*) ext; ff->cinfo = cinfo; // take control over the input reading: cinfo->input_ctrl = 1; ByteIOContext *pb = aacd_ff_create_byteioctx( ff ); if (!pb) return -1; AACD_TRACE( "start() opening stream" ); ff->bytesconsumed = 0; int err = av_open_input_stream( &ff->avfctx, pb, "filename.asf", ff->avifmt, NULL ); AVFormatContext *ic = ff->avfctx; if (err) { char s[80]; av_strerror( err, s, 80); AACD_ERROR("start() cannot open demuxer - [%d] - %s", err, s ); // we must dealloc what we allocated locally: aacd_ff_destroy_byteioctx( pb ); return -1; } AACD_TRACE( "start() stream opened" ); //err = av_find_stream_info(ic) AACD_DEBUG( "start() streams=%d", ic->nb_streams); dump_format(ic, 0, "", 0); ff->audio_stream_index = aacd_ff_find_stream( ic, AVMEDIA_TYPE_AUDIO ); if (ff->audio_stream_index < 0) { AACD_ERROR( "start() cannot find audio stream" ); return -1; } AVStream *st = ic->streams[ff->audio_stream_index]; st->discard = AVDISCARD_DEFAULT; AVCodecContext *avctx = st->codec; AACD_DEBUG( "start() samplerate=%d channels=%d codec=%x", avctx->sample_rate, avctx->channels, avctx->codec_id); AVCodec *codec = aacd_ffwma_find_codec( avctx->codec_id ); if (!codec) { AACD_ERROR("start() audio - not a WMA codec - %x", avctx->codec_id); return -1; } if (avcodec_open( avctx, codec )) { AACD_ERROR("start() audio cannot open audio codec - %x", avctx->codec_id); return -1; } cinfo->samplerate = avctx->sample_rate; cinfo->channels = avctx->channels; AACD_TRACE( "start() stop - ic->format=%x, ff->avfctx->format=%x", ic->iformat, ff->avfctx->iformat ); // we return more than we consumed: return ff->bytesconsumed; }