summaryrefslogtreecommitdiffstats
path: root/dom/media/platforms/ffmpeg/FFmpegLibWrapper.h
blob: 7ca1d9131eb805acd7994799ac55ea23db82eae4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#ifndef __FFmpegLibWrapper_h__
#define __FFmpegLibWrapper_h__

#include "FFmpegRDFTTypes.h"  // for AvRdftInitFn, etc.
#include "mozilla/Attributes.h"
#include "mozilla/Types.h"

struct AVCodec;
struct AVCodecContext;
struct AVCodecDescriptor;
struct AVFrame;
struct AVPacket;
struct AVDictionary;
struct AVCodecParserContext;
struct PRLibrary;
#ifdef MOZ_WAYLAND
struct AVCodecHWConfig;
struct AVVAAPIHWConfig;
struct AVHWFramesConstraints;
#endif
struct AVBufferRef;

namespace mozilla {

struct MOZ_ONLY_USED_TO_AVOID_STATIC_CONSTRUCTORS FFmpegLibWrapper {
  // The class is used only in static storage and so is zero initialized.
  FFmpegLibWrapper() = default;
  // The libraries are not unloaded in the destructor, because doing so would
  // require a static constructor to register the static destructor.  As the
  // class is in static storage, the destructor would only run on shutdown
  // anyway.
  ~FFmpegLibWrapper() = default;

  enum class LinkResult {
    Success,
    NoProvidedLib,
    NoAVCodecVersion,
    CannotUseLibAV57,
    BlockedOldLibAVVersion,
    UnknownFutureLibAVVersion,
    UnknownFutureFFMpegVersion,
    UnknownOlderFFMpegVersion,
    MissingFFMpegFunction,
    MissingLibAVFunction,
  };
  // Examine mAVCodecLib, mAVUtilLib and mVALib, and attempt to resolve
  // all symbols.
  // Upon failure, the entire object will be reset and any attached libraries
  // will be unlinked.
  LinkResult Link();

  // Reset the wrapper and unlink all attached libraries.
  void Unlink();

#ifdef MOZ_WAYLAND
  // Check if mVALib are available and we can use HW decode.
  bool IsVAAPIAvailable();
  void LinkVAAPILibs();
#endif

  // indicate the version of libavcodec linked to.
  // 0 indicates that the function wasn't initialized with Link().
  int mVersion;

  // libavcodec
  unsigned (*avcodec_version)();
  int (*av_lockmgr_register)(int (*cb)(void** mutex, int op));
  AVCodecContext* (*avcodec_alloc_context3)(const AVCodec* codec);
  int (*avcodec_close)(AVCodecContext* avctx);
  int (*avcodec_decode_audio4)(AVCodecContext* avctx, AVFrame* frame,
                               int* got_frame_ptr, const AVPacket* avpkt);
  int (*avcodec_decode_video2)(AVCodecContext* avctx, AVFrame* picture,
                               int* got_picture_ptr, const AVPacket* avpkt);
  AVCodec* (*avcodec_find_decoder)(int id);
  void (*avcodec_flush_buffers)(AVCodecContext* avctx);
  int (*avcodec_open2)(AVCodecContext* avctx, const AVCodec* codec,
                       AVDictionary** options);
  void (*avcodec_register_all)();
  void (*av_init_packet)(AVPacket* pkt);
  AVCodecParserContext* (*av_parser_init)(int codec_id);
  void (*av_parser_close)(AVCodecParserContext* s);
  int (*av_parser_parse2)(AVCodecParserContext* s, AVCodecContext* avctx,
                          uint8_t** poutbuf, int* poutbuf_size,
                          const uint8_t* buf, int buf_size, int64_t pts,
                          int64_t dts, int64_t pos);
  AVCodec* (*av_codec_iterate)(void** opaque);
  int (*av_codec_is_decoder)(const AVCodec* codec);
  void (*avcodec_align_dimensions)(AVCodecContext* s, int* width, int* height);
  int (*av_strerror)(int errnum, char* errbuf, size_t errbuf_size);
  AVCodecDescriptor* (*avcodec_descriptor_get)(int id);

  // only used in libavcodec <= 54
  AVFrame* (*avcodec_alloc_frame)();
  void (*avcodec_get_frame_defaults)(AVFrame* pic);

  // libavcodec v54 only
  void (*avcodec_free_frame)(AVFrame** frame);

  // libavcodec >= v55
  int (*avcodec_default_get_buffer2)(AVCodecContext* s, AVFrame* frame,
                                     int flags);

  // libavcodec v58 and later only
  int (*avcodec_send_packet)(AVCodecContext* avctx, const AVPacket* avpkt);
  int (*avcodec_receive_frame)(AVCodecContext* avctx, AVFrame* frame);

  // libavcodec optional
  AvRdftInitFn av_rdft_init;
  AvRdftCalcFn av_rdft_calc;
  AvRdftEndFn av_rdft_end;

  // libavutil
  void (*av_log_set_level)(int level);
  void* (*av_malloc)(size_t size);
  void (*av_freep)(void* ptr);
  int (*av_image_check_size)(unsigned int w, unsigned int h, int log_offset,
                             void* log_ctx);
  int (*av_image_get_buffer_size)(int pix_fmt, int width, int height,
                                  int align);

  // libavutil v55 and later only
  AVFrame* (*av_frame_alloc)();
  void (*av_frame_free)(AVFrame** frame);
  void (*av_frame_unref)(AVFrame* frame);
  AVBufferRef* (*av_buffer_create)(uint8_t* data, int size,
                                   void (*free)(void* opaque, uint8_t* data),
                                   void* opaque, int flags);

  // libavutil >= v56
  void* (*av_buffer_get_opaque)(const AVBufferRef* buf);

  // libavutil optional
  int (*av_frame_get_colorspace)(const AVFrame* frame);
  int (*av_frame_get_color_range)(const AVFrame* frame);

#ifdef MOZ_WAYLAND
  const AVCodecHWConfig* (*avcodec_get_hw_config)(const AVCodec* codec,
                                                  int index);
  AVBufferRef* (*av_hwdevice_ctx_alloc)(int);
  int (*av_hwdevice_ctx_init)(AVBufferRef* ref);
  AVVAAPIHWConfig* (*av_hwdevice_hwconfig_alloc)(AVBufferRef* device_ctx);
  AVHWFramesConstraints* (*av_hwdevice_get_hwframe_constraints)(
      AVBufferRef* ref, const void* hwconfig);
  void (*av_hwframe_constraints_free)(AVHWFramesConstraints** constraints);

  AVBufferRef* (*av_buffer_ref)(AVBufferRef* buf);
  void (*av_buffer_unref)(AVBufferRef** buf);
  int (*av_hwframe_transfer_get_formats)(AVBufferRef* hwframe_ctx, int dir,
                                         int** formats, int flags);
  int (*av_hwdevice_ctx_create_derived)(AVBufferRef** dst_ctx, int type,
                                        AVBufferRef* src_ctx, int flags);
  AVBufferRef* (*av_hwframe_ctx_alloc)(AVBufferRef* device_ctx);
  int (*av_dict_set)(AVDictionary** pm, const char* key, const char* value,
                     int flags);
  void (*av_dict_free)(AVDictionary** m);
  const char* (*avcodec_get_name)(int id);
  char* (*av_get_pix_fmt_string)(char* buf, int buf_size, int pix_fmt);

  int (*vaExportSurfaceHandle)(void*, unsigned int, uint32_t, uint32_t, void*);
  int (*vaSyncSurface)(void*, unsigned int);
  int (*vaInitialize)(void* dpy, int* major_version, int* minor_version);
  int (*vaTerminate)(void* dpy);
  void* (*vaGetDisplayDRM)(int fd);
#endif

  PRLibrary* mAVCodecLib;
  PRLibrary* mAVUtilLib;
#ifdef MOZ_WAYLAND
  PRLibrary* mVALib;
  PRLibrary* mVALibDrm;
#endif
};

}  // namespace mozilla

#endif  // FFmpegLibWrapper