go-pus/callbacks.c
DataHoarder 4421c708d1
Some checks failed
continuous-integration/drone/push Build is failing
Add support for setting and getting the ogg muxing delay
2022-07-20 12:04:58 +02:00

158 lines
3.6 KiB
C

//go:build !nolibopusfile
// +build !nolibopusfile
// Copyright © Go Opus Authors (see AUTHORS file)
//
// License for use of this code is detailed in the LICENSE file
// Allocate callback struct in C to ensure it's not managed by the Go GC. This
// plays nice with the CGo rules and avoids any confusion.
#include <opusfile.h>
#include <opusenc.h>
#include <stdint.h>
#include <stdio.h>
// Defined in Go. Uses the same signature as Go, no need for proxy function.
int go_readcallback(void *p, unsigned char *buf, int nbytes);
int go_writecallback(void *p, const unsigned char *buf, opus_int32 len);
int closecallback(void *p) {
return 0;
}
static struct OpusFileCallbacks callbacks = {
.read = go_readcallback,
};
static OpusEncCallbacks encodeCallbacks = {
.write = go_writecallback,
.close = closecallback,
};
static OggOpusComments* emptyComment = NULL;
// Proxy function for op_open_callbacks, because it takes a void * context but
// we want to pass it non-pointer data, namely an arbitrary uintptr_t
// value. This is legal C, but go test -race (-d=checkptr) complains anyway. So
// we have this wrapper function to shush it.
// https://groups.google.com/g/golang-nuts/c/995uZyRPKlU
OggOpusFile *
my_open_callbacks(uintptr_t p, int *error)
{
return op_open_callbacks((void *)p, &callbacks, NULL, 0, error);
}
OpusEncCallbacks *
my_write_callbacks()
{
return &encodeCallbacks;
}
OggOpusComments*
my_empty_comment()
{
if (emptyComment == NULL) {
emptyComment = ope_comments_create();
}
return emptyComment;
}
int
bridge_encoder_set_dtx(OggOpusEnc *st, opus_int32 use_dtx)
{
return ope_encoder_ctl(st, OPUS_SET_DTX(use_dtx));
}
int
bridge_encoder_set_application(OggOpusEnc *st, opus_int32 application)
{
return ope_encoder_ctl(st, OPUS_SET_APPLICATION(application));
}
int
bridge_encoder_get_dtx(OggOpusEnc *st, opus_int32 *dtx)
{
return ope_encoder_ctl(st, OPUS_GET_DTX(dtx));
}
int
bridge_encoder_get_sample_rate(OggOpusEnc *st, opus_int32 *sample_rate)
{
return ope_encoder_ctl(st, OPUS_GET_SAMPLE_RATE(sample_rate));
}
int
bridge_encoder_set_muxing_delay(OggOpusEnc *st, opus_int32 delay)
{
return ope_encoder_ctl(st, OPE_SET_MUXING_DELAY(delay));
}
int
bridge_encoder_get_muxing_delay(OggOpusEnc *st, opus_int32 *delay)
{
return ope_encoder_ctl(st, OPE_GET_MUXING_DELAY(delay));
}
int
bridge_encoder_set_bitrate(OggOpusEnc *st, opus_int32 bitrate)
{
return ope_encoder_ctl(st, OPUS_SET_BITRATE(bitrate));
}
int
bridge_encoder_get_bitrate(OggOpusEnc *st, opus_int32 *bitrate)
{
return ope_encoder_ctl(st, OPUS_GET_BITRATE(bitrate));
}
int
bridge_encoder_set_complexity(OggOpusEnc *st, opus_int32 complexity)
{
return ope_encoder_ctl(st, OPUS_SET_COMPLEXITY(complexity));
}
int
bridge_encoder_get_complexity(OggOpusEnc *st, opus_int32 *complexity)
{
return ope_encoder_ctl(st, OPUS_GET_COMPLEXITY(complexity));
}
int
bridge_encoder_set_max_bandwidth(OggOpusEnc *st, opus_int32 max_bw)
{
return ope_encoder_ctl(st, OPUS_SET_MAX_BANDWIDTH(max_bw));
}
int
bridge_encoder_get_max_bandwidth(OggOpusEnc *st, opus_int32 *max_bw)
{
return ope_encoder_ctl(st, OPUS_GET_MAX_BANDWIDTH(max_bw));
}
int
bridge_encoder_set_inband_fec(OggOpusEnc *st, opus_int32 fec)
{
return ope_encoder_ctl(st, OPUS_SET_INBAND_FEC(fec));
}
int
bridge_encoder_get_inband_fec(OggOpusEnc *st, opus_int32 *fec)
{
return ope_encoder_ctl(st, OPUS_GET_INBAND_FEC(fec));
}
int
bridge_encoder_set_packet_loss_perc(OggOpusEnc *st, opus_int32 loss_perc)
{
return ope_encoder_ctl(st, OPUS_SET_PACKET_LOSS_PERC(loss_perc));
}
int
bridge_encoder_get_packet_loss_perc(OggOpusEnc *st, opus_int32 *loss_perc)
{
return ope_encoder_ctl(st, OPUS_GET_PACKET_LOSS_PERC(loss_perc));
}