mpv/audio/filter/af_lavcac3enc.c

389 lines
11 KiB
C

/*
* audio filter for runtime AC-3 encoding with libavcodec.
*
* Copyright (C) 2007 Ulion <ulion A gmail P com>
*
* This file is part of mpv.
*
* mpv is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* mpv is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <inttypes.h>
#include <assert.h>
#include <libavcodec/avcodec.h>
#include <libavutil/intreadwrite.h>
#include <libavutil/common.h>
#include <libavutil/bswap.h>
#include <libavutil/mem.h>
#include "audio/aframe.h"
#include "audio/chmap_sel.h"
#include "audio/fmt-conversion.h"
#include "audio/format.h"
#include "common/av_common.h"
#include "common/common.h"
#include "filters/f_autoconvert.h"
#include "filters/f_utils.h"
#include "filters/filter_internal.h"
#include "filters/user_filters.h"
#include "options/m_option.h"
#define AC3_MAX_CHANNELS 6
#define AC3_MAX_CODED_FRAME_SIZE 3840
#define AC3_FRAME_SIZE (6 * 256)
const uint16_t ac3_bitrate_tab[19] = {
32, 40, 48, 56, 64, 80, 96, 112, 128,
160, 192, 224, 256, 320, 384, 448, 512, 576, 640
};
struct f_opts {
int add_iec61937_header;
int bit_rate;
int min_channel_num;
char *encoder;
char **avopts;
};
struct priv {
struct f_opts *opts;
struct mp_pin *in_pin;
struct mp_aframe *cur_format;
struct mp_aframe *in_frame;
struct mp_aframe_pool *out_pool;
struct AVCodec *lavc_acodec;
struct AVCodecContext *lavc_actx;
int bit_rate;
int out_samples; // upper bound on encoded output per AC3 frame
};
static bool reinit(struct mp_filter *f)
{
struct priv *s = f->priv;
mp_aframe_reset(s->cur_format);
static const int default_bit_rate[AC3_MAX_CHANNELS+1] = \
{0, 96000, 192000, 256000, 384000, 448000, 448000};
if (s->opts->add_iec61937_header) {
s->out_samples = AC3_FRAME_SIZE;
} else {
s->out_samples = AC3_MAX_CODED_FRAME_SIZE /
mp_aframe_get_sstride(s->in_frame);
}
int format = mp_aframe_get_format(s->in_frame);
int rate = mp_aframe_get_rate(s->in_frame);
struct mp_chmap chmap = {0};
mp_aframe_get_chmap(s->in_frame, &chmap);
int bit_rate = s->bit_rate;
if (!bit_rate && chmap.num < AC3_MAX_CHANNELS + 1)
bit_rate = default_bit_rate[chmap.num];
avcodec_close(s->lavc_actx);
// Put sample parameters
s->lavc_actx->sample_fmt = af_to_avformat(format);
s->lavc_actx->channels = chmap.num;
s->lavc_actx->channel_layout = mp_chmap_to_lavc(&chmap);
s->lavc_actx->sample_rate = rate;
s->lavc_actx->bit_rate = bit_rate;
if (avcodec_open2(s->lavc_actx, s->lavc_acodec, NULL) < 0) {
MP_ERR(f, "Couldn't open codec %s, br=%d.\n", "ac3", bit_rate);
return false;
}
if (s->lavc_actx->frame_size < 1) {
MP_ERR(f, "encoder didn't specify input frame size\n");
return false;
}
mp_aframe_config_copy(s->cur_format, s->in_frame);
return true;
}
static void reset(struct mp_filter *f)
{
struct priv *s = f->priv;
TA_FREEP(&s->in_frame);
}
static void destroy(struct mp_filter *f)
{
struct priv *s = f->priv;
reset(f);
avcodec_free_context(&s->lavc_actx);
}
static void swap_16(uint16_t *ptr, size_t size)
{
for (size_t n = 0; n < size; n++)
ptr[n] = av_bswap16(ptr[n]);
}
static void process(struct mp_filter *f)
{
struct priv *s = f->priv;
if (!mp_pin_in_needs_data(f->ppins[1]))
return;
bool err = true;
struct mp_aframe *out = NULL;
AVPacket pkt = {0};
av_init_packet(&pkt);
// Send input as long as it wants.
while (1) {
if (avcodec_is_open(s->lavc_actx)) {
int lavc_ret = avcodec_receive_packet(s->lavc_actx, &pkt);
if (lavc_ret >= 0)
break;
if (lavc_ret < 0 && lavc_ret != AVERROR(EAGAIN)) {
MP_FATAL(f, "Encode failed (receive).\n");
goto done;
}
}
AVFrame *frame = NULL;
struct mp_frame input = mp_pin_out_read(s->in_pin);
// The following code assumes no sample data buffering in the encoder.
if (input.type == MP_FRAME_EOF) {
mp_pin_in_write(f->ppins[1], input);
return;
} else if (input.type == MP_FRAME_AUDIO) {
TA_FREEP(&s->in_frame);
s->in_frame = input.data;
frame = mp_frame_to_av(input, NULL);
if (!frame)
goto done;
if (mp_aframe_get_channels(s->in_frame) < s->opts->min_channel_num) {
// Just pass it through.
s->in_frame = NULL;
mp_pin_in_write(f->ppins[1], input);
return;
}
if (!mp_aframe_config_equals(s->in_frame, s->cur_format)) {
if (!reinit(f))
goto done;
}
} else if (input.type) {
goto done;
} else {
return; // no data yet
}
int lavc_ret = avcodec_send_frame(s->lavc_actx, frame);
av_frame_free(&frame);
if (lavc_ret < 0 && lavc_ret != AVERROR(EAGAIN)) {
MP_FATAL(f, "Encode failed (send).\n");
goto done;
}
}
if (!s->in_frame)
goto done;
out = mp_aframe_create();
mp_aframe_set_format(out, AF_FORMAT_S_AC3);
mp_aframe_set_chmap(out, &(struct mp_chmap)MP_CHMAP_INIT_STEREO);
mp_aframe_set_rate(out, 48000);
if (mp_aframe_pool_allocate(s->out_pool, out, s->out_samples) < 0)
goto done;
int sstride = mp_aframe_get_sstride(out);
mp_aframe_copy_attributes(out, s->in_frame);
int frame_size = pkt.size;
int header_len = 0;
char hdr[8];
if (s->opts->add_iec61937_header && pkt.size > 5) {
int bsmod = pkt.data[5] & 0x7;
int len = frame_size;
frame_size = AC3_FRAME_SIZE * 2 * 2;
header_len = 8;
AV_WL16(hdr, 0xF872); // iec 61937 syncword 1
AV_WL16(hdr + 2, 0x4E1F); // iec 61937 syncword 2
hdr[5] = bsmod; // bsmod
hdr[4] = 0x01; // data-type ac3
AV_WL16(hdr + 6, len << 3); // number of bits in payload
}
if (frame_size > s->out_samples * sstride)
abort();
uint8_t **planes = mp_aframe_get_data_rw(out);
if (!planes)
goto done;
char *buf = planes[0];
memcpy(buf, hdr, header_len);
memcpy(buf + header_len, pkt.data, pkt.size);
memset(buf + header_len + pkt.size, 0,
frame_size - (header_len + pkt.size));
swap_16((uint16_t *)(buf + header_len), pkt.size / 2);
mp_aframe_set_size(out, frame_size / sstride);
mp_pin_in_write(f->ppins[1], MAKE_FRAME(MP_FRAME_AUDIO, out));
out = NULL;
err = 0;
done:
av_packet_unref(&pkt);
talloc_free(out);
if (err)
mp_filter_internal_mark_failed(f);
}
static const struct mp_filter_info af_lavcac3enc_filter = {
.name = "lavcac3enc",
.priv_size = sizeof(struct priv),
.process = process,
.reset = reset,
.destroy = destroy,
};
static struct mp_filter *af_lavcac3enc_create(struct mp_filter *parent,
void *options)
{
struct mp_filter *f = mp_filter_create(parent, &af_lavcac3enc_filter);
if (!f) {
talloc_free(options);
return NULL;
}
mp_filter_add_pin(f, MP_PIN_IN, "in");
mp_filter_add_pin(f, MP_PIN_OUT, "out");
struct priv *s = f->priv;
s->opts = talloc_steal(s, options);
s->cur_format = talloc_steal(s, mp_aframe_create());
s->out_pool = mp_aframe_pool_create(s);
s->lavc_acodec = avcodec_find_encoder_by_name(s->opts->encoder);
if (!s->lavc_acodec) {
MP_ERR(f, "Couldn't find encoder %s.\n", s->opts->encoder);
goto error;
}
s->lavc_actx = avcodec_alloc_context3(s->lavc_acodec);
if (!s->lavc_actx) {
MP_ERR(f, "Audio LAVC, couldn't allocate context!\n");
goto error;
}
if (mp_set_avopts(f->log, s->lavc_actx, s->opts->avopts) < 0)
goto error;
// For this one, we require the decoder to expert lists of all supported
// parameters. (Not all decoders do that, but the ones we're interested
// in do.)
if (!s->lavc_acodec->sample_fmts ||
!s->lavc_acodec->channel_layouts)
{
MP_ERR(f, "Audio encoder doesn't list supported parameters.\n");
goto error;
}
if (s->opts->bit_rate) {
int i;
for (i = 0; i < 19; i++) {
if (ac3_bitrate_tab[i] == s->opts->bit_rate) {
s->bit_rate = ac3_bitrate_tab[i] * 1000;
break;
}
}
if (i >= 19) {
MP_WARN(f, "unable set unsupported bitrate %d, using default "
"bitrate (check manpage to see supported bitrates).\n",
s->opts->bit_rate);
}
}
struct mp_autoconvert *conv = mp_autoconvert_create(f);
if (!conv)
abort();
const enum AVSampleFormat *lf = s->lavc_acodec->sample_fmts;
for (int i = 0; lf && lf[i] != AV_SAMPLE_FMT_NONE; i++) {
int mpfmt = af_from_avformat(lf[i]);
if (mpfmt)
mp_autoconvert_add_afmt(conv, mpfmt);
}
const uint64_t *lch = s->lavc_acodec->channel_layouts;
for (int n = 0; lch && lch[n]; n++) {
struct mp_chmap chmap = {0};
mp_chmap_from_lavc(&chmap, lch[n]);
if (mp_chmap_is_valid(&chmap))
mp_autoconvert_add_chmap(conv, &chmap);
}
// At least currently, the AC3 encoder doesn't export sample rates.
mp_autoconvert_add_srate(conv, 48000);
mp_pin_connect(conv->f->pins[0], f->ppins[0]);
struct mp_filter *fs = mp_fixed_aframe_size_create(f, AC3_FRAME_SIZE, true);
if (!fs)
abort();
mp_pin_connect(fs->pins[0], conv->f->pins[1]);
s->in_pin = fs->pins[1];
return f;
error:
talloc_free(f);
return NULL;
}
#define OPT_BASE_STRUCT struct f_opts
const struct mp_user_filter_entry af_lavcac3enc = {
.desc = {
.description = "runtime encode to ac3 using libavcodec",
.name = "lavcac3enc",
.priv_size = sizeof(OPT_BASE_STRUCT),
.priv_defaults = &(const OPT_BASE_STRUCT) {
.add_iec61937_header = 1,
.bit_rate = 640,
.min_channel_num = 3,
.encoder = "ac3",
},
.options = (const struct m_option[]) {
{"tospdif", OPT_FLAG(add_iec61937_header)},
{"bitrate", OPT_CHOICE(bit_rate,
{"auto", 0}, {"default", 0}), M_RANGE(32, 640)},
{"minch", OPT_INT(min_channel_num), M_RANGE(2, 6)},
{"encoder", OPT_STRING(encoder)},
{"o", OPT_KEYVALUELIST(avopts)},
{0}
},
},
.create = af_lavcac3enc_create,
};