libheif-rs icon indicating copy to clipboard operation
libheif-rs copied to clipboard

How do i make this work for HEVC compression?

Open markg85 opened this issue 1 year ago • 6 comments

Hi,

use libheif_rs::{
    Channel, ColorSpace, CompressionFormat, EncoderQuality, HeifContext, Image, LibHeif, Result,
    RgbChroma,
};
use tempfile::NamedTempFile;

fn main() -> Result<()> {
    let width = 640;
    let height = 480;

    let mut image = Image::new(width, height, ColorSpace::Rgb(RgbChroma::C444))?;

    image.create_plane(Channel::R, width, height, 8)?;
    image.create_plane(Channel::G, width, height, 8)?;
    image.create_plane(Channel::B, width, height, 8)?;

    let planes = image.planes_mut();
    let plane_r = planes.r.unwrap();
    let stride = plane_r.stride;

    let data_r = plane_r.data;
    let data_g = planes.g.unwrap().data;
    let data_b = planes.b.unwrap().data;

    // Fill data of planes by some "pixels"
    for y in 0..height {
        let mut pixel_index = stride * y as usize;
        for x in 0..width {
            let color = ((x * y) as u32).to_le_bytes();
            data_r[pixel_index] = color[0];
            data_g[pixel_index] = color[1];
            data_b[pixel_index] = color[2];
            pixel_index += 1;
        }
    }

    // Encode image and save it into file.
    let lib_heif = LibHeif::new();
    let mut context = HeifContext::new()?;
    let mut encoder = lib_heif.encoder_for_format(CompressionFormat::Av1)?;
    encoder.set_quality(EncoderQuality::LossLess)?;
    context.encode_image(&image, &mut encoder, None)?;

    let tmp_file = NamedTempFile::new().unwrap();
    let path = "/home/mark/GitProjects/fih_rust/foo.heic";
    let _ = tmp_file.persist(&path);
    context.write_to_file(&path)?;

    Ok(())
}

I just changed the last few lines to save the file somewhere. Change the path accordingly, obviously.

This code as-is works on my pc. However, i want to save the image as HEVC compression. When i change: let mut encoder = lib_heif.encoder_for_format(CompressionFormat::Av1)?;

to: let mut encoder = lib_heif.encoder_for_format(CompressionFormat::Hevc)?;

Then i get a segmentation fault. Any idea what i'm doing wrong here?

markg85 avatar Mar 05 '25 00:03 markg85

Do you have libde265-dev installed?

Cykooz avatar Mar 05 '25 06:03 Cykooz

Yes. Arch linux user here:

extra/libde265 1.0.15-3 (269.5 KiB 784.4 KiB) (Installed)
    Open h.265 video codec implementation

Also, ldd doesn't show anything weird either.

	linux-vdso.so.1 (0x000070d53f052000)
	libssl.so.3 => /usr/lib/libssl.so.3 (0x000070d53bd24000)
	libcrypto.so.3 => /usr/lib/libcrypto.so.3 (0x000070d53b800000)
	libde265.so.0 => /usr/lib/libde265.so.0 (0x000070d53b77c000)
	libx265.so.212 => /usr/lib/libx265.so.212 (0x000070d53a400000)
	libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0x000070d53a000000)
	libgcc_s.so.1 => /usr/lib/libgcc_s.so.1 (0x000070d53bcf6000)
	libaom.so.3 => /usr/lib/libaom.so.3 (0x000070d539600000)
	libsharpyuv.so.0 => /usr/lib/libsharpyuv.so.0 (0x000070d53eff6000)
	libm.so.6 => /usr/lib/libm.so.6 (0x000070d53a308000)
	libdav1d.so.7 => /usr/lib/libdav1d.so.7 (0x000070d53941e000)
	libc.so.6 => /usr/lib/libc.so.6 (0x000070d53922c000)
	/lib64/ld-linux-x86-64.so.2 => /usr/lib64/ld-linux-x86-64.so.2 (0x000070d53f054000)
	libmvec.so.1 => /usr/lib/libmvec.so.1 (0x000070d539f08000)

markg85 avatar Mar 05 '25 13:03 markg85

❯ heif-enc --list-encoders
AVC encoders:
AVIF encoders:
- aom = AOMedia Project AV1 Encoder v3.12.0 [default]
- svt = SVT-AV1 encoder v2.3.0-dirty
- rav1e = Rav1e encoder
HEIC encoders:
- x265 = x265 HEVC encoder (4.0) [default]
JPEG encoders:
JPEG 2000 encoders:
JPEG 2000 (HT) encoders:
Uncompressed encoders:
VVIC encoders:

I don't see libde265 in there though. Is that good or bad?

Probably irrelevant. Note that the package is installed with libde265 as dependency requirement to begin with: https://gitlab.archlinux.org/archlinux/packaging/packages/libheif/-/blob/main/PKGBUILD?ref_type=heads so libheif should be good.

Also, i just tried heif-enc to create a hevc encoded image, that does work!

markg85 avatar Mar 05 '25 16:03 markg85

"A segmentation fault" is quite vague result. I don't have any ideas about this error. Do you have some additional information about it?

PS: I don't have such issue on Ubuntu 24.04.

Cykooz avatar Mar 05 '25 17:03 Cykooz

I know it's vague. I'm a developer and would find that useless too ;) What i don't know, you might though, is how to get you more detailed information that you might find more helpful?

Right now my output is literally just that, segmentation fault. Surely there is a way to get a useful callstack out of this?

markg85 avatar Mar 05 '25 18:03 markg85

I can only assume that the error isn't in the Rust-code. I think that the Rust-code should panic instead of falling with a segmentation fault.

Cykooz avatar Mar 05 '25 19:03 Cykooz