示例#1
0
/**
 * Initialize our main context FFAudioIO, so that SwrContext, decode buffers and the encoder are set
 * to reasonable values.
 *
 * @param JNIEnv    env
 * @param aio       our context, FFAudioIO
 * @return a negative value, if something went wrong
 */
int ff_init_audioio(JNIEnv *env, FFAudioIO *aio) {
    int res = 0;
    int nb_planes;
    AVCodec *codec = NULL;

    aio->timestamp = 0;

    // allocate pointer to the audio buffers, i.e. the multiple planes/channels.
    nb_planes = av_sample_fmt_is_planar(aio->stream->codecpar->format)
        ? aio->stream->codecpar->channels
        : 1;

    // always init SWR to keep code simpler
    res = init_swr(env, aio);
    if (res < 0) {
        // exception is already thrown
        goto bail;
    }
    // if for some reason the codec delivers 24bit, we need to encode its output to little endian
    if (aio->stream->codecpar->bits_per_coded_sample == 24) {
        codec = ff_find_encoder(aio->stream->codecpar->format, aio->stream->codecpar->bits_per_coded_sample, ff_big_endian(aio->stream->codecpar->codec_id), 1);
        if (!codec) {
            res = AVERROR(EINVAL);
            throwIOExceptionIfError(env, res, "Could not find suitable encoder codec.");
            goto bail;
        }
        res = ff_init_encoder(env, aio, codec);
        if (res<0) {
            throwIOExceptionIfError(env, res, "Could not initialize encoder codec.");
            goto bail;
        }
    }

    // allocate the buffer the codec decodes to
    aio->audio_data = av_mallocz(sizeof(uint8_t *) * nb_planes);
    if (!aio->audio_data) {
        res = AVERROR(ENOMEM);
        throwIOExceptionIfError(env, res, "Could not allocate audio data buffers.");
        goto bail;
    }

    aio->decode_frame = av_frame_alloc();
    if (!aio->decode_frame) {
        res = AVERROR(ENOMEM);
        throwIOExceptionIfError(env, res, "Could not allocate frame.");
        goto bail;
    }

    // initialize packet
    av_init_packet(&(aio->decode_packet));
    aio->decode_packet.data = NULL;
    aio->decode_packet.size = 0;

bail:

    return res;
}
示例#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 = -1;
    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->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
            audio_stream_count++;
        }
    }

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

    // are there any audio streams at all?
    if (audio_stream_count == 0) {
        throwUnsupportedAudioFileExceptionIfError(env, -1, "Failed to find audio stream");
        goto bail;
    }

    // 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->codecpar->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->codecpar->codec_id);
            if (is_pcm(stream->codecpar->codec_id)) {
                frame_size = (stream->codecpar->bits_per_coded_sample / 8) * stream->codecpar->channels;
            }
            // TODO: Support VBR.

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

            #ifdef DEBUG
                fprintf(stderr, "stream->codecpar->bits_per_coded_sample: %i\n", stream->codecpar->bits_per_coded_sample);
                fprintf(stderr, "stream->codecpar->bits_per_raw_sample  : %i\n", stream->codecpar->bits_per_raw_sample);
                fprintf(stderr, "stream->codecpar->bit_rate             : %i\n", stream->codecpar->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->codecpar->sample_rate);
                fprintf(stderr, "sampleSize : %i\n", stream->codecpar->bits_per_coded_sample);
                fprintf(stderr, "channels   : %i\n", stream->codecpar->channels);
                fprintf(stderr, "frame_size : %i\n", (int)frame_size);
                fprintf(stderr, "codec_id   : %i\n", stream->codecpar->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->codecpar->codec_id,
                                                           (jfloat)stream->codecpar->sample_rate,
                                                           sample_size,
                                                           stream->codecpar->channels,
                                                           frame_size,
                                                           frame_rate,
                                                           big_endian,
                                                           duration_in_microseconds,
                                                           stream->codecpar->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;
}