changeset 36335:f77a74ebb95e

Quick an inefficient hack to enable planar encoding. Should fix bugzilla #2094.
author reimar
date Sun, 25 Aug 2013 11:30:45 +0000
parents c1033e9288b1
children e24ada1fc15f
files av_helpers.c libaf/af_lavcac3enc.c libmpcodecs/ae_lavc.c
diffstat 3 files changed, 27 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/av_helpers.c	Sun Aug 25 11:30:43 2013 +0000
+++ b/av_helpers.c	Sun Aug 25 11:30:45 2013 +0000
@@ -117,11 +117,13 @@
 
 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 n;
     int got;
     AVPacket pkt;
-    AVFrame frame;
+    AVFrame *frame = avcodec_alloc_frame();
     if ((ctx->channels == 6 || ctx->channels == 5) &&
         (!strcmp(ctx->codec->name,"ac3") || !strcmp(ctx->codec->name,"libfaac"))) {
         int isac3 = !strcmp(ctx->codec->name,"ac3");
@@ -132,10 +134,27 @@
     }
     pkt.data = dst;
     pkt.size = dst_len;
-    frame.data[0] = src;
-    frame.linesize[0] = src_len / ctx->channels;
-    frame.nb_samples = frame.linesize[0] / bps;
-    n = avcodec_encode_audio2(ctx, &pkt, &frame, &got);
+    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;
 }
--- a/libaf/af_lavcac3enc.c	Sun Aug 25 11:30:43 2013 +0000
+++ b/libaf/af_lavcac3enc.c	Sun Aug 25 11:30:45 2013 +0000
@@ -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) {
--- a/libmpcodecs/ae_lavc.c	Sun Aug 25 11:30:43 2013 +0000
+++ b/libmpcodecs/ae_lavc.c	Sun Aug 25 11:30:45 2013 +0000
@@ -181,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;