Skip to content

Commit

Permalink
Merge pull request #854 from MediaArea/thumbnails
Browse files Browse the repository at this point in the history
Fix thumbnail and panel generation fails with some type of streams
  • Loading branch information
dericed authored Dec 25, 2024
2 parents 652961e + f025922 commit 95c86bc
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 8 deletions.
3 changes: 2 additions & 1 deletion Source/Core/FFmpegVideoEncoder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,8 @@ void FFmpegVideoEncoder::makeVideo(const QString &video, const QVector<Source>&
videoEncCtx->time_base.den = source.den;

videoEncCtx->gop_size = 1; /* emit one intra frame every twelve frames at most */
videoEncCtx->pix_fmt = AV_PIX_FMT_YUVJ422P;
videoEncCtx->pix_fmt = AV_PIX_FMT_YUV420P;
videoEncCtx->color_range = AVCOL_RANGE_JPEG;
videoEncCtx->max_b_frames = 0;

if (videoEncCtx->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
Expand Down
25 changes: 19 additions & 6 deletions Source/Core/FileInformation.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1406,8 +1406,9 @@ struct Output {

AVFilterGraph* FilterGraph = { nullptr };

int Scale_OutputPixelFormat = { AV_PIX_FMT_YUVJ420P };
int Output_PixelFormat = { AV_PIX_FMT_YUVJ420P };
int Scale_OutputPixelFormat = { AV_PIX_FMT_YUV420P };
int Output_PixelFormat = { AV_PIX_FMT_YUV420P };
int Output_ColorRange = { AVCOL_RANGE_JPEG };
int Output_CodecID = { AV_CODEC_ID_MJPEG };
int Width = { 0 };
int Height = { 0 };
Expand Down Expand Up @@ -1462,6 +1463,7 @@ struct Output {
Output_CodecContext->width = size.width();
Output_CodecContext->height = size.height();
Output_CodecContext->pix_fmt = (AVPixelFormat) Output_PixelFormat;
Output_CodecContext->color_range = (AVColorRange) Output_ColorRange;
Output_CodecContext->time_base.num = timeBaseNum;
Output_CodecContext->time_base.den = timeBaseDen;

Expand Down Expand Up @@ -1513,6 +1515,7 @@ struct Output {
scaledFrame->width = Width;
scaledFrame->height= Height;
scaledFrame->format=(AVPixelFormat)Scale_OutputPixelFormat;
scaledFrame->color_range = (AVColorRange) Output_ColorRange;

av_image_alloc(scaledFrame->data, scaledFrame->linesize, scaledFrame->width, scaledFrame->height, (AVPixelFormat) Scale_OutputPixelFormat, 1);
if (sws_scale(ScaleContext, Frame->data, Frame->linesize, 0, Frame->height, scaledFrame->data, scaledFrame->linesize)<0)
Expand Down Expand Up @@ -1600,15 +1603,20 @@ void FileInformation::makeMkvReport(QString exportFileName, QByteArray attachmen
FFmpegVideoEncoder::Metadata streamMetadata;
streamMetadata << FFmpegVideoEncoder::MetadataEntry(QString("title"), QString("Frame Thumbnails"));

auto timeBase = QString::fromStdString(streamsStats->getStreams().begin()->get()->getTime_base());
auto timeBase = streamsStats->getReferenceStream() ? QString::fromStdString(streamsStats->getReferenceStream()->getTime_base()) : QString("1/25");
auto timeBaseSplitted = timeBase.split("/");
int num = timeBaseSplitted[0].toInt();
int den = timeBaseSplitted[1].toInt();

auto codecTimeBase = QString::fromStdString(streamsStats->getStreams().begin()->get()->getCodec_Time_Base());
auto codecTimeBase = streamsStats->getReferenceStream() ? QString::fromStdString(streamsStats->getReferenceStream()->getCodec_Time_Base()) : QString("0/1");
auto codecTimeBaseSplitted = codecTimeBase.split("/");
int codecNum = codecTimeBaseSplitted[0].toInt();
int codecDen = codecTimeBaseSplitted[1].toInt();
if (av_cmp_q(AVRational {codecNum, codecDen}, AVRational {0, 1}) == 0) // Codec time base is not always set
{
codecNum = num;
codecDen = den;
}

source.metadata = streamMetadata;
source.width = m_thumbnails_frames.empty() ? 0 : m_thumbnails_frames[0].size().width();
Expand Down Expand Up @@ -1698,15 +1706,20 @@ void FileInformation::makeMkvReport(QString exportFileName, QByteArray attachmen
panelSource.height = panelSize().height();

// 2do: take related stream instead of first one
auto timeBase = QString::fromStdString(streamsStats->getStreams().begin()->get()->getTime_base());
auto timeBase = streamsStats->getReferenceStream() ? QString::fromStdString(streamsStats->getReferenceStream()->getTime_base()) : QString("1/25");
auto timeBaseSplitted = timeBase.split("/");
int num = timeBaseSplitted[0].toInt();
int den = timeBaseSplitted[1].toInt();

auto codecTimeBase = QString::fromStdString(streamsStats->getStreams().begin()->get()->getCodec_Time_Base());
auto codecTimeBase = streamsStats->getReferenceStream() ? QString::fromStdString(streamsStats->getReferenceStream()->getCodec_Time_Base()) : QString("0/1");
auto codecTimeBaseSplitted = codecTimeBase.split("/");
int codecNum = codecTimeBaseSplitted[0].toInt();
int codecDen = codecTimeBaseSplitted[1].toInt();
if (av_cmp_q(AVRational {codecNum, codecDen}, AVRational {0, 1}) == 0) // Codec time base is not always set
{
codecNum = num;
codecDen = den;
}

std::shared_ptr<Output> output = std::make_shared<Output>();
output->scaleBeforeEncoding = true;
Expand Down
18 changes: 17 additions & 1 deletion Source/Core/StreamsStats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,11 @@ extern "C"

#include "Core/VideoStreamStats.h"
#include "Core/AudioStreamStats.h"
#include "StreamsStats.h"

using namespace tinyxml2;

StreamsStats::StreamsStats(QVector<QAVStream*> qavstreams)
StreamsStats::StreamsStats(QVector<QAVStream*> qavstreams) : nullCommonStreamStatsPtr(nullptr)
{
for (size_t pos = 0; pos < qavstreams.count(); ++pos)
{
Expand Down Expand Up @@ -112,3 +113,18 @@ int StreamsStats::avSampleFormat() const

return AV_SAMPLE_FMT_NONE;
}

const StreamsStats::CommonStreamStatsPtr& StreamsStats::getReferenceStream() const
{
for(auto& stream : streams) {
if(stream->getType() == AVMEDIA_TYPE_VIDEO)
return stream;
}

for(auto& stream : streams) {
if(stream->getType() == AVMEDIA_TYPE_AUDIO)
return stream;
}

return nullCommonStreamStatsPtr;
}
2 changes: 2 additions & 0 deletions Source/Core/StreamsStats.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ class StreamsStats {
int bitsPerRawVideoSample() const;
int avSampleFormat() const;

const CommonStreamStatsPtr& getReferenceStream() const;
const std::list<CommonStreamStatsPtr>& getStreams() const { return streams; }
private:
std::list<CommonStreamStatsPtr> streams;
CommonStreamStatsPtr nullCommonStreamStatsPtr;
};

#endif // StreamsStats_H

0 comments on commit 95c86bc

Please sign in to comment.