Skip to content

Commit cf29292

Browse files
uknunknownFlole998
authored andcommitted
allow NVENC, VAAPI and MMAL to coexist in the same build
- allow NVENC, VAAPI and MMAL to coexist in the same build. - give the user the capability for prioritize hw decoder or to match the hw decoder with hw encoder - refactor source code: remove duplicate source code in codec.js
1 parent 13804ab commit cf29292

6 files changed

Lines changed: 353 additions & 888 deletions

File tree

src/transcoding/codec.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,9 @@ tvh_codec_profile_video_destroy(TVHCodecProfile *_self);
136136
int
137137
tvh_codec_profile_video_get_hwaccel(TVHCodecProfile *self);
138138

139+
int
140+
tvh_codec_profile_video_get_hwaccel_details(TVHCodecProfile *self);
141+
139142
const enum AVPixelFormat *
140143
tvh_codec_profile_video_get_pix_fmts(TVHCodecProfile *self);
141144

src/transcoding/codec/internals.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,16 @@
119119
AV_DICT_SET_INT((d), "pix_fmt", ((v) != AV_PIX_FMT_NONE) ? (v) : (a), \
120120
AV_DICT_DONT_OVERWRITE)
121121

122+
#define HWACCEL_AUTO 0
123+
#if ENABLE_VAAPI
124+
#define HWACCEL_PRIORITIZE_VAAPI 1
125+
#endif
126+
#if ENABLE_NVENC
127+
#define HWACCEL_PRIORITIZE_NVDEC 2
128+
#endif
129+
#if ENABLE_MMAL
130+
#define HWACCEL_PRIORITIZE_MMAL 3
131+
#endif
122132

123133
/* codec_profile_class ====================================================== */
124134

@@ -221,6 +231,7 @@ typedef struct tvh_codec_profile_video {
221231
int height;
222232
int scaling_mode; // 0 --> up&down; 1 --> up; 2 --> down
223233
int hwaccel;
234+
int hwaccel_details;
224235
int pix_fmt;
225236
int crf;
226237
AVRational size;

src/transcoding/codec/profile.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,18 @@ tvh_codec_profile_video_get_hwaccel(TVHCodecProfile *self)
286286
return -1;
287287
}
288288

289+
290+
int
291+
tvh_codec_profile_video_get_hwaccel_details(TVHCodecProfile *self)
292+
{
293+
TVHCodec *codec = tvh_codec_profile_get_codec(self);
294+
if (codec && tvh_codec_is_enabled(codec) &&
295+
tvh_codec_get_type(codec) == AVMEDIA_TYPE_VIDEO) {
296+
return ((TVHVideoCodecProfile *)self)->hwaccel_details;
297+
}
298+
return -1;
299+
}
300+
289301
const enum AVPixelFormat *
290302
tvh_codec_profile_video_get_pix_fmts(TVHCodecProfile *self)
291303
{

src/transcoding/codec/profile_video_class.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,25 @@ scaling_mode_get_list( void *o, const char *lang )
3333
return strtab2htsmsg(tab, 1, lang);
3434
}
3535

36+
static htsmsg_t *
37+
hwaccel_get_list( void *o, const char *lang )
38+
{
39+
static const struct strtab tab[] = {
40+
{ N_("auto (recommended)"), HWACCEL_AUTO},
41+
#if ENABLE_VAAPI
42+
{ N_("prioritize VAAPI"), HWACCEL_PRIORITIZE_VAAPI},
43+
#endif
44+
#if ENABLE_NVENC
45+
{ N_("prioritize NVDEC"), HWACCEL_PRIORITIZE_NVDEC},
46+
#endif
47+
#if ENABLE_MMAL
48+
{ N_("prioritize MMAL"), HWACCEL_PRIORITIZE_MMAL},
49+
#endif
50+
};
51+
return strtab2htsmsg(tab, 1, lang);
52+
}
53+
54+
3655
/* TVHCodec ================================================================= */
3756

3857
static htsmsg_t *
@@ -215,6 +234,16 @@ const codec_profile_class_t codec_profile_video_class = {
215234
.off = offsetof(TVHVideoCodecProfile, hwaccel),
216235
.def.i = 0,
217236
},
237+
{
238+
.type = PT_INT,
239+
.id = "hwaccel_details",
240+
.name = N_("Hardware acceleration details"),
241+
.desc = N_("Force hardware acceleration."),
242+
.group = 2,
243+
.off = offsetof(TVHVideoCodecProfile, hwaccel_details),
244+
.list = hwaccel_get_list,
245+
.def.i = 0,
246+
},
218247
{
219248
.type = PT_INT,
220249
.id = "pix_fmt",

src/transcoding/transcode/stream.c

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,26 @@ tvh_stream_setup(TVHStream *self, TVHCodecProfile *profile, tvh_ssc_t *ssc)
5757
{
5858
enum AVCodecID icodec_id = streaming_component_type2codec_id(ssc->es_type);
5959
const AVCodec *icodec = NULL, *ocodec = NULL;
60+
int hwaccel = -1;
61+
int hwaccel_details = -1;
6062

6163
if (icodec_id == AV_CODEC_ID_NONE) {
6264
tvh_stream_log(self, LOG_ERR, "unknown decoder id for '%s'",
6365
streaming_component_type2txt(ssc->es_type));
6466
return -1;
6567
}
68+
if ((hwaccel = tvh_codec_profile_video_get_hwaccel(profile)) < 0) {
69+
return -1;
70+
}
71+
if ((hwaccel_details = tvh_codec_profile_video_get_hwaccel_details(profile)) < 0) {
72+
return -1;
73+
}
6674
#if ENABLE_MMAL
6775
if (idnode_is_instance(&profile->idnode,
6876
(idclass_t *)&codec_profile_video_class)) {
69-
if (tvh_codec_profile_video_get_hwaccel(profile) > 0) {
77+
if (hwaccel &&
78+
((hwaccel_details == HWACCEL_AUTO && strstr(profile->codec_name, "mmal")) ||
79+
hwaccel_details == HWACCEL_PRIORITIZE_MMAL)) {
7080
if (icodec_id == AV_CODEC_ID_H264) {
7181
icodec = avcodec_find_decoder_by_name("h264_mmal");
7282
} else if (icodec_id == AV_CODEC_ID_MPEG2VIDEO) {
@@ -76,16 +86,40 @@ tvh_stream_setup(TVHStream *self, TVHCodecProfile *profile, tvh_ssc_t *ssc)
7686
}
7787
#endif
7888
#if ENABLE_NVENC
79-
if (idnode_is_instance(&profile->idnode,
89+
if (!icodec && idnode_is_instance(&profile->idnode,
8090
(idclass_t *)&codec_profile_video_class)) {
81-
if (tvh_codec_profile_video_get_hwaccel(profile) > 0) {
91+
if (hwaccel &&
92+
((hwaccel_details == HWACCEL_AUTO && strstr(profile->codec_name, "nvenc")) ||
93+
hwaccel_details == HWACCEL_PRIORITIZE_NVDEC)) {
94+
// https://developer.nvidia.com/video-codec-sdk
8295
if (icodec_id == AV_CODEC_ID_H264) {
8396
icodec = avcodec_find_decoder_by_name("h264_cuvid");
8497
} else if (icodec_id == AV_CODEC_ID_HEVC) {
8598
icodec = avcodec_find_decoder_by_name("hevc_cuvid");
8699
}
87100
}
88101
}
102+
#endif
103+
#if ENABLE_VAAPI
104+
if (!icodec && idnode_is_instance(&profile->idnode,
105+
(idclass_t *)&codec_profile_video_class)) {
106+
if (hwaccel &&
107+
(hwaccel_details == HWACCEL_PRIORITIZE_VAAPI)) {
108+
if (icodec_id == AV_CODEC_ID_MPEG2VIDEO) {
109+
icodec = avcodec_find_decoder_by_name("mpeg2_vaapi");
110+
} else if (icodec_id == AV_CODEC_ID_H264) {
111+
icodec = avcodec_find_decoder_by_name("h264_vaapi");
112+
} else if (icodec_id == AV_CODEC_ID_HEVC) {
113+
icodec = avcodec_find_decoder_by_name("hevc_vaapi");
114+
} else if (icodec_id == AV_CODEC_ID_VP9) {
115+
icodec = avcodec_find_decoder_by_name("vp9_vaapi");
116+
} else if (icodec_id == AV_CODEC_ID_VP8) {
117+
icodec = avcodec_find_decoder_by_name("vp8_vaapi");
118+
}else if (icodec_id == AV_CODEC_ID_MJPEG) {
119+
icodec = avcodec_find_decoder_by_name("mjpeg_vaapi");
120+
}
121+
}
122+
}
89123
#endif
90124
if (!icodec && !(icodec = avcodec_find_decoder(icodec_id))) {
91125
tvh_stream_log(self, LOG_ERR, "failed to find decoder for '%s'",

0 commit comments

Comments
 (0)