lieff / minih264

Minimalistic H264/SVC encoder single header library
Creative Commons Zero v1.0 Universal
535 stars 53 forks source link

apple silicon support #12

Open taylorchu opened 6 months ago

taylorchu commented 6 months ago
  1. asm version seems to have undefined types
./asm/minih264e_asm.h:33:59: error: unknown type name 'pix_t'
H264E_API(int,  h264e_transform_sub_quant_dequant, (const pix_t *inp, const pix_t *pred, int inp_stride, int mode, quant_t *q, const uint16_t *qdat))
  1. intrinsic version has errors related to incompatible type 'uint8x8_t'
In file included from ./encoder.go:3:
In file included from ./encoder.h:7:
./minih264e.h:5604:62: error: call to undeclared function 'vtbl2q_u8'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
                vst1_s16(q->qv + 0, d4 = vreinterpret_s16_u8(vtbl2q_u8(vlut, vget_low_u8(q8))));
                                                             ^
./minih264e.h:5604:62: error: passing 'int' to parameter of incompatible type 'uint8x8_t' (vector of 8 'uint8_t' values)
                vst1_s16(q->qv + 0, d4 = vreinterpret_s16_u8(vtbl2q_u8(vlut, vget_low_u8(q8))));
                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/include/arm_neon.h:27007:20: note: expanded from macro 'vst1_s16'
  int16x4_t __s1 = __p1; \
                   ^~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/include/arm_neon.h:59122:46: note: passing argument to parameter '__p0' here
__ai int16x4_t vreinterpret_s16_u8(uint8x8_t __p0) {
                                             ^
In file included from ./encoder.go:3:
In file included from ./encoder.h:7:
./minih264e.h:5605:62: error: call to undeclared function 'vtbl2q_u8'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
                vst1_s16(q->qv + 4, d5 = vreinterpret_s16_u8(vtbl2q_u8(vlut, vget_high_u8(q8))));
                                                             ^
./minih264e.h:5605:62: error: passing 'int' to parameter of incompatible type 'uint8x8_t' (vector of 8 'uint8_t' values)
                vst1_s16(q->qv + 4, d5 = vreinterpret_s16_u8(vtbl2q_u8(vlut, vget_high_u8(q8))));
                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/include/arm_neon.h:27007:20: note: expanded from macro 'vst1_s16'
  int16x4_t __s1 = __p1; \
                   ^~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/include/arm_neon.h:59122:46: note: passing argument to parameter '__p0' here
__ai int16x4_t vreinterpret_s16_u8(uint8x8_t __p0) {
                                             ^
In file included from ./encoder.go:3:
In file included from ./encoder.h:7:
./minih264e.h:5606:62: error: call to undeclared function 'vtbl2q_u8'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
                vst1_s16(q->qv + 8, d6 = vreinterpret_s16_u8(vtbl2q_u8(vlut, vget_low_u8(q9))));
                                                             ^
./minih264e.h:5606:62: error: passing 'int' to parameter of incompatible type 'uint8x8_t' (vector of 8 'uint8_t' values)
                vst1_s16(q->qv + 8, d6 = vreinterpret_s16_u8(vtbl2q_u8(vlut, vget_low_u8(q9))));
                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/include/arm_neon.h:27007:20: note: expanded from macro 'vst1_s16'
  int16x4_t __s1 = __p1; \
                   ^~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/include/arm_neon.h:59122:46: note: passing argument to parameter '__p0' here
__ai int16x4_t vreinterpret_s16_u8(uint8x8_t __p0) {
                                             ^
In file included from ./encoder.go:3:
In file included from ./encoder.h:7:
./minih264e.h:5607:62: error: call to undeclared function 'vtbl2q_u8'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
                vst1_s16(q->qv +12, d7 = vreinterpret_s16_u8(vtbl2q_u8(vlut, vget_high_u8(q9))));
                                                             ^
./minih264e.h:5607:62: error: passing 'int' to parameter of incompatible type 'uint8x8_t' (vector of 8 'uint8_t' values)
                vst1_s16(q->qv +12, d7 = vreinterpret_s16_u8(vtbl2q_u8(vlut, vget_high_u8(q9))));
                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/include/arm_neon.h:27007:20: note: expanded from macro 'vst1_s16'
  int16x4_t __s1 = __p1; \
                   ^~~~
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/clang/15.0.0/include/arm_neon.h:59122:46: note: passing argument to parameter '__p0' here
__ai int16x4_t vreinterpret_s16_u8(uint8x8_t __p0) {
taylorchu commented 6 months ago
#include <stdint.h>
#include <stdlib.h>
#include <string.h>

#define H264E_ENABLE_PLAIN_C 1
#define MINIH264_IMPLEMENTATION
#include "minih264e.h"

typedef struct Encoder {
  H264E_create_param_t create_param;
  H264E_persist_t *enc;
  H264E_scratch_t *scratch;
} Encoder;

#define ALIGNED_ALLOC(n, size) aligned_alloc(n, (size + n - 1) / n * n)

int enc_new(Encoder **out) {
  H264E_create_param_t create_param;
  memset(&create_param, 0, sizeof(create_param));

  int sizeof_persist = 0, sizeof_scratch = 0;
  if (H264E_sizeof(&create_param, &sizeof_persist, &sizeof_scratch) != 0) {
    return 1001;
  }

  H264E_persist_t *enc = (H264E_persist_t *)ALIGNED_ALLOC(64, sizeof_persist);
  H264E_scratch_t *scratch =
      (H264E_scratch_t *)ALIGNED_ALLOC(64, sizeof_scratch);

  if (H264E_init(enc, &create_param) != 0) {
    return 1002;
  }

  Encoder *e = (Encoder *)calloc(1, sizeof(Encoder));
  e->create_param = create_param;
  e->enc = enc;
  e->scratch = scratch;
  *out = e;
  return 0;
}

int enc_encode(Encoder *e, uint8_t *y, uint8_t *cb, uint8_t *cr, void **out,
               int *out_size) {
  H264E_io_yuv_t yuv;
  memset(&yuv, 0, sizeof(yuv));
  yuv.yuv[0] = y;
  yuv.stride[0] = e->create_param.width;
  yuv.yuv[1] = cb;
  yuv.stride[1] = e->create_param.width / 2;
  yuv.yuv[2] = cr;
  yuv.stride[2] = e->create_param.width / 2;

  H264E_run_param_t run_param;
  memset(&run_param, 0, sizeof(run_param));

  if (H264E_encode(e->enc, e->scratch, &run_param, &yuv, (unsigned char **)out,
                   out_size) != 0) {
    return 2001;
  }
  return 0;
}

void enc_close(Encoder *e) {
  free(e->enc);
  free(e->scratch);
  free(e);
}