[vlc-commits] [Git][videolan/vlc][master] 2 commits: medialibrary: Implement IEmbeddedThumbnail interface with attachments

Jean-Baptiste Kempf gitlab at videolan.org
Wed May 19 17:09:26 UTC 2021



Jean-Baptiste Kempf pushed to branch master at VideoLAN / VLC


Commits:
1a5a3dd6 by Hugo Beauzée-Luyssen at 2021-05-19T16:48:24+00:00
medialibrary: Implement IEmbeddedThumbnail interface with attachments

refs #25751

- - - - -
a7b258c1 by Hugo Beauzée-Luyssen at 2021-05-19T16:48:24+00:00
medialibrary: Provide embedded thumbnails

Fix #25751

- - - - -


2 changed files:

- modules/misc/medialibrary/MetadataExtractor.cpp
- modules/misc/medialibrary/medialibrary.h


Changes:

=====================================
modules/misc/medialibrary/MetadataExtractor.cpp
=====================================
@@ -24,6 +24,64 @@
 
 #include "medialibrary.h"
 
+#include <vlc_image.h>
+#include <vlc_hash.h>
+#include <vlc_fs.h>
+
+EmbeddedThumbnail::EmbeddedThumbnail( input_attachment_t* a, vlc_fourcc_t fcc )
+    : m_attachment( vlc_input_attachment_Hold( a ) )
+    , m_fcc( fcc )
+{
+}
+
+EmbeddedThumbnail::~EmbeddedThumbnail()
+{
+    vlc_input_attachment_Release( m_attachment );
+}
+
+bool EmbeddedThumbnail::save( const std::string& path )
+{
+    std::unique_ptr<FILE, decltype(&fclose)> f{ vlc_fopen( path.c_str(), "wb" ),
+                                                &fclose };
+    if ( f == nullptr )
+        return false;
+    auto res = fwrite( m_attachment->p_data, m_attachment->i_data, 1, f.get() );
+    return res == 1;
+}
+
+size_t EmbeddedThumbnail::size() const
+{
+    return m_attachment->i_data;
+}
+
+std::string EmbeddedThumbnail::hash() const
+{
+    vlc_hash_md5_t md5;
+    vlc_hash_md5_Init( &md5 );
+    vlc_hash_md5_Update( &md5, m_attachment->p_data, m_attachment->i_data );
+    uint8_t bytes[VLC_HASH_MD5_DIGEST_SIZE];
+    vlc_hash_md5_Finish( &md5, bytes, sizeof(bytes) );
+    std::string res;
+    res.reserve( VLC_HASH_MD5_DIGEST_HEX_SIZE );
+    const char* hex = "0123456789ABCDEF";
+    for ( auto i = 0u; i < VLC_HASH_MD5_DIGEST_SIZE; ++i )
+        res.append( { hex[bytes[i] >> 4], hex[bytes[i] & 0xF] } );
+    return res;
+}
+
+std::string EmbeddedThumbnail::extension() const
+{
+    switch ( m_fcc )
+    {
+    case VLC_CODEC_JPEG:
+        return "jpg";
+    case VLC_CODEC_PNG:
+        return "png";
+    default:
+        vlc_assert_unreachable();
+    }
+}
+
 MetadataExtractor::MetadataExtractor( vlc_object_t* parent )
     : m_currentCtx( nullptr )
     , m_obj( parent )
@@ -126,6 +184,19 @@ void MetadataExtractor::onParserSubtreeAdded( input_item_t *,
     ctx->mde->addSubtree( *ctx, subtree );
 }
 
+void MetadataExtractor::onAttachmentFound( const vlc_event_t* p_event, void* data )
+{
+    auto ctx = static_cast<ParseContext*>( data );
+    for ( auto i = 0u; i < p_event->u.input_item_attachments_found.count; ++i )
+    {
+        auto a = p_event->u.input_item_attachments_found.attachments[i];
+        auto fcc = image_Mime2Fourcc( a->psz_mime );
+        if ( fcc != VLC_CODEC_PNG && fcc != VLC_CODEC_JPEG )
+            continue;
+        ctx->item.addEmbeddedThumbnail( std::make_shared<EmbeddedThumbnail>( a, fcc ) );
+    }
+}
+
 void MetadataExtractor::addSubtree( ParseContext& ctx, input_item_node_t *root )
 {
     for ( auto i = 0; i < root->i_children; ++i )
@@ -148,6 +219,10 @@ medialibrary::parser::Status MetadataExtractor::run( medialibrary::parser::IItem
     if ( ctx.inputItem == nullptr )
         return medialibrary::parser::Status::Fatal;
 
+    if ( vlc_event_attach( &ctx.inputItem->event_manager, vlc_InputItemAttachmentsFound,
+                      &MetadataExtractor::onAttachmentFound, &ctx ) != VLC_SUCCESS )
+        return medialibrary::parser::Status::Fatal;
+
     const input_item_parser_cbs_t cbs = {
         &MetadataExtractor::onParserEnded,
         &MetadataExtractor::onParserSubtreeAdded,
@@ -161,6 +236,8 @@ medialibrary::parser::Status MetadataExtractor::run( medialibrary::parser::IItem
     };
     if ( ctx.inputParser == nullptr )
     {
+        vlc_event_detach( &ctx.inputItem->event_manager, vlc_InputItemAttachmentsFound,
+                          &MetadataExtractor::onAttachmentFound, &ctx );
         m_currentCtx = nullptr;
         return medialibrary::parser::Status::Fatal;
     }
@@ -180,6 +257,8 @@ medialibrary::parser::Status MetadataExtractor::run( medialibrary::parser::IItem
         }
         m_currentCtx = nullptr;
     }
+    vlc_event_detach( &ctx.inputItem->event_manager, vlc_InputItemAttachmentsFound,
+                      &MetadataExtractor::onAttachmentFound, &ctx );
 
     if ( !ctx.success || ctx.inputParser == nullptr )
         return medialibrary::parser::Status::Fatal;


=====================================
modules/misc/medialibrary/medialibrary.h
=====================================
@@ -44,6 +44,20 @@ struct vlc_thumbnailer_request_t;
 
 class Logger;
 
+class EmbeddedThumbnail : public medialibrary::parser::IEmbeddedThumbnail
+{
+public:
+    EmbeddedThumbnail( input_attachment_t* a, vlc_fourcc_t fcc );
+    virtual ~EmbeddedThumbnail();
+    virtual bool save(const std::string& path) override;
+    virtual size_t size() const override;
+    virtual std::string hash() const override;
+    virtual std::string extension() const override;
+private:
+    input_attachment_t* m_attachment;
+    vlc_fourcc_t m_fcc;
+};
+
 class MetadataExtractor : public medialibrary::parser::IParserService
 {
 private:
@@ -91,6 +105,7 @@ private:
     static void onParserEnded( input_item_t *, int status, void *user_data );
     static void onParserSubtreeAdded( input_item_t *, input_item_node_t *subtree,
                                       void *user_data );
+    static void onAttachmentFound( const vlc_event_t* p_event, void* data );
 
 private:
     vlc::threads::condition_variable m_cond;



View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/66bada4cbff1b98b9efe8026aa079d0bbe648954...a7b258c17eab7b2055ffe4e964b4189b149005bd

-- 
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/66bada4cbff1b98b9efe8026aa079d0bbe648954...a7b258c17eab7b2055ffe4e964b4189b149005bd
You're receiving this email because of your account on code.videolan.org.




More information about the vlc-commits mailing list