Lazy migration from audio4 that's missing in ffmpeg5, may not be entirely right but tested to play at least .tta/.wma properly. https://github.com/xmms2/xmms2-devel/pull/11 Bug: https://bugs.gentoo.org/834398 Signed-off-by: Ionen Wolkens --- a/src/plugins/avcodec/avcodec.c +++ b/src/plugins/avcodec/avcodec.c @@ -32,4 +32,5 @@ typedef struct { AVCodecContext *codecctx; + AVPacket packet; guchar *buffer; @@ -150,4 +151,5 @@ data->buffer_size = AVCODEC_BUFFER_SIZE; data->codecctx = NULL; + data->packet.size = 0; data->read_out_frame = av_frame_alloc (); @@ -155,6 +157,4 @@ xmms_xform_private_data_set (xform, data); - avcodec_register_all (); - mimetype = xmms_xform_indata_get_str (xform, XMMS_STREAM_TYPE_MIMETYPE); @@ -467,43 +467,35 @@ xmms_avcodec_internal_decode_some (xmms_avcodec_data_t *data) { - int got_frame = 0; - gint bytes_read = 0; - AVPacket packet; + int rc = 0; - av_init_packet (&packet); - packet.data = data->buffer; - packet.size = data->buffer_length; - - /* clear buffers and reset fields to defaults */ - av_frame_unref (data->read_out_frame); - - bytes_read = avcodec_decode_audio4 ( - data->codecctx, data->read_out_frame, &got_frame, &packet); - - /* The DTS decoder of ffmpeg is buggy and always returns - * the input buffer length, get frame length from header */ - /* FIXME: Is ^^^^ still true? */ - if (!strcmp (data->codec_id, "dca") && bytes_read > 0) { - bytes_read = ((int)data->buffer[5] << 12) | - ((int)data->buffer[6] << 4) | - ((int)data->buffer[7] >> 4); - bytes_read = (bytes_read & 0x3fff) + 1; + if (data->packet.size == 0) { + av_init_packet (&data->packet); + data->packet.data = data->buffer; + data->packet.size = data->buffer_length; + + rc = avcodec_send_packet(data->codecctx, &data->packet); + if (rc == AVERROR_EOF) + rc = 0; + } + + if (rc == 0) { + rc = avcodec_receive_frame(data->codecctx, data->read_out_frame); + if (rc < 0) { + data->packet.size = 0; + data->buffer_length = 0; + if (rc == AVERROR(EAGAIN)) rc = 0; + else if (rc == AVERROR_EOF) rc = 1; + } + else + rc = 1; } - if (bytes_read < 0 || bytes_read > data->buffer_length) { + if (rc < 0) { + data->packet.size = 0; XMMS_DBG ("Error decoding data!"); return -1; } - if (bytes_read < data->buffer_length) { - data->buffer_length -= bytes_read; - g_memmove (data->buffer, - data->buffer + bytes_read, - data->buffer_length); - } else { - data->buffer_length = 0; - } - - return got_frame ? 1 : 0; + return rc; } --- a/src/plugins/avcodec/wscript +++ b/src/plugins/avcodec/wscript @@ -2,5 +2,5 @@ ## Code fragments for configuration -avcodec_decode_audio4_fragment = """ +avcodec_send_packet_fragment = """ #ifdef HAVE_LIBAVCODEC_AVCODEC_H # include "libavcodec/avcodec.h" @@ -10,9 +10,7 @@ int main(void) { AVCodecContext *ctx; - AVFrame *frame; - int got_frame; AVPacket *pkt; - avcodec_decode_audio4 (ctx, frame, &got_frame, pkt); + avcodec_send_packet (ctx, pkt); return 0; @@ -44,7 +42,7 @@ # * ffmpeg: commit e4de716, lavc 53.40.0, release 0.9 # * libav: commit 0eea212, lavc 53.25.0, release 0.8 - conf.check_cc(fragment=avcodec_decode_audio4_fragment, uselib="avcodec", - uselib_store="avcodec_decode_audio4", - msg="Checking for function avcodec_decode_audio4", mandatory=True) + conf.check_cc(fragment=avcodec_send_packet_fragment, uselib="avcodec", + uselib_store="avcodec_send_packet", + msg="Checking for function avcodec_send_packet", mandatory=True) # non-mandatory function avcodec_free_frame since