Skip to content

Commit c3146a4

Browse files
committed
add channels option to decoder
1 parent 73ac5f2 commit c3146a4

6 files changed

Lines changed: 46 additions & 20 deletions

File tree

c_src/xav/decoder.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ struct Decoder *decoder_alloc() {
1313
return decoder;
1414
}
1515

16-
int decoder_init(struct Decoder *decoder, const AVCodec *codec) {
16+
int decoder_init(struct Decoder *decoder, const AVCodec *codec, int channels) {
1717
decoder->media_type = codec->type;
1818
decoder->codec = codec;
1919

@@ -22,6 +22,10 @@ int decoder_init(struct Decoder *decoder, const AVCodec *codec) {
2222
return -1;
2323
}
2424

25+
if (codec->type == AVMEDIA_TYPE_AUDIO && channels != -1) {
26+
decoder->c->channels = channels;
27+
}
28+
2529
decoder->frame = av_frame_alloc();
2630
if (!decoder->frame) {
2731
return -1;
@@ -32,11 +36,7 @@ int decoder_init(struct Decoder *decoder, const AVCodec *codec) {
3236
return -1;
3337
}
3438

35-
if (avcodec_open2(decoder->c, decoder->codec, NULL) < 0) {
36-
return -1;
37-
}
38-
39-
return 0;
39+
return avcodec_open2(decoder->c, decoder->codec, NULL);
4040
}
4141

4242
int decoder_decode(struct Decoder *decoder, AVPacket *pkt, AVFrame *frame) {

c_src/xav/decoder.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ struct Decoder {
1616

1717
struct Decoder *decoder_alloc();
1818

19-
int decoder_init(struct Decoder *decoder, const AVCodec *codec);
19+
int decoder_init(struct Decoder *decoder, const AVCodec *codec, int channels);
2020

2121
int decoder_decode(struct Decoder *decoder, AVPacket *pkt, AVFrame *frame);
2222

c_src/xav/xav_decoder.c

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,14 @@ void free_frames(AVFrame **frames, int size) {
1313
}
1414

1515
ERL_NIF_TERM new (ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
16-
if (argc != 6) {
16+
if (argc != 7) {
1717
return xav_nif_raise(env, "invalid_arg_count");
1818
}
1919

2020
ERL_NIF_TERM ret;
2121
char *codec_name = NULL;
2222
char *out_format = NULL;
23+
int channels;
2324

2425
// resolve codec
2526
if (!xav_nif_get_atom(env, argv[0], &codec_name)) {
@@ -37,8 +38,13 @@ ERL_NIF_TERM new (ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
3738
goto clean;
3839
}
3940

41+
if (!enif_get_int(env, argv[1], &channels)) {
42+
ret = xav_nif_raise(env, "failed_to_get_int");
43+
goto clean;
44+
}
45+
4046
// resolve output format
41-
if (!xav_nif_get_atom(env, argv[1], &out_format)) {
47+
if (!xav_nif_get_atom(env, argv[2], &out_format)) {
4248
ret = xav_nif_raise(env, "failed_to_get_atom");
4349
goto clean;
4450
}
@@ -61,25 +67,25 @@ ERL_NIF_TERM new (ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
6167

6268
// resolve other params
6369
int out_sample_rate;
64-
if (!enif_get_int(env, argv[2], &out_sample_rate)) {
70+
if (!enif_get_int(env, argv[3], &out_sample_rate)) {
6571
ret = xav_nif_raise(env, "invalid_out_sample_rate");
6672
goto clean;
6773
}
6874

6975
int out_channels;
70-
if (!enif_get_int(env, argv[3], &out_channels)) {
76+
if (!enif_get_int(env, argv[4], &out_channels)) {
7177
ret = xav_nif_raise(env, "invalid_out_channels");
7278
goto clean;
7379
}
7480

7581
int out_width;
76-
if (!enif_get_int(env, argv[4], &out_width)) {
82+
if (!enif_get_int(env, argv[5], &out_width)) {
7783
ret = xav_nif_raise(env, "failed_to_get_int");
7884
goto clean;
7985
}
8086

8187
int out_height;
82-
if (!enif_get_int(env, argv[5], &out_height)) {
88+
if (!enif_get_int(env, argv[6], &out_height)) {
8389
ret = xav_nif_raise(env, "failed_to_get_int");
8490
goto clean;
8591
}
@@ -102,7 +108,7 @@ ERL_NIF_TERM new (ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[]) {
102108
goto clean;
103109
}
104110

105-
if (decoder_init(xav_decoder->decoder, codec) != 0) {
111+
if (decoder_init(xav_decoder->decoder, codec, channels)) {
106112
ret = xav_nif_raise(env, "failed_to_init_decoder");
107113
goto clean;
108114
}
@@ -393,7 +399,7 @@ void free_xav_decoder(ErlNifEnv *env, void *obj) {
393399
}
394400
}
395401

396-
static ErlNifFunc xav_funcs[] = {{"new", 6, new},
402+
static ErlNifFunc xav_funcs[] = {{"new", 7, new},
397403
{"decode", 4, decode, ERL_NIF_DIRTY_JOB_CPU_BOUND},
398404
{"flush", 1, flush, ERL_NIF_DIRTY_JOB_CPU_BOUND},
399405
{"pixel_formats", 0, pixel_formats},

lib/xav/decoder.ex

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ defmodule Xav.Decoder do
1313
@type t() :: reference()
1414

1515
@decoder_options_schema [
16+
channels: [
17+
type: :pos_integer,
18+
doc: """
19+
The number of channels of the encoded audio.
20+
21+
Some decoders require this field to be set by the user. (e.g. `G711`)
22+
"""
23+
],
1624
out_format: [
1725
type: :atom,
1826
doc: """
@@ -80,6 +88,7 @@ defmodule Xav.Decoder do
8088

8189
Xav.Decoder.NIF.new(
8290
codec,
91+
opts[:channels] || -1,
8392
opts[:out_format],
8493
opts[:out_sample_rate] || 0,
8594
opts[:out_channels] || 0,

lib/xav/decoder_nif.ex

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,15 @@ defmodule Xav.Decoder.NIF do
88
:ok = :erlang.load_nif(path, 0)
99
end
1010

11-
def new(_codec, _out_format, _out_sample_rate, _out_channels, _out_width, _out_height) do
11+
def new(
12+
_codec,
13+
_channels,
14+
_out_format,
15+
_out_sample_rate,
16+
_out_channels,
17+
_out_width,
18+
_out_height
19+
) do
1220
:erlang.nif_error(:undef)
1321
end
1422

test/encoder_test.exs

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,15 +124,18 @@ defmodule Xav.EncoderTest do
124124
)
125125

126126
encoded_data =
127-
File.stream!(audio_file, 20)
128-
|> Stream.map(&%Xav.Frame{type: :audio, data: &1, format: :s16, pts: 0})
127+
File.read!(audio_file)
128+
|> :binary.bin_to_list()
129+
|> Enum.chunk_every(20)
130+
|> Stream.map(
131+
&%Xav.Frame{type: :audio, data: :binary.list_to_bin(&1), format: :s16, pts: 0}
132+
)
129133
|> Stream.transform(
130134
fn -> encoder end,
131135
fn frame, encoder ->
132136
{Xav.Encoder.encode(encoder, frame), encoder}
133137
end,
134-
fn encoder -> {Xav.Encoder.flush(encoder), encoder} end,
135-
fn _encoder -> :ok end
138+
fn encoder -> {Xav.Encoder.flush(encoder), encoder} end
136139
)
137140
|> Stream.map(& &1.data)
138141
|> Enum.join()

0 commit comments

Comments
 (0)