From 5e485e35e977de105e89e88b228256b24ae423db Mon Sep 17 00:00:00 2001 From: Fynn Petersen-Frey <10599762+fyfrey@users.noreply.github.com> Date: Tue, 27 Feb 2024 16:47:04 +0100 Subject: [PATCH] feat(server): easy RKMPP video encoding (#7460) * feat(server): easy RKMPP video encoding * make linter happy --- docker/hwaccel.transcoding.yml | 6 ---- server/src/domain/media/media.service.spec.ts | 19 +++-------- server/src/domain/media/media.util.ts | 33 +++---------------- .../domain/repositories/media.repository.ts | 2 -- .../infra/repositories/media.repository.ts | 14 +------- 5 files changed, 11 insertions(+), 63 deletions(-) diff --git a/docker/hwaccel.transcoding.yml b/docker/hwaccel.transcoding.yml index f5585d815a..2f6ae3ebde 100644 --- a/docker/hwaccel.transcoding.yml +++ b/docker/hwaccel.transcoding.yml @@ -38,12 +38,6 @@ services: - /dev/dri:/dev/dri - /dev/dma_heap:/dev/dma_heap - /dev/mpp_service:/dev/mpp_service - volumes: - - /usr/bin/ffmpeg:/usr/bin/ffmpeg_mpp:ro - - /lib/aarch64-linux-gnu:/lib/ffmpeg-mpp:ro - - /lib/aarch64-linux-gnu/libblas.so.3:/lib/ffmpeg-mpp/libblas.so.3:ro # symlink is resolved by mounting - - /lib/aarch64-linux-gnu/liblapack.so.3:/lib/ffmpeg-mpp/liblapack.so.3:ro # symlink is resolved by mounting - - /lib/aarch64-linux-gnu/pulseaudio/libpulsecommon-15.99.so:/lib/ffmpeg-mpp/libpulsecommon-15.99.so:ro vaapi: devices: diff --git a/server/src/domain/media/media.service.spec.ts b/server/src/domain/media/media.service.spec.ts index f4c9aa53e7..dc5934e7b1 100644 --- a/server/src/domain/media/media.service.spec.ts +++ b/server/src/domain/media/media.service.spec.ts @@ -1801,7 +1801,7 @@ describe(MediaService.name, () => { { inputOptions: [], outputOptions: [ - `-c:v hevc_rkmpp_encoder`, + `-c:v hevc_rkmpp`, '-c:a copy', '-movflags faststart', '-fps_mode passthrough', @@ -1810,17 +1810,12 @@ describe(MediaService.name, () => { '-g 256', '-tag:v hvc1', '-v verbose', + '-vf scale=-2:720,format=yuv420p', '-level 153', '-rc_mode 3', - '-quality_min 0', - '-quality_max 100', '-b:v 10000k', - '-width 1280', - '-height 720', ], twoPass: false, - ffmpegPath: 'ffmpeg_mpp', - ldLibraryPath: '/lib/aarch64-linux-gnu:/lib/ffmpeg-mpp', }, ); }); @@ -1841,7 +1836,7 @@ describe(MediaService.name, () => { { inputOptions: [], outputOptions: [ - `-c:v h264_rkmpp_encoder`, + `-c:v h264_rkmpp`, '-c:a copy', '-movflags faststart', '-fps_mode passthrough', @@ -1849,16 +1844,12 @@ describe(MediaService.name, () => { '-map 0:1', '-g 256', '-v verbose', + '-vf scale=-2:720,format=yuv420p', '-level 51', '-rc_mode 2', - '-quality_min 51', - '-quality_max 51', - '-width 1280', - '-height 720', + '-qp_init 30', ], twoPass: false, - ffmpegPath: 'ffmpeg_mpp', - ldLibraryPath: '/lib/aarch64-linux-gnu:/lib/ffmpeg-mpp', }, ); }); diff --git a/server/src/domain/media/media.util.ts b/server/src/domain/media/media.util.ts index c9483c3736..e5890bdd03 100644 --- a/server/src/domain/media/media.util.ts +++ b/server/src/domain/media/media.util.ts @@ -607,16 +607,6 @@ export class VAAPIConfig extends BaseHWConfig { } export class RKMPPConfig extends BaseHWConfig { - getOptions(target: TranscodeTarget, videoStream: VideoStreamInfo, audioStream?: AudioStreamInfo): TranscodeOptions { - const options = super.getOptions(target, videoStream, audioStream); - options.ffmpegPath = 'ffmpeg_mpp'; - options.ldLibraryPath = '/lib/aarch64-linux-gnu:/lib/ffmpeg-mpp'; - if ([TranscodeTarget.ALL, TranscodeTarget.VIDEO].includes(target)) { - options.outputOptions.push(...this.getSizeOptions(videoStream)); - } - return options; - } - eligibleForTwoPass(): boolean { return false; } @@ -628,18 +618,6 @@ export class RKMPPConfig extends BaseHWConfig { return []; } - getFilterOptions(videoStream: VideoStreamInfo) { - return this.shouldToneMap(videoStream) ? this.getToneMapping() : []; - } - - getSizeOptions(videoStream: VideoStreamInfo) { - if (this.shouldScale(videoStream)) { - const { width, height } = this.getSize(videoStream); - return [`-width ${width}`, `-height ${height}`]; - } - return []; - } - getPresetOptions() { switch (this.config.targetVideoCodec) { case VideoCodec.H264: { @@ -659,12 +637,11 @@ export class RKMPPConfig extends BaseHWConfig { getBitrateOptions() { const bitrate = this.getMaxBitrateValue(); if (bitrate > 0) { - return ['-rc_mode 3', '-quality_min 0', '-quality_max 100', `-b:v ${bitrate}${this.getBitrateUnit()}`]; - } else { - // convert CQP from 51-10 to 0-100, values below 10 are set to 10 - const quality = Math.floor(125 - Math.max(this.config.crf, 10) * (125 / 51)); - return ['-rc_mode 2', `-quality_min ${quality}`, `-quality_max ${quality}`]; + // -b:v specifies max bitrate, average bitrate is derived automatically... + return ['-rc_mode 3', `-b:v ${bitrate}${this.getBitrateUnit()}`]; } + // use CRF value as QP value + return ['-rc_mode 2', `-qp_init ${this.config.crf}`]; } getSupportedCodecs() { @@ -672,6 +649,6 @@ export class RKMPPConfig extends BaseHWConfig { } getVideoCodec(): string { - return `${this.config.targetVideoCodec}_rkmpp_encoder`; + return `${this.config.targetVideoCodec}_rkmpp`; } } diff --git a/server/src/domain/repositories/media.repository.ts b/server/src/domain/repositories/media.repository.ts index 846b6156d6..ed6f884493 100644 --- a/server/src/domain/repositories/media.repository.ts +++ b/server/src/domain/repositories/media.repository.ts @@ -51,8 +51,6 @@ export interface TranscodeOptions { inputOptions: string[]; outputOptions: string[]; twoPass: boolean; - ffmpegPath?: string; - ldLibraryPath?: string; } export interface BitrateDistribution { diff --git a/server/src/infra/repositories/media.repository.ts b/server/src/infra/repositories/media.repository.ts index a981bbc072..1f9395ff21 100644 --- a/server/src/infra/repositories/media.repository.ts +++ b/server/src/infra/repositories/media.repository.ts @@ -76,18 +76,7 @@ export class MediaRepository implements IMediaRepository { transcode(input: string, output: string | Writable, options: TranscodeOptions): Promise { if (!options.twoPass) { return new Promise((resolve, reject) => { - const oldLdLibraryPath = process.env.LD_LIBRARY_PATH; - if (options.ldLibraryPath) { - // fluent ffmpeg does not allow to set environment variables, so we do it manually - process.env.LD_LIBRARY_PATH = this.chainPath(oldLdLibraryPath || '', options.ldLibraryPath); - } - try { - this.configureFfmpegCall(input, output, options).on('error', reject).on('end', resolve).run(); - } finally { - if (options.ldLibraryPath) { - process.env.LD_LIBRARY_PATH = oldLdLibraryPath; - } - } + this.configureFfmpegCall(input, output, options).on('error', reject).on('end', resolve).run(); }); } @@ -121,7 +110,6 @@ export class MediaRepository implements IMediaRepository { configureFfmpegCall(input: string, output: string | Writable, options: TranscodeOptions) { return ffmpeg(input, { niceness: 10 }) - .setFfmpegPath(options.ffmpegPath || 'ffmpeg') .inputOptions(options.inputOptions) .outputOptions(options.outputOptions) .output(output)