Exemplo n.º 1
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;
}
Exemplo n.º 2
0
static int create_ffaudiofileformats(JNIEnv *env, AVFormatContext *format_context, jobjectArray *array, jstring url) {
    int res = 0;
    jlong duration_in_microseconds = -1;
    jfloat frame_rate = -1;
    jobject vbr = NULL;
    jboolean big_endian = 1;
    jobject audio_format = NULL;
    jint frame_size = -1;
    jint sample_size = 0;
    int audio_stream_count = 0;
    int audio_stream_number = 0;

    // count possible audio streams
    int i;
    for (i=0; i<format_context->nb_streams; i++) {
        AVStream* stream = format_context->streams[i];
        if (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
            audio_stream_count++;
        }
    }

#ifdef DEBUG
    fprintf(stderr, "Found %i audio streams.\n", audio_stream_count);
#endif

    // create output array
    *array = (*env)->NewObjectArray(env, audio_stream_count, (*env)->FindClass(env, "javax/sound/sampled/AudioFileFormat"), NULL);
    if (array == NULL) {
        goto bail;
    }

#ifdef DEBUG
    fprintf(stderr, "Created audio file format array.\n");
#endif

    // iterate over audio streams
    for (i=0; i<format_context->nb_streams; i++) {
        AVStream* stream = format_context->streams[i];
        if (stream->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
            res = ff_open_stream(env, stream);
            if (res) {
                goto bail;
            }

            // create object
            duration_in_microseconds = duration(format_context, stream);
            frame_rate = get_frame_rate(stream, duration_in_microseconds);
            big_endian = ff_big_endian(stream->codec->codec_id);
            if (is_pcm(stream->codec->codec_id)) {
                frame_size = (stream->codec->bits_per_coded_sample / 8) * stream->codec->channels;
            }
            // TODO: Support VBR.

            sample_size = stream->codec->bits_per_coded_sample
                ? stream->codec->bits_per_coded_sample
                : stream->codec->bits_per_raw_sample;

            #ifdef DEBUG
                fprintf(stderr, "stream->codec->bits_per_coded_sample: %i\n", stream->codec->bits_per_coded_sample);
                fprintf(stderr, "stream->codec->bits_per_raw_sample  : %i\n", stream->codec->bits_per_raw_sample);
                fprintf(stderr, "stream->codec->bit_rate             : %i\n", stream->codec->bit_rate);
                fprintf(stderr, "format_context->packet_size         : %i\n", format_context->packet_size);
                fprintf(stderr, "frames     : %" PRId64 "\n", stream->nb_frames);
                fprintf(stderr, "sample_rate: %i\n", stream->codec->sample_rate);
                fprintf(stderr, "sampleSize : %i\n", stream->codec->bits_per_coded_sample);
                fprintf(stderr, "channels   : %i\n", stream->codec->channels);
                fprintf(stderr, "frame_size : %i\n", (int)frame_size);
                fprintf(stderr, "codec_id   : %i\n", stream->codec->codec_id);
                fprintf(stderr, "duration   : %" PRId64 "\n", (int64_t)duration_in_microseconds);
                fprintf(stderr, "frame_rate : %f\n", frame_rate);
                if (big_endian) {
                    fprintf(stderr, "big_endian  : true\n");
                } else {
                    fprintf(stderr, "big_endian  : false\n");
                }
            #endif
            audio_format = create_ffaudiofileformat(env, url,
                                                           stream->codec->codec_id,
                                                           (jfloat)stream->codec->sample_rate,
                                                           sample_size,
                                                           stream->codec->channels,
                                                           frame_size,
                                                           frame_rate,
                                                           big_endian,
                                                           duration_in_microseconds,
                                                           stream->codec->bit_rate,
                                                           vbr);

            (*env)->SetObjectArrayElement(env, *array, audio_stream_number, audio_format);
            audio_stream_number++;

            // clean up
            if (stream && stream->codec) {
                avcodec_close(stream->codec);
            }
        }
    }

bail:
    return res;
}