bytedeco / javacv

Java interface to OpenCV, FFmpeg, and more
Other
7.6k stars 1.59k forks source link

Could not get pixel format for color format 'bgra' range 'unknown'. #2209

Open LouisCAD opened 8 months ago

LouisCAD commented 8 months ago

Hello!

I'm trying to record an HEVC video with transparency/alpha channel.

I tried recording with VP9 & YUVA420P, it works fine, but with HEVC & BGRA, it leads to the error below:

[hevc_videotoolbox @ 0x15182bc50] Could not get pixel format for color format 'bgra' range 'unknown'.
Exception in thread "main" org.bytedeco.javacv.FFmpegFrameRecorder$Exception: avcodec_open2() error -22: Could not open video codec. (For more details, make sure FFmpegLogCallback.set() has been called.)
        at org.bytedeco.javacv.FFmpegFrameRecorder.startUnsafe(FFmpegFrameRecorder.java:791)
        at org.bytedeco.javacv.FFmpegFrameRecorder.start(FFmpegFrameRecorder.java:437)
        at louiscad.ComposeToVideoKt.recordComposable-vZmvyCw(ComposeToVideo.kt:100)

Here's what I'm setting in the code prior to calling start() on the FFmpegFrameRecorder:

frameRecorder.also {
    it.format = "mov"
    it.videoCodec = avcodec.AV_CODEC_ID_HEVC
    it.pixelFormat = avutil.AV_PIX_FMT_BGRA
}

Am I missing something? Is JavaCv failing to set something that ffmpeg needs?

With the following command, I'm able to convert my VP9 video to HEVC, but this extra step is very costly when I need to record long videos.

ffmpeg -c:v libvpx-vp9 -i input.webm -c:v hevc_videotoolbox -allow_sw 1 -alpha_quality 0.75 -vtag hvc1 -movflags +faststart output1.mov

I hope someone can help. Thank you in advance, and have a nice day!

saudet commented 8 months ago

That just means the codec doesn't support BGRA. Just keep using YUVA420P...

LouisCAD commented 8 months ago

The (working) ffmpeg command I shown above, plus the error I get if I ever try to use YUVA420P for HEVC proves that BGRA is supported, and that's the only pixel format that has an alpha channel, for HEVC:

[hevc_videotoolbox @ 0x123b0e8a0] Specified pixel format yuva420p is not supported by the hevc_videotoolbox encoder.
[hevc_videotoolbox @ 0x123b0e8a0] Supported pixel formats:
[hevc_videotoolbox @ 0x123b0e8a0]   videotoolbox_vld
[hevc_videotoolbox @ 0x123b0e8a0]   nv12
[hevc_videotoolbox @ 0x123b0e8a0]   yuv420p
[hevc_videotoolbox @ 0x123b0e8a0]   bgra
[hevc_videotoolbox @ 0x123b0e8a0]   p010le

Can you have another look?

LouisCAD commented 8 months ago

Just for full clarity:

Just keep using YUVA420P...

YUVA420P has never worked for HEVC, as the error message above suggests. YUV420P (no alpha channel) is supported, but YUVA420P (with alpha channel) is not.

saudet commented 8 months ago

Sounds like a bug in that codec

LouisCAD commented 8 months ago

Regarding the ffmpeg shell command I shown, do the provided options have an equivalent in JavaCV?

ffmpeg -c:v libvpx-vp9 -i input.webm -c:v hevc_videotoolbox -allow_sw 1 -alpha_quality 0.75 -vtag hvc1 -movflags +faststart output1.mov

saudet commented 8 months ago

We can easily accomplish this with the ffmpeg program: http://bytedeco.org/javacpp-presets/ffmpeg/apidocs/org/bytedeco/ffmpeg/ffmpeg.html

LouisCAD commented 8 months ago

How am I supposed to use that in conjunction with FFmpegFrameRecorder?

LouisCAD commented 8 months ago

Currently, I'm creating it with:

FFmpegFrameRecorder.createDefault(output, size.width, size.height)
saudet commented 8 months ago

It looks like we need to set the range somehow to either MPEG or JPEG: