javacpp-presets
javacpp-presets copied to clipboard
Impossible to convert between the formats supported by the filter 'Parsed_ebur128_0' and the filter 'auto_resampler_0'
Hi facing some issue with code . Which I have written after seeing this example : https://github.com/FFmpeg/FFmpeg/blob/master/doc/examples/filtering_audio.c program mentioned in link works fine.
but below mentioned java code is having some issue while linking filters.
import org.bytedeco.javacpp.BytePointer;
import org.bytedeco.javacpp.avcodec;
import org.bytedeco.javacpp.avfilter;
import org.bytedeco.javacpp.avformat;
import org.bytedeco.javacpp.avutil;
import java.nio.ByteBuffer;
import static org.bytedeco.javacpp.avcodec.av_packet_unref;
import static org.bytedeco.javacpp.avcodec.avcodec_alloc_context3;
import static org.bytedeco.javacpp.avcodec.avcodec_free_context;
import static org.bytedeco.javacpp.avcodec.avcodec_open2;
import static org.bytedeco.javacpp.avcodec.avcodec_parameters_to_context;
import static org.bytedeco.javacpp.avcodec.avcodec_receive_frame;
import static org.bytedeco.javacpp.avcodec.avcodec_send_packet;
import static org.bytedeco.javacpp.avfilter.AV_BUFFERSRC_FLAG_KEEP_REF;
import static org.bytedeco.javacpp.avfilter.av_buffersink_get_frame;
import static org.bytedeco.javacpp.avfilter.av_buffersrc_add_frame_flags;
import static org.bytedeco.javacpp.avfilter.avfilter_get_by_name;
import static org.bytedeco.javacpp.avfilter.avfilter_graph_alloc;
import static org.bytedeco.javacpp.avfilter.avfilter_graph_config;
import static org.bytedeco.javacpp.avfilter.avfilter_graph_create_filter;
import static org.bytedeco.javacpp.avfilter.avfilter_graph_free;
import static org.bytedeco.javacpp.avfilter.avfilter_graph_parse_ptr;
import static org.bytedeco.javacpp.avfilter.avfilter_inout_alloc;
import static org.bytedeco.javacpp.avfilter.avfilter_inout_free;
import static org.bytedeco.javacpp.avformat.av_dump_format;
import static org.bytedeco.javacpp.avformat.av_find_best_stream;
import static org.bytedeco.javacpp.avformat.av_read_frame;
import static org.bytedeco.javacpp.avformat.avformat_alloc_context;
import static org.bytedeco.javacpp.avformat.avformat_close_input;
import static org.bytedeco.javacpp.avformat.avformat_find_stream_info;
import static org.bytedeco.javacpp.avformat.avformat_open_input;
import static org.bytedeco.javacpp.avutil.AVERROR_EOF;
import static org.bytedeco.javacpp.avutil.AVMEDIA_TYPE_AUDIO;
import static org.bytedeco.javacpp.avutil.AV_CH_LAYOUT_MONO;
import static org.bytedeco.javacpp.avutil.AV_LOG_DEBUG;
import static org.bytedeco.javacpp.avutil.AV_LOG_ERROR;
import static org.bytedeco.javacpp.avutil.AV_LOG_INFO;
import static org.bytedeco.javacpp.avutil.AV_OPT_SEARCH_CHILDREN;
import static org.bytedeco.javacpp.avutil.AV_SAMPLE_FMT_S16;
import static org.bytedeco.javacpp.avutil.av_frame_alloc;
import static org.bytedeco.javacpp.avutil.av_frame_free;
import static org.bytedeco.javacpp.avutil.av_frame_unref;
import static org.bytedeco.javacpp.avutil.av_get_channel_layout_string;
import static org.bytedeco.javacpp.avutil.av_get_default_channel_layout;
import static org.bytedeco.javacpp.avutil.av_get_sample_fmt_name;
import static org.bytedeco.javacpp.avutil.av_log;
import static org.bytedeco.javacpp.avutil.av_log_set_level;
import static org.bytedeco.javacpp.avutil.av_make_error_string;
import static org.bytedeco.javacpp.avutil.av_opt_set_bin;
import static org.bytedeco.javacpp.avutil.av_strdup;
public class Ebur128Filter {
private String fileURI;
private String filterString = "ebur128=metadata=1:peak=true";
private avformat.AVFormatContext fmt_ctx;
private int audio_stream_index;
private avcodec.AVCodecContext dec_ctx;
private avfilter.AVFilterGraph filter_graph;
private avfilter.AVFilterContext buffersrc_ctx;
private avfilter.AVFilterContext buffersink_ctx;
public Ebur128Filter(String fileURI) {
this.fileURI = fileURI;
}
public void start() throws Exception {
av_log_set_level(AV_LOG_DEBUG);
avutil.AVFrame frame = null;
avutil.AVFrame filt_frame = null;
avcodec.AVPacket packet = null;
int ret = 0;
try {
frame = av_frame_alloc();
filt_frame = av_frame_alloc();
packet = new avcodec.AVPacket();
if (frame.isNull() || filt_frame.isNull()) {
throw new OutOfMemoryError();
}
open_input_file(fileURI);
init_filters(filterString);
av_dump_format(fmt_ctx, 0, fileURI, 0);
/* start reading frames*/
while (true) {
if ((ret = av_read_frame(fmt_ctx, packet)) < 0) {
break;
}
//av_dump_format(fmt_ctx, 0, fileURI, 0);
/*packet is from the best stream selected */
if (packet.stream_index() == audio_stream_index) {
/* send packet to decoder*/
ret = avcodec_send_packet(dec_ctx, packet);
if (ret < 0) {
av_log(null, AV_LOG_ERROR, "Error while sending a packet to the decoder\n");
break;
}
/* till methods keep on returning success codes */
while (ret >= 0) {
av_frame_unref(frame);
ret = avcodec_receive_frame(dec_ctx, frame);
if (ret == 35/*EAGAIN*/ || ret == AVERROR_EOF) {
break;
} else if (ret < 0) {
av_log(null, AV_LOG_ERROR, "Error while receiving a frame from the decoder\n");
throw new Exception();
}
if (ret >= 0) {
/* push the audio data from decoded frame into the filtergraph */
if ((ret = av_buffersrc_add_frame_flags(buffersrc_ctx, frame, AV_BUFFERSRC_FLAG_KEEP_REF)
) < 0) {
System.out.println("av_buffersrc_add_frame_flags: Error occurred: "
+ av_make_error_string(new BytePointer(256), 256, ret).getString());
av_log(null, AV_LOG_ERROR, "Error while feeding the audio filtergraph\n");
break;
}
/* pull filtered audio from the filtergraph */
while (true) {
av_frame_unref(filt_frame);
ret = av_buffersink_get_frame(buffersink_ctx, filt_frame);
if (ret == 35 /*EAGAIN*/ || ret == AVERROR_EOF) {
break;
}
if (ret < 0) {
throw new Exception();
}
print_frame(filt_frame);
av_frame_unref(filt_frame);
}
}
}
}
av_packet_unref(packet);
}
} finally {
avfilter_graph_free(filter_graph);
avcodec_free_context(dec_ctx);
avformat_close_input(fmt_ctx);
av_frame_free(frame);
av_frame_free(filt_frame);
if (ret < 0 && ret == AVERROR_EOF) {
System.out.println(": Error occurred: "
+ av_make_error_string(new BytePointer(256), 256, ret).getString());
}
}
}
private void print_frame(avutil.AVFrame filt_frame) {
}
private void init_filters(String filter_descr) throws Exception {
int ret;
avfilter.AVFilter abuffersrc;
avfilter.AVFilter abuffersink;
avfilter.AVFilterInOut outputs = null;
avfilter.AVFilterInOut inputs = null;
try {
abuffersrc = avfilter_get_by_name("abuffer");
abuffersink = avfilter_get_by_name("abuffersink");
outputs = avfilter_inout_alloc();
inputs = avfilter_inout_alloc();
int[] out_sample_fmts = {AV_SAMPLE_FMT_S16, -1};
long[] out_channel_layouts = {AV_CH_LAYOUT_MONO, -1};
int[] out_sample_rates = {8000, -1};
avfilter.AVFilterLink outlink = new avfilter.AVFilterLink();
avutil.AVRational time_base = fmt_ctx.streams(audio_stream_index).time_base();
buffersrc_ctx = new avfilter.AVFilterContext();
buffersink_ctx = new avfilter.AVFilterContext();
filter_graph = avfilter_graph_alloc();
if (outputs == null || outputs.isNull()
|| inputs == null || inputs.isNull()
|| filter_graph == null || filter_graph.isNull()) {
throw new OutOfMemoryError();
}
print_buffersink();
/*buffer audio src: the decoded frames from the decoder will be inserted here */
if (dec_ctx.channel_layout() == 0) {
dec_ctx.channel_layout(av_get_default_channel_layout(dec_ctx.channels()));
}
String args = String.format("time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%08X",
time_base.num(), time_base.den(), dec_ctx.sample_rate(),
av_get_sample_fmt_name(dec_ctx.sample_fmt()).getString(),
dec_ctx.channel_layout());
ret = avfilter_graph_create_filter(buffersrc_ctx, abuffersrc, "in", args, null, filter_graph);
print_buffersink();
if (ret < 0) {
System.out.println("cannot create audio buffer src: Error occurred: "
+ av_make_error_string(new BytePointer(256), 256, ret).getString());
throw new Exception("avfilter_graph_create_filter: Error occurred: "
+ av_make_error_string(new BytePointer(256), 256, ret).getString());
}
/*buffer audio sink : to terminate the filter chain */
ret = avfilter_graph_create_filter(buffersink_ctx, abuffersink, "out", null, null,
filter_graph);
print_buffersink();
if (ret < 0) {
System.out.println("cannot create audio buffer sink: Error occurred: "
+ av_make_error_string(new BytePointer(256), 256, ret).getString());
throw new Exception("avfilter_graph_create_filter: Error occurred: "
+ av_make_error_string(new BytePointer(256), 256, ret).getString());
}
//ret = av_opt_set_int_list(buffersink_ctx, "sample_fmts", out_sample_fmts, -1, AV_OPT_SEARCH_CHILDREN);
ByteBuffer bb = ByteBuffer.allocate((out_sample_fmts.length * 4));
for (final int val : out_sample_fmts) {
bb.putInt(val);
}
ret = av_opt_set_bin(buffersink_ctx, "sample_fmts", bb.array(),
4 * out_sample_fmts.length, AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {
//TODO raise error
}
bb = ByteBuffer.allocate((out_channel_layouts.length * 8));
for (final long val : out_channel_layouts) {
bb.putLong(val);
}
ret = av_opt_set_bin(buffersink_ctx, "channel_layouts", bb.array(),
8 * out_channel_layouts.length, AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {
//TODO raise error
}
bb = ByteBuffer.allocate((out_sample_rates.length * 4));
for (final int val : out_sample_rates) {
bb.putInt(val);
}
ret = av_opt_set_bin(buffersink_ctx, "channel_layouts", bb.array(),
4 * out_sample_rates.length, AV_OPT_SEARCH_CHILDREN);
if (ret < 0) {
//TODO raise error
}
/*
* Set the endpoints for the filter graph. The filter_graph will
* be linked to the graph described by filters_descr.
*/
/*
* The buffer source output must be connected to the input pad of
* the first filter described by filters_descr; since the first
* filter input label is not specified, it is set to "in" by
* default.
*/
outputs.name(av_strdup(new BytePointer("in")));
outputs.filter_ctx(buffersrc_ctx);
outputs.pad_idx(0);
outputs.next(null);
/*
* The buffer sink input must be connected to the output pad of
* the last filter described by filters_descr; since the last
* filter output label is not specified, it is set to "out" by
* default.
*/
inputs.name(av_strdup(new BytePointer("out")));
inputs.filter_ctx(buffersink_ctx);
inputs.pad_idx(0);
inputs.next(null);
if ((ret = avfilter_graph_parse_ptr(filter_graph, filter_descr,
inputs, outputs, null)) < 0) {
//TODO raise error
}
if ((ret = avfilter_graph_config(filter_graph, null)) < 0) {
//TODO raise error
}
/* Print summary of the sink buffer*/
print_buffersink();
} finally {
avfilter_inout_free(inputs);
avfilter_inout_free(outputs);
}
}
private void print_buffersink() {
avfilter.AVFilterLink outlink;
ByteBuffer buffer = ByteBuffer.allocateDirect(512);
BytePointer ptr = new BytePointer(buffer);
if (buffersink_ctx != null && !buffersink_ctx.isNull()
&& buffersink_ctx.nb_inputs() > 0
&& buffersink_ctx.inputs(0) !=null && !buffersink_ctx.inputs(0).isNull()) {
outlink = buffersink_ctx.inputs(0);
av_get_channel_layout_string(ptr, 512, -1, outlink.channel_layout());
av_log(null, AV_LOG_INFO, String.format("Output: srate:%dHz fmt:%s chlayout:%s\n",
(int) outlink.sample_rate(),
av_get_sample_fmt_name(outlink.format()),
ptr.getString()));
}
}
private void open_input_file(String fileURI) throws Exception {
int ret;
avcodec.AVCodec dec = new avcodec.AVCodec();
fmt_ctx = avformat_alloc_context();
if ((ret = avformat_open_input(fmt_ctx, fileURI, (avformat.AVInputFormat) null, (avutil.AVDictionary) null)) < 0) {
System.out.println("avformat_open_input(): Error occurred: "
+ av_make_error_string(new BytePointer(256), 256, ret).getString());
throw new Exception("avformat_open_input(): Error occurred: "
+ av_make_error_string(new BytePointer(256), 256, ret).getString());
}
if ((ret = avformat_find_stream_info(fmt_ctx, (avutil.AVDictionary) null)) < 0) {
System.out.println("avformat_find_stream_info(): Error occurred: "
+ av_make_error_string(new BytePointer(256), 256, ret).getString());
throw new Exception("avformat_find_stream_info(): Error occurred: "
+ av_make_error_string(new BytePointer(256), 256, ret).getString());
}
/* select the best audio stream */
ret = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, dec, 0);
if (ret < 0) {
System.out.println("av_find_best_stream(): Error occurred: "
+ av_make_error_string(new BytePointer(256), 256, ret).getString());
throw new Exception("av_find_best_stream(): Error occurred: "
+ av_make_error_string(new BytePointer(256), 256, ret).getString());
}
audio_stream_index = ret;
/* create decoding context */
dec_ctx = avcodec_alloc_context3(dec);
if (dec_ctx == null || dec_ctx.isNull()) {
throw new OutOfMemoryError();
}
// if (avcodec_open2(dec_ctx, dec, new avutil.AVDictionary()) < 0) {
// //TODO raise exception
// }
avcodec_parameters_to_context(dec_ctx, fmt_ctx.streams(audio_stream_index).codecpar());
/*init the audio decoder*/
if ((ret = avcodec_open2(dec_ctx, dec, (avutil.AVDictionary) null)) < 0) {
System.out.println("cannot open audio decoder: Error occurred: "
+ av_make_error_string(new BytePointer(256), 256, ret).getString());
throw new Exception("avcodec_open2: Error occurred: "
+ av_make_error_string(new BytePointer(256), 256, ret).getString());
}
}
}
=========================================================== But getting the below trace when running the start method.
[NULL @ 0x7fcefb31c600] Opening 'file://resources/sample.mp3' for reading
[file @ 0x7fcef9f6a100] Setting default whitelist 'file,crypto'
[mp3 @ 0x7fcefb31c600] Format mp3 probed with size=4096 and score=51
id3v2 ver:3 flags:00 len:0
[mp3 @ 0x7fcefb31c600] Skipping 0 bytes of junk at 10.
[mp3 @ 0x7fcefb31c600] Before avformat_find_stream_info() pos: 10 bytes read:65664 seeks:2 nb_streams:1
[mp3 @ 0x7fcefb31c600] All info found
[mp3 @ 0x7fcefb31c600] Estimating duration from bitrate, this may be inaccurate
[mp3 @ 0x7fcefb31c600] After avformat_find_stream_info() pos: 21514 bytes read:65664 seeks:2 frames:50
detected 4 logical cores
[in @ 0x7fcef9e63940] Setting 'time_base' to value '1/14112000'
[in @ 0x7fcef9e63940] Setting 'sample_rate' to value '44100'
[in @ 0x7fcef9e63940] Setting 'sample_fmt' to value 'fltp'
[in @ 0x7fcef9e63940] Setting 'channel_layout' to value '0x00000003'
[in @ 0x7fcef9e63940] tb:1/14112000 samplefmt:fltp samplerate:44100 chlayout:0x00000003
[Parsed_ebur128_0 @ 0x7fcef9e647c0] Setting 'metadata' to value '1'
[Parsed_ebur128_0 @ 0x7fcef9e647c0] Setting 'peak' to value 'true'
[Parsed_ebur128_0 @ 0x7fcef9e647c0] EBU +9 scale
[out @ 0x7fcef9e64040] auto-inserting filter 'auto_resampler_0' between the filter 'Parsed_ebur128_0' and the filter 'out'
Impossible to convert between the formats supported by the filter 'Parsed_ebur128_0' and the filter 'auto_resampler_0'
Output: srate:0Hz fmt:null chlayout:0 channelsInput #0, mp3, from 'file://resources/sample.mp3':
Duration: 00:00:27.74, start: 0.000000, bitrate: 128 kb/s
Stream #0:0, 50, 1/14112000: Audio: mp3, 44100 Hz, stereo, fltp, 128 kb/s
[Parsed_ebur128_0 @ 0x7fcef9e647c0] Format change is not supported
av_buffersrc_add_frame_flags: Error occurred: Not yet implemented in FFmpeg, patches welcome
error is raised when calling if ((ret = avfilter_graph_config(filter_graph, null)) < 0) {