UltraGrid
UltraGrid Low-Latency High-Resolution Transmission System
Loading...
Searching...
No Matches
libavcodec.c File Reference
#include <assert.h>
#include <limits.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "debug.h"
#include "host.h"
#include "lib_common.h"
#include "libavcodec/from_lavc_vid_conv.h"
#include "libavcodec/lavc_common.h"
#include "libavcodec/lavc_video.h"
#include "rtp/rtpdec_h264.h"
#include "rtp/rtpenc_h264.h"
#include "tv.h"
#include "utils/macros.h"
#include "video.h"
#include "video_codec.h"
#include "video_decompress.h"
#include "hwaccel_libav_common.h"
#include "hwaccel_vaapi.h"
#include "hwaccel_vdpau.h"
#include "hwaccel_videotoolbox.h"
Include dependency graph for libavcodec.c:

Go to the source code of this file.

Classes

struct  decoder_info
 
struct  state_libavcodec_decompress
 
struct  state_libavcodec_decompress::state_libavcodec_decompress_sws
 

Macros

#define MOD_NAME   "[lavd] "
 
#define SELECT_PIXFMT(pixfmt)
 

Enumerations

enum  { MAX_PREFERED = 10 , MAX_DECODERS = MAX_PREFERED + 1 + 1 , DEC_LEN = MAX_DECODERS + 1 }
 

Functions

 ADD_TO_PARAM ("force-lavd-decoder", "* force-lavd-decoder=<decoder>[:<decoder2>...]\n" " Forces specified Libavcodec decoder. If more need to be specified, use colon as a delimiter.\n" " Use '-c libavcodec:help' to see available decoders.\n")
 
 ADD_TO_PARAM ("lavd-accept-corrupted", "* lavd-accept-corrupted[=no]\n" " Pass corrupted frames to decoder. If decoder isn't error-resilient,\n" " may crash! Use \"no\" to disable even if enabled by default.\n")
 
 ADD_TO_PARAM ("lavd-thread-count", "* lavd-thread-count=<thread_count>[F][S][n][d]\n" " Use <thread_count> decoding threads (0 is usually auto).\n" " Flag 'F' enables frame parallelism (disabled by default), 'S' slice based, can be both (default slice), 'n' for none; 'd' - disable low delay\n")
 
 ADD_TO_PARAM ("use-hw-accel", "* use-hw-accel[=<api>|help]\n" " Try to use hardware accelerated decoding with lavd " "(NVDEC/VAAPI/VDPAU/VideoToolbox).\n" " Optionally with enforced API option.\n")
 
static void change_pixfmt (AVFrame *frame, unsigned char *dst, av_to_uv_convert_t *convert, codec_t out_codec, int width, int height, int pitch, int rgb_shift[static restrict 3], struct state_libavcodec_decompress_sws *sws)
 
static int check_av_opt_set (void *state, const char *key, const char *val)
 
static void check_duration (struct state_libavcodec_decompress *s, double duration_total_sec, double duration_pixfmt_change_sec)
 print hint to improve performance if not making it
 
static _Bool check_first_sps_vps (struct state_libavcodec_decompress *s, unsigned char *src, unsigned int src_len)
 
static bool configure_with (struct state_libavcodec_decompress *s, struct video_desc desc, void *extradata, int extradata_size)
 
static bool decode_frame (struct state_libavcodec_decompress *s, unsigned char *src, int src_len)
 
static void deconfigure (struct state_libavcodec_decompress *s)
 
static int drm_prime_init (struct AVCodecContext *s, struct hw_accel_state *state, codec_t out_codec)
 
static enum AVPixelFormat get_format_callback (struct AVCodecContext *s, const enum AVPixelFormat *fmt)
 
static bool get_usable_decoders (enum AVCodecID avcodec_id, const char *const preferred_decoders[static MAX_PREFERED+1], const AVCodec *usable_decoders[static DEC_LEN])
 
static void handle_lavd_error (const char *prefix, struct state_libavcodec_decompress *s, int ret)
 
static void jpeg_callback (void)
 
static decompress_status libavcodec_decompress (void *state, unsigned char *dst, unsigned char *src, unsigned int src_len, int frame_seq, struct video_frame_callbacks *callbacks, struct pixfmt_desc *internal_props)
 
static void libavcodec_decompress_done (void *state)
 
static int libavcodec_decompress_get_priority (codec_t compression, struct pixfmt_desc internal, codec_t ugc)
 
static int libavcodec_decompress_get_property (void *state, int property, void *val, size_t *len)
 
static void * libavcodec_decompress_init (void)
 
static int libavcodec_decompress_reconfigure (void *state, struct video_desc desc, int rshift, int gshift, int bshift, int pitch, codec_t out_codec)
 
static bool read_forced_pixfmt (codec_t compress, const unsigned char *src, unsigned int src_len, struct pixfmt_desc *internal_props)
 
static _Bool reconfigure_convert_if_needed (struct state_libavcodec_decompress *s, enum AVPixelFormat av_codec, codec_t out_codec, int width, int height)
 
 REGISTER_MODULE (libavcodec, &libavcodec_info, LIBRARY_CLASS_VIDEO_DECOMPRESS, VIDEO_DECOMPRESS_ABI_VERSION)
 
static void set_codec_context_params (struct state_libavcodec_decompress *s)
 
static bool validate_hwacc_param (void)
 

Variables

static const struct decoder_info decoders []
 
static const struct video_decompress_info libavcodec_info
 

Detailed Description

Author
Martin Pulec pulec.nosp@m.@ces.nosp@m.net.c.nosp@m.z

Definition in file libavcodec.c.

Macro Definition Documentation

◆ MOD_NAME

#define MOD_NAME   "[lavd] "

Definition at line 70 of file libavcodec.c.

◆ SELECT_PIXFMT

#define SELECT_PIXFMT ( pixfmt)
Value:
{ log_msg(LOG_LEVEL_INFO, MOD_NAME "Selected pixel format: %s\n", av_get_pix_fmt_name(pixfmt)); return pixfmt; }
#define MOD_NAME
Definition libavcodec.c:70
void log_msg(int level, const char *format,...)
Definition debug.cpp:130
#define LOG_LEVEL_INFO
normal reporting
Definition debug.h:62

Referenced by get_format_callback().

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
MAX_PREFERED 
MAX_DECODERS 
  • user forced + default
DEC_LEN 
  • terminating NULL

Definition at line 215 of file libavcodec.c.

215 {
216 MAX_PREFERED = 10,
217 MAX_DECODERS = MAX_PREFERED + 1 + 1,
218 DEC_LEN = MAX_DECODERS + 1,
219};
@ MAX_PREFERED
Definition libavcodec.c:216
@ DEC_LEN
Definition libavcodec.c:218
@ MAX_DECODERS
Definition libavcodec.c:217

Function Documentation

◆ ADD_TO_PARAM() [1/4]

ADD_TO_PARAM ( "force-lavd-decoder" ,
"* force-lavd- decoder = <decoder>[:<decoder2>...]\n" "  Forces specified Libavcodec decoder. If more need to be specified,
use colon as a delimiter.\n" " Use '-c libavcodec:help' to see available decoders.\n"  )

◆ ADD_TO_PARAM() [2/4]

ADD_TO_PARAM ( "lavd-accept-corrupted" ,
"* lavd-accept-corrupted\n" " Pass corrupted frames to decoder. If decoder isn't error- resilient[=no],
\n" " may crash! Use \"no\" to disable even if enabled by default.\n"  )

◆ ADD_TO_PARAM() [3/4]

ADD_TO_PARAM ( "lavd-thread-count" ,
"* lavd-thread- count = <thread_count>[F][S][n][d]\n" "  Use <thread_count> decoding threads (0 is usually auto).\n" "  Flag 'F' enables frame parallelism (disabled by default),
'S' slice based,
can be bothdefault slice,
'n' for none; 'd' - disable low delay\n"  )

◆ ADD_TO_PARAM() [4/4]

ADD_TO_PARAM ( "use-hw-accel" ,
"* use-hw-accel\n" " Try to use hardware accelerated decoding with lavd " "(NVDEC/VAAPI/VDPAU/VideoToolbox).\n" " Optionally with enforced API option.\n" [=< api >|help] )

◆ change_pixfmt()

static void change_pixfmt ( AVFrame * frame,
unsigned char * dst,
av_to_uv_convert_t * convert,
codec_t out_codec,
int width,
int height,
int pitch,
int rgb_shift[static restrict 3],
struct state_libavcodec_decompress_sws * sws )
static

Changes pixel format from frame to native

Todo
figure out color space transformations - eg. JPEG returns full-scale YUV. And not in the ITU-T Rec. 701 (eventually Rec. 609) scale.
Parameters
framevideo frame returned from libavcodec decompress
dstdestination buffer where data will be stored
av_codeclibav pixel format
out_codecrequested output codec
widthframe width
heightframe height

Definition at line 823 of file libavcodec.c.

827{
829
830 if (!sws->ctx) {
831 av_to_uv_convert(convert, (char *) dst, frame, width, height,
832 pitch, rgb_shift);
833 return;
834 }
835
836#ifdef HAVE_SWSCALE
837 if (get_ug_to_av_pixfmt(out_codec) != AV_PIX_FMT_NONE) { // the UG pixfmt can be used directly as dst for sws
838 lavd_sws_convert_to_buffer(sws, frame, (char *) dst);
839 return;
840 }
841
842 lavd_sws_convert(sws, frame);
843 av_to_uv_convert(convert, (char *) dst, sws->frame, width, height,
844 pitch, rgb_shift);
845#else
846 (void) out_codec;
847#endif // HAVE_SWSCALE
848}
convert_t convert
struct video_frame * frame
#define debug_file_dump(key, serialize, data)
Definition debug.h:86
void av_to_uv_convert(const av_to_uv_convert_t *convert, char *dst, AVFrame *in, int width, int height, int pitch, const int rgb_shift[3])
void serialize_video_avframe(const void *f, FILE *out)
Definition lavc_video.c:103
enum AVPixelFormat get_ug_to_av_pixfmt(codec_t ug_codec)
Definition utils.c:84

References av_to_uv_convert(), convert, debug_file_dump, frame, get_ug_to_av_pixfmt(), and serialize_video_avframe().

Referenced by libavcodec_decompress().

Here is the call graph for this function:

◆ check_av_opt_set()

static int check_av_opt_set ( void * state,
const char * key,
const char * val )
static

Definition at line 134 of file libavcodec.c.

134 {
135 int ret = av_opt_set(state, key, val, 0);
136 if (ret != 0) {
137 printf_libav_error(LOG_LEVEL_WARNING, ret, MOD_NAME "Unable to set %s to %s", key, val);
138 }
139 return ret;
140}
void ** state
int void * val
#define LOG_LEVEL_WARNING
less severe errors
Definition debug.h:60
void printf_libav_error(int verbosity, int rc, const char *msg,...)
const char * key
Definition cineform.cpp:125

References key, LOG_LEVEL_WARNING, MOD_NAME, printf_libav_error(), state, and val.

Referenced by set_codec_context_params().

Here is the call graph for this function:

◆ check_duration()

static void check_duration ( struct state_libavcodec_decompress * s,
double duration_total_sec,
double duration_pixfmt_change_sec )
static

print hint to improve performance if not making it

Definition at line 898 of file libavcodec.c.

899{
900 enum {
901 MOV_WIN_FRM = 100,
902 REPEAT_INT_SEC = 30,
903 TIME_SLOT_PERC_MAX = 66
904 };
905 double tpf = 1 / s->desc.fps;
906 tpf *= TIME_SLOT_PERC_MAX / 100.;
908 (s->mov_avg_comp_duration * (MOV_WIN_FRM - 1) +
909 duration_total_sec) /
910 MOV_WIN_FRM;
911 s->mov_avg_frames += 1;
912 if (s->mov_avg_frames < 2 * MOV_WIN_FRM ||
913 s->mov_avg_comp_duration < tpf) {
914 return;
915 }
916 const time_ns_t now = get_time_in_ns();
917 if (now < s->duration_warn_last_print + NS_IN_SEC * REPEAT_INT_SEC) {
918 return;
919 }
921 MSG(WARNING,
922 "Avg decompress time of last %d frames is %.2f ms which exceeds %.2f "
923 "ms (%d%% of TPF)!\n",
924 MOV_WIN_FRM, s->mov_avg_comp_duration * MS_IN_SEC, tpf * MS_IN_SEC,
925 TIME_SLOT_PERC_MAX);
926 const char *hint = NULL;
927 if ((s->codec_ctx->thread_type & FF_THREAD_FRAME) == 0 &&
928 (s->codec_ctx->codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) !=
929 0) {
930 hint = "\"--param lavd-thread-count=<n>FS\" option with small <n> or 0 (nr of logical cores)";
931 } else if (s->codec_ctx->thread_count == 1 && (s->codec_ctx->codec->capabilities & AV_CODEC_CAP_OTHER_THREADS) != 0) {
932 hint = "\"--param lavd-thread-count=<n>\" option with small <n> or 0 (nr of logical cores)";
933 }
934 if (hint) {
935 MSG(WARNING,
936 "Consider adding %s to increase throughput at the expense "
937 "of latency.\n",
938 hint);
939 }
940 if ((s->codec_ctx->flags & AV_CODEC_FLAG_LOW_DELAY) != 0) {
941 MSG(WARNING,
942 "Consider %sdisabling low delay decode using 'd' flag.\n",
943 hint != NULL ? "also " : "");
944 }
945
946 bool in_rgb = av_pix_fmt_desc_get(s->convert_in)->flags & AV_PIX_FMT_FLAG_RGB;
947 if (codec_is_a_rgb(s->out_codec) != in_rgb && duration_pixfmt_change_sec > s->mov_avg_comp_duration / 4) {
948 log_msg(LOG_LEVEL_WARNING, MOD_NAME "Also pixfmt change of last frame took %f ms.\n"
949 "Consider adding \"--conv-policy cds\" to prevent color space conversion.\n", duration_pixfmt_change_sec / 1000.0);
950 }
951}
#define MSG(l, fmt,...)
Definition debug.h:96
#define AV_CODEC_CAP_OTHER_THREADS
Definition lavc_common.h:95
struct video_desc desc
Definition libavcodec.c:78
enum AVPixelFormat convert_in
Definition libavcodec.c:85
AVCodecContext * codec_ctx
Definition libavcodec.c:73
double fps
Definition types.h:183
long long time_ns_t
Definition tv.h:81
#define MS_IN_SEC
Definition tv.h:87
#define NS_IN_SEC
Definition tv.h:92
static time_ns_t get_time_in_ns()
Definition tv.h:101
bool codec_is_a_rgb(codec_t codec)
Returns TRUE if specified pixelformat is some form of RGB (not YUV).

References AV_CODEC_CAP_OTHER_THREADS, state_libavcodec_decompress::codec_ctx, codec_is_a_rgb(), state_libavcodec_decompress::convert_in, state_libavcodec_decompress::desc, state_libavcodec_decompress::duration_warn_last_print, video_desc::fps, get_time_in_ns(), LOG_LEVEL_WARNING, log_msg(), MOD_NAME, state_libavcodec_decompress::mov_avg_comp_duration, state_libavcodec_decompress::mov_avg_frames, MS_IN_SEC, MSG, NS_IN_SEC, and state_libavcodec_decompress::out_codec.

Referenced by libavcodec_decompress().

Here is the call graph for this function:

◆ check_first_sps_vps()

static _Bool check_first_sps_vps ( struct state_libavcodec_decompress * s,
unsigned char * src,
unsigned int src_len )
static

This function handles beginning of H.264 stream that usually floods terminal output with errors because it usually doesn't start with IDR frame (even if it does, codec probing swallows this). As a workaround, we wait until first SPS NAL unit to avoid initial decoding errors.

A drawback may be that it can in theory happen that the SPS NAL unit is not at the beginning of the buffer, but it is not the case of libx264 and hopefully neither other decoders (if so, it needs to be reworked/removed).

Definition at line 860 of file libavcodec.c.

860 {
861 if (s->sps_vps_found) {
862 return 1;
863 }
864 _Thread_local static time_ns_t t0;
865 if (t0 == 0) {
866 t0 = get_time_in_ns();
867 }
868 if (get_time_in_ns() - t0 > 10 * NS_IN_SEC) { // after 10 seconds surrender and let decoder do the job
869 log_msg(LOG_LEVEL_WARNING, MOD_NAME "No SPS found, starting decode, anyway. Please report a bug to " PACKAGE_BUGREPORT " if decoding succeeds from now.\n");
870 s->sps_vps_found = 1;
871 return 1;
872 }
873
874 const unsigned char *const nal =
875 rtpenc_get_first_nal(src, src_len, s->desc.color_spec == H265);
876 if (nal == NULL) {
877 return 0;
878 }
879 const int nalu_type =
880 NALU_HDR_GET_TYPE(nal[0], s->desc.color_spec == H265);
881
882 switch (nalu_type) {
883 case NAL_H264_SPS:
884 case NAL_HEVC_VPS:
885 s->sps_vps_found = 1;
887 MOD_NAME "Received %s NALU, decoding begins.\n",
888 get_nalu_name(nalu_type));
889 return 1;
890 default:
892 MOD_NAME "Waiting for first SPS/VPS NALU...\n");
893 return 0;
894 }
895}
#define LOG_LEVEL_VERBOSE
Definition debug.h:63
@ NAL_H264_SPS
Definition rtpdec_h264.h:62
@ NAL_HEVC_VPS
Definition rtpdec_h264.h:66
#define NALU_HDR_GET_TYPE(nal, is_hevc)
Definition rtpdec_h264.h:88
const char * get_nalu_name(int type)
const unsigned char * rtpenc_get_first_nal(const unsigned char *src, long src_len, bool hevc)
_Bool sps_vps_found
to avoid initial error flood, start decoding after SPS (H.264) or VPS (HEVC) was received
Definition libavcodec.c:99
codec_t color_spec
Definition types.h:182
@ H265
H.264 frame.
Definition types.h:84

References video_desc::color_spec, state_libavcodec_decompress::desc, get_nalu_name(), get_time_in_ns(), H265, LOG_LEVEL_VERBOSE, LOG_LEVEL_WARNING, log_msg(), MOD_NAME, NAL_H264_SPS, NAL_HEVC_VPS, NALU_HDR_GET_TYPE, NS_IN_SEC, rtpenc_get_first_nal(), and state_libavcodec_decompress::sps_vps_found.

Referenced by libavcodec_decompress().

Here is the call graph for this function:

◆ configure_with()

static bool configure_with ( struct state_libavcodec_decompress * s,
struct video_desc desc,
void * extradata,
int extradata_size )
static

Definition at line 336 of file libavcodec.c.

338{
339 const struct decoder_info *dec = NULL;
340
342
343 for (unsigned int i = 0; i < sizeof decoders / sizeof decoders[0]; ++i) {
344 if (decoders[i].ug_codec == desc.color_spec) {
345 dec = &decoders[i];
346 break;
347 }
348 }
349
350 if (dec == NULL) {
351 log_msg(LOG_LEVEL_ERROR, "[lavd] Unsupported codec!!!\n");
352 return false;
353 }
354
355 if (dec->codec_callback) {
356 dec->codec_callback();
357 }
358
359 // priority list of decoders that can be used for the codec
360 const AVCodec *usable_decoders[DEC_LEN] = { NULL };
361 if (!get_usable_decoders(dec->avcodec_id, dec->preferred_decoders,
362 usable_decoders)) {
363 return false;
364 }
365
366 // initialize the codec - use the first decoder initialization of which succeeds
367 const AVCodec **codec_it = usable_decoders;
368 while (*codec_it) {
369 log_msg(LOG_LEVEL_VERBOSE, "[lavd] Trying decoder: %s\n", (*codec_it)->name);
370 s->codec_ctx = avcodec_alloc_context3(*codec_it);
371 if(s->codec_ctx == NULL) {
372 log_msg(LOG_LEVEL_ERROR, "[lavd] Unable to allocate codec context.\n");
373 return false;
374 }
375 if (extradata) {
376 s->codec_ctx->extradata = malloc(extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
377 memcpy(s->codec_ctx->extradata, extradata, extradata_size);
378 s->codec_ctx->extradata_size = extradata_size;
379 }
380 s->codec_ctx->width = desc.width;
381 s->codec_ctx->height = desc.height;
383 s->codec_ctx->codec_tag = get_fourcc(desc.color_spec);
384 }
386 if (avcodec_open2(s->codec_ctx, *codec_it, NULL) < 0) {
387 avcodec_free_context(&s->codec_ctx);
388 log_msg(LOG_LEVEL_WARNING, "[lavd] Unable to open decoder %s.\n", (*codec_it)->name);
389 codec_it++;
390 continue;
391 }
392 log_msg(LOG_LEVEL_NOTICE, "[lavd] Using decoder: %s\n", (*codec_it)->name);
393 log_msg(LOG_LEVEL_VERBOSE, MOD_NAME "Codec %s capabilities: 0x%08X; using thread type %d, count %d\n",
394 (*codec_it)->name, (*codec_it)->capabilities, s->codec_ctx->thread_type, s->codec_ctx->thread_count);
395 break;
396 }
397
398 if (s->codec_ctx == NULL) {
399 log_msg(LOG_LEVEL_ERROR, "[lavd] Decoder could have not been initialized for codec %s.\n",
401 return false;
402 }
403
404 s->frame = av_frame_alloc();
405 s->tmp_frame = av_frame_alloc();
406 if (s->frame == NULL || s->tmp_frame == NULL) {
407 log_msg(LOG_LEVEL_ERROR, "[lavd] Unable allocate frame.\n");
408 return false;
409 }
410
411 s->pkt = av_packet_alloc();
412
413 return true;
414}
struct video_desc desc
const char * get_codec_name(codec_t codec)
#define LOG_LEVEL_NOTICE
information that may be interesting
Definition debug.h:61
#define LOG_LEVEL_ERROR
general errors
Definition debug.h:59
static const struct decoder_item decoders[]
long long consecutive_failed_decodes
Definition libavcodec.c:88
unsigned int width
width of every tile (!)
Definition types.h:179
unsigned int height
height of every tile (!)
Definition types.h:180
@ PRORES_422_LT
Apple ProRes 422 (LT)
Definition types.h:106
@ PRORES
abstract Apple ProRes, must not be used in transmit
Definition types.h:100
codec_t ug_codec
Definition v4l2_common.h:68
uint32_t get_fourcc(codec_t codec)
static bool get_usable_decoders(enum AVCodecID avcodec_id, const char *const preferred_decoders[static MAX_PREFERED+1], const AVCodec *usable_decoders[static DEC_LEN])
Definition libavcodec.c:259
static void set_codec_context_params(struct state_libavcodec_decompress *s)
Definition libavcodec.c:145

References state_libavcodec_decompress::codec_ctx, video_desc::color_spec, state_libavcodec_decompress::consecutive_failed_decodes, DEC_LEN, decoders, desc, state_libavcodec_decompress::frame, get_codec_name(), get_fourcc(), get_usable_decoders(), video_desc::height, LOG_LEVEL_ERROR, LOG_LEVEL_NOTICE, LOG_LEVEL_VERBOSE, LOG_LEVEL_WARNING, log_msg(), MOD_NAME, state_libavcodec_decompress::pkt, PRORES, PRORES_422_LT, set_codec_context_params(), state_libavcodec_decompress::tmp_frame, ug_codec, and video_desc::width.

Referenced by handle_lavd_error(), libavcodec_decompress(), and libavcodec_decompress_reconfigure().

Here is the call graph for this function:

◆ decode_frame()

static bool decode_frame ( struct state_libavcodec_decompress * s,
unsigned char * src,
int src_len )
static

Definition at line 1003 of file libavcodec.c.

1005{
1006 bool frame_decoded = false;
1007 s->pkt->data = src;
1008 s->pkt->size = src_len;
1009 int ret = avcodec_send_packet(s->codec_ctx, s->pkt);
1010 if (ret != 0 && ret != AVERROR(EAGAIN)) {
1011 handle_lavd_error(MOD_NAME "send - ", s, ret);
1012 return false;
1013 }
1014 // we output to tmp_frame because even if receive fails,
1015 // it overrides previous potentially valid frame
1016 while ((ret = avcodec_receive_frame(s->codec_ctx, s->tmp_frame)) == 0) {
1017 if (frame_decoded) {
1019 MOD_NAME "Multiple frames decoded at once!\n");
1020 }
1021 frame_decoded = true;
1022 SWAP_PTR(s->frame, s->tmp_frame);
1023 }
1024 if (ret != AVERROR(EAGAIN) && ret != AVERROR_EOF) {
1025 handle_lavd_error(MOD_NAME "recv - ", s, ret);
1026 }
1027 return frame_decoded;
1028}
#define SWAP_PTR(a, b)
Definition macros.h:58
static void handle_lavd_error(const char *prefix, struct state_libavcodec_decompress *s, int ret)
Definition libavcodec.c:954

References state_libavcodec_decompress::codec_ctx, state_libavcodec_decompress::frame, handle_lavd_error(), LOG_LEVEL_WARNING, log_msg(), MOD_NAME, state_libavcodec_decompress::pkt, SWAP_PTR, and state_libavcodec_decompress::tmp_frame.

Referenced by libavcodec_decompress().

Here is the call graph for this function:

◆ deconfigure()

static void deconfigure ( struct state_libavcodec_decompress * s)
static

Definition at line 108 of file libavcodec.c.

109{
111
112 if(s->codec_ctx) {
114 avcodec_free_context(&s->codec_ctx);
115 }
116 av_frame_free(&s->frame);
117 av_frame_free(&s->tmp_frame);
118 av_packet_free(&s->pkt);
119
121
122 s->convert_in = AV_PIX_FMT_NONE;
123
124#ifdef HAVE_SWSCALE
125 sws_freeContext(s->sws.ctx);
126 s->sws.ctx = NULL;
127 if (s->sws.frame) {
128 av_freep(s->sws.frame->data);
129 }
130 av_frame_free(&s->sws.frame);
131#endif // defined HAVE_SWSCALE
132}
void av_to_uv_conversion_destroy(av_to_uv_convert_t **s)
void hwaccel_state_reset(struct hw_accel_state *hwaccel)
Uninitializes existing acceleration and resets hw_accel_state to initial state.
void lavd_flush(AVCodecContext *codec_ctx)
struct state_libavcodec_decompress::state_libavcodec_decompress_sws sws
struct hw_accel_state hwaccel
Definition libavcodec.c:97
av_to_uv_convert_t * convert
Definition libavcodec.c:84

References av_to_uv_conversion_destroy(), state_libavcodec_decompress::codec_ctx, state_libavcodec_decompress::convert, state_libavcodec_decompress::convert_in, state_libavcodec_decompress::state_libavcodec_decompress_sws::ctx, state_libavcodec_decompress::frame, state_libavcodec_decompress::state_libavcodec_decompress_sws::frame, state_libavcodec_decompress::hwaccel, hwaccel_state_reset(), lavd_flush(), state_libavcodec_decompress::pkt, state_libavcodec_decompress::sws, and state_libavcodec_decompress::tmp_frame.

Referenced by handle_lavd_error(), libavcodec_decompress_done(), and libavcodec_decompress_reconfigure().

Here is the call graph for this function:

◆ drm_prime_init()

static int drm_prime_init ( struct AVCodecContext * s,
struct hw_accel_state * state,
codec_t out_codec )
static

Definition at line 490 of file libavcodec.c.

493{
494 UNUSED(s), UNUSED(out_codec);
495 state->type = HWACCEL_DRM_PRIME;
496 AVBufferRef *ref = NULL;
497 int ret = create_hw_device_ctx(AV_HWDEVICE_TYPE_DRM, &ref);
498 if(ret < 0)
499 return ret;
500
501 s->hw_device_ctx = ref;
502 state->copy = out_codec != DRM_PRIME;
503 state->tmp_frame = av_frame_alloc();
504 if(!state->tmp_frame){
505 av_buffer_unref(&ref);
506 return -1;
507 }
508 return 0;
509}
#define UNUSED(x)
@ HWACCEL_DRM_PRIME
Definition types.h:121
@ DRM_PRIME
DRM Prime buffer, data contains struct drm_prime_frame.
Definition types.h:107

References DRM_PRIME, HWACCEL_DRM_PRIME, state_libavcodec_decompress::out_codec, state, and UNUSED.

Referenced by get_format_callback().

◆ get_format_callback()

static enum AVPixelFormat get_format_callback ( struct AVCodecContext * s,
const enum AVPixelFormat * fmt )
static

Definition at line 596 of file libavcodec.c.

597{
598#define SELECT_PIXFMT(pixfmt) { log_msg(LOG_LEVEL_INFO, MOD_NAME "Selected pixel format: %s\n", av_get_pix_fmt_name(pixfmt)); return pixfmt; }
599 MSG(VERBOSE, "Available output pixel formats: %s\n",
601
603 const char *hwaccel = get_commandline_param("use-hw-accel");
604#ifdef HWACC_COMMON_IMPL
605 hwaccel_state_reset(&state->hwaccel);
606
607 static const struct{
608 enum AVPixelFormat pix_fmt;
609 int (*init_func)(AVCodecContext *, struct hw_accel_state *, codec_t);
610 } accels[] = {
611#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(56, 39, 100)
612 {AV_PIX_FMT_VULKAN, vulkan_init},
613#endif
614#ifdef HWACC_VDPAU
615 {AV_PIX_FMT_VDPAU, vdpau_init},
616#endif
617 {AV_PIX_FMT_CUDA, hwacc_cuda_init},
618#ifdef HWACC_VAAPI
619 {AV_PIX_FMT_VAAPI, vaapi_init},
620#endif
621#ifdef __APPLE__
622 {AV_PIX_FMT_VIDEOTOOLBOX, videotoolbox_init},
623#endif
624#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(55, 75, 100)
625 {AV_PIX_FMT_DRM_PRIME, drm_prime_init},
626#endif
627 {AV_PIX_FMT_NONE, NULL}
628 };
629
630 if (hwaccel != NULL) {
631 struct state_libavcodec_decompress *state = (struct state_libavcodec_decompress *) s->opaque;
632 check_pixfmt_hw_eligibility(s->sw_pix_fmt);
633 const enum hw_accel_type forced_hwaccel =
634 strlen(hwaccel) > 0 ? hw_accel_from_str(hwaccel)
635 : HWACCEL_NONE;
636 for(const enum AVPixelFormat *it = fmt; *it != AV_PIX_FMT_NONE; it++){
637 for(unsigned i = 0; i < sizeof(accels) / sizeof(accels[0]); i++){
638 if (*it != accels[i].pix_fmt ||
639 state->block_accel[hw_accel_from_pixfmt(accels[i].pix_fmt)]) {
640 continue;
641 }
642 if (forced_hwaccel != HWACCEL_NONE &&
643 hw_accel_from_pixfmt(accels[i].pix_fmt) !=
644 forced_hwaccel) {
645 break;
646 }
647 int ret = accels[i].init_func(s, &state->hwaccel, state->out_codec);
648 if(ret < 0){
649 hwaccel_state_reset(&state->hwaccel);
650 break;
651 }
652 SELECT_PIXFMT(accels[i].pix_fmt);
653 }
654 }
655 if(forced_hwaccel != HWACCEL_NONE){
656 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Requested hw accel \"%s\" is not available\n", hwaccel);
657 return AV_PIX_FMT_NONE;
658 }
659 log_msg(LOG_LEVEL_WARNING, "[lavd] Falling back to software decoding!\n");
660 if (state->out_codec == HW_VDPAU) {
661 return AV_PIX_FMT_NONE;
662 }
663 }
664#endif
665
666 if (state->out_codec == VIDEO_CODEC_NONE) { // probe
668 if (c != VIDEO_CODEC_NONE) {
669 enum AVPixelFormat selected_fmt = lavd_get_av_to_ug_codec(fmt, c, hwaccel);
670 return selected_fmt;
671 }
672 } else {
673 enum AVPixelFormat f = lavd_get_av_to_ug_codec(fmt, state->out_codec, hwaccel);
674 if (f != AV_PIX_FMT_NONE) {
675 SELECT_PIXFMT(f);
676 }
677 }
678
679#ifdef HAVE_SWSCALE
680 for (const enum AVPixelFormat *fmt_it = fmt; *fmt_it != AV_PIX_FMT_NONE; fmt_it++) {
681 const AVPixFmtDescriptor *fmt_desc = av_pix_fmt_desc_get(*fmt_it);
682 if (fmt_desc && (fmt_desc->flags & AV_PIX_FMT_FLAG_HWACCEL) == 0U) {
683 SELECT_PIXFMT(*fmt_it);
684 }
685 }
686#endif
687
688 return AV_PIX_FMT_NONE;
689}
const char * fmt
enum AVPixelFormat lavd_get_av_to_ug_codec(const enum AVPixelFormat *fmt, codec_t c, bool use_hwaccel)
codec_t get_best_ug_codec_to_av(const enum AVPixelFormat *fmt, bool use_hwaccel)
const char * get_commandline_param(const char *key)
Definition host.cpp:894
enum hw_accel_type hw_accel_from_pixfmt(enum AVPixelFormat pixfmt)
enum hw_accel_type hw_accel_from_str(const char *str)
int vaapi_init(struct AVCodecContext *s, struct hw_accel_state *state, codec_t out_codec)
int vdpau_init(struct AVCodecContext *s, struct hw_accel_state *state, codec_t out_codec)
int videotoolbox_init(struct AVCodecContext *s, struct hw_accel_state *state, codec_t out_codec)
const char * get_avpixfmts_names(const enum AVPixelFormat *pixfmts)
#define AV_PIX_FMT_VULKAN
hw_accel_type
Definition types.h:114
@ HWACCEL_NONE
Definition types.h:115
codec_t
Definition types.h:65
@ VIDEO_CODEC_NONE
dummy color spec
Definition types.h:66
@ HW_VDPAU
VDPAU hardware surface.
Definition types.h:91
#define SELECT_PIXFMT(pixfmt)
static int drm_prime_init(struct AVCodecContext *s, struct hw_accel_state *state, codec_t out_codec)
Definition libavcodec.c:490

References AV_PIX_FMT_VULKAN, drm_prime_init(), fmt, get_avpixfmts_names(), get_best_ug_codec_to_av(), get_commandline_param(), hw_accel_from_pixfmt(), hw_accel_from_str(), HW_VDPAU, state_libavcodec_decompress::hwaccel, HWACCEL_NONE, hwaccel_state_reset(), lavd_get_av_to_ug_codec(), LOG_LEVEL_ERROR, LOG_LEVEL_WARNING, log_msg(), MOD_NAME, MSG, SELECT_PIXFMT, state, vaapi_init(), vdpau_init(), VIDEO_CODEC_NONE, and videotoolbox_init().

Referenced by set_codec_context_params().

Here is the call graph for this function:

◆ get_usable_decoders()

static bool get_usable_decoders ( enum AVCodecID avcodec_id,
const char *const preferred_decoders[static MAX_PREFERED+1],
const AVCodec * usable_decoders[static DEC_LEN] )
static

Definition at line 259 of file libavcodec.c.

263{
264 unsigned int codec_index = 0;
265 // first try codec specified from cmdline if any
266 const char *param = get_commandline_param("force-lavd-decoder");
267 if (param != NULL) {
268 char *val = alloca(strlen(param) + 1);
269 strcpy(val, param);
270 char *item = NULL;
271 char *save_ptr = NULL;
272 while ((item = strtok_r(val, ":", &save_ptr))) {
273 val = NULL;
274 const AVCodec *codec =
275 avcodec_find_decoder_by_name(item);
276 if (codec == NULL) {
279 "Forced decoder not found: %s\n",
280 item);
281 exit_uv(1);
282 return false;
283 }
284 if (codec->id != avcodec_id) {
285 log_msg(
288 "Forced decoder not valid for codec: %s\n",
289 item);
290 continue;
291 }
292 assert(codec_index < MAX_DECODERS);
293 usable_decoders[codec_index++] = codec;
294 }
295 }
296 // then try preferred codecs
297 const char *const *preferred_decoders_it = preferred_decoders;
298 while (*preferred_decoders_it) {
299 const AVCodec *codec =
300 avcodec_find_decoder_by_name(*preferred_decoders_it);
301 if (codec == NULL) {
303 "[lavd] Decoder not available: %s\n",
304 *preferred_decoders_it);
305 preferred_decoders_it++;
306 continue;
307 }
308 assert(codec_index < MAX_DECODERS);
309 preferred_decoders_it++;
310 }
311 // finally, add a default one if there are no preferred enc. or all fail
312 assert(codec_index < MAX_DECODERS);
313 const AVCodec *default_decoder = avcodec_find_decoder(avcodec_id);
314 if (default_decoder == NULL) {
316 "[lavd] No decoder found for the input codec "
317 "(libavcodec perhaps compiled without any)!\n"
318 "Use \"--param force-lavd-decoder=<d> to select a "
319 "different decoder than libavcodec if there is "
320 "any eligibe.\n");
321 } else {
322 usable_decoders[codec_index++] = default_decoder;
323 }
324 usable_decoders[codec_index] = NULL;
325 return true;
326}
void exit_uv(int status)
Definition host.cpp:625
const char * param
Definition settings.cpp:195
Definition hd-rum.c:27

References decoder_info::avcodec_id, exit_uv(), get_commandline_param(), LOG_LEVEL_ERROR, LOG_LEVEL_VERBOSE, LOG_LEVEL_WARNING, log_msg(), MAX_DECODERS, MOD_NAME, param, decoder_info::preferred_decoders, and val.

Referenced by configure_with().

Here is the call graph for this function:

◆ handle_lavd_error()

static void handle_lavd_error ( const char * prefix,
struct state_libavcodec_decompress * s,
int ret )
static

Definition at line 954 of file libavcodec.c.

956{
957 print_decoder_error(prefix, ret);
958 if(ret == AVERROR(EIO)){
960 if(s->consecutive_failed_decodes > 70 && !s->block_accel[s->hwaccel.type]){
961 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Decode failing, "
962 " blacklisting hw. accelerator...\n");
963 s->block_accel[s->hwaccel.type] = true;
964 deconfigure(s);
965 configure_with(s, s->desc, NULL, 0);
966 }
967 } else if (ret == AVERROR(EAGAIN) && strcmp(s->codec_ctx->codec->name, "hevc_qsv") == 0) {
968 if (s->consecutive_failed_decodes++ == 70) {
969 log_msg(LOG_LEVEL_ERROR, MOD_NAME "hevc_qsv decoder keeps failing, which may be caused by intra refresh period.\n"
970 "Try disabling intra refresh on encoder: `-c libavcodec:encoder=libx265:disable_intra_refresh`\n");
971 }
972 }
973}
void print_decoder_error(const char *mod_name, int rc)
enum hw_accel_type type
bool block_accel[HWACCEL_COUNT]
Definition libavcodec.c:87
static void deconfigure(struct state_libavcodec_decompress *s)
Definition libavcodec.c:108
static bool configure_with(struct state_libavcodec_decompress *s, struct video_desc desc, void *extradata, int extradata_size)
Definition libavcodec.c:336

References state_libavcodec_decompress::block_accel, state_libavcodec_decompress::codec_ctx, configure_with(), state_libavcodec_decompress::consecutive_failed_decodes, deconfigure(), state_libavcodec_decompress::desc, state_libavcodec_decompress::hwaccel, LOG_LEVEL_ERROR, log_msg(), MOD_NAME, print_decoder_error(), and hw_accel_state::type.

Referenced by decode_frame().

Here is the call graph for this function:

◆ jpeg_callback()

static void jpeg_callback ( void )
static

Definition at line 209 of file libavcodec.c.

210{
211 log_msg(LOG_LEVEL_WARNING, "[lavd] Warning: JPEG decoder "
212 "will use full-scale YUV.\n");
213}

References LOG_LEVEL_WARNING, and log_msg().

Here is the call graph for this function:

◆ libavcodec_decompress()

static decompress_status libavcodec_decompress ( void * state,
unsigned char * dst,
unsigned char * src,
unsigned int src_len,
int frame_seq,
struct video_frame_callbacks * callbacks,
struct pixfmt_desc * internal_props )
static

Definition at line 1030 of file libavcodec.c.

1032{
1033 UNUSED(frame_seq);
1035
1036 if (s->desc.color_spec == H264 || s->desc.color_spec == H265) {
1037 if (s->out_codec == VIDEO_CODEC_NONE &&
1038 read_forced_pixfmt(s->desc.color_spec, src, src_len,
1039 internal_props)) {
1040 return DECODER_GOT_CODEC;
1041 }
1042 if (!check_first_sps_vps(s, src, src_len)) {
1043 return DECODER_NO_FRAME;
1044 }
1045 }
1046
1048 int extradata_size = *(uint32_t *)(void *) src;
1049 if (s->codec_ctx == NULL) {
1050 if (!configure_with(s, s->desc, src + sizeof(uint32_t),
1051 extradata_size)) {
1052 return DECODER_NO_FRAME;
1053 }
1054 }
1055 src += extradata_size + sizeof(uint32_t);
1056 src_len -= extradata_size + sizeof(uint32_t);
1057 }
1058
1060
1061 if (!decode_frame(s, src, src_len)) {
1062 log_msg(LOG_LEVEL_DEBUG, MOD_NAME "No frame was decoded!\n");
1063 return DECODER_NO_FRAME;
1064 }
1066
1068
1069 s->frame->opaque = callbacks;
1070#ifdef HWACC_COMMON_IMPL
1071 if(s->hwaccel.copy){
1072 transfer_frame(&s->hwaccel, s->frame);
1073 }
1074#endif
1075 if (s->out_codec != VIDEO_CODEC_NONE) {
1076 if (!reconfigure_convert_if_needed(s, s->frame->format, s->out_codec, s->desc.width, s->desc.height)) {
1077 return DECODER_UNSUPP_PIXFMT;
1078 }
1079 change_pixfmt(s->frame, dst, s->convert, s->out_codec,
1080 s->desc.width, s->desc.height, s->pitch,
1081 s->rgb_shift, &s->sws);
1082 }
1084 log_msg(LOG_LEVEL_DEBUG, MOD_NAME "Decompressing %c frame took %f ms, pixfmt change %f ms.\n", av_get_picture_type_char(s->frame->pict_type),
1085 NS_TO_MS((double) (t1 - t0)), NS_TO_MS((double) (t2 - t1)));
1086 check_duration(s, (t2 - t0) / NS_IN_SEC_DBL, (t2 - t1) / NS_IN_SEC_DBL);
1087
1088 if (s->out_codec == VIDEO_CODEC_NONE) {
1090 MOD_NAME "Probed output pixel format: %s (%s)\n",
1091 av_get_pix_fmt_name(s->codec_ctx->pix_fmt),
1092 av_get_pix_fmt_name(s->codec_ctx->sw_pix_fmt));
1093 enum AVPixelFormat sw_fmt = s->codec_ctx->sw_pix_fmt == AV_PIX_FMT_NONE ? s->codec_ctx->pix_fmt : s->codec_ctx->sw_pix_fmt;
1094 *internal_props = av_pixfmt_get_desc(sw_fmt);
1095 internal_props->accel_type =
1096 hw_accel_from_pixfmt(s->codec_ctx->pix_fmt);
1097 return DECODER_GOT_CODEC;
1098 }
1099
1100 return DECODER_GOT_FRAME;
1101}
@ DECODER_GOT_CODEC
Internal pixel format was determined.
@ DECODER_NO_FRAME
@ DECODER_UNSUPP_PIXFMT
Decoder can't decode to selected out_codec.
@ DECODER_GOT_FRAME
#define LOG_LEVEL_DEBUG
Definition kernels.cu:48
struct pixfmt_desc av_pixfmt_get_desc(enum AVPixelFormat pixfmt)
bool libav_codec_has_extradata(codec_t codec)
bool copy
Specifies whether to use the copy mode.
enum hw_accel_type accel_type
Definition types.h:143
#define NS_IN_SEC_DBL
Definition tv.h:93
#define NS_TO_MS(val_ns)
Definition tv.h:98
@ H264
H.264 frame.
Definition types.h:83
static void change_pixfmt(AVFrame *frame, unsigned char *dst, av_to_uv_convert_t *convert, codec_t out_codec, int width, int height, int pitch, int rgb_shift[static restrict 3], struct state_libavcodec_decompress_sws *sws)
Definition libavcodec.c:823
static _Bool check_first_sps_vps(struct state_libavcodec_decompress *s, unsigned char *src, unsigned int src_len)
Definition libavcodec.c:860
static bool read_forced_pixfmt(codec_t compress, const unsigned char *src, unsigned int src_len, struct pixfmt_desc *internal_props)
Definition libavcodec.c:976
static void check_duration(struct state_libavcodec_decompress *s, double duration_total_sec, double duration_pixfmt_change_sec)
print hint to improve performance if not making it
Definition libavcodec.c:898
static _Bool reconfigure_convert_if_needed(struct state_libavcodec_decompress *s, enum AVPixelFormat av_codec, codec_t out_codec, int width, int height)
Definition libavcodec.c:772
static bool decode_frame(struct state_libavcodec_decompress *s, unsigned char *src, int src_len)

References pixfmt_desc::accel_type, av_pixfmt_get_desc(), change_pixfmt(), check_duration(), check_first_sps_vps(), state_libavcodec_decompress::codec_ctx, video_desc::color_spec, configure_with(), state_libavcodec_decompress::consecutive_failed_decodes, state_libavcodec_decompress::convert, hw_accel_state::copy, decode_frame(), DECODER_GOT_CODEC, DECODER_GOT_FRAME, DECODER_NO_FRAME, DECODER_UNSUPP_PIXFMT, state_libavcodec_decompress::desc, state_libavcodec_decompress::frame, get_time_in_ns(), H264, H265, video_desc::height, hw_accel_from_pixfmt(), state_libavcodec_decompress::hwaccel, libav_codec_has_extradata(), LOG_LEVEL_DEBUG, LOG_LEVEL_VERBOSE, log_msg(), MOD_NAME, NS_IN_SEC_DBL, NS_TO_MS, state_libavcodec_decompress::out_codec, state_libavcodec_decompress::pitch, read_forced_pixfmt(), reconfigure_convert_if_needed(), state_libavcodec_decompress::rgb_shift, state, state_libavcodec_decompress::sws, UNUSED, VIDEO_CODEC_NONE, and video_desc::width.

Here is the call graph for this function:

◆ libavcodec_decompress_done()

static void libavcodec_decompress_done ( void * state)
static

Definition at line 1135 of file libavcodec.c.

1136{
1137 struct state_libavcodec_decompress *s =
1139
1140 deconfigure(s);
1141
1142 free(s);
1143}

References deconfigure(), and state.

Here is the call graph for this function:

◆ libavcodec_decompress_get_priority()

static int libavcodec_decompress_get_priority ( codec_t compression,
struct pixfmt_desc internal,
codec_t ugc )
static
Todo
This should be take into account existing conversions.

Definition at line 1149 of file libavcodec.c.

1149 {
1150 if (internal.accel_type != HWACCEL_NONE &&
1151 hw_accel_to_ug_pixfmt(internal.accel_type) == ugc) {
1152 return VDEC_PRIO_PREFERRED;
1153 }
1154
1155 unsigned i = 0;
1156 for ( ; i < sizeof decoders / sizeof decoders[0]; ++i) {
1157 if (decoders[i].ug_codec == compression) {
1158 const AVCodec *const decoder =
1159 avcodec_find_decoder(decoders[i].avcodec_id);
1160 if (decoder != NULL) {
1161 break;
1162 }
1163 MSG(WARNING,
1164 "Codec %s supported by lavd but "
1165 "not compiled in FFmpeg build.\n",
1166 get_codec_name(compression));
1167 }
1168 }
1169 if (i == sizeof decoders / sizeof decoders[0]) { // lavd doesn't handle this compression
1170 return VDEC_PRIO_NA;
1171 }
1172
1173 switch (ugc) {
1174 case VIDEO_CODEC_NONE:
1175 return VDEC_PRIO_PROBE_LO; // for probe
1176 case UYVY:
1177 case RG48:
1178 case RGB:
1179 case RGBA:
1180 case R10k:
1181 case R12L:
1182 case v210:
1183 case Y416:
1184 break;
1185 default:
1186 return VDEC_PRIO_NA;
1187 }
1188 if (internal.depth == 0) { // unspecified internal format
1189 return VDEC_PRIO_LOW;
1190 }
1191 return codec_is_a_rgb(ugc) == internal.rgb ? VDEC_PRIO_NORMAL
1193}
@ VDEC_PRIO_PREFERRED
@ VDEC_PRIO_NA
decoder cannot handle the codec in any way
@ VDEC_PRIO_LOW
@ VDEC_PRIO_NOT_PREFERRED
@ VDEC_PRIO_PROBE_LO
@ VDEC_PRIO_NORMAL
codec_t hw_accel_to_ug_pixfmt(enum hw_accel_type type)
@ R10k
RGB 10-bit packed - RGBX, big-endian (2 bit padding)
Definition types.h:73
@ RGB
RGB 8-bit (packed into 24-bit word)
Definition types.h:80
@ UYVY
YCbCr 422 8-bit - Cb Y0 Cr Y1.
Definition types.h:71
@ RG48
16-bit RGB little-endian (RlRhGl...)
Definition types.h:95
@ Y416
interleaved little-endian YCbCr 4444 16-bit - UYVA
Definition types.h:99
@ R12L
RGB 12-bit packed, little-endian.
Definition types.h:74
@ RGBA
RGBA 8-bit, big-endian.
Definition types.h:70
@ v210
YCbCr 422 10-bit - xVY0U|xY2UY1|xUY3V|xY5VY4, little-endian (2 bit padding /'x'/),...
Definition types.h:75

References codec_is_a_rgb(), decoders, get_codec_name(), hw_accel_to_ug_pixfmt(), HWACCEL_NONE, MSG, R10k, R12L, RG48, RGB, RGBA, ug_codec, UYVY, v210, VDEC_PRIO_LOW, VDEC_PRIO_NA, VDEC_PRIO_NORMAL, VDEC_PRIO_NOT_PREFERRED, VDEC_PRIO_PREFERRED, VDEC_PRIO_PROBE_LO, VIDEO_CODEC_NONE, and Y416.

Here is the call graph for this function:

◆ libavcodec_decompress_get_property()

static int libavcodec_decompress_get_property ( void * state,
int property,
void * val,
size_t * len )
static

Definition at line 1107 of file libavcodec.c.

1108{
1109 struct state_libavcodec_decompress *s =
1111 int ret = false;
1112
1113 switch(property) {
1115 if (*len < sizeof(int)) {
1116 return false;
1117 }
1118 *(int *) val = false;
1119 if (s->codec_ctx && strcmp(s->codec_ctx->codec->name, "h264") == 0) {
1120 *(int *) val = true;
1121 }
1122 if (get_commandline_param("lavd-accept-corrupted")) {
1123 *(int *) val =
1124 strcmp(get_commandline_param("lavd-accept-corrupted"), "no") != 0;
1125 }
1126
1127 *len = sizeof(int);
1128 ret = true;
1129 break;
1130 }
1131
1132 return ret;
1133}
int void size_t * len
int property
#define DECOMPRESS_PROPERTY_ACCEPTS_CORRUPTED_FRAME

References state_libavcodec_decompress::codec_ctx, DECOMPRESS_PROPERTY_ACCEPTS_CORRUPTED_FRAME, get_commandline_param(), len, property, state, and val.

Here is the call graph for this function:

◆ libavcodec_decompress_init()

static void * libavcodec_decompress_init ( void )
static

Definition at line 442 of file libavcodec.c.

443{
444 if (!validate_hwacc_param()) {
445 return NULL;
446 }
447
449 calloc(1, sizeof(struct state_libavcodec_decompress));
450
452
453#if LIBAVCODEC_VERSION_INT <= AV_VERSION_INT(58, 9, 100)
454 /* register all the codecs (you can also register only the codec
455 * you wish to have smaller code */
456 avcodec_register_all();
457#endif
458
460
461 return s;
462}
void hwaccel_state_init(struct hw_accel_state *hwaccel)
Initializes hw_accel_state structure.
void ug_set_av_logging()
Sets specified log level either given explicitly or from UG-wide log_level.
static bool validate_hwacc_param(void)
Definition libavcodec.c:418

References state_libavcodec_decompress::hwaccel, hwaccel_state_init(), ug_set_av_logging(), and validate_hwacc_param().

Here is the call graph for this function:

◆ libavcodec_decompress_reconfigure()

static int libavcodec_decompress_reconfigure ( void * state,
struct video_desc desc,
int rshift,
int gshift,
int bshift,
int pitch,
codec_t out_codec )
static

Definition at line 464 of file libavcodec.c.

466{
469
470 s->pitch = pitch;
471 s->rgb_shift[R_SHIFT_IDX] = rshift;
472 s->rgb_shift[G_SHIFT_IDX] = gshift;
473 s->rgb_shift[B_SHIFT_IDX] = bshift;
474 for(int i = 0; i < HWACCEL_COUNT; i++){
475 s->block_accel[i] = get_commandline_param("use-hw-accel") == NULL;
476 }
477 s->out_codec = out_codec;
478 s->desc = desc;
479
480 deconfigure(s);
482 // for codecs that have metadata we have to defer initialization
483 // because we don't have the data right now
484 return true;
485 }
486 return configure_with(s, desc, NULL, 0);
487}
@ B_SHIFT_IDX
Definition lavc_common.h:69
@ G_SHIFT_IDX
Definition lavc_common.h:68
@ R_SHIFT_IDX
Definition lavc_common.h:67
@ HWACCEL_COUNT
Definition types.h:122

References B_SHIFT_IDX, state_libavcodec_decompress::block_accel, video_desc::color_spec, configure_with(), deconfigure(), desc, state_libavcodec_decompress::desc, G_SHIFT_IDX, get_commandline_param(), HWACCEL_COUNT, libav_codec_has_extradata(), state_libavcodec_decompress::out_codec, state_libavcodec_decompress::pitch, R_SHIFT_IDX, state_libavcodec_decompress::rgb_shift, and state.

Here is the call graph for this function:

◆ read_forced_pixfmt()

static bool read_forced_pixfmt ( codec_t compress,
const unsigned char * src,
unsigned int src_len,
struct pixfmt_desc * internal_props )
static

Definition at line 976 of file libavcodec.c.

978{
979 if (compress == H264) {
980 char expected_prefix[] = { START_CODE_3B, H264_NAL_SEI_PREFIX, sizeof (unsigned char[]) { UG_ORIG_FORMAT_ISO_IEC_11578_GUID } + 1, UG_ORIG_FORMAT_ISO_IEC_11578_GUID };
981 if (src_len < sizeof expected_prefix + 2 || memcmp(src + src_len - sizeof expected_prefix - 2, expected_prefix, sizeof expected_prefix) != 0) {
982 return false;
983 }
984 } else if (compress == H265) {
985 char expected_prefix[] = { START_CODE_3B, HEVC_NAL_SEI_PREFIX, sizeof (unsigned char []) { UG_ORIG_FORMAT_ISO_IEC_11578_GUID } + 1, UG_ORIG_FORMAT_ISO_IEC_11578_GUID };
986 if (src_len < sizeof expected_prefix + 2 || memcmp(src + src_len - sizeof expected_prefix - 2, expected_prefix, sizeof expected_prefix) != 0) {
987 return false;
988 }
989 } else {
990 return false;
991 }
992 unsigned format = src[src_len - 2];
993 internal_props->depth = 8 + (format >> 4) * 2;
994 int subs_a = ((format >> 2) & 0x3) + 1;
995 int subs_b = ((format >> 1) & 0x1) * subs_a;
996 internal_props->subsampling = 4000 + subs_a * 100 + subs_b * 10;
997 internal_props->rgb = format & 0x1;
998 log_msg(LOG_LEVEL_VERBOSE, MOD_NAME "Stream properties read from metadata.\n");
999 return true;
1000}
#define H264_NAL_SEI_PREFIX
Definition rtpenc_h264.h:52
#define UG_ORIG_FORMAT_ISO_IEC_11578_GUID
custom orig format byte syntax - highest 1 bit zero, next 2 bits (depth-8)/2, next 3 bits subsampling...
Definition rtpenc_h264.h:55
#define START_CODE_3B
Definition rtpenc_h264.h:50
#define HEVC_NAL_SEI_PREFIX
Definition rtpenc_h264.h:53
int depth
bit depth; 0 means that whole struct is undefined
Definition types.h:140
bool rgb
Definition types.h:142
int subsampling
in 'JabA' format, eg. '4444'
Definition types.h:141

References pixfmt_desc::depth, H264, H264_NAL_SEI_PREFIX, H265, HEVC_NAL_SEI_PREFIX, LOG_LEVEL_VERBOSE, log_msg(), MOD_NAME, pixfmt_desc::rgb, START_CODE_3B, pixfmt_desc::subsampling, and UG_ORIG_FORMAT_ISO_IEC_11578_GUID.

Referenced by libavcodec_decompress().

Here is the call graph for this function:

◆ reconfigure_convert_if_needed()

static _Bool reconfigure_convert_if_needed ( struct state_libavcodec_decompress * s,
enum AVPixelFormat av_codec,
codec_t out_codec,
int width,
int height )
static

Definition at line 772 of file libavcodec.c.

772 {
773 assert(av_codec != AV_PIX_FMT_NONE);
774 if (s->convert_in == av_codec) {
775 return 1;
776 }
778 s->convert = get_av_to_uv_conversion(av_codec, out_codec);
779 if (s->convert != NULL) {
780 s->convert_in = av_codec;
781 return 1;
782 }
783#ifdef HAVE_SWSCALE
784 if (get_ug_to_av_pixfmt(out_codec) != AV_PIX_FMT_NONE) { // the UG pixfmt can be used directly as dst for sws
785 if (!lavd_sws_convert_reconfigure(&s->sws, av_codec, get_ug_to_av_pixfmt(out_codec), width, height)) {
786 return 0;
787 }
788 s->convert_in = av_codec;
789 return 1;
790 }
791
792 // else try to find swscale
793 enum AVPixelFormat sws_out_codec = pick_av_convertible_to_ug(out_codec, &s->convert);
794 if (!sws_out_codec) {
795 log_msg(LOG_LEVEL_ERROR, MOD_NAME "Unsupported pixel format: %s (id %d)\n",
796 av_get_pix_fmt_name(av_codec), av_codec);
797 return 0;
798 }
799 if (!lavd_sws_convert_reconfigure(&s->sws, av_codec, sws_out_codec, width, height)) {
800 return 0;
801 }
802 s->convert_in = av_codec;
803 return 1;
804#else
805 UNUSED(width), UNUSED(height);
806 return 0;
807#endif
808}
av_to_uv_convert_t * get_av_to_uv_conversion(int av_codec, codec_t uv_codec)
enum AVPixelFormat pick_av_convertible_to_ug(codec_t color_spec, av_to_uv_convert_t **av_conv)

References av_to_uv_conversion_destroy(), state_libavcodec_decompress::convert, state_libavcodec_decompress::convert_in, get_av_to_uv_conversion(), get_ug_to_av_pixfmt(), LOG_LEVEL_ERROR, log_msg(), MOD_NAME, pick_av_convertible_to_ug(), state_libavcodec_decompress::sws, and UNUSED.

Referenced by libavcodec_decompress().

Here is the call graph for this function:

◆ REGISTER_MODULE()

REGISTER_MODULE ( libavcodec ,
& libavcodec_info,
LIBRARY_CLASS_VIDEO_DECOMPRESS ,
VIDEO_DECOMPRESS_ABI_VERSION  )

◆ set_codec_context_params()

static void set_codec_context_params ( struct state_libavcodec_decompress * s)
static

< decoder may use <cpu_count> frame threads with AV_CODEC_CAP_OTHER_THREADS (latency)

Definition at line 145 of file libavcodec.c.

146{
147 int thread_count = 0;
148 int req_thread_type = 0;
149 bool req_low_delay = true;
150 const char *thread_count_opt = get_commandline_param("lavd-thread-count");
151 if (thread_count_opt != NULL) {
152 char *endptr = NULL;
153 errno = 0;
154 long val = strtol(thread_count_opt, &endptr, 0);
155 if (errno == 0 && thread_count_opt[0] != '\0' && val >= 0 && val <= INT_MAX && (*endptr == '\0' || toupper(*endptr) == 'F' || toupper(*endptr) == 'S')) {
156 thread_count = val;
157 while (*endptr) {
158 switch (toupper(*endptr)) {
159 case 'F': req_thread_type |= FF_THREAD_FRAME; break;
160 case 'S': req_thread_type |= FF_THREAD_SLICE; break;
161 case 'n': req_thread_type = -1; break;
162 case 'd': req_low_delay = false; break;
163 }
164 endptr++;
165 }
166 } else {
167 log_msg(LOG_LEVEL_WARNING, MOD_NAME "Wrong value for thread count: %s\n", thread_count_opt);
168 }
169 }
170
171 s->codec_ctx->thread_count = thread_count; // zero should mean count equal to the number of virtual cores
172 s->codec_ctx->thread_type = 0;
173 if (req_thread_type == 0) {
174 req_thread_type = FF_THREAD_SLICE;
175 } if (req_thread_type == -1) {
176 req_thread_type = 0;
177 }
178 if ((req_thread_type & FF_THREAD_FRAME) != 0U) {
179 if (s->codec_ctx->codec->capabilities & AV_CODEC_CAP_FRAME_THREADS) {
180 s->codec_ctx->thread_type |= FF_THREAD_FRAME;
181 } else {
182 log_msg(LOG_LEVEL_WARNING, MOD_NAME "Warning: Codec doesn't support frame-based multithreading but requested.\n");
183 }
184 }
185 if ((req_thread_type & FF_THREAD_SLICE) != 0U) {
186 if (s->codec_ctx->codec->capabilities & AV_CODEC_CAP_SLICE_THREADS) {
187 s->codec_ctx->thread_type |= FF_THREAD_SLICE;
188 } else {
189 log_msg(LOG_LEVEL_VERBOSE, MOD_NAME "Warning: Codec doesn't support slice-based multithreading.\n");
190 }
191 }
192 log_msg(LOG_LEVEL_INFO, MOD_NAME "Setting thread count to %d, type: %s\n", s->codec_ctx->thread_count, lavc_thread_type_to_str(s->codec_ctx->thread_type));
193
194 s->codec_ctx->flags |= req_low_delay ? AV_CODEC_FLAG_LOW_DELAY : 0;
195 s->codec_ctx->flags2 |= AV_CODEC_FLAG2_FAST;
196 // set by decoder
197 s->codec_ctx->pix_fmt = AV_PIX_FMT_NONE;
198 // callback to negotiate pixel format that is supported by UG
199 s->codec_ctx->get_format = get_format_callback;
200 s->codec_ctx->opaque = s;
201
202 if (strstr(s->codec_ctx->codec->name, "cuvid") != NULL) {
203 char gpu[3];
204 snprintf(gpu, sizeof gpu, "%u", cuda_devices[0]);
205 check_av_opt_set(s->codec_ctx->priv_data, "gpu", gpu);
206 }
207}
unsigned int cuda_devices[MAX_CUDA_DEVICES]
Definition host.cpp:167
const char * lavc_thread_type_to_str(int thread_type)
static enum AVPixelFormat get_format_callback(struct AVCodecContext *s, const enum AVPixelFormat *fmt)
Definition libavcodec.c:596
static int check_av_opt_set(void *state, const char *key, const char *val)
Definition libavcodec.c:134

References check_av_opt_set(), state_libavcodec_decompress::codec_ctx, cuda_devices, get_commandline_param(), get_format_callback(), lavc_thread_type_to_str(), LOG_LEVEL_INFO, LOG_LEVEL_VERBOSE, LOG_LEVEL_WARNING, log_msg(), MOD_NAME, and val.

Referenced by configure_with().

Here is the call graph for this function:

◆ validate_hwacc_param()

static bool validate_hwacc_param ( void )
static
Return values
falseif 1. hwacc not enabled; 2. help; 3. incorect hwacc spec

Definition at line 418 of file libavcodec.c.

419{
420 const char *const hwaccel = get_commandline_param("use-hw-accel");
421 if (hwaccel == NULL) {
422 return true;
423 }
424#if !defined HWACC_COMMON_IMPL
425 MSG(FATAL, "HW acceleration not compiled in!\n");
426 exit_uv(1);
427 return NULL;
428#endif
429 if (strlen(hwaccel) == 0 ||
430 hw_accel_from_str(hwaccel) != HWACCEL_NONE) {
431 return true;
432 }
433 if (strcmp(hwaccel, "help") == 0) {
434 exit_uv(0);
435 return false;
436 }
437 MSG(ERROR, "Wrong HW acceleration specified: %s\n", hwaccel);
438 exit_uv(1);
439 return false;
440}

References exit_uv(), get_commandline_param(), hw_accel_from_str(), HWACCEL_NONE, and MSG.

Referenced by libavcodec_decompress_init().

Here is the call graph for this function:

Variable Documentation

◆ decoders

const struct decoder_info decoders[]
static
Initial value:
= {
{ H264, AV_CODEC_ID_H264, NULL, { NULL } },
{ H265, AV_CODEC_ID_HEVC, NULL, { NULL } },
{ MJPG, AV_CODEC_ID_MJPEG, jpeg_callback, { NULL } },
{ JPEG, AV_CODEC_ID_MJPEG, jpeg_callback, { NULL } },
{ J2K, AV_CODEC_ID_JPEG2000, NULL, { NULL } },
{ J2KR, AV_CODEC_ID_JPEG2000, NULL, { NULL } },
{ VP8, AV_CODEC_ID_VP8, NULL, { NULL } },
{ VP9, AV_CODEC_ID_VP9, NULL, { NULL } },
{ HFYU, AV_CODEC_ID_HUFFYUV, NULL, { NULL } },
{ FFV1, AV_CODEC_ID_FFV1, NULL, { NULL } },
{ AV1, AV_CODEC_ID_AV1, NULL, { "libdav1d" } },
{ PRORES_4444, AV_CODEC_ID_PRORES, NULL, { NULL } },
{ PRORES_4444_XQ, AV_CODEC_ID_PRORES, NULL, { NULL } },
{ PRORES_422_HQ, AV_CODEC_ID_PRORES, NULL, { NULL } },
{ PRORES_422, AV_CODEC_ID_PRORES, NULL, { NULL } },
{ PRORES_422_PROXY, AV_CODEC_ID_PRORES, NULL, { NULL } },
{ PRORES_422_LT, AV_CODEC_ID_PRORES, NULL, { NULL } },
{ CFHD, AV_CODEC_ID_CFHD, NULL, { NULL } }
}
@ VP8
VP8 frame.
Definition types.h:86
@ PRORES_422_PROXY
Apple ProRes 422 (Proxy)
Definition types.h:105
@ AV1
AOMedia Video 1.
Definition types.h:96
@ J2KR
JPEG 2000 RGB.
Definition types.h:90
@ CFHD
Cineform.
Definition types.h:94
@ J2K
JPEG 2000.
Definition types.h:89
@ PRORES_422_HQ
Apple ProRes 422 (HQ)
Definition types.h:103
@ PRORES_4444
Apple ProRes 4444.
Definition types.h:101
@ JPEG
JPEG image, restart intervals may be used. Compatible with GPUJPEG.
Definition types.h:81
@ HFYU
HuffYUV.
Definition types.h:92
@ MJPG
JPEG image, without restart intervals.
Definition types.h:85
@ FFV1
FFV1.
Definition types.h:93
@ PRORES_422
Apple ProRes 422.
Definition types.h:104
@ VP9
VP9 frame.
Definition types.h:87
@ PRORES_4444_XQ
Apple ProRes 4444 (XQ)
Definition types.h:102
static void jpeg_callback(void)
Definition libavcodec.c:209

Definition at line 237 of file libavcodec.c.

237 {
238 { H264, AV_CODEC_ID_H264, NULL, { NULL /* "h264_cuvid" */ } },
239 { H265, AV_CODEC_ID_HEVC, NULL, { NULL /* "hevc_cuvid" */ } },
240 { MJPG, AV_CODEC_ID_MJPEG, jpeg_callback, { NULL } },
241 { JPEG, AV_CODEC_ID_MJPEG, jpeg_callback, { NULL } },
242 { J2K, AV_CODEC_ID_JPEG2000, NULL, { NULL } },
243 { J2KR, AV_CODEC_ID_JPEG2000, NULL, { NULL } },
244 { VP8, AV_CODEC_ID_VP8, NULL, { NULL } },
245 { VP9, AV_CODEC_ID_VP9, NULL, { NULL } },
246 { HFYU, AV_CODEC_ID_HUFFYUV, NULL, { NULL } },
247 { FFV1, AV_CODEC_ID_FFV1, NULL, { NULL } },
248 { AV1, AV_CODEC_ID_AV1, NULL, { "libdav1d" } },
249 { PRORES_4444, AV_CODEC_ID_PRORES, NULL, { NULL } },
250 { PRORES_4444_XQ, AV_CODEC_ID_PRORES, NULL, { NULL } },
251 { PRORES_422_HQ, AV_CODEC_ID_PRORES, NULL, { NULL } },
252 { PRORES_422, AV_CODEC_ID_PRORES, NULL, { NULL } },
253 { PRORES_422_PROXY, AV_CODEC_ID_PRORES, NULL, { NULL } },
254 { PRORES_422_LT, AV_CODEC_ID_PRORES, NULL, { NULL } },
255 { CFHD, AV_CODEC_ID_CFHD, NULL, { NULL } }
256};

◆ libavcodec_info

const struct video_decompress_info libavcodec_info
static
Initial value:
= {
}
static audio_channel * libavcodec_decompress(void *, audio_channel *)
Definition libavcodec.c:666
static int libavcodec_decompress_reconfigure(void *state, struct video_desc desc, int rshift, int gshift, int bshift, int pitch, codec_t out_codec)
Definition libavcodec.c:464
static void libavcodec_decompress_done(void *state)
static int libavcodec_decompress_get_property(void *state, int property, void *val, size_t *len)
static void * libavcodec_decompress_init(void)
Definition libavcodec.c:442
static int libavcodec_decompress_get_priority(codec_t compression, struct pixfmt_desc internal, codec_t ugc)

Definition at line 1195 of file libavcodec.c.