Hi,
the attached patch should fix this bug.
Note that the package now depends on libavresample.
--
Anton Khirnov
Index: cmus-2.5.0/ffmpeg.c
===================================================================
--- cmus-2.5.0.orig/ffmpeg.c 2012-11-07 08:46:17.000000000 +0000
+++ cmus-2.5.0/ffmpeg.c 2014-03-01 09:26:32.099123054 +0000
@@ -26,18 +26,12 @@
#endif
#include <stdio.h>
-#ifdef HAVE_FFMPEG_AVCODEC_H
-#include <ffmpeg/avcodec.h>
-#include <ffmpeg/avformat.h>
-#include <ffmpeg/avio.h>
-#else
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
-#ifndef AVUTIL_MATHEMATICS_H
+#include <libavresample/avresample.h>
+#include <libavutil/opt.h>
#include <libavutil/mathematics.h>
-#endif
-#endif
#if (LIBAVFORMAT_VERSION_INT < ((52<<16)+(31<<8)+0))
# define NUM_FFMPEG_KEYS 8
@@ -77,6 +71,7 @@
uint8_t *buffer_malloc;
uint8_t *buffer_pos; /* current buffer position */
int buffer_used_len;
+ int buffer_size;
};
struct ffmpeg_private {
@@ -87,6 +82,13 @@
struct ffmpeg_input *input;
struct ffmpeg_output *output;
+
+ AVFrame *frame;
+
+ AVAudioResampleContext *avr;
+ uint64_t resample_channel_layout;
+ int resample_sample_rate;
+ int resample_sample_fmt;
};
static struct ffmpeg_input *ffmpeg_input_create(void)
@@ -112,7 +114,8 @@
{
struct ffmpeg_output *output = xnew(struct ffmpeg_output, 1);
- output->buffer_malloc = xnew(uint8_t, AVCODEC_MAX_AUDIO_FRAME_SIZE + 15);
+ output->buffer_size = 192000 + 15;
+ output->buffer_malloc = xnew(uint8_t, output->buffer_size);
output->buffer = output->buffer_malloc;
/* align to 16 bytes so avcodec can SSE/Altivec/etc */
while ((intptr_t) output->buffer % 16)
@@ -241,20 +244,12 @@
break;
}
-#if (LIBAVCODEC_VERSION_INT > ((51<<16)+(64<<8)+0))
- if (cc->sample_fmt == AV_SAMPLE_FMT_FLT || cc->sample_fmt == AV_SAMPLE_FMT_DBL) {
-#else
- if (cc->sample_fmt == AV_SAMPLE_FMT_FLT) {
-#endif
- err = -IP_ERROR_SAMPLE_FORMAT;
- break;
- }
/* We assume below that no more errors follow. */
} while (0);
if (err < 0) {
/* Clean up. cc is never opened at this point. (See above assumption.) */
- av_close_input_file(ic);
+ avformat_close_input(&ic);
return err;
}
@@ -262,11 +257,12 @@
priv->codec_context = cc;
priv->input_context = ic;
priv->codec = codec;
+ priv->frame = av_frame_alloc();
priv->stream_index = stream_index;
priv->input = ffmpeg_input_create();
if (priv->input == NULL) {
avcodec_close(cc);
- av_close_input_file(ic);
+ avformat_close_input(&ic);
free(priv);
return -IP_ERROR_INTERNAL;
}
@@ -300,8 +296,10 @@
{
struct ffmpeg_private *priv = ip_data->private;
+ av_frame_free(&priv->frame);
+ avresample_free(&priv->avr);
avcodec_close(priv->codec_context);
- av_close_input_file(priv->input_context);
+ avformat_close_input(&priv->input_context);
ffmpeg_input_free(priv->input);
ffmpeg_output_free(priv->output);
free(priv);
@@ -313,14 +311,18 @@
* This returns the number of bytes added to the buffer.
* It returns < 0 on error. 0 on EOF.
*/
-static int ffmpeg_fill_buffer(AVFormatContext *ic, AVCodecContext *cc, struct ffmpeg_input *input,
+static int ffmpeg_fill_buffer(struct ffmpeg_private *priv, struct ffmpeg_input *input,
struct ffmpeg_output *output)
{
+ AVFormatContext *ic = priv->input_context;
+ AVCodecContext *cc = priv->codec_context;
+ AVFrame *frame = priv->frame;
+
while (1) {
/* frame_size specifies the size of output->buffer for
* avcodec_decode_audio2. */
- int frame_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
- int len;
+ AVPacket avpkt;
+ int len, got_output, ret;
if (input->curr_pkt_size <= 0) {
av_free_packet(&input->pkt);
@@ -335,26 +337,11 @@
continue;
}
- /* The change to avcodec_decode_audio2 occurred between
- * 51.28.0 and 51.29.0 */
-#if (LIBAVCODEC_VERSION_INT <= ((51<<16) + (28<<8) + 0))
- len = avcodec_decode_audio(cc, (int16_t *)output->buffer, &frame_size,
- input->curr_pkt_buf, input->curr_pkt_size);
- /* The change to avcodec_decode_audio3 occurred between
- * 52.25.0 and 52.26.0 */
-#elif (LIBAVCODEC_VERSION_INT <= ((52<<16) + (25<<8) + 0))
- len = avcodec_decode_audio2(cc, (int16_t *) output->buffer, &frame_size,
- input->curr_pkt_buf, input->curr_pkt_size);
-#else
- {
- AVPacket avpkt;
- av_init_packet(&avpkt);
- avpkt.data = input->curr_pkt_buf;
- avpkt.size = input->curr_pkt_size;
- len = avcodec_decode_audio3(cc, (int16_t *) output->buffer, &frame_size, &avpkt);
- av_free_packet(&avpkt);
- }
-#endif
+ av_init_packet(&avpkt);
+ avpkt.data = input->curr_pkt_buf;
+ avpkt.size = input->curr_pkt_size;
+ len = avcodec_decode_audio4(cc, frame, &got_output, &avpkt);
+
if (len < 0) {
/* this is often reached when seeking, not sure why */
input->curr_pkt_size = 0;
@@ -362,10 +349,34 @@
}
input->curr_pkt_size -= len;
input->curr_pkt_buf += len;
- if (frame_size > 0) {
+ if (got_output) {
+ if (!priv->avr ||
+ frame->format != priv->resample_sample_fmt ||
+ frame->sample_rate != priv->resample_sample_rate ||
+ frame->channel_layout != priv->resample_channel_layout) {
+
+ avresample_free(&priv->avr);
+
+ priv->avr = avresample_alloc_context();
+ av_opt_set_int(priv->avr, "in_channel_layout", frame->channel_layout, 0);
+ av_opt_set_int(priv->avr, "out_channel_layout", frame->channel_layout, 0);
+ av_opt_set_int(priv->avr, "in_sample_rate", frame->sample_rate, 0);
+ av_opt_set_int(priv->avr, "out_sample_rate", frame->sample_rate, 0);
+ av_opt_set_int(priv->avr, "in_sample_fmt", frame->format, 0);
+ av_opt_set_int(priv->avr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
+
+ ret = avresample_open(priv->avr);
+ if (ret < 0)
+ return -IP_ERROR_INTERNAL;
+ }
+
+ len = avresample_convert(priv->avr, (uint8_t**)&output->buffer,
+ output->buffer_size, frame->nb_samples,
+ frame->extended_data, frame->linesize[0], frame->nb_samples);
+
output->buffer_pos = output->buffer;
- output->buffer_used_len = frame_size;
- return frame_size;
+ output->buffer_used_len = len * 2 * cc->channels;
+ return output->buffer_used_len;
}
}
/* This should never get here. */
@@ -380,7 +391,7 @@
int out_size;
if (output->buffer_used_len == 0) {
- rc = ffmpeg_fill_buffer(priv->input_context, priv->codec_context, priv->input, priv->output);
+ rc = ffmpeg_fill_buffer(priv, priv->input, priv->output);
if (rc <= 0) {
return rc;
}
@@ -494,7 +505,7 @@
long bitrate = -1;
#if (LIBAVFORMAT_VERSION_INT > ((51<<16)+(43<<8)+0))
/* ape codec returns silly numbers */
- if (priv->codec->id == CODEC_ID_APE)
+ if (priv->codec->id == AV_CODEC_ID_APE)
return -1;
#endif
if (priv->input->curr_duration > 0) {
_______________________________________________
pkg-multimedia-maintainers mailing list
pkg-multimedia-maintainers@lists.alioth.debian.org
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-multimedia-maintainers