mirror of
https://github.com/immich-app/immich.git
synced 2025-01-01 08:31:59 +00:00
Set hardware decoding options for rkmpp when hardware decoding is enabled with no OpenCL on non-HDR file
This commit is contained in:
parent
b9096f3e99
commit
e46db37e44
3 changed files with 49 additions and 12 deletions
|
@ -2212,6 +2212,30 @@ describe(MediaService.name, () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should set hardware decoding options for rkmpp when hardware decoding is enabled with no OpenCL on non-HDR file', async () => {
|
||||||
|
storageMock.readdir.mockResolvedValue(['renderD128']);
|
||||||
|
storageMock.stat.mockResolvedValue({ isFile: () => false, isCharacterDevice: () => false } as Stats);
|
||||||
|
mediaMock.probe.mockResolvedValue(probeStub.noAudioStreams);
|
||||||
|
systemMock.get.mockResolvedValue({
|
||||||
|
ffmpeg: { accel: TranscodeHWAccel.RKMPP, accelDecode: true, crf: 30, maxBitrate: '0' },
|
||||||
|
});
|
||||||
|
assetMock.getByIds.mockResolvedValue([assetStub.video]);
|
||||||
|
await sut.handleVideoConversion({ id: assetStub.video.id });
|
||||||
|
expect(mediaMock.transcode).toHaveBeenCalledWith(
|
||||||
|
'/original/path.ext',
|
||||||
|
'upload/encoded-video/user-id/as/se/asset-id.mp4',
|
||||||
|
expect.objectContaining({
|
||||||
|
inputOptions: expect.arrayContaining(['-hwaccel rkmpp', '-hwaccel_output_format drm_prime', '-afbc rga']),
|
||||||
|
outputOptions: expect.arrayContaining([
|
||||||
|
expect.stringContaining(
|
||||||
|
'scale_rkrga=-2:720:format=nv12:afbc=1',
|
||||||
|
),
|
||||||
|
]),
|
||||||
|
twoPass: false,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
it('should use software decoding and tone-mapping if hardware decoding is disabled', async () => {
|
it('should use software decoding and tone-mapping if hardware decoding is disabled', async () => {
|
||||||
storageMock.readdir.mockResolvedValue(['renderD128']);
|
storageMock.readdir.mockResolvedValue(['renderD128']);
|
||||||
storageMock.stat.mockResolvedValue({ isFile: () => true, isCharacterDevice: () => true } as Stats);
|
storageMock.stat.mockResolvedValue({ isFile: () => true, isCharacterDevice: () => true } as Stats);
|
||||||
|
|
|
@ -502,7 +502,7 @@ export class MediaService extends BaseService {
|
||||||
const maliDeviceStat = await this.storageRepository.stat('/dev/mali0');
|
const maliDeviceStat = await this.storageRepository.stat('/dev/mali0');
|
||||||
this.maliOpenCL = maliIcdStat.isFile() && maliDeviceStat.isCharacterDevice();
|
this.maliOpenCL = maliIcdStat.isFile() && maliDeviceStat.isCharacterDevice();
|
||||||
} catch {
|
} catch {
|
||||||
this.logger.debug('OpenCL not available for transcoding, so RKMPP acceleration will use CPU decoding');
|
this.logger.debug('OpenCL not available for transcoding, so RKMPP acceleration will use CPU tonemapping');
|
||||||
this.maliOpenCL = false;
|
this.maliOpenCL = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,9 +58,8 @@ export class BaseConfig implements VideoCodecSWConfig {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case TranscodeHWAccel.RKMPP: {
|
case TranscodeHWAccel.RKMPP: {
|
||||||
handler =
|
handler = config.accelDecode
|
||||||
config.accelDecode && hasMaliOpenCL
|
? new RkmppHwDecodeConfig(config, devices, hasMaliOpenCL)
|
||||||
? new RkmppHwDecodeConfig(config, devices)
|
|
||||||
: new RkmppSwDecodeConfig(config, devices);
|
: new RkmppSwDecodeConfig(config, devices);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -968,6 +967,16 @@ export class RkmppSwDecodeConfig extends BaseHWConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
export class RkmppHwDecodeConfig extends RkmppSwDecodeConfig {
|
export class RkmppHwDecodeConfig extends RkmppSwDecodeConfig {
|
||||||
|
protected hasMaliOpenCL: boolean;
|
||||||
|
constructor(
|
||||||
|
protected config: SystemConfigFFmpegDto,
|
||||||
|
devices: string[] = [],
|
||||||
|
hasMaliOpenCL = false,
|
||||||
|
) {
|
||||||
|
super(config, devices);
|
||||||
|
this.hasMaliOpenCL = hasMaliOpenCL;
|
||||||
|
}
|
||||||
|
|
||||||
getBaseInputOptions() {
|
getBaseInputOptions() {
|
||||||
if (this.devices.length === 0) {
|
if (this.devices.length === 0) {
|
||||||
throw new Error('No RKMPP device found');
|
throw new Error('No RKMPP device found');
|
||||||
|
@ -978,14 +987,18 @@ export class RkmppHwDecodeConfig extends RkmppSwDecodeConfig {
|
||||||
|
|
||||||
getFilterOptions(videoStream: VideoStreamInfo) {
|
getFilterOptions(videoStream: VideoStreamInfo) {
|
||||||
if (this.shouldToneMap(videoStream)) {
|
if (this.shouldToneMap(videoStream)) {
|
||||||
const { primaries, transfer, matrix } = this.getColors();
|
if (this.hasMaliOpenCL) {
|
||||||
return [
|
const { primaries, transfer, matrix } = this.getColors();
|
||||||
`scale_rkrga=${this.getScaling(videoStream)}:format=p010:afbc=1`,
|
return [
|
||||||
'hwmap=derive_device=opencl:mode=read',
|
`scale_rkrga=${this.getScaling(videoStream)}:format=p010:afbc=1`,
|
||||||
`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=opencl:mode=read',
|
||||||
'hwmap=derive_device=rkmpp:mode=write:reverse=1',
|
`tonemap_opencl=format=nv12:r=pc:p=${primaries}:t=${transfer}:m=${matrix}:tonemap=${this.config.tonemap}:desat=0:tonemap_mode=lum:peak=100`,
|
||||||
'format=drm_prime',
|
'hwmap=derive_device=rkmpp:mode=write:reverse=1',
|
||||||
];
|
'format=drm_prime',
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
return super.getFilterOptions(videoStream);
|
||||||
|
}
|
||||||
} else if (this.shouldScale(videoStream)) {
|
} 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`];
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue