aboutsummarylogtreecommitdiffstats
path: root/0003-ffmpeg7-audaspace.patch
blob: 5c6879ef8dd4b8dfcd456e7e6fd8f9d7b3d456df (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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
index c0e16d6a887..3257daab442 100644
--- a/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGReader.cpp
@@ -31,6 +31,10 @@ AUD_NAMESPACE_BEGIN
 #define FFMPEG_OLD_CODE
 #endif
 
+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 28, 100)
+#define HAVE_CH_LAYOUT
+#endif
+
 SampleFormat FFMPEGReader::convertSampleFormat(AVSampleFormat format)
 {
 	switch(av_get_packed_sample_fmt(format))
@@ -104,15 +108,22 @@ int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
 	packet.size = orig_size;
 #else
 	avcodec_send_packet(m_codecCtx, &packet);
+	
 
 	while(true)
 	{
 		auto ret = avcodec_receive_frame(m_codecCtx, m_frame);
 
+#ifdef HAVE_CH_LAYOUT
+		int nb_channels = m_codecCtx->ch_layout.nb_channels;
+#else
+		int nb_channels = m_codecCtx->channels;
+#endif
+
 		if(ret != 0)
 			break;
 
-		int data_size = av_samples_get_buffer_size(nullptr, m_codecCtx->channels, m_frame->nb_samples, m_codecCtx->sample_fmt, 1);
+		int data_size = av_samples_get_buffer_size(nullptr, nb_channels, m_frame->nb_samples, m_codecCtx->sample_fmt, 1);
 
 		if(buf_size - buf_pos < data_size)
 		{
@@ -122,12 +133,12 @@ int FFMPEGReader::decode(AVPacket& packet, Buffer& buffer)
 
 		if(m_tointerleave)
 		{
-			int single_size = data_size / m_codecCtx->channels / m_frame->nb_samples;
-			for(int channel = 0; channel < m_codecCtx->channels; channel++)
+			int single_size = data_size / nb_channels / m_frame->nb_samples;
+			for(int channel = 0; channel < nb_channels; channel++)
 			{
 				for(int i = 0; i < m_frame->nb_samples; i++)
 				{
-					std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((m_codecCtx->channels * i) + channel) * single_size,
+					std::memcpy(((data_t*)buffer.getBuffer()) + buf_pos + ((nb_channels * i) + channel) * single_size,
 						   m_frame->data[channel] + i * single_size, single_size);
 				}
 			}
@@ -207,7 +218,11 @@ void FFMPEGReader::init(int stream)
 	if(avcodec_open2(m_codecCtx, aCodec, nullptr) < 0)
 		AUD_THROW(FileException, "File couldn't be read, ffmpeg codec couldn't be opened.");
 
+#ifdef HAVE_CH_LAYOUT
+	m_specs.channels = (Channels) m_codecCtx->ch_layout.nb_channels;
+#else
 	m_specs.channels = (Channels) m_codecCtx->channels;
+#endif
 	m_tointerleave = av_sample_fmt_is_planar(m_codecCtx->sample_fmt);
 
 	switch(av_get_packed_sample_fmt(m_codecCtx->sample_fmt))
@@ -344,8 +359,12 @@ std::vector<StreamInfo> FFMPEGReader::queryStreams()
 			info.specs.channels = Channels(m_formatCtx->streams[i]->codec->channels);
 			info.specs.rate = m_formatCtx->streams[i]->codec->sample_rate;
 			info.specs.format = convertSampleFormat(m_formatCtx->streams[i]->codec->sample_fmt);
+#else
+#ifdef HAVE_CH_LAYOUT
+			info.specs.channels = Channels(m_formatCtx->streams[i]->codecpar->ch_layout.nb_channels);
 #else
 			info.specs.channels = Channels(m_formatCtx->streams[i]->codecpar->channels);
+#endif
 			info.specs.rate = m_formatCtx->streams[i]->codecpar->sample_rate;
 			info.specs.format = convertSampleFormat(AVSampleFormat(m_formatCtx->streams[i]->codecpar->format));
 #endif
diff --git a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp
index 9cadfe9c092..2f435c14b56 100644
--- a/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp
+++ b/extern/audaspace/plugins/ffmpeg/FFMPEGWriter.cpp
@@ -34,6 +34,10 @@ AUD_NAMESPACE_BEGIN
 #define FFMPEG_OLD_CODE
 #endif
 
+#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(57, 28, 100)
+#define HAVE_CH_LAYOUT
+#endif
+
 void FFMPEGWriter::encode()
 {
 	sample_t* data = m_input_buffer.getBuffer();
@@ -77,8 +81,12 @@ void FFMPEGWriter::encode()
 
 	m_frame->nb_samples = m_input_samples;
 	m_frame->format = m_codecCtx->sample_fmt;
+#ifdef HAVE_CH_LAYOUT
+	av_channel_layout_copy(&m_frame->ch_layout, &m_codecCtx->ch_layout);
+#else
 	m_frame->channel_layout = m_codecCtx->channel_layout;
 	m_frame->channels = m_specs.channels;
+#endif
 
 	if(avcodec_fill_audio_frame(m_frame, m_specs.channels, m_codecCtx->sample_fmt, reinterpret_cast<data_t*>(data), m_input_buffer.getSize(), 0) < 0)
 		AUD_THROW(FileException, "File couldn't be written, filling the audio frame failed with ffmpeg.");
@@ -237,6 +245,39 @@ FFMPEGWriter::FFMPEGWriter(const std::string &filename, DeviceSpecs specs, Conta
 		break;
 	}
 
+#ifdef HAVE_CH_LAYOUT
+	AVChannelLayout channel_layout{};
+
+	switch(m_specs.channels)
+	{
+	case CHANNELS_MONO:
+		channel_layout = AV_CHANNEL_LAYOUT_MONO;
+		break;
+	case CHANNELS_STEREO:
+		channel_layout = AV_CHANNEL_LAYOUT_STEREO;
+		break;
+	case CHANNELS_STEREO_LFE:
+		channel_layout = AV_CHANNEL_LAYOUT_2POINT1;
+		break;
+	case CHANNELS_SURROUND4:
+		channel_layout = AV_CHANNEL_LAYOUT_QUAD;
+		break;
+	case CHANNELS_SURROUND5:
+		channel_layout = AV_CHANNEL_LAYOUT_5POINT0_BACK;
+		break;
+	case CHANNELS_SURROUND51:
+		channel_layout = AV_CHANNEL_LAYOUT_5POINT1_BACK;
+		break;
+	case CHANNELS_SURROUND61:
+		channel_layout = AV_CHANNEL_LAYOUT_6POINT1_BACK;
+		break;
+	case CHANNELS_SURROUND71:
+		channel_layout = AV_CHANNEL_LAYOUT_7POINT1;
+		break;
+	default:
+		AUD_THROW(FileException, "File couldn't be written, channel layout not supported.");
+	}
+#else
 	uint64_t channel_layout = 0;
 
 	switch(m_specs.channels)
@@ -268,6 +309,7 @@ FFMPEGWriter::FFMPEGWriter(const std::string &filename, DeviceSpecs specs, Conta
 	default:
 		AUD_THROW(FileException, "File couldn't be written, channel layout not supported.");
 	}
+#endif
 
 	try
 	{
@@ -405,8 +447,12 @@ FFMPEGWriter::FFMPEGWriter(const std::string &filename, DeviceSpecs specs, Conta
 
 		m_codecCtx->codec_type = AVMEDIA_TYPE_AUDIO;
 		m_codecCtx->bit_rate = bitrate;
+#ifdef HAVE_CH_LAYOUT
+		av_channel_layout_copy(&m_codecCtx->ch_layout, &channel_layout);
+#else
 		m_codecCtx->channel_layout = channel_layout;
 		m_codecCtx->channels = m_specs.channels;
+#endif
 		m_stream->time_base.num = m_codecCtx->time_base.num = 1;
 		m_stream->time_base.den = m_codecCtx->time_base.den = m_codecCtx->sample_rate;