fix(server): use hw decoding for rkmpp w/o OpenCL if possible (#13848)

* Set hardware decoding options for rkmpp when hardware decoding is enabled with no OpenCL on non-HDR file

* Use hw decoding, sw tone-mapping on HDR files using RKMPP w/o OpenCL

* fallback to software decoding if is hdr video

* if hw decoding failed with hw dec config enabled, try sw dec+hw enc first, then full sw dec+enc

* fix unit test

* fix format, adjust log message

* formatting

---------

Co-authored-by: mertalev <101130780+mertalev@users.noreply.github.com>
This commit is contained in:
San 2024-11-22 16:08:49 +08:00 committed by GitHub
parent 1935b88d13
commit 1c82804f63
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 81 additions and 21 deletions

View file

@ -59,10 +59,9 @@ export class BaseConfig implements VideoCodecSWConfig {
break;
}
case TranscodeHWAccel.RKMPP: {
handler =
config.accelDecode && hasMaliOpenCL
? new RkmppHwDecodeConfig(config, devices)
: new RkmppSwDecodeConfig(config, devices);
handler = config.accelDecode
? new RkmppHwDecodeConfig(config, devices, hasMaliOpenCL)
: new RkmppSwDecodeConfig(config, devices);
break;
}
default: {
@ -977,6 +976,16 @@ export class RkmppSwDecodeConfig extends BaseHWConfig {
}
export class RkmppHwDecodeConfig extends RkmppSwDecodeConfig {
protected hasMaliOpenCL: boolean;
constructor(
protected config: SystemConfigFFmpegDto,
devices: string[] = [],
hasMaliOpenCL = false,
) {
super(config, devices);
this.hasMaliOpenCL = hasMaliOpenCL;
}
getBaseInputOptions() {
if (this.devices.length === 0) {
throw new Error('No RKMPP device found');
@ -988,15 +997,26 @@ export class RkmppHwDecodeConfig extends RkmppSwDecodeConfig {
getFilterOptions(videoStream: VideoStreamInfo) {
if (this.shouldToneMap(videoStream)) {
const { primaries, transfer, matrix } = this.getColors();
if (this.hasMaliOpenCL) {
return [
// use RKMPP for scaling, OpenCL for tone mapping
`scale_rkrga=${this.getScaling(videoStream)}:format=p010:afbc=1:async_depth=4`,
'hwmap=derive_device=opencl:mode=read',
`tonemap_opencl=format=nv12:r=pc:p=${primaries}:t=${transfer}:m=${matrix}:tonemap=${this.config.tonemap}:desat=0:tonemap_mode=lum:peak=100`,
'hwmap=derive_device=rkmpp:mode=write:reverse=1',
'format=drm_prime',
];
}
return [
`scale_rkrga=${this.getScaling(videoStream)}:format=p010:afbc=1`,
'hwmap=derive_device=opencl:mode=read',
`tonemap_opencl=format=nv12:r=pc:p=${primaries}:t=${transfer}:m=${matrix}:tonemap=${this.config.tonemap}:desat=0:tonemap_mode=lum:peak=100`,
'hwmap=derive_device=rkmpp:mode=write:reverse=1',
'format=drm_prime',
// use RKMPP for scaling, CPU for tone mapping (only works on RK3588, which supports 10-bit output)
`scale_rkrga=${this.getScaling(videoStream)}:format=p010:afbc=1:async_depth=4`,
'hwdownload',
'format=p010',
`tonemapx=tonemap=${this.config.tonemap}:desat=0:p=${primaries}:t=${transfer}:m=${matrix}:r=pc:peak=100:format=yuv420p`,
'hwupload',
];
} else if (this.shouldScale(videoStream)) {
return [`scale_rkrga=${this.getScaling(videoStream)}:format=nv12:afbc=1`];
return [`scale_rkrga=${this.getScaling(videoStream)}:format=nv12:afbc=1:async_depth=4`];
}
return [];
}