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