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