47 JNIEnv *env, jclass streamClass) {
48 jclass audioFormat_class =
49 (*env)->FindClass(env,
"javax/sound/sampled/AudioFormat");
50 if (!audioFormat_class)
52 jclass encoding_class =
53 (*env)->FindClass(env,
"javax/sound/sampled/AudioFormat$Encoding");
58 (*env)->GetMethodID(env, audioFormat_class,
"getEncoding",
59 "()Ljavax/sound/sampled/AudioFormat$Encoding;");
63 (*env)->GetMethodID(env, audioFormat_class,
"getSampleRate",
"()F");
64 if (!getSampleRate_MID)
67 (*env)->GetMethodID(env, audioFormat_class,
"getFrameSize",
"()I");
68 if (!getFrameSize_MID)
70 getSampleSizeInBits_MID =
71 (*env)->GetMethodID(env, audioFormat_class,
"getSampleSizeInBits",
"()I");
72 if (!getSampleSizeInBits_MID)
75 (*env)->GetMethodID(env, audioFormat_class,
"getChannels",
"()I");
79 (*env)->GetMethodID(env, audioFormat_class,
"isBigEndian",
"()Z");
82 toString_MID = (*env)->GetMethodID(env, encoding_class,
"toString",
83 "()Ljava/lang/String;");
98 JNIEnv *env, jobject
object, jobject target_format, jlong aio_pointer) {
100 enum AVSampleFormat out_sample_fmt = AV_SAMPLE_FMT_NONE;
101 AVChannelLayout out_ch_layout = AV_CHANNEL_LAYOUT_STEREO;
104 AVCodec *encoder = NULL;
105 int dither_method = SWR_DITHER_NONE;
106 int output_sample_bits = 0;
110 jfloat sample_rate = 0;
111 jint sample_size_in_bits = 0;
113 jboolean big_endian = JNI_FALSE;
114 jobject encoding = NULL;
115 jstring jencoding_name = NULL;
116 const char *encoding_name = NULL;
120 sample_rate = (*env)->CallFloatMethod(env, target_format, getSampleRate_MID);
121 if ((*env)->ExceptionCheck(env))
123 sample_size_in_bits =
124 (*env)->CallIntMethod(env, target_format, getSampleSizeInBits_MID);
125 if ((*env)->ExceptionCheck(env))
127 channels = (*env)->CallIntMethod(env, target_format, getChannels_MID);
128 if ((*env)->ExceptionCheck(env))
130 big_endian = (*env)->CallBooleanMethod(env, target_format, isBigEndian_MID);
131 if ((*env)->ExceptionCheck(env))
133 encoding = (*env)->CallObjectMethod(env, target_format, getEncoding_MID);
134 if ((*env)->ExceptionCheck(env))
138 "Target format has no encoding.");
142 (jstring)(*env)->CallObjectMethod(env, encoding, toString_MID);
143 (*env)->DeleteLocalRef(env, encoding);
144 if ((*env)->ExceptionCheck(env))
146 if (!jencoding_name) {
148 "Target format has no encoding name.");
152 encoding_name = (*env)->GetStringUTFChars(env, jencoding_name, NULL);
153 if (!encoding_name) {
155 (*env)->DeleteLocalRef(env, jencoding_name);
158 is_float = strcmp(
"PCM_FLOAT", encoding_name) == 0;
159 is_signed = strcmp(
"PCM_SIGNED", encoding_name) == 0;
162 fprintf(stderr,
"encoding = %s\n", encoding_name);
163 fprintf(stderr,
"signed = %d\n", is_signed);
164 fprintf(stderr,
"float = %d\n", is_float);
165 fprintf(stderr,
"bits = %d\n", (
int)sample_size_in_bits);
168 (*env)->ReleaseStringUTFChars(env, jencoding_name, encoding_name);
169 (*env)->DeleteLocalRef(env, jencoding_name);
171 if (sample_size_in_bits <= 8) {
172 out_sample_fmt = AV_SAMPLE_FMT_U8;
173 }
else if (sample_size_in_bits <= 16) {
174 out_sample_fmt = AV_SAMPLE_FMT_S16;
175 }
else if (sample_size_in_bits <= 32 && is_float) {
176 out_sample_fmt = AV_SAMPLE_FMT_FLT;
177 }
else if (sample_size_in_bits <= 32) {
178 out_sample_fmt = AV_SAMPLE_FMT_S32;
179 }
else if (sample_size_in_bits <= 64 && is_float) {
180 out_sample_fmt = AV_SAMPLE_FMT_DBL;
182 fprintf(stderr,
"Will use 64 bit PCM_FLOAT even though it might not have "
184 out_sample_fmt = AV_SAMPLE_FMT_DBL;
187 if (aio->
stream->codecpar->ch_layout.nb_channels == channels) {
188 av_channel_layout_copy(&out_ch_layout, &aio->
stream->codecpar->ch_layout);
189 }
else if (channels == 1) {
190 out_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_MONO;
191 }
else if (channels == 2) {
192 out_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
194 fprintf(stderr,
"Undetermined channel layout, will use stereo.\n");
196 out_ch_layout = (AVChannelLayout)AV_CHANNEL_LAYOUT_STEREO;
199 if (aio->
stream->codecpar->bits_per_coded_sample > sample_size_in_bits) {
200 dither_method = SWR_DITHER_TRIANGULAR;
201 output_sample_bits = sample_size_in_bits;
205 fprintf(stderr,
"setting out format to: %d\n", out_sample_fmt);
215 res = AVERROR(ENOMEM);
221 av_opt_set_sample_fmt(aio->
swr_context,
"in_sample_fmt",
222 aio->
stream->codecpar->format, 0);
223 av_opt_set_chlayout(aio->
swr_context,
"in_chlayout",
224 &aio->
stream->codecpar->ch_layout, 0);
226 aio->
stream->codecpar->sample_rate, 0);
228 av_opt_set_chlayout(aio->
swr_context,
"out_chlayout", &out_ch_layout, 0);
229 av_opt_set_int(aio->
swr_context,
"out_sample_rate", (
int)round(sample_rate),
231 av_opt_set_sample_fmt(aio->
swr_context,
"out_sample_fmt", out_sample_fmt, 0);
232 av_opt_set_int(aio->
swr_context,
"dither_method", dither_method, 0);
233 av_opt_set_int(aio->
swr_context,
"output_sample_bits", output_sample_bits, 0);
234 av_channel_layout_uninit(&out_ch_layout);
238 res = AVERROR(ENOMEM);
244 fprintf(stderr,
"open codec: dither method : %d\n", dither_method);
248 encoder =
ff_find_encoder(out_sample_fmt, sample_size_in_bits, big_endian,
251 res = AVERROR(EINVAL);
262 return (jlong)(intptr_t)aio;