mirror of
https://github.com/telegramdesktop/tdesktop
synced 2025-03-25 04:38:23 +00:00
Add some checks to video sound stream decoding.
This commit is contained in:
parent
05e3ddce0c
commit
574f4a73cb
@ -20,10 +20,25 @@ Copyright (c) 2014-2017 John Preston, https://desktop.telegram.org
|
||||
*/
|
||||
#include "media/media_child_ffmpeg_loader.h"
|
||||
|
||||
#include "core/crash_reports.h"
|
||||
|
||||
namespace {
|
||||
|
||||
constexpr AVSampleFormat AudioToFormat = AV_SAMPLE_FMT_S16;
|
||||
constexpr int64_t AudioToChannelLayout = AV_CH_LAYOUT_STEREO;
|
||||
constexpr int32 AudioToChannels = 2;
|
||||
|
||||
bool IsPlanarFormat(int format) {
|
||||
return (format == AV_SAMPLE_FMT_U8P)
|
||||
|| (format == AV_SAMPLE_FMT_S16P)
|
||||
|| (format == AV_SAMPLE_FMT_S32P)
|
||||
|| (format == AV_SAMPLE_FMT_FLTP)
|
||||
|| (format == AV_SAMPLE_FMT_DBLP)
|
||||
|| (format == AV_SAMPLE_FMT_S64P);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
VideoSoundData::~VideoSoundData() {
|
||||
if (context) {
|
||||
avcodec_close(context);
|
||||
@ -179,11 +194,48 @@ AudioPlayerLoader::ReadResult ChildFFMpegLoader::readFromReadyFrame(QByteArray &
|
||||
return ReadResult::Error;
|
||||
}
|
||||
}
|
||||
|
||||
// See the same check in media_audio_ffmpeg_loader.cpp.
|
||||
if (_frame->extended_data[1] == nullptr) {
|
||||
const auto params = _parentData->context;
|
||||
if (IsPlanarFormat(params->sample_fmt) && params->channels > 1) {
|
||||
LOG(("Audio Error: Inconsistent frame layout/channels in file, codec: (%1;%2;%3), frame: (%4;%5;%6)."
|
||||
).arg(params->channel_layout
|
||||
).arg(params->channels
|
||||
).arg(params->sample_fmt
|
||||
).arg(_frame->channel_layout
|
||||
).arg(_frame->channels
|
||||
).arg(_frame->format
|
||||
));
|
||||
return ReadResult::Error;
|
||||
} else {
|
||||
const auto key = "ffmpeg_" + std::to_string(ptrdiff_t(this));
|
||||
const auto value = QString("codec: (%1;%2;%3), frame: (%4;%5;%6), ptrs: (%7;%8;%9)"
|
||||
).arg(params->channel_layout
|
||||
).arg(params->channels
|
||||
).arg(params->sample_fmt
|
||||
).arg(_frame->channel_layout
|
||||
).arg(_frame->channels
|
||||
).arg(_frame->format
|
||||
).arg(ptrdiff_t(_frame->data[0])
|
||||
).arg(ptrdiff_t(_frame->extended_data[0])
|
||||
).arg(ptrdiff_t(_frame->data[1])
|
||||
);
|
||||
CrashReports::SetAnnotation(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
if ((res = swr_convert(_swrContext, _dstSamplesData, dstSamples, (const uint8_t**)_frame->extended_data, _frame->nb_samples)) < 0) {
|
||||
char err[AV_ERROR_MAX_STRING_SIZE] = { 0 };
|
||||
LOG(("Audio Error: Unable to swr_convert for file '%1', data size '%2', error %3, %4").arg(_file.name()).arg(_data.size()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||
return ReadResult::Error;
|
||||
}
|
||||
|
||||
if (_frame->extended_data[1] == nullptr) {
|
||||
const auto key = "ffmpeg_" + std::to_string(ptrdiff_t(this));
|
||||
CrashReports::ClearAnnotation(key);
|
||||
}
|
||||
|
||||
int32 resultLen = av_samples_get_buffer_size(0, AudioToChannels, res, AudioToFormat, 1);
|
||||
result.append((const char*)_dstSamplesData[0], resultLen);
|
||||
samplesAdded += resultLen / _sampleSize;
|
||||
|
Loading…
Reference in New Issue
Block a user