From fc77164d651a14f5584bf8b0b82d16d404ee2535 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Gonzalo=20Garramu=C3=B1o?= Date: Tue, 12 Mar 2024 07:33:36 -0300 Subject: [PATCH] Added gif format. Fixed listing of codecs. --- bin/compile_ffmpeg_windows.sh | 4 + mrv2/docs/HISTORY.md | 1 + mrv2/lib/mrvWidgets/mrvAboutUI.fl | 25 ++--- mrv2/lib/mrvWidgets/mrvVersion.cpp | 171 +++++++++++++++++++++-------- mrv2/lib/mrvWidgets/mrvVersion.h | 2 +- tlRender | 2 +- 6 files changed, 143 insertions(+), 62 deletions(-) diff --git a/bin/compile_ffmpeg_windows.sh b/bin/compile_ffmpeg_windows.sh index b9cf523a3..782d0f7f7 100755 --- a/bin/compile_ffmpeg_windows.sh +++ b/bin/compile_ffmpeg_windows.sh @@ -450,6 +450,7 @@ if [[ $BUILD_FFMPEG == ON || $BUILD_FFMPEG == 1 ]]; then --enable-decoder=dnxhd --enable-decoder=eac3 --enable-decoder=flac + --enable-decoder=gif --enable-decoder=h264 --enable-decoder=hevc --enable-decoder=mjpeg @@ -519,6 +520,7 @@ if [[ $BUILD_FFMPEG == ON || $BUILD_FFMPEG == 1 ]]; then --enable-encoder=cfhd --enable-encoder=dnxhd --enable-encoder=eac3 + --enable-encoder=gif --enable-encoder=mjpeg --enable-encoder=mpeg2video --enable-encoder=mpeg4 @@ -579,6 +581,7 @@ if [[ $BUILD_FFMPEG == ON || $BUILD_FFMPEG == 1 ]]; then --enable-demuxer=dtshd --enable-demuxer=eac3 --enable-demuxer=flac + --enable-demuxer=gif --enable-demuxer=h264 --enable-demuxer=hevc --enable-demuxer=m4v @@ -624,6 +627,7 @@ if [[ $BUILD_FFMPEG == ON || $BUILD_FFMPEG == 1 ]]; then --enable-muxer=dts --enable-muxer=eac3 --enable-muxer=flac + --enable-muxer=gif --enable-muxer=h264 --enable-muxer=hevc --enable-muxer=m4v diff --git a/mrv2/docs/HISTORY.md b/mrv2/docs/HISTORY.md index bff75a83e..6df42d3c9 100644 --- a/mrv2/docs/HISTORY.md +++ b/mrv2/docs/HISTORY.md @@ -56,6 +56,7 @@ v1.0.9 - Entering a Text annotation on the viewport can be confirmed by doing SHIFT + Enter. - Added FFmpeg's actual version information, not just each library. +- Fixed listing of codecs in the About Window v1.0.8 diff --git a/mrv2/lib/mrvWidgets/mrvAboutUI.fl b/mrv2/lib/mrvWidgets/mrvAboutUI.fl index 7860aa02a..b8a6e9610 100644 --- a/mrv2/lib/mrvWidgets/mrvAboutUI.fl +++ b/mrv2/lib/mrvWidgets/mrvAboutUI.fl @@ -7,11 +7,6 @@ i18n_gnu_function gettext i18n_gnu_static_function gettext_noop header_name {.h} code_name {.cxx} -snap { - ver 1 - current_suite FLTK - current_preset 0 -} decl {\#include "string"} {public local } @@ -32,8 +27,8 @@ class AboutUI {open Function {make_window(ViewerUI* main)} {open private } { Fl_Window uiMain { - label {About mrv2} open selected - xywh {740 284 535 395} type Double resizable + label {About mrv2} open + xywh {1336 308 535 395} type Double resizable code0 {//main->uiMain->add(o);} modal visible } { Fl_Group {} {open @@ -115,8 +110,8 @@ o->value(-1);} } } Fl_Group {} { - label Codecs - xywh {5 25 530 370} hide + label Codecs open + xywh {5 25 530 370} } { Fl_Browser {} { label Video @@ -128,12 +123,12 @@ o->value(-1);} Fl_Browser {} { label Audio xywh {20 200 500 110} color 49 align 1 textcolor 32 - code0 {static int widths[] = { 20, 20, 20, 20, 150, 0 }; o->column_widths( widths ); mrv::ffmpeg_audio_codecs(*o); + code0 {static int widths[] = { 20, 20, 20, 20, 20, 150, 0 }; o->column_widths( widths ); mrv::ffmpeg_audio_codecs(*o); o->value(-1);} class {mrv::Browser} } Fl_Browser {} { - label Subtitles + label Subtitles selected xywh {20 330 500 55} color 49 align 1 textcolor 32 code0 {mrv::ffmpeg_subtitle_codecs(*o); o->value(-1);} @@ -141,19 +136,19 @@ o->value(-1);} } } Fl_Group {} { - label Protocols + label Protocols open xywh {5 30 530 365} hide } { Fl_Browser {} { xywh {20 45 500 320} color 49 textcolor 32 - code0 {o->add( mrv::ffmpeg_protocols().c_str() ); + code0 {mrv::ffmpeg_protocols(*o); o->value(-1);} class {mrv::Browser} } } Fl_Group {} { - label {Motion Estimation Methods} - xywh {5 30 530 365} + label {Motion Estimation Methods} open + xywh {5 30 530 365} hide } { Fl_Browser {} { xywh {20 41 495 334} color 49 textcolor 32 diff --git a/mrv2/lib/mrvWidgets/mrvVersion.cpp b/mrv2/lib/mrvWidgets/mrvVersion.cpp index c85fb5097..432e93956 100644 --- a/mrv2/lib/mrvWidgets/mrvVersion.cpp +++ b/mrv2/lib/mrvWidgets/mrvVersion.cpp @@ -130,6 +130,8 @@ extern "C" # pragma warning(disable : 4275) #endif +#include + #include "mrvCore/mrvOS.h" #include "mrvCore/mrvCPU.h" @@ -177,6 +179,67 @@ namespace mrv o << "Release level: Unknown"; o << " (" << std::hex << release_level << ")" << std::dec; } + + +#ifdef TLRENDER_FFMPEG + const AVCodec* next_codec_for_id(enum AVCodecID id, void **iter, + int encoder) + { + const AVCodec* c = nullptr; + while ((c = av_codec_iterate(iter))) + { + if (c->id == id && + (encoder ? av_codec_is_encoder(c) : av_codec_is_decoder(c))) + return c; + } + return NULL; + } + + void print_codecs_for_id(std::ostringstream& o, + enum AVCodecID id, int encoder) + { + void *iter = NULL; + const AVCodec *codec; + + o << " (" << (encoder ? "encoders" : "decoders") << ":"; + + while ((codec = next_codec_for_id(id, &iter, encoder))) + o << ' ' << codec->name; + + o << ')'; + } + + int compare_codec_desc(const void *a, const void *b) + { + const AVCodecDescriptor * const *da = (const AVCodecDescriptor* const *) a; + const AVCodecDescriptor * const *db = (const AVCodecDescriptor* const *) b; + + return ( + (*da)->type != (*db)->type + ? FFDIFFSIGN((*da)->type, (*db)->type) + : strcmp((*da)->name, (*db)->name)); + } + + int get_codecs_sorted(const AVCodecDescriptor ***rcodecs) + { + const AVCodecDescriptor *desc = NULL; + const AVCodecDescriptor **codecs; + unsigned nb_codecs = 0, i = 0; + + while ((desc = avcodec_descriptor_next(desc))) + nb_codecs++; + if (!(codecs = (const AVCodecDescriptor**)av_calloc( + nb_codecs, sizeof(*codecs)))) + return AVERROR(ENOMEM); + desc = NULL; + while ((desc = avcodec_descriptor_next(desc))) + codecs[i++] = desc; + qsort(codecs, nb_codecs, sizeof(*codecs), compare_codec_desc); + *rcodecs = codecs; + return nb_codecs; + } +#endif + } // namespace const char* kVersion = MRV2_VERSION; @@ -198,7 +261,7 @@ namespace mrv encode(enc), decode(dec), blob(blo), - name(n), + name(string::toLower(n)), module(mod), description(desc) { @@ -449,6 +512,8 @@ namespace mrv long_name = ofmt->long_name; encode = true; } + if (name && strcmp(ofmt->name, name) == 0) + encode = true; } opaque = NULL; while ((ifmt = av_demuxer_iterate(&opaque))) @@ -458,7 +523,7 @@ namespace mrv { name = ifmt->name; long_name = ifmt->long_name; - encode = true; + decode = true; } if (name && strcmp(ifmt->name, name) == 0) decode = true; @@ -469,7 +534,7 @@ namespace mrv last_name = name; f = new FormatInfo( - decode, encode, false, name, "FFMPEG", long_name); + decode, encode, false, name, "FFmpeg", long_name); formats.push_back(f); } #endif @@ -496,50 +561,66 @@ namespace mrv static void ffmpeg_codecs(mrv::Browser& browser, int type) { #ifdef TLRENDER_FFMPEG - const AVCodec* p; - const AVCodec* p2; - const char* last_name; + const AVCodecDescriptor **codecs; + unsigned i; + int nb_codecs = get_codecs_sorted(&codecs); + + if (nb_codecs < 0) + return; + + char buf[256]; + for (i = 0; i < nb_codecs; i++) { + const AVCodecDescriptor *desc = codecs[i]; + const AVCodec *codec; + void *iter = NULL; + + if (desc->type != type) + continue; + + if (strstr(desc->name, "_deprecated")) + continue; + + bool decode = avcodec_find_decoder(desc->id); + bool encode = avcodec_find_encoder(desc->id); + if (!decode && !encode) + continue; std::ostringstream o; - last_name = "000"; - for (;;) - { - int decode = 0; - int encode = 0; - int cap = 0; - - p2 = NULL; - void* opaque = NULL; - while ((p = av_codec_iterate(&opaque))) - { - if ((p2 == NULL || strcmp(p->name, p2->name) < 0) && - strcmp(p->name, last_name) > 0) - { - p2 = p; - decode = encode = cap = 0; - } - if (p2 && strcmp(p->name, p2->name) == 0) - { - encode = av_codec_is_encoder(p); - decode = av_codec_is_decoder(p); - cap |= p->capabilities; - } + o << (decode ? 'D' : ' ') + << '\t' + << (encode ? 'E' : ' ') + << '\t' + << ((desc->props & AV_CODEC_PROP_INTRA_ONLY) ? 'I' : ' ') + << '\t' + << ((desc->props & AV_CODEC_PROP_LOSSY) ? 'L' : ' ') + << '\t' + << ((desc->props & AV_CODEC_PROP_LOSSLESS) ? 'S' : ' ') + << '\t' + << desc->name + << '\t' + << (desc->long_name ? desc->long_name : ""); + + /* print decoders/encoders when there's more than one or their + * names are different from codec name */ + while ((codec = next_codec_for_id(desc->id, &iter, 0))) { + if (strcmp(codec->name, desc->name)) { + print_codecs_for_id(o, desc->id, 0); + break; } - - if (p2 == NULL) + } + iter = NULL; + while ((codec = next_codec_for_id(desc->id, &iter, 1))) { + if (strcmp(codec->name, desc->name)) { + print_codecs_for_id(o, desc->id, 1); break; - last_name = p2->name; - - if (p2->type != type) - continue; - - std::ostringstream o; - o << (decode ? "D\t" : " \t") << (encode ? "E\t" : " \t") << "\t" - << (cap & AV_CODEC_CAP_DRAW_HORIZ_BAND ? "S\t" : " \t") - << (cap & AV_CODEC_CAP_DR1 ? "D\t" : " \t") << p2->name; - - browser.add(o.str().c_str()); + } } + + + browser.add(o.str().c_str()); + } + + av_free(codecs); #endif } @@ -564,19 +645,19 @@ namespace mrv #endif } - std::string ffmpeg_protocols() + void ffmpeg_protocols(mrv::Browser& b) { - std::ostringstream o; #ifdef TLRENDER_FFMPEG void* opaque = NULL; const char* up; for (up = avio_enum_protocols(&opaque, 0); up; up = avio_enum_protocols(&opaque, 0)) { + std::ostringstream o; o << " " << up << ":"; + b.add(o.str().c_str()); } #endif - return o.str(); } void ffmpeg_motion_estimation_methods(mrv::Browser* b) diff --git a/mrv2/lib/mrvWidgets/mrvVersion.h b/mrv2/lib/mrvWidgets/mrvVersion.h index cc08caf2f..fe9f85a79 100644 --- a/mrv2/lib/mrvWidgets/mrvVersion.h +++ b/mrv2/lib/mrvWidgets/mrvVersion.h @@ -15,7 +15,7 @@ namespace mrv void ffmpeg_video_codecs(mrv::Browser& b); void ffmpeg_audio_codecs(mrv::Browser& b); void ffmpeg_subtitle_codecs(mrv::Browser& b); - std::string ffmpeg_protocols(); + void ffmpeg_protocols(mrv::Browser& b); void ffmpeg_motion_estimation_methods(mrv::Browser* b); const char* version(); diff --git a/tlRender b/tlRender index d64d71f1c..130e2fa02 160000 --- a/tlRender +++ b/tlRender @@ -1 +1 @@ -Subproject commit d64d71f1c5091b9ed1e030366aaaeba75c14ed55 +Subproject commit 130e2fa024a3d1c181e471808cffcf586d33d916