1 /*
2 This file is part of Telegram Desktop,
3 the official desktop application for the Telegram messaging service.
4 
5 For license and copyright information please follow this link:
6 https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL
7 */
8 #include "media/audio/media_audio_capture.h"
9 
10 #include "media/audio/media_audio_ffmpeg_loader.h"
11 #include "ffmpeg/ffmpeg_utility.h"
12 #include "base/timer.h"
13 
14 #include <al.h>
15 #include <alc.h>
16 
17 #include <numeric>
18 
19 namespace Media {
20 namespace Capture {
21 namespace {
22 
23 constexpr auto kCaptureFrequency = Player::kDefaultFrequency;
24 constexpr auto kCaptureSkipDuration = crl::time(400);
25 constexpr auto kCaptureFadeInDuration = crl::time(300);
26 constexpr auto kCaptureBufferSlice = 256 * 1024;
27 constexpr auto kCaptureUpdateDelta = crl::time(100);
28 
29 Instance *CaptureInstance = nullptr;
30 
ErrorHappened(ALCdevice * device)31 bool ErrorHappened(ALCdevice *device) {
32 	ALenum errCode;
33 	if ((errCode = alcGetError(device)) != ALC_NO_ERROR) {
34 		LOG(("Audio Capture Error: %1, %2").arg(errCode).arg((const char *)alcGetString(device, errCode)));
35 		return true;
36 	}
37 	return false;
38 }
39 
40 } // namespace
41 
42 class Instance::Inner final : public QObject {
43 public:
44 	Inner(QThread *thread);
45 	~Inner();
46 
47 	void start(Fn<void(Update)> updated, Fn<void()> error);
48 	void stop(Fn<void(Result&&)> callback = nullptr);
49 
50 private:
51 	void process();
52 
53 	[[nodiscard]] bool processFrame(int32 offset, int32 framesize);
54 	void fail();
55 
56 	[[nodiscard]] bool writeFrame(AVFrame *frame);
57 
58 	// Writes the packets till EAGAIN is got from av_receive_packet()
59 	// Returns number of packets written or -1 on error
60 	[[nodiscard]] int writePackets();
61 
62 	Fn<void(Update)> _updated;
63 	Fn<void()> _error;
64 
65 	struct Private;
66 	const std::unique_ptr<Private> d;
67 	base::Timer _timer;
68 	QByteArray _captured;
69 
70 };
71 
Start()72 void Start() {
73 	Assert(CaptureInstance == nullptr);
74 	CaptureInstance = new Instance();
75 	instance()->check();
76 }
77 
Finish()78 void Finish() {
79 	delete base::take(CaptureInstance);
80 }
81 
Instance()82 Instance::Instance() : _inner(std::make_unique<Inner>(&_thread)) {
83 	CaptureInstance = this;
84 	_thread.start();
85 }
86 
start()87 void Instance::start() {
88 	_updates.fire_done();
89 	InvokeQueued(_inner.get(), [=] {
90 		_inner->start([=](Update update) {
91 			crl::on_main(this, [=] {
92 				_updates.fire_copy(update);
93 			});
94 		}, [=] {
95 			crl::on_main(this, [=] {
96 				_updates.fire_error({});
97 			});
98 		});
99 		crl::on_main(this, [=] {
100 			_started = true;
101 		});
102 	});
103 }
104 
stop(Fn<void (Result &&)> callback)105 void Instance::stop(Fn<void(Result&&)> callback) {
106 	InvokeQueued(_inner.get(), [=] {
107 		if (!callback) {
108 			_inner->stop();
109 			crl::on_main(this, [=] { _started = false; });
110 			return;
111 		}
112 		_inner->stop([=](Result &&result) {
113 			crl::on_main([=, result = std::move(result)]() mutable {
114 				callback(std::move(result));
115 				_started = false;
116 			});
117 		});
118 	});
119 }
120 
check()121 void Instance::check() {
122 	_available = false;
123 	if (auto device = alcGetString(0, ALC_CAPTURE_DEFAULT_DEVICE_SPECIFIER)) {
124 		if (!QString::fromUtf8(device).isEmpty()) {
125 			_available = true;
126 			return;
127 		}
128 	}
129 	LOG(("Audio Error: No capture device found!"));
130 }
131 
~Instance()132 Instance::~Instance() {
133 	InvokeQueued(_inner.get(), [copy = base::take(_inner)] {
134 	});
135 	_thread.quit();
136 	_thread.wait();
137 }
138 
instance()139 Instance *instance() {
140 	return CaptureInstance;
141 }
142 
143 struct Instance::Inner::Private {
144 	ALCdevice *device = nullptr;
145 	AVOutputFormat *fmt = nullptr;
146 	uchar *ioBuffer = nullptr;
147 	AVIOContext *ioContext = nullptr;
148 	AVFormatContext *fmtContext = nullptr;
149 	AVStream *stream = nullptr;
150 	AVCodec *codec = nullptr;
151 	AVCodecContext *codecContext = nullptr;
152 	bool opened = false;
153 	bool processing = false;
154 
155 	int srcSamples = 0;
156 	int dstSamples = 0;
157 	int maxDstSamples = 0;
158 	int dstSamplesSize = 0;
159 	int fullSamples = 0;
160 	uint8_t **srcSamplesData = nullptr;
161 	uint8_t **dstSamplesData = nullptr;
162 	SwrContext *swrContext = nullptr;
163 
164 	int32 lastUpdate = 0;
165 	uint16 levelMax = 0;
166 
167 	QByteArray data;
168 	int32 dataPos = 0;
169 
170 	int64 waveformMod = 0;
171 	int64 waveformEach = (kCaptureFrequency / 100);
172 	uint16 waveformPeak = 0;
173 	QVector<uchar> waveform;
174 
_read_dataMedia::Capture::Instance::Inner::Private175 	static int _read_data(void *opaque, uint8_t *buf, int buf_size) {
176 		auto l = reinterpret_cast<Private*>(opaque);
177 
178 		int32 nbytes = qMin(l->data.size() - l->dataPos, int32(buf_size));
179 		if (nbytes <= 0) {
180 			return 0;
181 		}
182 
183 		memcpy(buf, l->data.constData() + l->dataPos, nbytes);
184 		l->dataPos += nbytes;
185 		return nbytes;
186 	}
187 
_write_dataMedia::Capture::Instance::Inner::Private188 	static int _write_data(void *opaque, uint8_t *buf, int buf_size) {
189 		auto l = reinterpret_cast<Private*>(opaque);
190 
191 		if (buf_size <= 0) return 0;
192 		if (l->dataPos + buf_size > l->data.size()) l->data.resize(l->dataPos + buf_size);
193 		memcpy(l->data.data() + l->dataPos, buf, buf_size);
194 		l->dataPos += buf_size;
195 		return buf_size;
196 	}
197 
_seek_dataMedia::Capture::Instance::Inner::Private198 	static int64_t _seek_data(void *opaque, int64_t offset, int whence) {
199 		auto l = reinterpret_cast<Private*>(opaque);
200 
201 		int32 newPos = -1;
202 		switch (whence) {
203 		case SEEK_SET: newPos = offset; break;
204 		case SEEK_CUR: newPos = l->dataPos + offset; break;
205 		case SEEK_END: newPos = l->data.size() + offset; break;
206 		case AVSEEK_SIZE: {
207 			// Special whence for determining filesize without any seek.
208 			return l->data.size();
209 		} break;
210 		}
211 		if (newPos < 0) {
212 			return -1;
213 		}
214 		l->dataPos = newPos;
215 		return l->dataPos;
216 	}
217 };
218 
Inner(QThread * thread)219 Instance::Inner::Inner(QThread *thread)
220 : d(std::make_unique<Private>())
221 , _timer(thread, [=] { process(); }) {
222 	moveToThread(thread);
223 }
224 
~Inner()225 Instance::Inner::~Inner() {
226 	stop();
227 }
228 
fail()229 void Instance::Inner::fail() {
230 	stop();
231 	if (const auto error = base::take(_error)) {
232 		InvokeQueued(this, error);
233 	}
234 }
235 
start(Fn<void (Update)> updated,Fn<void ()> error)236 void Instance::Inner::start(Fn<void(Update)> updated, Fn<void()> error) {
237 	_updated = std::move(updated);
238 	_error = std::move(error);
239 
240 	// Start OpenAL Capture
241 	d->device = alcCaptureOpenDevice(nullptr, kCaptureFrequency, AL_FORMAT_MONO16, kCaptureFrequency / 5);
242 	if (!d->device) {
243 		LOG(("Audio Error: capture device not present!"));
244 		fail();
245 		return;
246 	}
247 	alcCaptureStart(d->device);
248 	if (ErrorHappened(d->device)) {
249 		alcCaptureCloseDevice(d->device);
250 		d->device = nullptr;
251 		fail();
252 		return;
253 	}
254 
255 	// Create encoding context
256 
257 	d->ioBuffer = (uchar*)av_malloc(FFmpeg::kAVBlockSize);
258 
259 	d->ioContext = avio_alloc_context(d->ioBuffer, FFmpeg::kAVBlockSize, 1, static_cast<void*>(d.get()), &Private::_read_data, &Private::_write_data, &Private::_seek_data);
260 	int res = 0;
261 	char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
262 	const AVOutputFormat *fmt = nullptr;
263 	void *i = nullptr;
264 	while ((fmt = av_muxer_iterate(&i))) {
265 		if (fmt->name == qstr("opus")) {
266 			break;
267 		}
268 	}
269 	if (!fmt) {
270 		LOG(("Audio Error: Unable to find opus AVOutputFormat for capture"));
271 		fail();
272 		return;
273 	}
274 
275 	if ((res = avformat_alloc_output_context2(&d->fmtContext, (AVOutputFormat*)fmt, 0, 0)) < 0) {
276 		LOG(("Audio Error: Unable to avformat_alloc_output_context2 for capture, error %1, %2").arg(res).arg(av_make_error_string(err, sizeof(err), res)));
277 		fail();
278 		return;
279 	}
280 	d->fmtContext->pb = d->ioContext;
281 	d->fmtContext->flags |= AVFMT_FLAG_CUSTOM_IO;
282 	d->opened = true;
283 
284 	// Add audio stream
285 	d->codec = avcodec_find_encoder(fmt->audio_codec);
286 	if (!d->codec) {
287 		LOG(("Audio Error: Unable to avcodec_find_encoder for capture"));
288 		fail();
289 		return;
290 	}
291 	d->stream = avformat_new_stream(d->fmtContext, d->codec);
292 	if (!d->stream) {
293 		LOG(("Audio Error: Unable to avformat_new_stream for capture"));
294 		fail();
295 		return;
296 	}
297 	d->stream->id = d->fmtContext->nb_streams - 1;
298 	d->codecContext = avcodec_alloc_context3(d->codec);
299 	if (!d->codecContext) {
300 		LOG(("Audio Error: Unable to avcodec_alloc_context3 for capture"));
301 		fail();
302 		return;
303 	}
304 
305 	av_opt_set_int(d->codecContext, "refcounted_frames", 1, 0);
306 
307 	d->codecContext->sample_fmt = AV_SAMPLE_FMT_FLTP;
308 	d->codecContext->bit_rate = 32000;
309 	d->codecContext->channel_layout = AV_CH_LAYOUT_MONO;
310 	d->codecContext->sample_rate = kCaptureFrequency;
311 	d->codecContext->channels = 1;
312 
313 	if (d->fmtContext->oformat->flags & AVFMT_GLOBALHEADER) {
314 		d->codecContext->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
315 	}
316 
317 	// Open audio stream
318 	if ((res = avcodec_open2(d->codecContext, d->codec, nullptr)) < 0) {
319 		LOG(("Audio Error: Unable to avcodec_open2 for capture, error %1, %2").arg(res).arg(av_make_error_string(err, sizeof(err), res)));
320 		fail();
321 		return;
322 	}
323 
324 	// Alloc source samples
325 
326 	d->srcSamples = (d->codecContext->codec->capabilities & AV_CODEC_CAP_VARIABLE_FRAME_SIZE) ? 10000 : d->codecContext->frame_size;
327 	//if ((res = av_samples_alloc_array_and_samples(&d->srcSamplesData, 0, d->codecContext->channels, d->srcSamples, d->codecContext->sample_fmt, 0)) < 0) {
328 	//	LOG(("Audio Error: Unable to av_samples_alloc_array_and_samples for capture, error %1, %2").arg(res).arg(av_make_error_string(err, sizeof(err), res)));
329 	//	onStop(false);
330 	//	emit error();
331 	//	return;
332 	//}
333 	// Using _captured directly
334 
335 	// Prepare resampling
336 	d->swrContext = swr_alloc();
337 	if (!d->swrContext) {
338 		fprintf(stderr, "Could not allocate resampler context\n");
339 		exit(1);
340 	}
341 
342 	av_opt_set_int(d->swrContext, "in_channel_count", d->codecContext->channels, 0);
343 	av_opt_set_int(d->swrContext, "in_sample_rate", d->codecContext->sample_rate, 0);
344 	av_opt_set_sample_fmt(d->swrContext, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
345 	av_opt_set_int(d->swrContext, "out_channel_count", d->codecContext->channels, 0);
346 	av_opt_set_int(d->swrContext, "out_sample_rate", d->codecContext->sample_rate, 0);
347 	av_opt_set_sample_fmt(d->swrContext, "out_sample_fmt", d->codecContext->sample_fmt, 0);
348 
349 	if ((res = swr_init(d->swrContext)) < 0) {
350 		LOG(("Audio Error: Unable to swr_init for capture, error %1, %2").arg(res).arg(av_make_error_string(err, sizeof(err), res)));
351 		fail();
352 		return;
353 	}
354 
355 	d->maxDstSamples = d->srcSamples;
356 	if ((res = av_samples_alloc_array_and_samples(&d->dstSamplesData, 0, d->codecContext->channels, d->maxDstSamples, d->codecContext->sample_fmt, 0)) < 0) {
357 		LOG(("Audio Error: Unable to av_samples_alloc_array_and_samples for capture, error %1, %2").arg(res).arg(av_make_error_string(err, sizeof(err), res)));
358 		fail();
359 		return;
360 	}
361 	d->dstSamplesSize = av_samples_get_buffer_size(0, d->codecContext->channels, d->maxDstSamples, d->codecContext->sample_fmt, 0);
362 
363 	if ((res = avcodec_parameters_from_context(d->stream->codecpar, d->codecContext)) < 0) {
364 		LOG(("Audio Error: Unable to avcodec_parameters_from_context for capture, error %1, %2").arg(res).arg(av_make_error_string(err, sizeof(err), res)));
365 		fail();
366 		return;
367 	}
368 
369 	// Write file header
370 	if ((res = avformat_write_header(d->fmtContext, 0)) < 0) {
371 		LOG(("Audio Error: Unable to avformat_write_header for capture, error %1, %2").arg(res).arg(av_make_error_string(err, sizeof(err), res)));
372 		fail();
373 		return;
374 	}
375 
376 	_timer.callEach(50);
377 	_captured.clear();
378 	_captured.reserve(kCaptureBufferSlice);
379 	DEBUG_LOG(("Audio Capture: started!"));
380 }
381 
stop(Fn<void (Result &&)> callback)382 void Instance::Inner::stop(Fn<void(Result&&)> callback) {
383 	if (!_timer.isActive()) {
384 		return; // in stop() already
385 	}
386 	_timer.cancel();
387 
388 	const auto needResult = (callback != nullptr);
389 	const auto hadDevice = (d->device != nullptr);
390 	if (hadDevice) {
391 		alcCaptureStop(d->device);
392 		if (d->processing) {
393 			Assert(!needResult); // stop in the middle of processing - error.
394 		} else {
395 			process(); // get last data
396 		}
397 		alcCaptureCloseDevice(d->device);
398 		d->device = nullptr;
399 	}
400 
401 	// Write what is left
402 	if (needResult && !_captured.isEmpty()) {
403 		auto fadeSamples = kCaptureFadeInDuration * kCaptureFrequency / 1000;
404 		auto capturedSamples = static_cast<int>(_captured.size() / sizeof(short));
405 		if ((_captured.size() % sizeof(short)) || (d->fullSamples + capturedSamples < kCaptureFrequency) || (capturedSamples < fadeSamples)) {
406 			d->fullSamples = 0;
407 			d->dataPos = 0;
408 			d->data.clear();
409 			d->waveformMod = 0;
410 			d->waveformPeak = 0;
411 			d->waveform.clear();
412 		} else {
413 			float64 coef = 1. / fadeSamples, fadedFrom = 0;
414 			for (short *ptr = ((short*)_captured.data()) + capturedSamples, *end = ptr - fadeSamples; ptr != end; ++fadedFrom) {
415 				--ptr;
416 				*ptr = qRound(fadedFrom * coef * *ptr);
417 			}
418 			if (capturedSamples % d->srcSamples) {
419 				int32 s = _captured.size();
420 				_captured.resize(s + (d->srcSamples - (capturedSamples % d->srcSamples)) * sizeof(short));
421 				memset(_captured.data() + s, 0, _captured.size() - s);
422 			}
423 
424 			int32 framesize = d->srcSamples * d->codecContext->channels * sizeof(short), encoded = 0;
425 			while (_captured.size() >= encoded + framesize) {
426 				if (!processFrame(encoded, framesize)) {
427 					break;
428 				}
429 				encoded += framesize;
430 			}
431 			// Drain the codec.
432 			if (!writeFrame(nullptr) || encoded != _captured.size()) {
433 				d->fullSamples = 0;
434 				d->dataPos = 0;
435 				d->data.clear();
436 				d->waveformMod = 0;
437 				d->waveformPeak = 0;
438 				d->waveform.clear();
439 			}
440 		}
441 	}
442 	DEBUG_LOG(("Audio Capture: "
443 		"stopping (need result: %1), size: %2, samples: %3"
444 		).arg(Logs::b(callback != nullptr)
445 		).arg(d->data.size()
446 		).arg(d->fullSamples));
447 	_captured = QByteArray();
448 
449 	// Finish stream
450 	if (needResult && hadDevice) {
451 		av_write_trailer(d->fmtContext);
452 	}
453 
454 	QByteArray result = d->fullSamples ? d->data : QByteArray();
455 	VoiceWaveform waveform;
456 	qint32 samples = d->fullSamples;
457 	if (needResult && samples && !d->waveform.isEmpty()) {
458 		int64 count = d->waveform.size(), sum = 0;
459 		if (count >= Player::kWaveformSamplesCount) {
460 			QVector<uint16> peaks;
461 			peaks.reserve(Player::kWaveformSamplesCount);
462 
463 			uint16 peak = 0;
464 			for (int32 i = 0; i < count; ++i) {
465 				uint16 sample = uint16(d->waveform.at(i)) * 256;
466 				if (peak < sample) {
467 					peak = sample;
468 				}
469 				sum += Player::kWaveformSamplesCount;
470 				if (sum >= count) {
471 					sum -= count;
472 					peaks.push_back(peak);
473 					peak = 0;
474 				}
475 			}
476 
477 			auto sum = std::accumulate(peaks.cbegin(), peaks.cend(), 0LL);
478 			peak = qMax(int32(sum * 1.8 / peaks.size()), 2500);
479 
480 			waveform.resize(peaks.size());
481 			for (int32 i = 0, l = peaks.size(); i != l; ++i) {
482 				waveform[i] = char(qMin(31U, uint32(qMin(peaks.at(i), peak)) * 31 / peak));
483 			}
484 		}
485 	}
486 	if (hadDevice) {
487 		if (d->codecContext) {
488 			avcodec_free_context(&d->codecContext);
489 			d->codecContext = nullptr;
490 		}
491 		if (d->srcSamplesData) {
492 			if (d->srcSamplesData[0]) {
493 				av_freep(&d->srcSamplesData[0]);
494 			}
495 			av_freep(&d->srcSamplesData);
496 		}
497 		if (d->dstSamplesData) {
498 			if (d->dstSamplesData[0]) {
499 				av_freep(&d->dstSamplesData[0]);
500 			}
501 			av_freep(&d->dstSamplesData);
502 		}
503 		d->fullSamples = 0;
504 		if (d->swrContext) {
505 			swr_free(&d->swrContext);
506 			d->swrContext = nullptr;
507 		}
508 		if (d->opened) {
509 			avformat_close_input(&d->fmtContext);
510 			d->opened = false;
511 		}
512 		if (d->ioContext) {
513 			av_freep(&d->ioContext->buffer);
514 			av_freep(&d->ioContext);
515 			d->ioBuffer = nullptr;
516 		} else if (d->ioBuffer) {
517 			av_freep(&d->ioBuffer);
518 		}
519 		if (d->fmtContext) {
520 			avformat_free_context(d->fmtContext);
521 			d->fmtContext = nullptr;
522 		}
523 		d->fmt = nullptr;
524 		d->stream = nullptr;
525 		d->codec = nullptr;
526 
527 		d->lastUpdate = 0;
528 		d->levelMax = 0;
529 
530 		d->dataPos = 0;
531 		d->data.clear();
532 
533 		d->waveformMod = 0;
534 		d->waveformPeak = 0;
535 		d->waveform.clear();
536 	}
537 
538 	if (needResult) {
539 		callback({ result, waveform, samples });
540 	}
541 }
542 
process()543 void Instance::Inner::process() {
544 	Expects(!d->processing);
545 
546 	d->processing = true;
547 	const auto guard = gsl::finally([&] { d->processing = false; });
548 
549 	if (!d->device) {
550 		_timer.cancel();
551 		return;
552 	}
553 	ALint samples;
554 	alcGetIntegerv(d->device, ALC_CAPTURE_SAMPLES, 1, &samples);
555 	if (ErrorHappened(d->device)) {
556 		fail();
557 		return;
558 	}
559 	if (samples > 0) {
560 		// Get samples from OpenAL
561 		auto s = _captured.size();
562 		auto news = s + static_cast<int>(samples * sizeof(short));
563 		if (news / kCaptureBufferSlice > s / kCaptureBufferSlice) {
564 			_captured.reserve(((news / kCaptureBufferSlice) + 1) * kCaptureBufferSlice);
565 		}
566 		_captured.resize(news);
567 		alcCaptureSamples(d->device, (ALCvoid *)(_captured.data() + s), samples);
568 		if (ErrorHappened(d->device)) {
569 			fail();
570 			return;
571 		}
572 
573 		// Count new recording level and update view
574 		auto skipSamples = kCaptureSkipDuration * kCaptureFrequency / 1000;
575 		auto fadeSamples = kCaptureFadeInDuration * kCaptureFrequency / 1000;
576 		auto levelindex = d->fullSamples + static_cast<int>(s / sizeof(short));
577 		for (auto ptr = (const short*)(_captured.constData() + s), end = (const short*)(_captured.constData() + news); ptr < end; ++ptr, ++levelindex) {
578 			if (levelindex > skipSamples) {
579 				uint16 value = qAbs(*ptr);
580 				if (levelindex < skipSamples + fadeSamples) {
581 					value = qRound(value * float64(levelindex - skipSamples) / fadeSamples);
582 				}
583 				if (d->levelMax < value) {
584 					d->levelMax = value;
585 				}
586 			}
587 		}
588 		qint32 samplesFull = d->fullSamples + _captured.size() / sizeof(short), samplesSinceUpdate = samplesFull - d->lastUpdate;
589 		if (samplesSinceUpdate > kCaptureUpdateDelta * kCaptureFrequency / 1000) {
590 			_updated(Update{ .samples = samplesFull, .level = d->levelMax });
591 			d->lastUpdate = samplesFull;
592 			d->levelMax = 0;
593 		}
594 		// Write frames
595 		int32 framesize = d->srcSamples * d->codecContext->channels * sizeof(short), encoded = 0;
596 		while (uint32(_captured.size()) >= encoded + framesize + fadeSamples * sizeof(short)) {
597 			if (!processFrame(encoded, framesize)) {
598 				return;
599 			}
600 			encoded += framesize;
601 		}
602 
603 		// Collapse the buffer
604 		if (encoded > 0) {
605 			int32 goodSize = _captured.size() - encoded;
606 			memmove(_captured.data(), _captured.constData() + encoded, goodSize);
607 			_captured.resize(goodSize);
608 		}
609 	} else {
610 		DEBUG_LOG(("Audio Capture: no samples to capture."));
611 	}
612 }
613 
processFrame(int32 offset,int32 framesize)614 bool Instance::Inner::processFrame(int32 offset, int32 framesize) {
615 	// Prepare audio frame
616 
617 	if (framesize % sizeof(short)) { // in the middle of a sample
618 		LOG(("Audio Error: Bad framesize in writeFrame() for capture, framesize %1, %2").arg(framesize));
619 		fail();
620 		return false;
621 	}
622 	auto samplesCnt = static_cast<int>(framesize / sizeof(short));
623 
624 	int res = 0;
625 	char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
626 
627 	auto srcSamplesDataChannel = (short*)(_captured.data() + offset);
628 	auto srcSamplesData = &srcSamplesDataChannel;
629 
630 	//	memcpy(d->srcSamplesData[0], _captured.constData() + offset, framesize);
631 	auto skipSamples = static_cast<int>(kCaptureSkipDuration * kCaptureFrequency / 1000);
632 	auto fadeSamples = static_cast<int>(kCaptureFadeInDuration * kCaptureFrequency / 1000);
633 	if (d->fullSamples < skipSamples + fadeSamples) {
634 		int32 fadedCnt = qMin(samplesCnt, skipSamples + fadeSamples - d->fullSamples);
635 		float64 coef = 1. / fadeSamples, fadedFrom = d->fullSamples - skipSamples;
636 		short *ptr = srcSamplesDataChannel, *zeroEnd = ptr + qMin(samplesCnt, qMax(0, skipSamples - d->fullSamples)), *end = ptr + fadedCnt;
637 		for (; ptr != zeroEnd; ++ptr, ++fadedFrom) {
638 			*ptr = 0;
639 		}
640 		for (; ptr != end; ++ptr, ++fadedFrom) {
641 			*ptr = qRound(fadedFrom * coef * *ptr);
642 		}
643 	}
644 
645 	d->waveform.reserve(d->waveform.size() + (samplesCnt / d->waveformEach) + 1);
646 	for (short *ptr = srcSamplesDataChannel, *end = ptr + samplesCnt; ptr != end; ++ptr) {
647 		uint16 value = qAbs(*ptr);
648 		if (d->waveformPeak < value) {
649 			d->waveformPeak = value;
650 		}
651 		if (++d->waveformMod == d->waveformEach) {
652 			d->waveformMod -= d->waveformEach;
653 			d->waveform.push_back(uchar(d->waveformPeak / 256));
654 			d->waveformPeak = 0;
655 		}
656 	}
657 
658 	// Convert to final format
659 
660 	d->dstSamples = av_rescale_rnd(swr_get_delay(d->swrContext, d->codecContext->sample_rate) + d->srcSamples, d->codecContext->sample_rate, d->codecContext->sample_rate, AV_ROUND_UP);
661 	if (d->dstSamples > d->maxDstSamples) {
662 		d->maxDstSamples = d->dstSamples;
663 		av_freep(&d->dstSamplesData[0]);
664 		if ((res = av_samples_alloc(d->dstSamplesData, 0, d->codecContext->channels, d->dstSamples, d->codecContext->sample_fmt, 1)) < 0) {
665 			LOG(("Audio Error: Unable to av_samples_alloc for capture, error %1, %2").arg(res).arg(av_make_error_string(err, sizeof(err), res)));
666 			fail();
667 			return false;
668 		}
669 		d->dstSamplesSize = av_samples_get_buffer_size(0, d->codecContext->channels, d->maxDstSamples, d->codecContext->sample_fmt, 0);
670 	}
671 
672 	if ((res = swr_convert(d->swrContext, d->dstSamplesData, d->dstSamples, (const uint8_t **)srcSamplesData, d->srcSamples)) < 0) {
673 		LOG(("Audio Error: Unable to swr_convert for capture, error %1, %2").arg(res).arg(av_make_error_string(err, sizeof(err), res)));
674 		fail();
675 		return false;
676 	}
677 
678 	// Write audio frame
679 
680 	AVFrame *frame = av_frame_alloc();
681 
682 	frame->format = d->codecContext->sample_fmt;
683 	frame->channels = d->codecContext->channels;
684 	frame->channel_layout = d->codecContext->channel_layout;
685 	frame->sample_rate = d->codecContext->sample_rate;
686 	frame->nb_samples = d->dstSamples;
687 	frame->pts = av_rescale_q(d->fullSamples, AVRational { 1, d->codecContext->sample_rate }, d->codecContext->time_base);
688 
689 	avcodec_fill_audio_frame(frame, d->codecContext->channels, d->codecContext->sample_fmt, d->dstSamplesData[0], d->dstSamplesSize, 0);
690 
691 	if (!writeFrame(frame)) {
692 		return false;
693 	}
694 
695 	d->fullSamples += samplesCnt;
696 
697 	av_frame_free(&frame);
698 	return true;
699 }
700 
writeFrame(AVFrame * frame)701 bool Instance::Inner::writeFrame(AVFrame *frame) {
702 	int res = 0;
703 	char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
704 
705 	res = avcodec_send_frame(d->codecContext, frame);
706 	if (res == AVERROR(EAGAIN)) {
707 		const auto packetsWritten = writePackets();
708 		if (packetsWritten < 0) {
709 			if (frame && packetsWritten == AVERROR_EOF) {
710 				LOG(("Audio Error: EOF in packets received when EAGAIN was got in avcodec_send_frame()"));
711 				fail();
712 				return false;
713 			}
714 			return true;
715 		} else if (!packetsWritten) {
716 			LOG(("Audio Error: No packets received when EAGAIN was got in avcodec_send_frame()"));
717 			fail();
718 			return false;
719 		}
720 		res = avcodec_send_frame(d->codecContext, frame);
721 	}
722 	if (res < 0) {
723 		LOG(("Audio Error: Unable to avcodec_send_frame for capture, error %1, %2").arg(res).arg(av_make_error_string(err, sizeof(err), res)));
724 		fail();
725 		return false;
726 	}
727 
728 	if (!frame) { // drain
729 		if ((res = writePackets()) != AVERROR_EOF) {
730 			LOG(("Audio Error: not EOF in packets received when draining the codec, result %1").arg(res));
731 			fail();
732 			return false;
733 		}
734 	}
735 	return true;
736 }
737 
writePackets()738 int Instance::Inner::writePackets() {
739 	AVPacket *pkt = av_packet_alloc();
740 	const auto guard = gsl::finally([&] { av_packet_free(&pkt); });
741 
742 	int res = 0;
743 	char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
744 
745 	int written = 0;
746 	do {
747 		if ((res = avcodec_receive_packet(d->codecContext, pkt)) < 0) {
748 			if (res == AVERROR(EAGAIN)) {
749 				return written;
750 			} else if (res == AVERROR_EOF) {
751 				return res;
752 			}
753 			LOG(("Audio Error: Unable to avcodec_receive_packet for capture, error %1, %2").arg(res).arg(av_make_error_string(err, sizeof(err), res)));
754 			fail();
755 			return res;
756 		}
757 
758 		av_packet_rescale_ts(pkt, d->codecContext->time_base, d->stream->time_base);
759 		pkt->stream_index = d->stream->index;
760 		if ((res = av_interleaved_write_frame(d->fmtContext, pkt)) < 0) {
761 			LOG(("Audio Error: Unable to av_interleaved_write_frame for capture, error %1, %2").arg(res).arg(av_make_error_string(err, sizeof(err), res)));
762 			fail();
763 			return -1;
764 		}
765 
766 		++written;
767 		av_packet_unref(pkt);
768 	} while (true);
769 	return written;
770 }
771 
772 } // namespace Capture
773 } // namespace Media
774