示例#1
0
/*
 * 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;
}
示例#7
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;
}
示例#8
0
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;
        }
示例#11
0
/*
 * 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;
}