mattdesl / mp4-h264

[project suspended] MP4 + H264 encoding for the browser with WASM
MIT License
223 stars 12 forks source link

A way to encode the video vertically flipped? #2

Closed mourner closed 3 years ago

mourner commented 3 years ago

I'm using gl.readPixels(..., encoder.memory().subarray(ptr)) encode frames directly from an existing GL context, but the videos come out vertically flipped, and I haven't found any way to solve this on the GL side — for now I'm just flipping the videos in ffmpeg locally.

I could add a utility function to manually flip RGBA values in the memory buffer after each read, but this seems wasteful — anything that could be done on the encoder side to support this use case?

mattdesl commented 3 years ago

Good call. This is common enough coming from WebGL that it could probably be added to the C/C++ code during RGB -> YUV conversion, I doubt it will have any real performance overhead as we're already scanning through pixels there.

I've added this flag in 1.0.6, still undocumented, which you could try and let me know:

Encoder.create({
  ...
  // flips input RGB image on Y axis
  // only affects encodeRGB / encodeRGBPointer functions
  rgbFlipY: true
});

It's a bit weird that the option isn't there for YUV data... 🤷‍♂️

mourner commented 3 years ago

This works great for me, thanks so much!

Just for the record, here's the code I used to flip on the JS side and it was a pretty small (~1ms) overhead compared to both the reading and the encoding part:

for (let y = 0, row = width * 4, temp = new Uint8Array(width * 4); y < height / 2; y++) {
    const top = y * row;
    const bottom = (height - y - 1) * row;
    temp.set(pixels.subarray(top, top + row));
    pixels.copyWithin(top, bottom, bottom + row);
    pixels.set(temp, bottom);
}