LCOV - code coverage report
Current view: top level - src/media/video - accel.h (source / functions) Coverage Total Hit
Test: jami-coverage-filtered.info Lines: 16.7 % 6 1
Test Date: 2026-06-13 09:18:46 Functions: 16.7 % 6 1

            Line data    Source code
       1              : /*
       2              :  *  Copyright (C) 2004-2026 Savoir-faire Linux Inc.
       3              :  *
       4              :  *  This program is free software: you can redistribute it and/or modify
       5              :  *  it under the terms of the GNU General Public License as published by
       6              :  *  the Free Software Foundation, either version 3 of the License, or
       7              :  *  (at your option) any later version.
       8              :  *
       9              :  *  This program is distributed in the hope that it will be useful,
      10              :  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
      11              :  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      12              :  *  GNU General Public License for more details.
      13              :  *
      14              :  *  You should have received a copy of the GNU General Public License
      15              :  *  along with this program. If not, see <https://www.gnu.org/licenses/>.
      16              :  */
      17              : #pragma once
      18              : 
      19              : #include "libav_deps.h"
      20              : #include "media_codec.h"
      21              : #include "video/video_base.h"
      22              : 
      23              : #include <memory>
      24              : #include <string>
      25              : #include <list>
      26              : 
      27              : extern "C" {
      28              : #include <libavutil/hwcontext.h>
      29              : }
      30              : 
      31              : namespace jami {
      32              : namespace video {
      33              : 
      34              : enum class DeviceState : uint8_t { NOT_TESTED, USABLE, NOT_USABLE };
      35              : 
      36              : /**
      37              :  * @brief Provides an abstraction layer to the hardware acceleration APIs in FFmpeg.
      38              :  */
      39              : class HardwareAccel
      40              : {
      41              : public:
      42              :     /**
      43              :      * @brief Transfers hardware frame to main memory.
      44              :      *
      45              :      * Transfers a hardware decoded frame back to main memory. Should be called after
      46              :      * the frame is decoded using avcodec_send_packet/avcodec_receive_frame.
      47              :      *
      48              :      * If @frame is software, this is a no-op.
      49              :      *
      50              :      * @param frame Refrerence to the decoded hardware frame.
      51              :      * @param desiredFormat Software pixel format that the hardware outputs.
      52              :      * @returns Software frame.
      53              :      */
      54              :     static std::unique_ptr<VideoFrame> transferToMainMemory(const VideoFrame& frame, AVPixelFormat desiredFormat);
      55              : 
      56              :     /**
      57              :      * @brief Constructs a HardwareAccel object
      58              :      *
      59              :      * Made public so std::unique_ptr can access it. Should not be called.
      60              :      */
      61              :     HardwareAccel(AVCodecID id,
      62              :                   const std::string& name,
      63              :                   AVHWDeviceType hwType,
      64              :                   AVPixelFormat format,
      65              :                   AVPixelFormat swFormat,
      66              :                   CodecType type,
      67              :                   bool dynBitrate);
      68              : 
      69              :     /**
      70              :      * @brief Dereferences hardware contexts.
      71              :      */
      72              :     ~HardwareAccel();
      73              : 
      74              :     /**
      75              :      * @brief Codec that is being accelerated.
      76              :      */
      77            0 :     AVCodecID getCodecId() const { return id_; };
      78              : 
      79              :     /**
      80              :      * @brief Name of the hardware layer/API being used.
      81              :      */
      82            0 :     const std::string& getName() const { return name_; };
      83              : 
      84              :     /**
      85              :      * @brief Hardware format.
      86              :      */
      87            0 :     AVPixelFormat getFormat() const { return format_; };
      88              : 
      89              :     /**
      90              :      * @brief Software format.
      91              :      *
      92              :      * For encoding it is the format expected by the hardware. For decoding
      93              :      * it is the format output by the hardware.
      94              :      */
      95           23 :     AVPixelFormat getSoftwareFormat() const { return swFormat_; }
      96              : 
      97              :     /**
      98              :      * @brief Gets the name of the codec.
      99              :      *
     100              :      * Decoding: avcodec_get_name(id_)
     101              :      * Encoding: avcodec_get_name(id_) + '_' + name_
     102              :      */
     103              :     std::string getCodecName() const;
     104              : 
     105              :     /**
     106              :      * @brief If hardware decoder can feed hardware encoder directly.
     107              :      *
     108              :      * Returns whether or not the decoder is linked to an encoder or vice-versa. Being linked
     109              :      * means an encoder can directly use the decoder's hardware frame, without first
     110              :      * transferring it to main memory.
     111              :      */
     112            0 :     bool isLinked() const { return linked_; }
     113              : 
     114              :     /**
     115              :      * @brief Set some extra details in the codec context.
     116              :      *
     117              :      * Should be called after a successful
     118              :      * setup (setupDecoder or setupEncoder).
     119              :      * For decoding, sets the hw_device_ctx and get_format callback. If the decoder has
     120              :      * a frames context, mark as linked.
     121              :      * For encoding, sets hw_device_ctx and hw_frames_ctx, and may set some hardware
     122              :      * codec options.
     123              :      */
     124              :     void setDetails(AVCodecContext* codecCtx);
     125              : 
     126              :     /**
     127              :      * @brief Transfers a frame to/from the GPU memory.
     128              :      *
     129              :      * Transfers a hardware decoded frame back to main memory. Should be called after
     130              :      * the frame is decoded using avcodec_send_packet/avcodec_receive_frame or before
     131              :      * the frame is encoded using avcodec_send_frame/avcodec_receive_packet.
     132              :      *
     133              :      * @param frame Hardware frame when decoding, software frame when encoding.
     134              :      * @returns Software frame when decoding, hardware frame when encoding.
     135              :      */
     136              :     std::unique_ptr<VideoFrame> transfer(const VideoFrame& frame);
     137              : 
     138              :     /**
     139              :      * @brief Links this HardwareAccel's frames context with the passed in context.
     140              :      *
     141              :      * This serves to skip transferring a decoded frame back to main memory before encoding.
     142              :      */
     143              :     bool linkHardware(AVBufferRef* framesCtx);
     144              : 
     145              :     static std::list<HardwareAccel> getCompatibleAccel(AVCodecID id, int width, int height, CodecType type);
     146              :     int initAPI(bool linkable, AVBufferRef* framesCtx);
     147            0 :     bool dynBitrate() { return dynBitrate_; }
     148              : 
     149              : private:
     150              :     bool initDevice(const std::string& device);
     151              :     bool initFrame();
     152              : 
     153              :     AVCodecID id_ {AV_CODEC_ID_NONE};
     154              :     std::string name_;
     155              :     AVHWDeviceType hwType_ {AV_HWDEVICE_TYPE_NONE};
     156              :     AVPixelFormat format_ {AV_PIX_FMT_NONE};
     157              :     AVPixelFormat swFormat_ {AV_PIX_FMT_NONE};
     158              :     CodecType type_ {CODEC_NONE};
     159              :     bool linked_ {false};
     160              :     int width_ {0};
     161              :     int height_ {0};
     162              :     bool dynBitrate_ {false};
     163              : 
     164              :     AVBufferRef* deviceCtx_ {nullptr};
     165              :     AVBufferRef* framesCtx_ {nullptr};
     166              : 
     167              :     int init_device(const char* name, const char* device, int flags);
     168              :     int init_device_type(std::string& dev);
     169              : 
     170              :     std::list<std::pair<std::string, DeviceState>>* possible_devices_;
     171              : };
     172              : 
     173              : } // namespace video
     174              : } // namespace jami
        

Generated by: LCOV version 2.0-1