2
* Decoder plugin for ffmpeg avcodec formats
4
* Copyright (C) 2006-2011 XMMS2 Team
6
* This library is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License as published by the Free Software Foundation; either
9
* version 2.1 of the License, or (at your option) any later version.
11
* This library is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
* Lesser General Public License for more details.
17
#include "xmms_configuration.h"
18
#include "xmms/xmms_xformplugin.h"
19
#include "xmms/xmms_sample.h"
20
#include "xmms/xmms_log.h"
27
#include "avcodec_compat.h"
29
#define AVCODEC_BUFFER_SIZE 16384
32
AVCodecContext *codecctx;
41
xmms_sample_format_t sampleformat;
46
const gchar *codec_id;
48
gssize extradata_size;
51
} xmms_avcodec_data_t;
53
static gboolean xmms_avcodec_plugin_setup (xmms_xform_plugin_t *xform_plugin);
54
static gboolean xmms_avcodec_init (xmms_xform_t *xform);
55
static void xmms_avcodec_destroy (xmms_xform_t *xform);
56
static gint xmms_avcodec_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
58
static gint64 xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples,
59
xmms_xform_seek_mode_t whence, xmms_error_t *err);
65
XMMS_XFORM_PLUGIN ("avcodec",
66
"AVCodec Decoder", XMMS_VERSION,
67
"ffmpeg libavcodec decoder",
68
xmms_avcodec_plugin_setup);
71
xmms_avcodec_plugin_setup (xmms_xform_plugin_t *xform_plugin)
73
xmms_xform_methods_t methods;
75
XMMS_XFORM_METHODS_INIT (methods);
76
methods.init = xmms_avcodec_init;
77
methods.destroy = xmms_avcodec_destroy;
78
methods.read = xmms_avcodec_read;
79
methods.seek = xmms_avcodec_seek;
81
xmms_xform_plugin_methods_set (xform_plugin, &methods);
83
xmms_magic_add ("Shorten header", "audio/x-ffmpeg-shorten",
84
"0 string ajkg", NULL);
85
xmms_magic_add ("A/52 (AC-3) header", "audio/x-ffmpeg-ac3",
86
"0 beshort 0x0b77", NULL);
87
xmms_magic_add ("DTS header", "audio/x-ffmpeg-dca",
88
"0 belong 0x7ffe8001", NULL);
90
xmms_xform_plugin_indata_add (xform_plugin,
91
XMMS_STREAM_TYPE_MIMETYPE,
99
xmms_avcodec_destroy (xmms_xform_t *xform)
101
xmms_avcodec_data_t *data;
103
g_return_if_fail (xform);
105
data = xmms_xform_private_data_get (xform);
106
g_return_if_fail (data);
108
avcodec_close (data->codecctx);
109
av_free (data->codecctx);
111
g_string_free (data->outbuf, TRUE);
112
g_free (data->buffer);
113
g_free (data->extradata);
118
xmms_avcodec_init (xmms_xform_t *xform)
120
xmms_avcodec_data_t *data;
122
const gchar *mimetype;
123
const guchar *tmpbuf;
127
g_return_val_if_fail (xform, FALSE);
129
data = g_new0 (xmms_avcodec_data_t, 1);
130
data->outbuf = g_string_new (NULL);
131
data->buffer = g_malloc (AVCODEC_BUFFER_SIZE);
132
data->buffer_size = AVCODEC_BUFFER_SIZE;
133
data->codecctx = NULL;
135
xmms_xform_private_data_set (xform, data);
138
avcodec_register_all ();
140
mimetype = xmms_xform_indata_get_str (xform,
141
XMMS_STREAM_TYPE_MIMETYPE);
142
data->codec_id = mimetype + strlen ("audio/x-ffmpeg-");
144
codec = avcodec_find_decoder_by_name (data->codec_id);
146
XMMS_DBG ("No supported decoder with name '%s' found", data->codec_id);
150
if (codec->type != AVMEDIA_TYPE_AUDIO) {
151
XMMS_DBG ("Codec '%s' found but its type is not audio", data->codec_id);
155
ret = xmms_xform_indata_get_int (xform, XMMS_STREAM_TYPE_FMT_SAMPLERATE);
157
data->samplerate = ret;
159
ret = xmms_xform_indata_get_int (xform, XMMS_STREAM_TYPE_FMT_CHANNELS);
161
data->channels = ret;
164
/* bitrate required for WMA files */
165
xmms_xform_auxdata_get_int (xform,
169
/* ALAC and MAC require bits per sample field to be 16 */
170
xmms_xform_auxdata_get_int (xform,
174
xmms_xform_auxdata_get_int (xform,
178
ret = xmms_xform_auxdata_get_bin (xform, "decoder_config",
179
&tmpbuf, &tmpbuflen);
182
data->extradata = g_memdup (tmpbuf, tmpbuflen);
183
data->extradata_size = tmpbuflen;
185
/* This should be a list of known formats that don't have a
186
* demuxer so they will be handled slightly differently... */
187
if (!strcmp (data->codec_id, "shorten") ||
188
!strcmp (data->codec_id, "adpcm_swf") ||
189
!strcmp (data->codec_id, "pcm_s16le") ||
190
!strcmp (data->codec_id, "ac3") ||
191
!strcmp (data->codec_id, "dca")) {
192
/* number 1024 taken from libavformat raw.c RAW_PACKET_SIZE */
193
data->extradata = g_malloc0 (1024);
194
data->extradata_size = 1024;
195
data->no_demuxer = TRUE;
197
/* A demuxer plugin forgot to give decoder config? */
198
xmms_log_error ("Decoder config data not found!");
203
data->codecctx = avcodec_alloc_context3 (codec);
204
data->codecctx->sample_rate = data->samplerate;
205
data->codecctx->channels = data->channels;
206
data->codecctx->bit_rate = data->bitrate;
207
CONTEXT_BPS (data->codecctx) = data->samplebits;
208
data->codecctx->block_align = data->block_align;
209
data->codecctx->extradata = data->extradata;
210
data->codecctx->extradata_size = data->extradata_size;
211
data->codecctx->codec_id = codec->id;
212
data->codecctx->codec_type = codec->type;
214
if (avcodec_open2 (data->codecctx, codec, NULL) < 0) {
215
XMMS_DBG ("Opening decoder '%s' failed", codec->name);
221
/* some codecs need to have something read before they set
222
* the samplerate and channels correctly, unfortunately... */
223
if ((ret = xmms_avcodec_read (xform, buf, 42, &error)) > 0) {
224
g_string_insert_len (data->outbuf, 0, buf, ret);
226
XMMS_DBG ("First read failed, codec is not working...");
227
avcodec_close (data->codecctx);
232
data->samplerate = data->codecctx->sample_rate;
233
data->channels = data->codecctx->channels;
235
xmms_xform_outdata_type_add (xform,
236
XMMS_STREAM_TYPE_MIMETYPE,
238
XMMS_STREAM_TYPE_FMT_FORMAT,
239
XMMS_SAMPLE_FORMAT_S16,
240
XMMS_STREAM_TYPE_FMT_CHANNELS,
242
XMMS_STREAM_TYPE_FMT_SAMPLERATE,
244
XMMS_STREAM_TYPE_END);
246
XMMS_DBG ("Decoder '%s' initialized successfully!", codec->name);
251
if (data->codecctx) {
252
av_free (data->codecctx);
254
g_string_free (data->outbuf, TRUE);
255
g_free (data->extradata);
262
xmms_avcodec_read (xmms_xform_t *xform, xmms_sample_t *buf, gint len,
265
xmms_avcodec_data_t *data;
266
char outbuf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
267
gint outbufsize, bytes_read = 0;
270
data = xmms_xform_private_data_get (xform);
271
g_return_val_if_fail (data, -1);
273
size = MIN (data->outbuf->len, len);
276
av_init_packet (&packet);
278
if (data->no_demuxer || data->buffer_length == 0) {
281
bytes_read = xmms_xform_read (xform,
282
(gchar *) (data->buffer + data->buffer_length),
283
data->buffer_size - data->buffer_length,
286
if (bytes_read < 0) {
287
XMMS_DBG ("Error while reading data");
289
} else if (bytes_read == 0) {
294
read_total = bytes_read;
296
/* If we have a demuxer plugin, make sure we read the whole packet */
297
while (read_total == data->buffer_size && !data->no_demuxer) {
298
/* multiply the buffer size and try to read again */
299
data->buffer = g_realloc (data->buffer, data->buffer_size * 2);
300
bytes_read = xmms_xform_read (xform,
301
(gchar *) data->buffer +
305
data->buffer_size *= 2;
307
if (bytes_read < 0) {
308
XMMS_DBG ("Error while reading data");
312
read_total += bytes_read;
314
if (read_total < data->buffer_size) {
315
/* finally double the buffer size for performance reasons, the
316
* hotspot handling likes to fit two frames in the buffer */
317
data->buffer = g_realloc (data->buffer, data->buffer_size * 2);
318
data->buffer_size *= 2;
319
XMMS_DBG ("Reallocated avcodec internal buffer to be %d bytes",
326
/* Update the buffer length */
327
data->buffer_length += read_total;
330
packet.data = data->buffer;
331
packet.size = data->buffer_length;
333
outbufsize = sizeof (outbuf);
334
bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) outbuf,
335
&outbufsize, &packet);
337
/* The DTS decoder of ffmpeg is buggy and always returns
338
* the input buffer length, get frame length from header */
339
if (!strcmp (data->codec_id, "dca") && bytes_read > 0) {
340
bytes_read = ((int)data->buffer[5] << 12) |
341
((int)data->buffer[6] << 4) |
342
((int)data->buffer[7] >> 4);
343
bytes_read = (bytes_read & 0x3fff) + 1;
346
if (bytes_read < 0 || bytes_read > data->buffer_length) {
347
XMMS_DBG ("Error decoding data!");
349
} else if (bytes_read != data->buffer_length) {
350
g_memmove (data->buffer,
351
data->buffer + bytes_read,
352
data->buffer_length - bytes_read);
355
data->buffer_length -= bytes_read;
357
if (outbufsize > 0) {
358
g_string_append_len (data->outbuf, outbuf, outbufsize);
361
size = MIN (data->outbuf->len, len);
364
memcpy (buf, data->outbuf->str, size);
365
g_string_erase (data->outbuf, 0, size);
371
xmms_avcodec_seek (xmms_xform_t *xform, gint64 samples, xmms_xform_seek_mode_t whence, xmms_error_t *err)
373
xmms_avcodec_data_t *data;
374
char outbuf[AVCODEC_MAX_AUDIO_FRAME_SIZE];
375
gint outbufsize, bytes_read = 0;
378
g_return_val_if_fail (xform, -1);
379
g_return_val_if_fail (whence == XMMS_XFORM_SEEK_SET, -1);
381
data = xmms_xform_private_data_get (xform);
382
g_return_val_if_fail (data, FALSE);
384
/* We can't seek without a demuxer in general case */
385
if (data->no_demuxer) {
386
xmms_error_set (err, XMMS_ERROR_GENERIC,
387
"Can't seek in avcodec plugin without a demuxer!");
391
/* The buggy ape decoder doesn't flush buffers, so we need to finish decoding
392
* the frame before seeking to avoid segfaults... this hack sucks */
393
while (data->buffer_length > 0) {
395
av_init_packet (&packet);
396
packet.data = data->buffer;
397
packet.size = data->buffer_length;
399
outbufsize = sizeof (outbuf);
400
bytes_read = avcodec_decode_audio3 (data->codecctx, (short *) outbuf,
401
&outbufsize, &packet);
403
if (bytes_read < 0 || bytes_read > data->buffer_length) {
404
XMMS_DBG ("Error decoding data!");
408
data->buffer_length -= bytes_read;
409
g_memmove (data->buffer, data->buffer + bytes_read, data->buffer_length);
412
ret = xmms_xform_seek (xform, samples, whence, err);
415
avcodec_flush_buffers (data->codecctx);
417
data->buffer_length = 0;
418
g_string_erase (data->outbuf, 0, -1);