Files
mediadevices/pkg/codec/x264/bridge.h
2020-11-01 01:08:03 -07:00

99 lines
2.2 KiB
C

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <x264.h>
#define ERR_DEFAULT_PRESET -1
#define ERR_APPLY_PROFILE -2
#define ERR_ALLOC_PICTURE -3
#define ERR_OPEN_ENGINE -4
#define ERR_ENCODE -5
typedef struct Slice {
unsigned char *data;
int data_len;
} Slice;
typedef struct Encoder {
x264_t *h;
x264_picture_t pic_in, pic_out;
x264_param_t param;
} Encoder;
Encoder *enc_new(x264_param_t param, char *preset, int *rc) {
Encoder *e = (Encoder *)malloc(sizeof(Encoder));
if (x264_param_default_preset(&e->param, preset, "zerolatency") < 0) {
free(preset);
*rc = ERR_DEFAULT_PRESET;
goto fail;
}
free(preset);
/* Configure non-default params */
e->param.i_csp = param.i_csp;
e->param.i_width = param.i_width;
e->param.i_height = param.i_height;
e->param.i_fps_num = param.i_fps_num;
e->param.i_fps_den = 1;
// Intra refres:
e->param.i_keyint_max = param.i_keyint_max;
// Rate control:
e->param.rc.i_rc_method = X264_RC_ABR;
e->param.rc.i_bitrate = param.rc.i_bitrate;
e->param.rc.i_vbv_max_bitrate = param.rc.i_vbv_max_bitrate;
e->param.rc.i_vbv_buffer_size = param.rc.i_vbv_buffer_size;
// For streaming:
e->param.b_repeat_headers = 1;
e->param.b_annexb = 1;
if (x264_param_apply_profile(&e->param, "high") < 0) {
*rc = ERR_APPLY_PROFILE;
goto fail;
}
if (x264_picture_alloc(&e->pic_in, param.i_csp, param.i_width, param.i_height) < 0) {
*rc = ERR_ALLOC_PICTURE;
goto fail;
}
e->h = x264_encoder_open(&e->param);
if (!e->h) {
*rc = ERR_OPEN_ENGINE;
x264_picture_clean(&e->pic_in);
goto fail;
}
return e;
fail:
free(e);
return NULL;
}
Slice enc_encode(Encoder *e, uint8_t *y, uint8_t *cb, uint8_t *cr, int *rc) {
x264_nal_t *nal;
int i_nal;
e->pic_in.img.plane[0] = y;
e->pic_in.img.plane[1] = cb;
e->pic_in.img.plane[2] = cr;
int frame_size = x264_encoder_encode(e->h, &nal, &i_nal, &e->pic_in, &e->pic_out);
Slice s = {.data_len = frame_size};
if (frame_size <= 0) {
*rc = ERR_ENCODE;
return s;
}
e->pic_in.i_pts++;
s.data = nal->p_payload;
return s;
}
void enc_close(Encoder *e, int *rc) {
x264_encoder_close(e->h);
x264_picture_clean(&e->pic_in);
free(e);
}