From 6d04eb97cd4f24515df6a58d16c37a216c9a1f85 Mon Sep 17 00:00:00 2001 From: adamroach Date: Sat, 5 Mar 2022 00:43:21 -0600 Subject: [PATCH] Fixing Stride Handling for OpenH264 The golang image.YCbCr struct can contain fields of arbitrary stride lengths, which don't necessarily match the field widths. This patch passes the stride values from the image.YCbCr struct into the OpenH264 encode calls. --- pkg/codec/openh264/bridge.cpp | 5 ++--- pkg/codec/openh264/bridge.hpp | 2 ++ pkg/codec/openh264/openh264.go | 12 +++++++----- 3 files changed, 11 insertions(+), 8 deletions(-) diff --git a/pkg/codec/openh264/bridge.cpp b/pkg/codec/openh264/bridge.cpp index 82438dc3..c6c64a9d 100644 --- a/pkg/codec/openh264/bridge.cpp +++ b/pkg/codec/openh264/bridge.cpp @@ -88,9 +88,8 @@ Slice enc_encode(Encoder *e, Frame f, int *eresult) { pic.iPicWidth = f.width; pic.iPicHeight = f.height; pic.iColorFormat = videoFormatI420; - // We always received I420 format - pic.iStride[0] = pic.iPicWidth; - pic.iStride[1] = pic.iStride[2] = pic.iPicWidth / 2; + pic.iStride[0] = f.ystride; + pic.iStride[1] = pic.iStride[2] = f.cstride; pic.pData[0] = (unsigned char *)f.y; pic.pData[1] = (unsigned char *)f.u; pic.pData[2] = (unsigned char *)f.v; diff --git a/pkg/codec/openh264/bridge.hpp b/pkg/codec/openh264/bridge.hpp index 874f06e6..982ca927 100644 --- a/pkg/codec/openh264/bridge.hpp +++ b/pkg/codec/openh264/bridge.hpp @@ -12,6 +12,8 @@ typedef struct Slice { typedef struct Frame { void *y, *u, *v; + int ystride; + int cstride; int height; int width; } Frame; diff --git a/pkg/codec/openh264/openh264.go b/pkg/codec/openh264/openh264.go index ccfa9abd..f778cd06 100644 --- a/pkg/codec/openh264/openh264.go +++ b/pkg/codec/openh264/openh264.go @@ -65,11 +65,13 @@ func (e *encoder) Read() ([]byte, func(), error) { bounds := yuvImg.Bounds() var rv C.int s := C.enc_encode(e.engine, C.Frame{ - y: unsafe.Pointer(&yuvImg.Y[0]), - u: unsafe.Pointer(&yuvImg.Cb[0]), - v: unsafe.Pointer(&yuvImg.Cr[0]), - height: C.int(bounds.Max.Y - bounds.Min.Y), - width: C.int(bounds.Max.X - bounds.Min.X), + y: unsafe.Pointer(&yuvImg.Y[0]), + u: unsafe.Pointer(&yuvImg.Cb[0]), + v: unsafe.Pointer(&yuvImg.Cr[0]), + ystride: C.int(yuvImg.YStride), + cstride: C.int(yuvImg.CStride), + height: C.int(bounds.Max.Y - bounds.Min.Y), + width: C.int(bounds.Max.X - bounds.Min.X), }, &rv) if err := errResult(rv); err != nil { return nil, func() {}, fmt.Errorf("failed in encoding: %v", err)