Skip to content

Commit

Permalink
Limit number of decoding threads to at most 16 to avoid ffmpeg warning
Browse files Browse the repository at this point in the history
Add missing header for hdr10+
Partially add feature to print indexing progress
  • Loading branch information
myrsloik committed Sep 30, 2023
1 parent b406a8d commit d66c0fd
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 10 deletions.
2 changes: 1 addition & 1 deletion src/audiosource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ void LWAudioDecoder::OpenFile(const std::string &SourceFile, int Track, int Thre

if (Threads < 1)
Threads = static_cast<int>(std::thread::hardware_concurrency());
CodecContext->thread_count = Threads;
CodecContext->thread_count = std::min(Threads, 16);

// Probably guard against mid-stream format changes
CodecContext->flags |= AV_CODEC_FLAG_DROPCHANGED;
Expand Down
21 changes: 18 additions & 3 deletions src/vapoursynth.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <memory>
#include <limits>
#include <string>
#include <chrono>

struct BestVideoSourceData {
VSVideoInfo VI = {};
Expand Down Expand Up @@ -149,7 +150,7 @@ static const VSFrame *VS_CC BestVideoSourceGetFrame(int n, int ActivationReason,
}

if (Src->HDR10Plus && Src->HDR10PlusSize > 0) {
vsapi->mapSetData(Props, "HDR10Plus", reinterpret_cast<const char *>(Src->HDR10Plus), Src->HDR10PlusSize, dtBinary, maReplace);
vsapi->mapSetData(Props, "HDR10Plus", reinterpret_cast<const char *>(Src->HDR10Plus), static_cast<int>(Src->HDR10PlusSize), dtBinary, maReplace);
}

vsapi->mapSetInt(Props, "FlipVertical", VP.FlipVerical, maAppend);
Expand Down Expand Up @@ -193,8 +194,22 @@ static void VS_CC CreateBestVideoSource(const VSMap *In, VSMap *Out, void *, VSC

try {
D->V.reset(new BestVideoSource(Source, HWDevice ? HWDevice : "", Track, VariableFormat, Threads, CachePath ? CachePath : "", &Opts));
if (Exact)
D->V->GetExactDuration();
if (Exact) {
auto NextUpdate = std::chrono::high_resolution_clock::now();
D->V->GetExactDuration([vsapi, Core, Track = std::to_string(D->V->GetTrack()), &NextUpdate](int64_t Cur, int64_t Total) {
if (NextUpdate < std::chrono::high_resolution_clock::now()) {
if (Cur == INT64_MAX && Cur == Total) {
vsapi->logMessage(mtInformation, ("BestSource track #" + Track + " indexing complete").c_str(), Core);
} else if (Total > 0) {
int Percentage = static_cast<int>((static_cast<double>(Cur) / static_cast<double>(Total)) * 100);
vsapi->logMessage(mtInformation, ("BestSource track #" + Track + " index progress " + std::to_string(Percentage) + "%").c_str(), Core);
} else {
vsapi->logMessage(mtInformation, ("BestSource track #" + Track + " index progress " + std::to_string(Cur / (1024 * 1024)) + "MB").c_str(), Core);
}
NextUpdate = std::chrono::high_resolution_clock::now() + std::chrono::seconds(1);
}
});
}
const VideoProperties &VP = D->V->GetVideoProperties();
if (VP.VF.ColorFamily == 0 || !vsapi->queryVideoFormat(&D->VI.format, VP.VF.ColorFamily, VP.VF.Float, VP.VF.Bits, VP.VF.SubSamplingW, VP.VF.SubSamplingH, Core))
throw VideoException("Unsupported video format from decoder (probably less than 8 bit or palette)");
Expand Down
31 changes: 26 additions & 5 deletions src/videosource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@

#include "../libp2p/p2p_api.h"

#define VERSION_CHECK(LIB, cmp, major, minor, micro) ((LIB) cmp (AV_VERSION_INT(major, minor, micro)))


extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
Expand All @@ -34,10 +37,11 @@ extern "C" {
#include <libavutil/stereo3d.h>
#include <libavutil/display.h>
#include <libavutil/mastering_display_metadata.h>
#if VERSION_CHECK(LIBAVUTIL_VERSION_INT, >=, 58, 5, 100)
#include <libavutil/hdr_dynamic_metadata.h>
#endif
}

#define VERSION_CHECK(LIB, cmp, major, minor, micro) ((LIB) cmp (AV_VERSION_INT(major, minor, micro)))

static bool GetSampleTypeIsFloat(const AVPixFmtDescriptor *Desc) {
return !!(Desc->flags & AV_PIX_FMT_FLAG_FLOAT);
}
Expand Down Expand Up @@ -190,7 +194,7 @@ void LWVideoDecoder::OpenFile(const std::string &SourceFile, const std::string &
if (Threads < 1) {
int HardwareConcurrency = std::thread::hardware_concurrency();
if (Type != AV_HWDEVICE_TYPE_CUDA)
Threads = HardwareConcurrency;
Threads = std::min(HardwareConcurrency, 16);
else if (CodecContext->codec_id == AV_CODEC_ID_H264)
Threads = 1;
else
Expand Down Expand Up @@ -257,6 +261,14 @@ LWVideoDecoder::~LWVideoDecoder() {
Free();
}

int64_t LWVideoDecoder::GetSourceSize() const {
return avio_size(FormatContext->pb);
}

int64_t LWVideoDecoder::GetSourcePostion() const {
return avio_tell(FormatContext->pb);
}

int LWVideoDecoder::GetTrack() const {
return TrackNumber;
}
Expand Down Expand Up @@ -675,7 +687,7 @@ void BestVideoSource::SetSeekPreRoll(int64_t Frames) {
PreRoll = std::max<int64_t>(Frames, 0);
}

bool BestVideoSource::GetExactDuration() {
bool BestVideoSource::GetExactDuration(const std::function<void(int64_t Current, int64_t Total)> &Progress) {
if (HasExactNumVideoFrames)
return true;
int Index = -1;
Expand All @@ -691,7 +703,16 @@ bool BestVideoSource::GetExactDuration() {

LWVideoDecoder *Decoder = Decoders[Index];

while (Decoder->SkipAVFrames(INT64_MAX));
int64_t FileSize = Progress ? Decoder->GetSourceSize() : -1;

while (Decoder->SkipAVFrames(Progress ? 1 : INT64_MAX)) {
if (Progress)
Progress(Decoder->GetSourcePostion(), FileSize);
};

if (Progress)
Progress(INT64_MAX, INT64_MAX);

VP.NumFrames = Decoder->GetFrameNumber();
VP.NumFields = Decoder->GetFieldNumber();

Expand Down
5 changes: 4 additions & 1 deletion src/videosource.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <list>
#include <string>
#include <map>
#include <functional>

struct AVFormatContext;
struct AVCodecContext;
Expand Down Expand Up @@ -114,6 +115,8 @@ struct LWVideoDecoder {
public:
LWVideoDecoder(const std::string &SourceFile, const std::string &HWDeviceName, int Track, bool VariableFormat, int Threads, const std::map<std::string, std::string> &LAVFOpts); // Positive track numbers are absolute. Negative track numbers mean nth audio track to simplify things.
~LWVideoDecoder();
int64_t GetSourceSize() const;
int64_t GetSourcePostion() const;
int GetTrack() const; // Useful when opening nth video track to get the actual number
int64_t GetFrameNumber() const;
int64_t GetFieldNumber() const;
Expand Down Expand Up @@ -209,7 +212,7 @@ class BestVideoSource {
int GetTrack() const; // Useful when opening nth video track to get the actual number
void SetMaxCacheSize(size_t Bytes); /* default max size is 1GB */
void SetSeekPreRoll(int64_t Frames); /* the number of frames to cache before the position being fast forwarded to, default is 10 frames */
bool GetExactDuration();
bool GetExactDuration(const std::function<void(int64_t Current, int64_t Total)> &Progress = nullptr);
const VideoProperties &GetVideoProperties() const;
BestVideoFrame *GetFrame(int64_t N);
BestVideoFrame *GetFrameExtendLast(int64_t N);
Expand Down

0 comments on commit d66c0fd

Please sign in to comment.