diff -urw mplayer-export-2013-08-11/av_helpers.c mplayer-export-2013-10-03/av_helpers.c --- mplayer-export-2013-08-11/av_helpers.c 2013-08-13 13:24:52.000000000 -0400 +++ mplayer-export-2013-10-03/av_helpers.c 2013-10-03 20:29:50.000000000 -0400 @@ -22,6 +22,7 @@ #include "libavformat/avformat.h" #include "mp_msg.h" #include "av_helpers.h" +#include "libaf/reorder_ch.h" int avcodec_initialized; int avformat_initialized; @@ -113,3 +114,47 @@ av_log_set_callback(mp_msp_av_log_callback); } } + +int lavc_encode_audio(AVCodecContext *ctx, void *src, int src_len, void *dst, int dst_len) +{ + void *orig_src = src; + int bps = av_get_bytes_per_sample(ctx->sample_fmt); + int planar = ctx->channels > 1 && av_sample_fmt_is_planar(ctx->sample_fmt); + int isac3 = ctx->codec->id == AV_CODEC_ID_AC3; + int n; + int got; + AVPacket pkt; + AVFrame *frame = avcodec_alloc_frame(); + if ((ctx->channels == 6 || ctx->channels == 5) && + (isac3 || !strcmp(ctx->codec->name,"libfaac"))) { + reorder_channel_nch(src, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, + isac3 ? AF_CHANNEL_LAYOUT_LAVC_DEFAULT : AF_CHANNEL_LAYOUT_AAC_DEFAULT, + ctx->channels, + src_len / bps, bps); + } + pkt.data = dst; + pkt.size = dst_len; + frame->nb_samples = src_len / ctx->channels / bps; + if (planar) { + // TODO: this is horribly inefficient. + int ch; + src = av_mallocz(src_len); + for (ch = 0; ch < ctx->channels; ch++) { + uint8_t *tmps = (uint8_t *)orig_src + ch*bps; + uint8_t *tmpd = (uint8_t *)src + ch*src_len/ctx->channels; + int s; + for (s = 0; s < frame->nb_samples; s++) { + memcpy(tmpd, tmps, bps); + tmps += ctx->channels * bps; + tmpd += bps; + } + } + } + n = avcodec_fill_audio_frame(frame, ctx->channels, ctx->sample_fmt, src, src_len, 1); + if (n < 0) return 0; + n = avcodec_encode_audio2(ctx, &pkt, frame, &got); + avcodec_free_frame(&frame); + if (planar) av_free(src); + if (n < 0) return n; + return got ? pkt.size : 0; +} diff -urw mplayer-export-2013-08-11/av_helpers.h mplayer-export-2013-10-03/av_helpers.h --- mplayer-export-2013-08-11/av_helpers.h 2013-08-13 13:24:52.000000000 -0400 +++ mplayer-export-2013-10-03/av_helpers.h 2013-10-03 20:29:50.000000000 -0400 @@ -21,7 +21,10 @@ #ifndef MPLAYER_AV_HELPERS_H #define MPLAYER_AV_HELPERS_H +struct AVCodecContext; + void init_avcodec(void); void init_avformat(void); +int lavc_encode_audio(struct AVCodecContext *ctx, void *src, int src_len, void *dst, int dst_len); #endif /* MPLAYER_AV_HELPERS_H */ diff -urw mplayer-export-2013-08-11/libaf/af_lavcac3enc.c mplayer-export-2013-10-03/libaf/af_lavcac3enc.c --- mplayer-export-2013-08-11/libaf/af_lavcac3enc.c 2013-08-13 13:24:58.000000000 -0400 +++ mplayer-export-2013-10-03/libaf/af_lavcac3enc.c 2013-10-03 20:30:59.000000000 -0400 @@ -106,7 +106,7 @@ // Put sample parameters s->lavc_actx->channels = af->data->nch; s->lavc_actx->sample_rate = af->data->rate; - s->lavc_actx->sample_fmt = AV_SAMPLE_FMT_S16; + s->lavc_actx->sample_fmt = AV_SAMPLE_FMT_S16P; s->lavc_actx->bit_rate = bit_rate; if(avcodec_open2(s->lavc_actx, s->lavc_acodec, NULL) < 0) { @@ -202,6 +202,7 @@ while (left > 0) { + void *in = NULL; if (left + s->pending_len < s->expect_len) { memcpy(s->pending_data + s->pending_len, src, left); src += left; @@ -220,31 +221,18 @@ src += needs; left -= needs; } - - if (c->nch >= 5) - reorder_channel_nch(s->pending_data, - AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, - AF_CHANNEL_LAYOUT_LAVC_DEFAULT, - c->nch, - s->expect_len / 2, 2); - - len = avcodec_encode_audio(s->lavc_actx, dest, destsize, - (void *)s->pending_data); + in = s->pending_data; s->pending_len = 0; } else { - if (c->nch >= 5) - reorder_channel_nch(src, - AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, - AF_CHANNEL_LAYOUT_LAVC_DEFAULT, - c->nch, - s->expect_len / 2, 2); - len = avcodec_encode_audio(s->lavc_actx,dest,destsize,(void *)src); + in = src; src += s->expect_len; left -= s->expect_len; } + len = lavc_encode_audio(s->lavc_actx, in, s->expect_len, dest, destsize); mp_msg(MSGT_AFILTER, MSGL_DBG2, "avcodec_encode_audio got %d, pending %d.\n", len, s->pending_len); + if (len < 0) len = 0; if (s->add_iec61937_header) { int bsmod = dest[5] & 0x7; diff -urw mplayer-export-2013-08-11/libmpcodecs/ae_lavc.c mplayer-export-2013-10-03/libmpcodecs/ae_lavc.c --- mplayer-export-2013-08-11/libmpcodecs/ae_lavc.c 2013-08-13 13:24:51.000000000 -0400 +++ mplayer-export-2013-10-03/libmpcodecs/ae_lavc.c 2013-10-03 20:29:41.000000000 -0400 @@ -118,20 +118,9 @@ static int encode_lavc(audio_encoder_t *encoder, uint8_t *dest, void *src, int size, int max_size) { int n; - if ((encoder->params.channels == 6 || encoder->params.channels == 5) && - (!strcmp(lavc_acodec->name,"ac3") || - !strcmp(lavc_acodec->name,"libfaac"))) { - int isac3 = !strcmp(lavc_acodec->name,"ac3"); - int bps = av_get_bytes_per_sample(lavc_actx->sample_fmt); - reorder_channel_nch(src, AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT, - isac3 ? AF_CHANNEL_LAYOUT_LAVC_DEFAULT - : AF_CHANNEL_LAYOUT_AAC_DEFAULT, - encoder->params.channels, - size / bps, bps); - } - n = avcodec_encode_audio(lavc_actx, dest, size, src); - compressed_frame_size = n; - return n; + n = lavc_encode_audio(lavc_actx, src, size, dest, max_size); + compressed_frame_size = n < 0 ? 0 : n; + return compressed_frame_size; } @@ -192,13 +181,13 @@ const enum AVSampleFormat *fmts; lavc_actx->sample_fmt = lavc_acodec->sample_fmts[0]; // fallback to first format for (fmts = lavc_acodec->sample_fmts; *fmts != AV_SAMPLE_FMT_NONE; fmts++) { - if (samplefmt2affmt(*fmts) == encoder->params.sample_format) { // preferred format found + if (samplefmt2affmt(av_get_packed_sample_fmt(*fmts)) == encoder->params.sample_format) { // preferred format found lavc_actx->sample_fmt = *fmts; break; } } } - encoder->input_format = samplefmt2affmt(lavc_actx->sample_fmt); + encoder->input_format = samplefmt2affmt(av_get_packed_sample_fmt(lavc_actx->sample_fmt)); if (encoder->input_format == AF_FORMAT_UNKNOWN) { mp_msg(MSGT_MENCODER,MSGL_ERR, "Audio encoder requires unknown or unsupported input format\n"); return 0;