#ifndef LIBAVCODEC_COMMON_H_ #define LIBAVCODEC_COMMON_H_ #include "debug.h" #include "types.h" #ifdef __cplusplus extern "C" { #endif #include #include #include #include #include #include #ifdef __cplusplus } #endif #define R 0 #define G 1 #define B 2 /// /// compat /// // avcodec #ifndef AV_CODEC_CAP_FRAME_THREADS #define AV_CODEC_CAP_FRAME_THREADS CODEC_CAP_FRAME_THREADS #endif #ifndef AV_CODEC_CAP_SLICE_THREADS #define AV_CODEC_CAP_SLICE_THREADS CODEC_CAP_SLICE_THREADS #endif #ifndef AV_CODEC_CAP_VARIABLE_FRAME_SIZE #define AV_CODEC_CAP_VARIABLE_FRAME_SIZE CODEC_CAP_VARIABLE_FRAME_SIZE #endif #ifndef AV_CODEC_FLAG2_FAST #define AV_CODEC_FLAG2_FAST CODEC_FLAG2_FAST #endif #ifndef AV_INPUT_BUFFER_PADDING_SIZE #define AV_INPUT_BUFFER_PADDING_SIZE FF_INPUT_BUFFER_PADDING_SIZE #endif #if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(54, 24, 0) #define AV_CODEC_ID_H264 CODEC_ID_H264 #define AV_CODEC_ID_JPEG2000 CODEC_ID_JPEG2000 #define AV_CODEC_ID_MJPEG CODEC_ID_MJPEG #define AV_CODEC_ID_VP8 CODEC_ID_VP8 #endif // av_frame_* was inbetween moved from lavc to lavu #if LIBAVCODEC_VERSION_MAJOR < 55 #define av_frame_alloc avcodec_alloc_frame #define av_frame_free avcodec_free_frame #define av_frame_unref avcodec_get_frame_defaults #undef av_frame_free #define av_frame_free av_free #endif #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 28, 0) #define AV_CODEC_ID_VP9 AV_CODEC_ID_NONE #endif #if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(55, 35, 100) #define AV_CODEC_ID_HEVC AV_CODEC_ID_NONE #endif #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55, 52, 0) #define avcodec_free_context av_freep #endif #if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(56, 55, 1) #define AV_CODEC_FLAG_INTERLACED_DCT CODEC_FLAG_INTERLACED_DCT #endif #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(57, 8, 0) #define av_packet_unref av_free_packet #endif #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 26, 0) #define AV_CODEC_ID_AV1 AV_CODEC_ID_NONE #endif // avutil #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51, 42, 0) // FFMPEG commit 78071a1420b #define AV_PIX_FMT_NONE PIX_FMT_NONE #define AV_PIX_FMT_NV12 PIX_FMT_NV12 #define AV_PIX_FMT_BGR24 PIX_FMT_BGR24 #define AV_PIX_FMT_RGB24 PIX_FMT_RGB24 #define AV_PIX_FMT_RGBA PIX_FMT_RGBA #define AV_PIX_FMT_UYVY422 PIX_FMT_RGBA #define AV_PIX_FMT_YUV420P PIX_FMT_YUV420P #define AV_PIX_FMT_YUV422P PIX_FMT_YUV422P #define AV_PIX_FMT_YUV444P PIX_FMT_YUV444P #define AV_PIX_FMT_YUVJ420P PIX_FMT_YUVJ420P #define AV_PIX_FMT_YUVJ422P PIX_FMT_YUVJ422P #define AV_PIX_FMT_YUVJ444P PIX_FMT_YUVJ444P #define AV_PIX_FMT_YUYV422 PIX_FMT_YUYV422 #define AVPixelFormat PixelFormat #define AVCodecID CodecID #endif #if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51, 74, 100) #define AV_PIX_FMT_GBRP12LE PIX_FMT_GBRP12LE #endif /** * @todo * Is this stuff still needed? */ #define LAVCD_LOCK_NAME "lavcd_lock" static void print_decoder_error(const char *mod_name, int rc) __attribute__((unused)); static void print_libav_error(int verbosity, const char *msg, int rc) __attribute__((unused)); static bool libav_codec_has_extradata(codec_t codec) __attribute__((unused)); static void print_decoder_error(const char *mod_name, int rc) { char buf[1024]; switch (rc) { case 0: break; case EAGAIN: log_msg(LOG_LEVEL_VERBOSE, "%s No frame returned - needs more input data.\n", mod_name); break; case EINVAL: log_msg(LOG_LEVEL_ERROR, "%s Decoder in invalid state!\n", mod_name); break; default: av_strerror(rc, buf, 1024); log_msg(LOG_LEVEL_WARNING, "%s Error while decoding frame (rc == %d): %s.\n", mod_name, rc, buf); break; } } static void print_libav_error(int verbosity, const char *msg, int rc) { char errbuf[1024]; av_strerror(rc, errbuf, sizeof(errbuf)); log_msg(verbosity, "%s: %s\n", msg, errbuf); } static bool libav_codec_has_extradata(codec_t codec) { return codec == HFYU || codec == FFV1; } #ifdef __cplusplus extern "C" { #endif typedef void uv_to_av_convert(AVFrame * __restrict out_frame, unsigned char * __restrict in_data, int width, int height); typedef uv_to_av_convert *pixfmt_callback_t; /** * Conversions from UltraGrid to FFMPEG formats. * * Currently do not add an "upgrade" conversion (UYVY->10b) because also * UltraGrid decoder can be used first and thus conversion v210->UYVY->10b * may be used resulting in a precision loss. If needed, put the upgrade * conversions below the others. */ struct uv_to_av_conversion { codec_t src; enum AVPixelFormat dst; pixfmt_callback_t func; }; const struct uv_to_av_conversion *get_uv_to_av_conversions(void); typedef void av_to_uv_convert(char * __restrict dst_buffer, AVFrame * __restrict in_frame, int width, int height, int pitch, int * __restrict rgb_shift); typedef av_to_uv_convert *av_to_uv_convert_p; struct av_to_uv_conversion { int av_codec; codec_t uv_codec; av_to_uv_convert_p convert; bool native; ///< there is a 1:1 mapping between the FFMPEG and UV codec (matching ///< color space, channel count (w/wo alpha), bit-depth, ///< subsampling etc.). Supported out are: RGB, UYVY, v210 (in future ///< also 10,12 bit RGB). Subsampling doesn't need to be respected (we do ///< not have codec for eg. 4:4:4 UYVY). }; const struct av_to_uv_conversion *get_av_to_uv_conversions(void); codec_t get_av_to_ug_codec(enum AVCodecID av_codec); enum AVCodecID get_ug_to_av_codec(codec_t ug_codec); struct uv_to_av_pixfmt { codec_t uv_codec; enum AVPixelFormat av_pixfmt; }; codec_t get_av_to_ug_pixfmt(enum AVPixelFormat av_pixfmt) ATTRIBUTE(pure); enum AVPixelFormat get_ug_to_av_pixfmt(codec_t ug_codec) ATTRIBUTE(pure); const struct uv_to_av_pixfmt *get_av_to_ug_pixfmts(void) ATTRIBUTE(pure); #ifdef __cplusplus } #endif #endif // LIBAVCODEC_COMMON_H_