mirror of
https://github.com/chrisbenincasa/tunarr.git
synced 2026-04-18 09:03:35 -04:00
fix(streaming): fix nvidia hwdownload compat with ffmpeg 7.2
Closes #1252
This commit is contained in:
@@ -51,4 +51,26 @@ describe('ScaleCudaFilter', () => {
|
||||
new PixelFormatP010(),
|
||||
);
|
||||
});
|
||||
|
||||
test('format only, 10-bit, passthrough', () => {
|
||||
const currentState = new FrameState({
|
||||
isAnamorphic: false,
|
||||
paddedSize: FrameSize.withDimensions(1920, 1080),
|
||||
scaledSize: FrameSize.withDimensions(1920, 1080),
|
||||
frameDataLocation: FrameDataLocation.Hardware,
|
||||
pixelFormat: new PixelFormatYuv420P10Le(),
|
||||
});
|
||||
|
||||
// sizes are equal
|
||||
const filter = ScaleCudaFilter.formatOnly(
|
||||
currentState,
|
||||
new PixelFormatP010(),
|
||||
true,
|
||||
);
|
||||
|
||||
expect(filter.filter).to.eq('scale_cuda=format=p010:passthrough=1');
|
||||
expect(filter.nextState(currentState).pixelFormat).toMatchPixelFormat(
|
||||
new PixelFormatP010(),
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -25,16 +25,22 @@ export class ScaleCudaFilter extends FilterOption {
|
||||
private currentState: FrameState,
|
||||
private scaledSize: FrameSize,
|
||||
private paddedSize: FrameSize,
|
||||
private passthrough: boolean = false,
|
||||
) {
|
||||
super();
|
||||
this.filter = this.generateFilter();
|
||||
}
|
||||
|
||||
static formatOnly(currentState: FrameState, targetPixelFormat: PixelFormat) {
|
||||
static formatOnly(
|
||||
currentState: FrameState,
|
||||
targetPixelFormat: PixelFormat,
|
||||
passthrough: boolean = false,
|
||||
) {
|
||||
return new ScaleCudaFilter(
|
||||
currentState.update({ pixelFormat: targetPixelFormat }),
|
||||
currentState.scaledSize,
|
||||
currentState.paddedSize,
|
||||
passthrough,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -63,7 +69,8 @@ export class ScaleCudaFilter extends FilterOption {
|
||||
if (this.currentState.scaledSize.equals(this.scaledSize)) {
|
||||
const targetPixelFormat = this.supportedPixelFormat;
|
||||
if (targetPixelFormat) {
|
||||
scale = `${this.filterName}=format=${targetPixelFormat.name}`;
|
||||
const passthrough = this.passthrough ? ':passthrough=1' : '';
|
||||
scale = `${this.filterName}=format=${targetPixelFormat.name}${passthrough}`;
|
||||
}
|
||||
} else {
|
||||
let aspectRatio = '';
|
||||
|
||||
@@ -49,6 +49,7 @@ import { WatermarkOpacityFilter } from '../../filter/watermark/WatermarkOpacityF
|
||||
import { WatermarkScaleFilter } from '../../filter/watermark/WatermarkScaleFilter.ts';
|
||||
import {
|
||||
PixelFormatNv12,
|
||||
PixelFormatP010,
|
||||
PixelFormatYuv420P,
|
||||
PixelFormatYuv420P10Le,
|
||||
PixelFormatYuva420P,
|
||||
@@ -155,6 +156,22 @@ export class NvidiaPipelineBuilder extends SoftwarePipelineBuilder {
|
||||
currentState = this.decoder?.nextState(currentState) ?? currentState;
|
||||
this.videoInputSource.frameDataLocation = currentState.frameDataLocation;
|
||||
|
||||
// Workaround change to required pixel format from https://github.com/FFmpeg/FFmpeg/commit/30e6effff94c6f4310aa2db571917bb2952f4d9e
|
||||
// Specifically, CUDA pixel formats use 16-bit (p016) internally starting on 7.2 it seems. Preemptively convert
|
||||
// to p010 here to avoid potential hwdownload issues later in pipeline.
|
||||
if (
|
||||
this.decoder instanceof ImplicitNvidiaDecoder &&
|
||||
videoStream.bitDepth() === 10
|
||||
) {
|
||||
const filter = ScaleCudaFilter.formatOnly(
|
||||
currentState,
|
||||
new PixelFormatP010(),
|
||||
true,
|
||||
);
|
||||
currentState = filter.nextState(currentState);
|
||||
this.videoInputSource.addFilter(filter);
|
||||
}
|
||||
|
||||
currentState = this.setDeinterlace(currentState);
|
||||
currentState = this.setScale(currentState);
|
||||
currentState = this.setPad(currentState);
|
||||
|
||||
Reference in New Issue
Block a user