--- /dev/null
+/*
+Copyright (C) 2020 David Knapp (Cloudwalk)
+
+This program is free software; you can redistribute it and/or
+modify it under the terms of the GNU General Public License
+as published by the Free Software Foundation; either version 2
+of the License, or (at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+
+See the GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+*/
+
+#include "darkplaces.h"
+
+#include "libavcodec/avcodec.h"
+#include "libavformat/avformat.h"
+
+// Decoding functions
+AVCodec *(*qavcodec_find_decoder) (enum AVCodecID id);
+AVCodec *(*qavcodec_find_decoder_by_name) (const char *name);
+int (*qavcodec_default_get_buffer2) (AVCodecContext *s, AVFrame *frame, int flags);
+void (*qavcodec_align_dimensions) (AVCodecContext *s, int *width, int *height);
+void (*qavcodec_align_dimensions2) (AVCodecContext *s, int *width, int *height, int linesize_align[AV_NUM_DATA_POINTERS]);
+int (*qavcodec_enum_to_chroma_pos) (int *xpos, int *ypos, enum AVChromaLocation pos);
+enum AVChromaLocation (*qavcodec_chroma_pos_to_enum) (int xpos, int ypos);
+int (*qavcodec_send_packet) (AVCodecContext *avctx, const AVPacket *avpkt);
+int (*qavcodec_receive_frame) (AVCodecContext *avctx, AVFrame *frame);
+int (*qavcodec_send_frame) (AVCodecContext *avctx, const AVFrame *frame);
+int (*qavcodec_receive_packet) (AVCodecContext *avctx, AVPacket *avpkt);
+int (*qavcodec_get_hw_frames_parameters) (AVCodecContext *avctx, AVBufferRef *device_ref, enum AVPixelFormat hw_pix_fmt, AVBufferRef **out_frames_ref);
+
+// Encoding functions
+AVCodec *(*qavcodec_find_encoder) (enum AVCodecID id);
+AVCodec *(*qavcodec_find_encoder_by_name) (const char *name);
+int (*qavcodec_encode_subtitle) (AVCodecContext *avctx, uint8_t *buf, int buf_size, const AVSubtitle *sub);
+
+// Core functions
+const AVCodecHWConfig *(*qavcodec_get_hw_config) (const AVCodec *codec, int index);
+const AVCodec *(*qav_codec_iterate) (void **opaque);
+unsigned (*qavcodec_version) (void);
+const char *(*qavcodec_configuration) (void);
+const char *(*qavcodec_license) (void);
+AVCodecContext *(*qavcodec_alloc_context3) (const AVCodec *codec);
+void (*qavcodec_free_context) (AVCodecContext **avctx);
+int (*qavcodec_get_context_defaults3) (AVCodecContext *s, const AVCodec *codec);
+const AVClass *(*qavcodec_get_class) (void);
+const AVClass *(*qavcodec_get_frame_class) (void);
+const AVClass *(*qavcodec_get_subtitle_rect_class) (void);
+AVCodecParameters *(*qavcodec_parameters_alloc) (void);
+void (*qavcodec_parameters_free) (AVCodecParameters **par);
+int (*qavcodec_parameters_copy) (AVCodecParameters *dst, const AVCodecParameters *src);
+int (*qavcodec_parameters_from_context) (AVCodecParameters *par, const AVCodecContext *codec);
+int (*qavcodec_parameters_to_context) (AVCodecContext *codec, const AVCodecParameters *par);
+int (*qavcodec_open2) (AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options);
+int (*qavcodec_close) (AVCodecContext *avctx);
+void (*qavsubtitle_free) (AVSubtitle *sub);
+
+// Demuxing functions
+AVInputFormat *(*qav_find_input_format) (const char *short_name);
+AVInputFormat *(*qav_probe_input_format) (AVProbeData *pd, int is_opened);
+AVInputFormat *(*qav_probe_input_format2) (AVProbeData *pd, int is_opened, int *score_max);
+AVInputFormat *(*qav_probe_input_format3) (AVProbeData *pd, int is_opened, int *score_ret);
+int (*qav_probe_input_buffer2) (AVIOContext *pb, AVInputFormat **fmt, const char *url, void *logctx, unsigned int offset, unsigned int max_probe_size);
+int (*qav_probe_input_buffer) (AVIOContext *pb, AVInputFormat **fmt, const char *url, void *logctx, unsigned int offset, unsigned int max_probe_size);
+int (*qavformat_open_input) (AVFormatContext **ps, const char *url, AVInputFormat *fmt, AVDictionary **options);
+int (*qavformat_find_stream_info) (AVFormatContext *ic, AVDictionary **options);
+AVProgram *(*qav_find_program_from_stream) (AVFormatContext *ic, AVProgram *last, int s);
+void (*qav_program_add_stream_index) (AVFormatContext *ac, int progid, unsigned int idx);
+int (*qav_find_best_stream) (AVFormatContext *ic, enum AVMediaType type, int wanted_stream_nb, int related_stream, AVCodec **decoder_ret, int flags);
+int (*qav_read_frame) (AVFormatContext *s, AVPacket *pkt);
+int (*qav_seek_frame) (AVFormatContext *s, int stream_index, int64_t timestamp, int flags);
+int (*qavformat_seek_file) (AVFormatContext *s, int stream_index, int64_t min_ts, int64_t ts, int64_t max_ts, int flags);
+int (*qavformat_flush) (AVFormatContext *s);
+int (*qav_read_play) (AVFormatContext *s);
+int (*qav_read_pause) (AVFormatContext *s);
+void (*qavformat_close_input) (AVFormatContext **s);
+
+// Muxing functions
+av_warn_unused_result int (*qavformat_write_header) (AVFormatContext *s, AVDictionary **options);
+av_warn_unused_result int (*qavformat_init_output) (AVFormatContext *s, AVDictionary **options);
+int (*qav_write_frame) (AVFormatContext *s, AVPacket *pkt);
+int (*qav_interleaved_write_frame) (AVFormatContext *s, AVPacket *pkt);
+int (*qav_write_uncoded_frame) (AVFormatContext *s, int stream_index, AVFrame *frame);
+int (*qav_interleaved_write_uncoded_frame) (AVFormatContext *s, int stream_index, AVFrame *frame);
+int (*qav_write_uncoded_frame_query) (AVFormatContext *s, int stream_index);
+int (*qav_write_trailer) (AVFormatContext *s);
+AVOutputFormat *(*qav_guess_format) (const char *short_name, const char *filename, const char *mime_type);
+enum AVCodecID (*qav_guess_codec) (AVOutputFormat *fmt, const char *short_name, const char *filename, const char *mime_type, enum AVMediaType type);
+int (*qav_get_output_timestamp) (struct AVFormatContext *s, int stream, int64_t *dts, int64_t *wall);
+
+// Core functions
+unsigned (*qavformat_version) (void);
+const char *(*qavformat_configuration) (void);
+const char *(*qavformat_license) (void);
+void (*qav_register_all) (void);
+void (*qav_register_input_format) (AVInputFormat *format);
+void (*qav_register_output_format) (AVOutputFormat *format);
+int (*qavformat_network_init) (void);
+int (*qavformat_network_deinit) (void);
+AVInputFormat *(*qav_iformat_next) (const AVInputFormat *f);
+AVOutputFormat *(*qav_oformat_next) (const AVOutputFormat *f);
+AVFormatContext *(*qavformat_alloc_context) (void);
+void (*qavformat_free_context) (AVFormatContext *s);
+const AVClass *(*qavformat_get_class) (void);
+AVStream *(*qavformat_new_stream) (AVFormatContext *s, const AVCodec *c);
+uint8_t *(*qav_stream_new_side_data) (AVStream *stream, enum AVPacketSideDataType type, int size);
+uint8_t *(*qav_stream_get_side_data) (const AVStream *stream, enum AVPacketSideDataType type, int *size);
+AVProgram *(*qav_new_program) (AVFormatContext *s, int id);
+
+// Utility functions
+void (*qav_hex_dump) (FILE *f, const uint8_t *buf, int size);
+void (*qav_hex_dump_log) (void *avcl, int level, const uint8_t *buf, int size);
+void (*qav_pkt_dump2) (FILE *f, const AVPacket *pkt, int dump_payload, const AVStream *st);
+void (*qav_pkt_dump_log2) (void *avcl, int level, const AVPacket *pkt, int dump_payload, const AVStream *st);
+enum AVCodecID (*qav_codec_get_id) (const struct AVCodecTag *const *tags, unsigned int tag);
+unsigned int (*qav_codec_get_tag) (const struct AVCodecTag *const *tags, enum AVCodecID id);
+int (*qav_codec_get_tag2) (const struct AVCodecTag *const *tags, enum AVCodecID id, unsigned int *tag);
+int (*qav_find_default_stream_index) (AVFormatContext *s);
+int (*qav_index_search_timestamp) (AVStream *st, int64_t timestamp, int flags);
+int (*qav_add_index_entry) (AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags);
+void (*qav_url_split) (char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url);
+void (*qav_dump_format) (AVFormatContext *ic, int index, const char *url, int is_output);
+int (*qav_get_frame_filename2) (char *buf, int buf_size, const char *path, int number, int flags);
+int (*qav_get_frame_filename) (char *buf, int buf_size, const char *path, int number);
+int (*qav_filename_number_test) (const char *filename);
+int (*qav_sdp_create) (AVFormatContext *ac[], int n_files, char *buf, int size);
+int (*qav_match_ext) (const char *filename, const char *extensions);
+int (*qavformat_query_codec) (const AVOutputFormat *ofmt, enum AVCodecID codec_id, int std_compliance);
+AVRational (*qav_guess_sample_aspect_ratio) (AVFormatContext *format, AVStream *stream, AVFrame *frame);
+AVRational (*qav_guess_frame_rate) (AVFormatContext *ctx, AVStream *stream, AVFrame *frame);
+int (*qavformat_match_stream_specifier) (AVFormatContext *s, AVStream *st, const char *spec);
+int (*qavformat_queue_attached_pictures) (AVFormatContext *s);
+int (*qavformat_transfer_internal_stream_timing_info) (const AVOutputFormat *ofmt, AVStream *ost, const AVStream *ist, enum AVTimebaseSource copy_tb);
+AVRational (*qav_stream_get_codec_timebase) (const AVStream *st);
+
+static dllfunction_t libavcodecfuncs[] =
+{
+ {"avcodec_find_decoder", (void **) &qavcodec_find_decoder},
+ {"avcodec_find_decoder_by_name", (void **) &qavcodec_find_decoder_by_name},
+ {"avcodec_default_get_buffer2", (void **) &qavcodec_default_get_buffer2},
+ {"avcodec_align_dimensions", (void **) &qavcodec_align_dimensions},
+ {"avcodec_align_dimensions2", (void **) &qavcodec_align_dimensions},
+ {"avcodec_enum_to_chroma_pos", (void **) &qavcodec_enum_to_chroma_pos},
+ {"avcodec_chroma_pos_to_enum", (void **) &qavcodec_chroma_pos_to_enum},
+ {"avcodec_send_packet", (void **) &qavcodec_send_packet},
+ {"avcodec_receive_frame", (void **) &qavcodec_receive_frame},
+ {"avcodec_send_frame", (void **) &qavcodec_send_frame},
+ {"avcodec_receive_packet", (void **) &qavcodec_receive_packet},
+ {"avcodec_get_hw_frames_parameters", (void **) &qavcodec_get_hw_frames_parameters},
+ {"avcodec_get_hw_config", (void **) &qavcodec_get_hw_config},
+ {"av_codec_iterate", (void **) &qav_codec_iterate},
+ {"avcodec_version", (void **) &qavcodec_version},
+ {"avcodec_configuration", (void **) &qavcodec_configuration},
+ {"avcodec_license", (void **) &qavcodec_license},
+ {"avcodec_alloc_context3", (void **) &qavcodec_alloc_context3},
+ {"avcodec_free_context", (void **) &qavcodec_free_context},
+ {"avcodec_get_context_defaults3", (void **) &qavcodec_get_context_defaults3},
+ {"avcodec_get_class", (void **) &qavcodec_get_class},
+ {"avcodec_get_frame_class", (void **) &qavcodec_get_frame_class},
+ {"avcodec_get_subtitle_rect_class", (void **) &qavcodec_get_subtitle_rect_class},
+ {"avcodec_parameters_alloc", (void **) &qavcodec_parameters_alloc},
+ {"avcodec_parameters_free", (void **) &qavcodec_parameters_free},
+ {"avcodec_parameters_copy", (void **) &qavcodec_parameters_copy},
+ {"avcodec_parameters_from_context", (void **) &qavcodec_parameters_from_context},
+ {"avcodec_parameters_to_context", (void **) &qavcodec_parameters_to_context},
+ {"avcodec_open2", (void **) &qavcodec_open2},
+ {"avcodec_close", (void **) &qavcodec_close},
+ {"avsubtitle_free", (void **) &qavsubtitle_free},
+ {NULL, NULL}
+};
+
+static dllfunction_t libavformatfuncs[] =
+{
+ {"av_find_input_format", (void **) &qav_find_input_format},
+ {"av_probe_input_format", (void **) &qav_probe_input_format},
+ {"av_probe_input_format2", (void **) &qav_probe_input_format2},
+ {"av_probe_input_format3", (void **) &qav_probe_input_format3},
+ {"av_probe_input_buffer2", (void **) &qav_probe_input_buffer2},
+ {"av_probe_input_buffer", (void **) &qav_probe_input_buffer},
+ {"avformat_open_input", (void **) &qavformat_open_input},
+ {"avformat_find_stream_info", (void **) &qavformat_find_stream_info},
+ {"av_find_program_from_stream", (void **) &qav_find_program_from_stream},
+ {"av_program_add_stream_index", (void **) &qav_program_add_stream_index},
+ {"av_find_best_stream", (void **) &qav_find_best_stream},
+ {"av_read_frame", (void **) &qav_read_frame},
+ {"av_seek_frame", (void **) &qav_seek_frame},
+ {"avformat_seek_file", (void **) &qavformat_seek_file},
+ {"avformat_flush", (void **) &qavformat_flush},
+ {"av_read_play", (void **) &qav_read_play},
+ {"av_read_pause", (void **) &qav_read_pause},
+ {"avformat_close_input", (void **) &qavformat_close_input},
+ {"avformat_write_header", (void **) &qavformat_write_header},
+ {"avformat_init_output", (void **) &qavformat_init_output},
+ {"av_write_frame", (void **) &qav_write_frame},
+ {"av_interleaved_write_frame", (void **) &qav_interleaved_write_frame},
+ {"av_write_uncoded_frame", (void **) &qav_write_uncoded_frame},
+ {"av_interleaved_write_uncoded_frame", (void **) &qav_interleaved_write_uncoded_frame},
+ {"av_write_uncoded_frame_query", (void **) &qav_write_uncoded_frame_query},
+ {"av_write_trailer", (void **) &qav_write_trailer},
+ {"av_guess_format", (void **) &qav_guess_format},
+ {"av_guess_codec", (void **) &qav_guess_codec},
+ {"av_get_output_timestamp", (void **) &qav_get_output_timestamp},
+ {"avformat_version", (void **) &qavformat_version},
+ {"avformat_configuration", (void **) &qavformat_configuration},
+ {"avformat_license", (void **) &qavformat_license},
+ {"av_register_all", (void **) &qav_register_all},
+ {"av_register_input_format", (void **) &qav_register_input_format},
+ {"av_register_output_format", (void **) &qav_register_output_format},
+ {"avformat_network_init", (void **) &qavformat_network_init},
+ {"avformat_network_deinit", (void **) &qavformat_network_deinit},
+ {"av_iformat_next", (void **) &qav_iformat_next},
+ {"av_oformat_next", (void **) &qav_oformat_next},
+ {"avformat_alloc_context", (void **) &qavformat_alloc_context},
+ {"avformat_free_context", (void **) &qavformat_free_context},
+ {"avformat_get_class", (void **) &qavformat_get_class},
+ {"avformat_new_stream", (void **) &qavformat_new_stream},
+ {"av_stream_new_side_data", (void **) &qav_stream_new_side_data},
+ {"av_stream_get_side_data", (void **) &qav_stream_get_side_data},
+ {"av_new_program", (void **) &qav_new_program},
+ {"av_hex_dump", (void **) &qav_hex_dump},
+ {"av_hex_dump_log", (void **) &qav_hex_dump_log},
+ {"av_pkt_dump2", (void **) &qav_pkt_dump2},
+ {"av_pkt_dump_log2", (void **) &qav_pkt_dump_log2},
+ {"av_codec_get_id", (void **) &qav_codec_get_id},
+ {"av_codec_get_tag", (void **) &qav_codec_get_tag},
+ {"av_codec_get_tag2", (void **) &qav_codec_get_tag2},
+ {"av_find_default_stream_index", (void **) &qav_find_default_stream_index},
+ {"av_index_search_timestamp", (void **) &qav_index_search_timestamp},
+ {"av_add_index_entry", (void **) &qav_add_index_entry},
+ {"av_url_split", (void **) &qav_url_split},
+ {"av_dump_format", (void **) &qav_dump_format},
+ {"av_get_frame_filename2", (void **) &qav_get_frame_filename2},
+ {"av_get_frame_filename", (void **) &qav_get_frame_filename},
+ {"av_filename_number_test", (void **) &qav_filename_number_test},
+ {"av_sdp_create", (void **) &qav_sdp_create},
+ {"av_match_ext", (void **) &qav_match_ext},
+ {"avformat_query_codec", (void **) &qavformat_query_codec},
+ {"av_guess_sample_aspect_ratio", (void **) &qav_guess_sample_aspect_ratio},
+ {"av_guess_frame_rate", (void **) &qav_guess_frame_rate},
+ {"avformat_match_stream_specifier", (void **) &qavformat_match_stream_specifier},
+ {"avformat_queue_attached_pictures", (void **) &qavformat_queue_attached_pictures},
+ {"avformat_transfer_internal_stream_timing_info", (void **) &qavformat_transfer_internal_stream_timing_info},
+ {"av_stream_get_codec_timebase", (void **) &qav_stream_get_codec_timebase},
+ {NULL, NULL}
+};
+
+static dllhandle_t libavcodec_dll = NULL;
+static dllhandle_t libavformat_dll = NULL;
+
+qbool LibAV_LoadLibrary(void)
+{
+ const char* dllnames_libavcodec [] =
+ {
+#if defined(WIN32)
+ "libavcodec.dll",
+#elif defined(MACOSX)
+ "libavcodec.dylib",
+#else
+ "libavcodec.so",
+#endif
+ NULL
+ };
+
+ const char* dllnames_libavformat [] =
+ {
+#if defined(WIN32)
+ "libavformat.dll",
+#elif defined(MACOSX)
+ "libavformat.dylib",
+#else
+ "libavformat.so",
+#endif
+ NULL
+ };
+
+ if (libavcodec_dll && libavformat_dll) // Already loaded?
+ return true;
+
+// COMMANDLINEOPTION: -nolibav disables libav support
+ if (Sys_CheckParm("-nolibav"))
+ return false;
+
+ // Load the DLL
+ if (Sys_LoadLibrary (dllnames_libavcodec, &libavcodec_dll, libavcodecfuncs))
+ {
+ if(Sys_LoadLibrary(dllnames_libavformat, &libavformat_dll, libavformatfuncs))
+ return true;
+ Con_Printf(CON_ERROR "Failed to load the libavformat library. Cannot use libavcodec without it\n");
+ Sys_UnloadLibrary(&libavcodec_dll);
+ }
+
+ return false;
+}
\ No newline at end of file