/*
 * 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;
}
/*
 * 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;
}