2
0
mirror of https://github.com/telegramdesktop/tdesktop synced 2025-08-31 06:26:18 +00:00

Send mp4 and quicktime files as videos.

This commit is contained in:
John Preston
2017-03-09 12:47:45 +03:00
parent eaae662b7d
commit 9ed8cbe2d1
10 changed files with 204 additions and 125 deletions

View File

@@ -368,17 +368,9 @@ bool FFMpegReaderImplementation::start(Mode mode, TimeMs &positionMs) {
_codec = avcodec_find_decoder(_codecContext->codec_id);
_audioStreamId = av_find_best_stream(_fmtContext, AVMEDIA_TYPE_AUDIO, -1, -1, 0, 0);
if (_mode == Mode::OnlyGifv) {
if (_audioStreamId >= 0) { // should be no audio stream
_audioStreamId = -1;
return false;
}
if (dataSize() > AnimationInMemory) {
return false;
}
if (_codecContext->codec_id != AV_CODEC_ID_H264) {
return false;
}
if (_mode == Mode::Inspecting) {
_hasAudioStream = (_audioStreamId >= 0);
_audioStreamId = -1;
} else if (_mode == Mode::Silent || !_playId) {
_audioStreamId = -1;
}
@@ -390,7 +382,7 @@ bool FFMpegReaderImplementation::start(Mode mode, TimeMs &positionMs) {
std::unique_ptr<VideoSoundData> soundData;
if (_audioStreamId >= 0) {
AVCodecContext *audioContext = avcodec_alloc_context3(nullptr);
auto audioContext = avcodec_alloc_context3(nullptr);
if (!audioContext) {
LOG(("Audio Error: Unable to avcodec_alloc_context3 %1").arg(logData()));
return false;
@@ -418,9 +410,8 @@ bool FFMpegReaderImplementation::start(Mode mode, TimeMs &positionMs) {
}
}
}
if (positionMs > 0) {
int64 ts = (positionMs * _fmtContext->streams[_streamId]->time_base.den) / (1000LL * _fmtContext->streams[_streamId]->time_base.num);
auto ts = (positionMs * _fmtContext->streams[_streamId]->time_base.den) / (1000LL * _fmtContext->streams[_streamId]->time_base.num);
if (av_seek_frame(_fmtContext, _streamId, ts, 0) < 0) {
if (av_seek_frame(_fmtContext, _streamId, ts, AVSEEK_FLAG_BACKWARD) < 0) {
return false;
@@ -446,6 +437,44 @@ bool FFMpegReaderImplementation::start(Mode mode, TimeMs &positionMs) {
return true;
}
bool FFMpegReaderImplementation::inspectAt(TimeMs &positionMs) {
if (positionMs > 0) {
auto ts = (positionMs * _fmtContext->streams[_streamId]->time_base.den) / (1000LL * _fmtContext->streams[_streamId]->time_base.num);
if (av_seek_frame(_fmtContext, _streamId, ts, 0) < 0) {
if (av_seek_frame(_fmtContext, _streamId, ts, AVSEEK_FLAG_BACKWARD) < 0) {
return false;
}
}
}
_packetQueue.clear();
AVPacket packet;
auto readResult = readPacket(&packet);
if (readResult == PacketResult::Ok && positionMs > 0) {
positionMs = countPacketMs(&packet);
}
if (readResult == PacketResult::Ok) {
processPacket(&packet);
}
return true;
}
bool FFMpegReaderImplementation::isGifv() const {
if (_hasAudioStream) {
return false;
}
if (dataSize() > AnimationInMemory) {
return false;
}
if (_codecContext->codec_id != AV_CODEC_ID_H264) {
return false;
}
return true;
}
QString FFMpegReaderImplementation::logData() const {
return qsl("for file '%1', data size '%2'").arg(_location ? _location->name() : QString()).arg(_data->size());
}
@@ -501,8 +530,8 @@ FFMpegReaderImplementation::PacketResult FFMpegReaderImplementation::readPacket(
}
void FFMpegReaderImplementation::processPacket(AVPacket *packet) {
bool videoPacket = (packet->stream_index == _streamId);
bool audioPacket = (_audioStreamId >= 0 && packet->stream_index == _audioStreamId);
auto videoPacket = (packet->stream_index == _streamId);
auto audioPacket = (_audioStreamId >= 0 && packet->stream_index == _audioStreamId);
if (audioPacket || videoPacket) {
if (videoPacket) {
_lastReadVideoMs = countPacketMs(packet);