summaryrefslogtreecommitdiffstats
path: root/audio/out
diff options
context:
space:
mode:
authorRudolf Polzer <divverent@xonotic.org>2012-12-03 20:16:17 +0100
committerRudolf Polzer <divverent@xonotic.org>2012-12-03 20:16:17 +0100
commit1085539bde0937dd156566b3dea957f3efbe0b29 (patch)
tree45cf9258bd5b4ff281c83f7a9c11738ecd001c32 /audio/out
parent54d998d5e7f101312cf26e9fc4d199fa9fed33c2 (diff)
downloadmpv-1085539bde0937dd156566b3dea957f3efbe0b29.tar.bz2
mpv-1085539bde0937dd156566b3dea957f3efbe0b29.tar.xz
af_lavcac3enc, encode: support planar formats
This fixes operation with current ffmpeg releases. Note that this planarization is slow and should be reverted once proper planar audio support is there in mpv.
Diffstat (limited to 'audio/out')
-rw-r--r--audio/out/ao_lavc.c58
1 files changed, 55 insertions, 3 deletions
diff --git a/audio/out/ao_lavc.c b/audio/out/ao_lavc.c
index c2fd2e6d63..0a648e1b6b 100644
--- a/audio/out/ao_lavc.c
+++ b/audio/out/ao_lavc.c
@@ -46,6 +46,7 @@ struct priv {
uint8_t *buffer;
size_t buffer_size;
AVStream *stream;
+ bool planarize;
int pcmhack;
int aframesize;
int aframecount;
@@ -112,27 +113,32 @@ static int init(struct ao *ao, char *params)
++sampleformat) {
switch (*sampleformat) {
case AV_SAMPLE_FMT_U8:
+ case AV_SAMPLE_FMT_U8P:
if (ao->format == AF_FORMAT_U8)
goto out_search;
break;
case AV_SAMPLE_FMT_S16:
+ case AV_SAMPLE_FMT_S16P:
if (ao->format == AF_FORMAT_S16_BE)
goto out_search;
if (ao->format == AF_FORMAT_S16_LE)
goto out_search;
break;
case AV_SAMPLE_FMT_S32:
+ case AV_SAMPLE_FMT_S32P:
if (ao->format == AF_FORMAT_S32_BE)
goto out_search;
if (ao->format == AF_FORMAT_S32_LE)
goto out_search;
break;
case AV_SAMPLE_FMT_FLT:
+ case AV_SAMPLE_FMT_FLTP:
if (ao->format == AF_FORMAT_FLOAT_BE)
goto out_search;
if (ao->format == AF_FORMAT_FLOAT_LE)
goto out_search;
break;
+ // FIXME do we need support for AV_SAMPLE_FORMAT_DBL/DBLP?
default:
break;
}
@@ -151,17 +157,22 @@ out_search:
++sampleformat) {
switch (*sampleformat) {
case AV_SAMPLE_FMT_U8:
+ case AV_SAMPLE_FMT_U8P:
ao->format = AF_FORMAT_U8;
goto out_takefirst;
case AV_SAMPLE_FMT_S16:
+ case AV_SAMPLE_FMT_S16P:
ao->format = AF_FORMAT_S16_NE;
goto out_takefirst;
case AV_SAMPLE_FMT_S32:
+ case AV_SAMPLE_FMT_S32P:
ao->format = AF_FORMAT_S32_NE;
goto out_takefirst;
case AV_SAMPLE_FMT_FLT:
+ case AV_SAMPLE_FMT_FLTP:
ao->format = AF_FORMAT_FLOAT_NE;
goto out_takefirst;
+ // FIXME do we need support for AV_SAMPLE_FORMAT_DBL/DBLP?
default:
break;
}
@@ -204,6 +215,32 @@ out_takefirst:
break;
}
+ // detect if we have to planarize
+ ac->planarize = false;
+ {
+ bool found_format = false;
+ bool found_alternate_format = false;
+ for (sampleformat = codec->sample_fmts;
+ sampleformat && *sampleformat != AV_SAMPLE_FMT_NONE;
+ ++sampleformat) {
+ if (*sampleformat == ac->stream->codec->sample_fmt)
+ found_format = true;
+ if (*sampleformat ==
+ av_get_alt_sample_fmt(ac->stream->codec->sample_fmt, 1))
+ found_alternate_format = true;
+ }
+ if (!found_format && found_alternate_format) {
+ ac->stream->codec->sample_fmt =
+ av_get_alt_sample_fmt(ac->stream->codec->sample_fmt, 1);
+ ac->planarize = true;
+ }
+ if (!found_format && !found_alternate_format) {
+ // shouldn't happen
+ mp_msg(MSGT_ENCODE, MSGL_ERR,
+ "ao-lavc: sample format not found\n");
+ }
+ }
+
ac->stream->codec->bits_per_raw_sample = ac->sample_size * 8;
switch (ao->channels) {
@@ -274,6 +311,10 @@ out_takefirst:
ao->untimed = true;
ao->priv = ac;
+ if (ac->planarize)
+ mp_msg(MSGT_ENCODE, MSGL_WARN,
+ "ao-lavc: need to planarize audio data\n");
+
return 0;
}
@@ -297,7 +338,7 @@ static void uninit(struct ao *ao, bool cut_audio)
if (!encode_lavc_start(ectx)) {
mp_msg(MSGT_ENCODE, MSGL_WARN,
- "ao-lavc: not even ready to encode audio at end -> dropped");
+ "ao-lavc: not even ready to encode audio at end -> dropped");
return;
}
@@ -357,8 +398,14 @@ static int encode(struct ao *ao, double apts, void *data)
{
frame = avcodec_alloc_frame();
frame->nb_samples = ac->aframesize;
- if(avcodec_fill_audio_frame(frame, ao->channels, ac->stream->codec->sample_fmt, data, ac->aframesize * ao->channels * ac->sample_size, 1))
- {
+
+ if (ac->planarize) {
+ void *data2 = talloc_size(ao, ac->aframesize * ao->channels * ac->sample_size);
+ reorder_to_planar(data2, data, ac->sample_size, ao->channels, ac->aframesize);
+ data = data2;
+ }
+
+ if (avcodec_fill_audio_frame(frame, ao->channels, ac->stream->codec->sample_fmt, data, ac->aframesize * ao->channels * ac->sample_size, 1)) {
mp_msg(MSGT_ENCODE, MSGL_ERR, "ao-lavc: error filling\n");
return -1;
}
@@ -392,6 +439,11 @@ static int encode(struct ao *ao, double apts, void *data)
}
avcodec_free_frame(&frame);
+
+ if (ac->planarize) {
+ talloc_free(data);
+ data = NULL;
+ }
}
else
{