diff options
Diffstat (limited to 'audio/filter/af_lavcac3enc.c')
-rw-r--r-- | audio/filter/af_lavcac3enc.c | 82 |
1 files changed, 46 insertions, 36 deletions
diff --git a/audio/filter/af_lavcac3enc.c b/audio/filter/af_lavcac3enc.c index c7582cf52b..45ebfa12a2 100644 --- a/audio/filter/af_lavcac3enc.c +++ b/audio/filter/af_lavcac3enc.c @@ -47,7 +47,7 @@ #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] = { +const static 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 }; @@ -68,8 +68,9 @@ struct priv { struct mp_aframe *in_frame; struct mp_aframe_pool *out_pool; - struct AVCodec *lavc_acodec; + const struct AVCodec *lavc_acodec; struct AVCodecContext *lavc_actx; + AVPacket *lavc_pkt; int bit_rate; int out_samples; // upper bound on encoded output per AC3 frame }; @@ -134,6 +135,7 @@ static void destroy(struct mp_filter *f) struct priv *s = f->priv; reset(f); + av_packet_free(&s->lavc_pkt); avcodec_free_context(&s->lavc_actx); } @@ -152,57 +154,57 @@ static void process(struct mp_filter *f) bool err = true; struct mp_aframe *out = NULL; - AVPacket pkt = {0}; - av_init_packet(&pkt); + AVPacket *pkt = s->lavc_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); + 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; + goto error; } } 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) { + switch (input.type) { + case MP_FRAME_NONE: + goto done; // no data yet + case MP_FRAME_EOF: mp_pin_in_write(f->ppins[1], input); - return; - } else if (input.type == MP_FRAME_AUDIO) { + goto done; + case MP_FRAME_AUDIO: TA_FREEP(&s->in_frame); s->in_frame = input.data; frame = mp_frame_to_av(input, NULL); if (!frame) - goto done; + goto error; 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; + goto done; } if (!mp_aframe_config_equals(s->in_frame, s->cur_format)) { if (!reinit(f)) - goto done; + goto error; } - } else if (input.type) { - goto done; - } else { - return; // no data yet + break; + default: goto error; // unexpected packet type } 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; + goto error; } } if (!s->in_frame) - goto done; + goto error; out = mp_aframe_create(); mp_aframe_set_format(out, AF_FORMAT_S_AC3); @@ -210,18 +212,18 @@ static void process(struct mp_filter *f) mp_aframe_set_rate(out, 48000); if (mp_aframe_pool_allocate(s->out_pool, out, s->out_samples) < 0) - goto done; + goto error; int sstride = mp_aframe_get_sstride(out); mp_aframe_copy_attributes(out, s->in_frame); - int frame_size = pkt.size; + 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; + 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; @@ -239,20 +241,22 @@ static void process(struct mp_filter *f) uint8_t **planes = mp_aframe_get_data_rw(out); if (!planes) - goto done; + goto error; 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); + 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); + err = false; + // fall through +error: + av_packet_unref(pkt); talloc_free(out); if (err) mp_filter_internal_mark_failed(f); @@ -295,10 +299,14 @@ static struct mp_filter *af_lavcac3enc_create(struct mp_filter *parent, goto error; } + s->lavc_pkt = av_packet_alloc(); + if (!s->lavc_pkt) + 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 + // For this one, we require the decoder to export lists of all supported // parameters. (Not all decoders do that, but the ones we're interested // in do.) if (!s->lavc_acodec->sample_fmts || @@ -357,6 +365,8 @@ static struct mp_filter *af_lavcac3enc_create(struct mp_filter *parent, return f; error: + av_packet_free(&s->lavc_pkt); + avcodec_free_context(&s->lavc_actx); talloc_free(f); return NULL; } @@ -375,12 +385,12 @@ const struct mp_user_filter_entry af_lavcac3enc = { .encoder = "ac3", }, .options = (const struct m_option[]) { - OPT_FLAG("tospdif", add_iec61937_header, 0), - OPT_CHOICE_OR_INT("bitrate", bit_rate, 0, 32, 640, - ({"auto", 0}, {"default", 0})), - OPT_INTRANGE("minch", min_channel_num, 0, 2, 6), - OPT_STRING("encoder", encoder, 0), - OPT_KEYVALUELIST("o", avopts, 0), + {"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} }, }, |