예제 #1
0
/**
 * Opens the given URL to determine its AudioFileFormat.
 *
 * @param env JNIEnv
 * @param instance calling FFAudioFileReader instance
 * @param url URL (as jstring)
 * @return AudioFileFormat objects
 */
 JNIEXPORT jobjectArray JNICALL Java_com_tagtraum_ffsampledsp_FFAudioFileReader_getAudioFileFormatsFromURL(JNIEnv *env, jobject instance, jstring url) {

#ifdef DEBUG
    fprintf(stderr, "openFromUrl_1\n");
#endif

    int res = 0;
    AVFormatContext *format_context = NULL;
    jobjectArray array = NULL;
    //AVStream *stream = NULL;
    //int stream_index = 0;

    init_ids(env);

    const char *input_url = (*env)->GetStringUTFChars(env, url, NULL);
    res = ff_open_format_context(env, &format_context, input_url);
    if (res) {
        goto bail;
    }

    res = create_ffaudiofileformats(env, format_context, &array, url);
    if (res) {
        goto bail;
    }

bail:
    if (format_context) {
        avformat_close_input(&format_context);
    }
    (*env)->ReleaseStringUTFChars(env, url, input_url);

    return array;
}
예제 #2
0
/**
 * Opens the input file/url, allocates a AVFormatContext for it and opens the audio stream with an
 * appropriate decoder.
 *
 * @param env JNIEnv
 * @param format_context AVFormatContext
 * @param openedStream opened audio AVStream
 * @param stream_index[in] index of the desired <em>audio</em> stream
 * @param stream_index[out] index of the selected stream (index of <em>all</em> streams)
 * @param url URL to open
 * @return negative value, if something went wrong
 */
int ff_open_file(JNIEnv *env, AVFormatContext **format_context, AVStream **openedStream, AVCodecContext **context, int *stream_index, const char *url) {
    int res = 0;
    res = ff_open_format_context(env, format_context, url);
    if (res) {
        // exception has already been thrown
        goto bail;
    }

#ifdef DEBUG
    fprintf(stderr, "Desired audio stream index: %i.\n", *stream_index);
#endif

    if (*stream_index < 0) {
        // use best audio stream
        res = open_codec_context(stream_index, *format_context, *context, AVMEDIA_TYPE_AUDIO);
        if (res) {
            throwUnsupportedAudioFileExceptionIfError(env, res, "Failed to open codec context.");
            goto bail;
        }
        *openedStream = (*format_context)->streams[*stream_index];
    } else {
        // find xth audio stream
        // count possible audio streams
        int i;
        int audio_stream_number = 0;
        AVStream* stream = NULL;

        AVFormatContext* deref_format_context = *format_context;
        for (i=0; i<deref_format_context->nb_streams; i++) {
            stream = deref_format_context->streams[i];
            if (stream->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
                if (audio_stream_number == *stream_index) {
                    *stream_index = i;
                #ifdef DEBUG
                    fprintf(stderr, "Found desired audio stream at index: %i.\n", i);
                #endif
                    break;
                }
                audio_stream_number++;
            }
            stream = NULL;
        }
        if (stream == NULL) {
            // we didn't find a stream with the given index
            res = -1;
            throwIndexOutOfBoundsExceptionIfError(env, res, *stream_index);
            goto bail;
        }
        res = ff_open_stream(env, stream, context);
        if (res) {
            goto bail;
        }
        *openedStream = stream;
    }

#ifdef DEBUG
    fprintf(stderr, "Opened stream index: %i.\n", *stream_index);
    fprintf(stderr, "Opened stream: %ld.\n", (long) *openedStream);
#endif

bail:

    return res;
}
예제 #3
0
/**
 * Opens the byte buffer to determine its AudioFileFormat.
 *
 * @param env JNIEnv
 * @param instance calling FFAudioFileReader instance
 * @param byte_buffer audio data
 * @return AudioFileFormat objects
 */
 JNIEXPORT jobjectArray JNICALL Java_com_tagtraum_ffsampledsp_FFAudioFileReader_getAudioFileFormatsFromBuffer(JNIEnv *env, jobject instance, jobject byte_buffer) {
    int res = 0;
    AVFormatContext *format_context = NULL;
    //AVStream *stream = NULL;
    jobjectArray array = NULL;

    unsigned char* callbackBuffer = NULL;
    FFCallback *callback = NULL;
    AVIOContext *io_context;

    init_ids(env);

    callback = calloc(1, sizeof(FFCallback));
    if (!callback) {
        res = AVERROR(ENOMEM);
        throwIOExceptionIfError(env, res, "Could not allocate callback.");
        goto bail;
    }
    callback->env = env;
    callback->byte_buffer = byte_buffer;
    callback->call_count = 0;

    format_context = avformat_alloc_context();
    if (!format_context) {
        res = AVERROR(ENOMEM);
        throwIOExceptionIfError(env, res, "Could not allocate format context.");
        goto bail;
    }

    // limit probe to less than what we read in one chunk...
    format_context->probesize = 8*1024; // this corresponds to the Java code!
    format_context->max_analyze_duration = 5*AV_TIME_BASE;

    callbackBuffer = (unsigned char*)av_malloc(CALLBACK_BUFFERSIZE * sizeof(uint8_t));
    if (!callbackBuffer) {
        res = AVERROR(ENOMEM);
        throwIOExceptionIfError(env, res, "Could not allocate callback buffer.");
        goto bail;
    }

    io_context = avio_alloc_context(
        callbackBuffer,      // IOBuffer
        CALLBACK_BUFFERSIZE, // Buffer Size (32kb corresponds to Java code)
        0,                   // Write flag, only reading, so 0
        callback,            // FFCallback pointer (opaque)
        read_callback,       // Read callback
        NULL,                // Write callback
        NULL                 // Seek callback
    );
    if (!io_context) {
        res = AVERROR(ENOMEM);
        throwIOExceptionIfError(env, res, "Could not allocate custom IO context.");
        goto bail;
    }
    // we didn't supply a seek function in avio_alloc_context, so we need to make sure we don't seek..
    io_context->seekable = 0;

    format_context->pb = io_context;

    res = ff_open_format_context(env, &format_context, "MemoryAVIOContext");
    if (res) {
        goto bail;
    }

    res = create_ffaudiofileformats(env, format_context, &array, NULL);
    if (res) {
        goto bail;
    }

bail:

    /*
    if (stream && stream->codec) {
        avcodec_close(stream->codec);
    }
    */
    if (format_context) {
        AVFormatContext *s = format_context;
        if ((s->iformat && s->iformat->flags & AVFMT_NOFILE) || (s->flags & AVFMT_FLAG_CUSTOM_IO)) {
            if (s->pb) {
                avio_flush(s->pb);
                av_free(s->pb->buffer);
                av_free(s->pb);
            }
        }

        avformat_close_input(&format_context);
    }
    if (callback) {
        free(callback);
    }

    return array;
}