blob: 082444a6f0e5b761e76552657d34397e3fce94f5 [file] [log] [blame]
// Copyright 2018 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// This class defines an interface for dispatching calls to the ffmpeg
// libraries.
#ifndef STARBOARD_SHARED_FFMPEG_FFMPEG_DISPATCH_H_
#define STARBOARD_SHARED_FFMPEG_FFMPEG_DISPATCH_H_
#include "starboard/common/mutex.h"
#include "starboard/types.h"
struct AVCodec;
struct AVCodecContext;
struct AVCodecParameters;
struct AVDictionary;
struct AVDictionaryEntry;
struct AVFormatContext;
struct AVFrame;
struct AVInputFormat;
struct AVIOContext;
struct AVPacket;
namespace starboard {
namespace shared {
namespace ffmpeg {
// derived from AV_VERSION_INT(a, b, c) ((a)<<16 | (b)<<8 | (c))
// https://github.com/FFmpeg/FFmpeg/blob/master/doc/APIchanges#L1981
constexpr int kAVCodecSupportsAvFrameAlloc = 3616101;
constexpr int kAVCodecSupportsAvcodecFreeContext = 3620708;
constexpr int kAVCodecSupportsAvPacketAlloc = 3738724;
// https://github.com/libav/libav/blob/8e401dbe90cc77b1f3067a917d9fa48cefa3fcdb/libavutil/version.h
// AV_VERSION_INT(52, 8, 0)
constexpr int kAVUtilSupportsBufferCreate = 3409920;
// https://github.com/FFmpeg/FFmpeg/blob/70d25268c21cbee5f08304da95be1f647c630c15/doc/APIchanges#L195
// avcodec_decode_audio4 and avcodec_decode_video2 replaced by
// avcodec_receive_frame()
//
// The APIs were removed in this change:
// https://github.com/FFmpeg/FFmpeg/commit/7c1f347b184b6738abdc22fdcda40baa9f932522#diff-76418b674d0db8d5027d2e1e325dbe9b92b65b09d9f20cdd305ad14b0e46562d
// (note the values in libavcodec/version.h)
// AV_VERSION_INT(58, 137, 100)
constexpr int kAVCodecHasUniformDecodeAPI = 3836260;
// https://github.com/FFmpeg/FFmpeg/blob/70d25268c21cbee5f08304da95be1f647c630c15/doc/APIchanges#L86
// no longer required
constexpr int kAVFormatDoesNotHaveRegisterAll = 3936356;
class FFMPEGDispatch {
public:
FFMPEGDispatch();
~FFMPEGDispatch();
static FFMPEGDispatch* GetInstance();
// Register an ffmpeg decoder specialization for the given combination of
// major versions of the libavcodec, libavformat, and libavutil libraries.
// Returns true if the specialization did not exist yet, or if it matched
// an already existing registration.
static bool RegisterSpecialization(int specialization,
int avcodec,
int avformat,
int avutil);
bool is_valid() const;
unsigned (*avutil_version)(void);
void* (*av_malloc)(size_t size);
void (*av_freep)(void* ptr);
AVFrame* (*av_frame_alloc)(void);
void (*av_frame_free)(AVFrame** frame);
void (*av_frame_unref)(AVFrame* frame);
int (*av_samples_get_buffer_size)(int* linesize,
int nb_channels,
int nb_samples,
int sample_fmt,
int align);
int (*av_opt_set_int)(void* obj,
const char* name,
int64_t val,
int search_flags);
int (*av_image_check_size)(unsigned int w,
unsigned int h,
int log_offset,
void* log_ctx);
void* (*av_buffer_create)(uint8_t* data,
int size,
void (*free)(void* opaque, uint8_t* data),
void* opaque,
int flags);
unsigned (*avcodec_version)(void);
AVCodecContext* (*avcodec_alloc_context3)(const AVCodec* codec);
void (*avcodec_free_context)(AVCodecContext** avctx);
AVCodec* (*avcodec_find_decoder)(int id);
int (*avcodec_close)(AVCodecContext* avctx);
int (*avcodec_open2)(AVCodecContext* avctx,
const AVCodec* codec,
AVDictionary** options);
void (*av_init_packet)(AVPacket* pkt);
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);
int (*avcodec_send_packet)(AVCodecContext* avctx, const AVPacket* avpkt);
int (*avcodec_receive_frame)(AVCodecContext* avctx, AVFrame* frame);
void (*avcodec_flush_buffers)(AVCodecContext* avctx);
AVFrame* (*avcodec_alloc_frame)(void);
void (*avcodec_get_frame_defaults)(AVFrame* frame);
void (*avcodec_align_dimensions2)(AVCodecContext* avctx,
int* width,
int* height,
int linesize_align[]);
unsigned (*avformat_version)(void);
void (*av_register_all)(void);
void (*av_free)(void* ptr);
AVPacket* (*av_packet_alloc)(void);
void (*av_packet_free)(AVPacket** pkt);
void (*av_free_packet)(AVPacket* pkt);
AVDictionaryEntry* (*av_dict_get)(const AVDictionary* m,
const char* key,
const AVDictionaryEntry* prev,
int flags);
// Note: |rnd| represents type enum AVRounding.
int64_t (*av_rescale_rnd)(int64_t a, int64_t b, int64_t c, int rnd);
int (*av_seek_frame)(AVFormatContext* s,
int stream_index,
int64_t timestamp,
int flags);
int (*av_read_frame)(AVFormatContext* s, AVPacket* pkt);
void (*av_packet_unref)(AVPacket* pkt);
int (*avformat_open_input)(AVFormatContext** ps,
const char* filename,
AVInputFormat* fmt,
AVDictionary** options);
void (*avformat_close_input)(AVFormatContext** s);
AVFormatContext* (*avformat_alloc_context)(void);
int (*avformat_find_stream_info)(AVFormatContext* ic, AVDictionary** options);
AVIOContext* (*avio_alloc_context)(
unsigned char* buffer,
int buffer_size,
int write_flag,
void* opaque,
int (*read_packet)(void* opaque, uint8_t* buf, int buf_size),
int (*write_packet)(void* opaque, uint8_t* buf, int buf_size),
int64_t (*seek)(void* opaque, int64_t offset, int whence));
int (*avcodec_parameters_to_context)(AVCodecContext* codec,
const AVCodecParameters* par);
int specialization_version() const;
// In Ffmpeg, the calls to avcodec_open2() and avcodec_close() are not
// synchronized internally so it is the responsibility of its user to ensure
// that these calls don't overlap. The following functions acquires a lock
// internally before calling avcodec_open2() and avcodec_close() to enforce
// this.
int OpenCodec(AVCodecContext* codec_context, const AVCodec* codec);
void CloseCodec(AVCodecContext* codec_context);
void FreeFrame(AVFrame** frame);
void FreeContext(AVCodecContext** avctx);
};
} // namespace ffmpeg
} // namespace shared
} // namespace starboard
#endif // STARBOARD_SHARED_FFMPEG_FFMPEG_DISPATCH_H_