summaryrefslogtreecommitdiff
blob: b338e57cdfca508f435edf71e41a1d170d495910 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
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 <ionen@gentoo.org>
--- 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