Skip to content

Commit 61816b8

Browse files
committed
fix MediaAudioEncoder
1 parent 4137672 commit 61816b8

6 files changed

Lines changed: 86 additions & 71 deletions

File tree

native/common/ff_av_encoder.cpp

Lines changed: 39 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -5,70 +5,31 @@ JNIEXPORT jlong JNICALL Java_javaforce_media_MediaAudioEncoder_nstart
55
{
66
FFContext *ctx = newFFContext(e,c);
77
if (ctx == NULL) return 0;
8+
9+
ctx->config_audio_bit_rate = bit_rate;
10+
ctx->chs = chs;
11+
ctx->freq = freq;
12+
813
int ret;
9-
// printf("context=%p\n", ctx);
10-
ctx->audio_codec = (*_avcodec_find_decoder)(codec_id);
14+
ctx->audio_codec = (*_avcodec_find_encoder)(codec_id);
1115
if (ctx->audio_codec == NULL) {
12-
printf("MediaAudioDecoder : codec == null\n");
16+
printf("MediaAudioEncoder : codec == null\n");
1317
return 0;
1418
}
1519
ctx->audio_codec_ctx = (*_avcodec_alloc_context3)(ctx->audio_codec);
1620

1721
//set default values
1822
ctx->audio_codec_ctx->codec_id = (AVCodecID)codec_id;
1923

20-
ret = (*_avcodec_open2)(ctx->audio_codec_ctx, ctx->audio_codec, NULL);
21-
if (ret < 0) {
22-
printf("MediaAudioEncoder:avcodec_open2() failed : %d\n", ret);
24+
if (!encoder_init_audio(ctx)) {
25+
printf("MediaAudioEncoder.encoder_init_audio() failed\n");
2326
return 0;
2427
}
2528

26-
ctx->config_audio_bit_rate = bit_rate;
27-
ctx->chs = chs;
28-
ctx->freq = freq;
29-
30-
//create audio frame
31-
ctx->audio_frame = (*_av_frame_alloc)();
32-
if (ctx->audio_frame == NULL) {
33-
printf("MediaAudioEncoder:av_frame_alloc() failed\n");
34-
return 0;
35-
}
36-
ctx->audio_frame->format = ctx->audio_codec_ctx->sample_fmt;
37-
ctx->audio_frame->sample_rate = ctx->freq;
38-
(*_av_channel_layout_copy)(&ctx->audio_frame->ch_layout, &ctx->audio_codec_ctx->ch_layout);
39-
ctx->audio_frame_size = ctx->audio_codec_ctx->frame_size * ctx->chs; //max samples that encoder will accept
40-
ctx->audio_frame_size_variable = (ctx->audio_codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE) != 0;
41-
ctx->audio_frame->nb_samples = ctx->audio_codec_ctx->frame_size;
42-
ret = (*_av_frame_get_buffer)(ctx->audio_frame, 0);
43-
if (ret < 0) {
44-
printf("MediaAudioEncoder:av_frame_get_buffer() failed : %d\n", ret);
45-
return 0;
46-
}
47-
if (!ctx->audio_frame_size_variable) {
48-
ctx->audio_buffer = (short*)(*_av_malloc)(ctx->audio_frame_size * 2);
49-
ctx->audio_buffer_size = 0;
50-
}
51-
if (ctx->audio_codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16 || ctx->audio_codec_ctx->sample_rate != ctx->freq) {
52-
//create audio conversion context
53-
ctx->swr_ctx = (*_swr_alloc)();
54-
(*_swr_alloc_set_opts2)(&ctx->swr_ctx,
55-
&ctx->audio_codec_ctx->ch_layout, ctx->audio_codec_ctx->sample_fmt, ctx->audio_codec_ctx->sample_rate, //output
56-
&ctx->audio_codec_ctx->ch_layout, AV_SAMPLE_FMT_S16, ctx->freq, //input
57-
0, NULL);
58-
59-
ret = (*_swr_init)(ctx->swr_ctx);
60-
if (ret < 0) {
61-
printf("MediaAudioEncoder:resample init failed : %d\n", ret);
62-
}
63-
}
64-
6529
//create audio packet
6630
ctx->pkt = AVPacket_New();
6731
(*_av_init_packet)(ctx->pkt);
6832

69-
ctx->chs = chs;
70-
ctx->freq = freq;
71-
7233
ctx->encode_buffer = (uint8_t*)(*_av_malloc)(1024*1024);
7334
ctx->encode_buffer_size = 1024*1024;
7435

@@ -106,57 +67,72 @@ JNIEXPORT void JNICALL Java_javaforce_media_MediaAudioEncoder_nstop
10667

10768
static jbyteArray av_encoder_addAudioFrame(FFContext *ctx, short *sams, int offset, int length)
10869
{
70+
if (ff_debug_log) printf("MediaAudioEncoder.av_encoder_addAudioFrame:%p,%p,%d,%d\n", ctx, sams, offset, length);
10971
int ret;
11072
int nb_samples = length / ctx->chs;
11173
int buffer_size = (*_av_samples_get_buffer_size)(NULL, ctx->chs, nb_samples, AV_SAMPLE_FMT_S16, 0);
74+
if (ff_debug_log) printf("MediaAudioEncoder.av_encoder_addAudioFrame:buffer_size:%d\n", buffer_size);
11275
void* samples_data = (*_av_mallocz)(buffer_size);
11376
//copy sams -> samples_data
11477
memcpy(samples_data, sams + offset, length * 2);
11578

11679
if (ctx->swr_ctx != NULL) {
11780
//convert sample format (some codecs do not support S16)
11881
//sample rate is not changed
119-
ret = (*_av_samples_alloc)(ctx->audio_dst_data, ctx->audio_dst_linesize, ctx->chs
120-
, nb_samples, ctx->audio_codec_ctx->sample_fmt, 0);
82+
if (ff_debug_log) printf("MediaAudioEncoder.av_encoder_addAudioFrame:av_samples_alloc:%p,%p,%d,%d,%d,0\n", ctx->audio_dst_data, ctx->audio_dst_linesize, ctx->chs, nb_samples, ctx->audio_codec_ctx->sample_fmt);
83+
ret = (*_av_samples_alloc)(ctx->audio_dst_data, ctx->audio_dst_linesize, ctx->chs, nb_samples, ctx->audio_codec_ctx->sample_fmt, 0);
84+
if (ff_debug_log) printf("MediaAudioEncoder.av_encoder_addAudioFrame:av_samples_alloc=%d\n", ret);
12185
if (ret < 0) {
12286
printf("MediaAudioEncoder:av_samples_alloc() failed : %d\n", ret);
12387
return NULL;
12488
}
12589
ctx->audio_src_data[0] = (uint8_t*)samples_data;
126-
ret = (*_swr_convert)(ctx->swr_ctx, ctx->audio_dst_data, nb_samples
127-
, ctx->audio_src_data, nb_samples);
90+
if (ff_debug_log) printf("MediaAudioEncoder.av_encoder_addAudioFrame:swr_convert:%p,%p,%d,%p,%d\n", ctx->swr_ctx, ctx->audio_dst_data, nb_samples, ctx->audio_src_data, nb_samples);
91+
ret = (*_swr_convert)(ctx->swr_ctx, ctx->audio_dst_data, nb_samples, ctx->audio_src_data, nb_samples);
92+
if (ret < 0) {
93+
printf("MediaAudioEncoder:swr_convert() failed : %d\n", ret);
94+
return NULL;
95+
}
12896
} else {
12997
ctx->audio_dst_data[0] = (uint8_t*)samples_data;
13098
}
13199

132100
(*_av_frame_make_writable)(ctx->audio_frame); //ensure we can write to it now
133101
ctx->audio_frame->nb_samples = nb_samples;
134102
buffer_size = (*_av_samples_get_buffer_size)(NULL, ctx->chs, nb_samples, ctx->audio_codec_ctx->sample_fmt, 0);
135-
ret = (*_avcodec_fill_audio_frame)(ctx->audio_frame, ctx->chs, ctx->audio_codec_ctx->sample_fmt, ctx->audio_dst_data[0]
136-
, buffer_size, 0);
103+
if (ff_debug_log) printf("MediaAudioEncoder.av_encoder_addAudioFrame:avcodec_fill_audio_frame\n");
104+
ret = (*_avcodec_fill_audio_frame)(ctx->audio_frame, ctx->chs, ctx->audio_codec_ctx->sample_fmt, ctx->audio_dst_data[0], buffer_size, 0);
137105
if (ret < 0) {
138106
printf("MediaAudioEncoder:avcodec_fill_audio_frame() failed : %d\n", ret);
139107
return NULL;
140108
}
141109

142110
ctx->audio_frame->pts = ctx->audio_pts; //(*_av_rescale_q)(ctx->audio_pts, ctx->audio_codec_ctx->time_base, ctx->audio_stream->time_base);
111+
if (ff_debug_log) printf("MediaAudioEncoder.av_encoder_addAudioFrame:send_frame:%p,%p\n", ctx->audio_codec_ctx, ctx->audio_frame);
143112
ret = (*_avcodec_send_frame)(ctx->audio_codec_ctx, ctx->audio_frame);
113+
if (ff_debug_log) printf("MediaAudioEncoder.av_encoder_addAudioFrame:send_frame=%d\n", ret);
144114
if (ret < 0) {
145-
printf("MediaAudioEncoder:avcodec_send_frame() failed : %d\n", ret);
115+
printf("MediaAudioEncoder:avcodec_send_frame() failed : %d:%s\n", ret, ctx->error_string(ret));
146116
return NULL;
147117
}
148118

119+
if (ff_debug_log) printf("MediaAudioEncoder.av_encoder_addAudioFrame:init_packet:%p\n", ctx->pkt);
120+
if (ctx->pkt == NULL) {
121+
printf("MediaAudioEncode:ctx->pkt == null\n");
122+
return NULL;
123+
}
149124
(*_av_init_packet)(ctx->pkt);
150125
ctx->pkt->data = NULL;
151126
ctx->pkt->size = 0;
152127

153128
ret = (*_avcodec_receive_packet)(ctx->audio_codec_ctx, ctx->pkt);
154129
if (ret < 0) {
155-
printf("MediaAudioDecoder:avcodec_receive_packet() failed : %d\n", ret);
130+
printf("MediaAudioEncoder:avcodec_receive_packet() failed : %d\n", ret);
156131
return NULL;
157132
}
133+
if (ff_debug_log) printf("MediaAudioEncoder.av_encoder_addAudioFrame:receive_frame:%d\n", ret);
158134

159-
(*_av_packet_rescale_ts)(ctx->pkt, ctx->audio_codec_ctx->time_base, ctx->audio_stream->time_base);
135+
//(*_av_packet_rescale_ts)(ctx->pkt, ctx->audio_codec_ctx->time_base, ctx->audio_stream->time_base);
160136
ctx->last_dts = ctx->pkt->dts;
161137
ctx->last_pts = ctx->pkt->pts;
162138
ctx->last_duration = ctx->pkt->duration;
@@ -173,10 +149,13 @@ static jbyteArray av_encoder_addAudioFrame(FFContext *ctx, short *sams, int offs
173149

174150
ctx->e->SetByteArrayRegion(array, 0, ctx->pkt->size, (jbyte*)ctx->pkt->data);
175151

152+
(*_av_free)(samples_data);
153+
176154
return array;
177155
}
178156

179157
static jbyteArray av_encoder_addAudio(FFContext *ctx, short *sams, int offset, int length) {
158+
if (ff_debug_log) printf("MediaAudioEncoder.av_encoder_addAudio:%p,%d,%d\n", sams, offset, length);
180159
int frame_size = length;
181160
if (!ctx->audio_frame_size_variable) {
182161
frame_size = ctx->audio_frame_size;
@@ -248,9 +227,9 @@ JNIEXPORT jlong JNICALL Java_javaforce_media_MediaVideoEncoder_nstart
248227
if (ctx == NULL) return 0;
249228
int ret;
250229
// printf("context=%p\n", ctx);
251-
ctx->video_codec = (*_avcodec_find_decoder)(codec_id);
230+
ctx->video_codec = (*_avcodec_find_encoder)(codec_id);
252231
if (ctx->video_codec == NULL) {
253-
printf("MediaVideoDecoder : codec == null\n");
232+
printf("MediaVideoEncoder : codec == null\n");
254233
return 0;
255234
}
256235
ctx->video_codec_ctx = (*_avcodec_alloc_context3)(ctx->video_codec);
@@ -359,7 +338,7 @@ static jbyteArray av_encoder_addVideo(FFContext *ctx, int *px)
359338
return NULL;
360339
}
361340

362-
(*_av_packet_rescale_ts)(ctx->pkt, ctx->video_codec_ctx->time_base, ctx->video_stream->time_base);
341+
//(*_av_packet_rescale_ts)(ctx->pkt, ctx->video_codec_ctx->time_base, ctx->video_stream->time_base);
363342
// printf("packet:%lld/%lld/%lld\n", pkt->dts, pkt->pts, pkt->duration);
364343
ctx->last_dts = ctx->pkt->dts;
365344
ctx->last_pts = ctx->pkt->pts;

native/common/ff_context.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
//ffmpeg struct context
2+
13
struct FFContext {
24
JNIEnv *e; //only valid during native function
35
jobject c; //only valid during native function
@@ -121,6 +123,13 @@ struct FFContext {
121123
mid_ff_write = e->GetMethodID(cls_mio, "write", "(Ljavaforce/media/MediaCoder;[B)I");
122124
mid_ff_seek = e->GetMethodID(cls_mio, "seek", "(Ljavaforce/media/MediaCoder;JI)J");
123125
}
126+
127+
char errmsg[256];
128+
129+
char* error_string(int errnum) {
130+
(*_av_strerror)(errnum, errmsg, 256);
131+
return errmsg;
132+
}
124133
};
125134

126135
#define ffiobufsiz (64 * 1024)

native/common/ff_encoder.cpp

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -228,8 +228,13 @@ static jboolean encoder_init_audio(FFContext *ctx) {
228228
}
229229
ctx->audio_codec_ctx->time_base.num = 1;
230230
ctx->audio_codec_ctx->time_base.den = ctx->freq;
231-
ctx->audio_stream->time_base.num = 1;
232-
ctx->audio_stream->time_base.den = ctx->freq;
231+
if (ctx->audio_stream != NULL) {
232+
ctx->audio_stream->time_base.num = 1;
233+
ctx->audio_stream->time_base.den = ctx->freq;
234+
}
235+
if (ctx->audio_codec_ctx->frame_size == 0) {
236+
ctx->audio_codec_ctx->frame_size = 160;
237+
}
233238

234239
//set audio codec options
235240
switch (ctx->audio_codec_ctx->codec_id) {
@@ -246,8 +251,10 @@ static jboolean encoder_init_audio(FFContext *ctx) {
246251
ctx->audio_codec_ctx->sample_rate = 48000;
247252
ctx->audio_codec_ctx->time_base.num = 1;
248253
ctx->audio_codec_ctx->time_base.den = 48000;
249-
ctx->audio_stream->time_base.num = 1;
250-
ctx->audio_stream->time_base.den = 48000;
254+
if (ctx->audio_stream != NULL) {
255+
ctx->audio_stream->time_base.num = 1;
256+
ctx->audio_stream->time_base.den = 48000;
257+
}
251258
}
252259
break;
253260
}
@@ -258,17 +265,20 @@ static jboolean encoder_init_audio(FFContext *ctx) {
258265
}
259266

260267
//open audio codec
268+
if (ff_debug_log) printf("avcodec_open2\n");
261269
int ret = (*_avcodec_open2)(ctx->audio_codec_ctx, ctx->audio_codec, NULL);
262270
if (ret < 0) {
263271
printf("MediaEncoder:avcodec_open2() failed : %d\n", ret);
264272
return JNI_FALSE;
265273
}
266274

267275
//copy params (after codec is opened)
268-
ret = (*_avcodec_parameters_from_context)(ctx->audio_stream->codecpar, ctx->audio_codec_ctx);
269-
if (ret < 0) {
270-
printf("MediaEncoder:avcodec_parameters_from_context() failed : %d\n", ret);
271-
return JNI_FALSE;
276+
if (ctx->audio_stream != NULL) {
277+
ret = (*_avcodec_parameters_from_context)(ctx->audio_stream->codecpar, ctx->audio_codec_ctx);
278+
if (ret < 0) {
279+
printf("MediaEncoder:avcodec_parameters_from_context() failed : %d\n", ret);
280+
return JNI_FALSE;
281+
}
272282
}
273283

274284
//create audio frame
@@ -280,7 +290,7 @@ static jboolean encoder_init_audio(FFContext *ctx) {
280290
ctx->audio_frame->format = ctx->audio_codec_ctx->sample_fmt;
281291
ctx->audio_frame->sample_rate = ctx->freq;
282292
(*_av_channel_layout_copy)(&ctx->audio_frame->ch_layout, &ctx->audio_codec_ctx->ch_layout);
283-
printf("audio:frame_size=%d chs=%d\n", ctx->audio_codec_ctx->frame_size, ctx->chs);
293+
printf("encoder_init_audio:frame_size=%d chs=%d\n", ctx->audio_codec_ctx->frame_size, ctx->chs);
284294
ctx->audio_frame_size = ctx->audio_codec_ctx->frame_size * ctx->chs; //max samples that encoder will accept
285295
ctx->audio_frame_size_variable = (ctx->audio_codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE) != 0;
286296
ctx->audio_frame->nb_samples = ctx->audio_codec_ctx->frame_size;
@@ -307,6 +317,7 @@ static jboolean encoder_init_audio(FFContext *ctx) {
307317
ret = (*_swr_init)(ctx->swr_ctx);
308318
if (ret < 0) {
309319
printf("MediaEncoder:resample init failed : %d\n", ret);
320+
return JNI_FALSE;
310321
}
311322
return JNI_TRUE;
312323
}

native/common/ff_output.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ JNIEXPORT jlong JNICALL Java_javaforce_media_MediaOutput_ncreateFile
3333

3434
ctx->pkt = AVPacket_New();
3535
(*_av_init_packet)(ctx->pkt);
36+
ctx->pkt->data = NULL;
37+
ctx->pkt->size = 0;
3638

3739
return (jlong)ctx;
3840
}
@@ -73,6 +75,11 @@ JNIEXPORT jlong JNICALL Java_javaforce_media_MediaOutput_ncreateIO
7375
ctx->last_pts = -1;
7476
ctx->last_dts = -1;
7577

78+
ctx->pkt = AVPacket_New();
79+
(*_av_init_packet)(ctx->pkt);
80+
ctx->pkt->data = NULL;
81+
ctx->pkt->size = 0;
82+
7683
printf("MediaOutput.ncreateIO() = %p\n", ctx);
7784

7885
return (jlong)ctx;

native/common/ffmpeg.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ AVFrame* (*_av_frame_alloc)();
137137
void (*_av_frame_free)(void** frame);
138138
void (*_av_buffer_unref)(AVBufferRef **buf);
139139
int (*_av_channel_layout_copy) (AVChannelLayout* dst, const AVChannelLayout* src);
140+
char* (*_av_strerror)(int errnum, char* buf, size_t bufsiz);
140141
int (*_avutil_version)();
141142

142143
//swresample functions (audio resample)
@@ -339,6 +340,7 @@ static jboolean ffmpeg_init(const char* codecFile, const char* deviceFile, const
339340
getFunction(util, (void**)&_av_frame_free, "av_frame_free");
340341
getFunction(util, (void**)&_av_buffer_unref, "av_buffer_unref");
341342
getFunction(util, (void**)&_av_channel_layout_copy, "av_channel_layout_copy");
343+
getFunction(util, (void**)&_av_strerror, "av_strerror");
342344
getFunction(util, (void**)&_avutil_version, "avutil_version");
343345

344346
getFunction(scale, (void**)&_sws_getContext, "sws_getContext");

src/javaforce/media/MediaAudioEncoder.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
* @author pquiring
66
*/
77

8+
import javaforce.*;
89
import javaforce.voip.*;
910

1011
public class MediaAudioEncoder extends MediaCoder {
@@ -28,13 +29,19 @@ public void stop() {
2829
private Packet packet;
2930
public native byte[] nencode(long ctx, short[] samples, int offset, int length);
3031
public Packet encode(short[] samples, int offset, int length) {
31-
if (ctx == 0) return null;
32+
if (ctx == 0) {
33+
JFLog.log("MediaAudioEncoder no ctx");
34+
return null;
35+
}
3236
if (packet == null) {
3337
packet = new Packet();
3438
packet.stream = getStream();
3539
}
3640
packet.data = nencode(ctx, samples, offset, length);
37-
if (packet.data == null) return null;
41+
if (packet.data == null) {
42+
JFLog.log("MediaAudioEncoder.nencode:data == null");
43+
return null;
44+
}
3845
packet.length = packet.data.length;
3946
return packet;
4047
}

0 commit comments

Comments
 (0)