|
|
@ -12,9 +12,9 @@ import (
|
|
|
|
"time"
|
|
|
|
"time"
|
|
|
|
"unsafe"
|
|
|
|
"unsafe"
|
|
|
|
|
|
|
|
|
|
|
|
"gitlab.com/ics_cinnamon/joy4/av"
|
|
|
|
"git.icomsys.co.kr/ljhwan026/joy4/av"
|
|
|
|
"gitlab.com/ics_cinnamon/joy4/av/avutil"
|
|
|
|
"git.icomsys.co.kr/ljhwan026/joy4/av/avutil"
|
|
|
|
"gitlab.com/ics_cinnamon/joy4/codec/aacparser"
|
|
|
|
"git.icomsys.co.kr/ljhwan026/joy4/codec/aacparser"
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
|
const debug = false
|
|
|
|
const debug = false
|
|
|
@ -78,12 +78,34 @@ func (self *Resampler) Resample(in av.AudioFrame) (out av.AudioFrame, err error)
|
|
|
|
self.inSampleRate = in.SampleRate
|
|
|
|
self.inSampleRate = in.SampleRate
|
|
|
|
self.inChannelLayout = in.ChannelLayout
|
|
|
|
self.inChannelLayout = in.ChannelLayout
|
|
|
|
avr := C.swr_alloc()
|
|
|
|
avr := C.swr_alloc()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
cs1 := C.CString("in_channel_layout")
|
|
|
|
|
|
|
|
cs2 := C.CString("out_channel_layout")
|
|
|
|
|
|
|
|
cs3 := C.CString("in_sample_rate")
|
|
|
|
|
|
|
|
cs4 := C.CString("out_sample_rate")
|
|
|
|
|
|
|
|
cs5 := C.CString("in_sample_fmt")
|
|
|
|
|
|
|
|
cs6 := C.CString("out_sample_fmt")
|
|
|
|
|
|
|
|
defer C.free(unsafe.Pointer(cs1))
|
|
|
|
|
|
|
|
defer C.free(unsafe.Pointer(cs2))
|
|
|
|
|
|
|
|
defer C.free(unsafe.Pointer(cs3))
|
|
|
|
|
|
|
|
defer C.free(unsafe.Pointer(cs4))
|
|
|
|
|
|
|
|
defer C.free(unsafe.Pointer(cs5))
|
|
|
|
|
|
|
|
defer C.free(unsafe.Pointer(cs6))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), cs1, C.int64_t(channelLayoutAV2FF(self.inChannelLayout)), 0)
|
|
|
|
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), cs2, C.int64_t(channelLayoutAV2FF(self.OutChannelLayout)), 0)
|
|
|
|
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), cs3, C.int64_t(self.inSampleRate), 0)
|
|
|
|
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), cs4, C.int64_t(self.OutSampleRate), 0)
|
|
|
|
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), cs5, C.int64_t(sampleFormatAV2FF(self.inSampleFormat)), 0)
|
|
|
|
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), cs6, C.int64_t(sampleFormatAV2FF(self.OutSampleFormat)), 0)
|
|
|
|
|
|
|
|
/*
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), C.CString("in_channel_layout"), C.int64_t(channelLayoutAV2FF(self.inChannelLayout)), 0)
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), C.CString("in_channel_layout"), C.int64_t(channelLayoutAV2FF(self.inChannelLayout)), 0)
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), C.CString("out_channel_layout"), C.int64_t(channelLayoutAV2FF(self.OutChannelLayout)), 0)
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), C.CString("out_channel_layout"), C.int64_t(channelLayoutAV2FF(self.OutChannelLayout)), 0)
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), C.CString("in_sample_rate"), C.int64_t(self.inSampleRate), 0)
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), C.CString("in_sample_rate"), C.int64_t(self.inSampleRate), 0)
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), C.CString("out_sample_rate"), C.int64_t(self.OutSampleRate), 0)
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), C.CString("out_sample_rate"), C.int64_t(self.OutSampleRate), 0)
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), C.CString("in_sample_fmt"), C.int64_t(sampleFormatAV2FF(self.inSampleFormat)), 0)
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), C.CString("in_sample_fmt"), C.int64_t(sampleFormatAV2FF(self.inSampleFormat)), 0)
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), C.CString("out_sample_fmt"), C.int64_t(sampleFormatAV2FF(self.OutSampleFormat)), 0)
|
|
|
|
C.av_opt_set_int(unsafe.Pointer(avr), C.CString("out_sample_fmt"), C.int64_t(sampleFormatAV2FF(self.OutSampleFormat)), 0)
|
|
|
|
|
|
|
|
*/
|
|
|
|
C.swr_init(avr)
|
|
|
|
C.swr_init(avr)
|
|
|
|
self.avr = avr
|
|
|
|
self.avr = avr
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -238,7 +260,10 @@ func (self *AudioEncoder) SetOption(key string, val interface{}) (err error) {
|
|
|
|
|
|
|
|
|
|
|
|
sval := fmt.Sprint(val)
|
|
|
|
sval := fmt.Sprint(val)
|
|
|
|
if key == "profile" {
|
|
|
|
if key == "profile" {
|
|
|
|
ff.profile = C.avcodec_profile_name_to_int(ff.codec, C.CString(sval))
|
|
|
|
cs1 := C.CString(sval)
|
|
|
|
|
|
|
|
defer C.free(unsafe.Pointer(cs1))
|
|
|
|
|
|
|
|
ff.profile = C.avcodec_profile_name_to_int(ff.codec, cs1)
|
|
|
|
|
|
|
|
//ff.profile = C.avcodec_profile_name_to_int(ff.codec, C.CString(sval))
|
|
|
|
if ff.profile == C.FF_PROFILE_UNKNOWN {
|
|
|
|
if ff.profile == C.FF_PROFILE_UNKNOWN {
|
|
|
|
err = fmt.Errorf("ffmpeg: profile `%s` invalid", sval)
|
|
|
|
err = fmt.Errorf("ffmpeg: profile `%s` invalid", sval)
|
|
|
|
return
|
|
|
|
return
|
|
|
@ -246,13 +271,19 @@ func (self *AudioEncoder) SetOption(key string, val interface{}) (err error) {
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
C.av_dict_set(&ff.options, C.CString(key), C.CString(sval), 0)
|
|
|
|
cs2 := C.CString(sval)
|
|
|
|
|
|
|
|
defer C.free(unsafe.Pointer(cs2))
|
|
|
|
|
|
|
|
C.av_dict_set(&ff.options, C.CString(key), cs2, 0)
|
|
|
|
|
|
|
|
//C.av_dict_set(&ff.options, C.CString(key), C.CString(sval), 0)
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func (self *AudioEncoder) GetOption(key string, val interface{}) (err error) {
|
|
|
|
func (self *AudioEncoder) GetOption(key string, val interface{}) (err error) {
|
|
|
|
ff := &self.ff.ff
|
|
|
|
ff := &self.ff.ff
|
|
|
|
entry := C.av_dict_get(ff.options, C.CString(key), nil, 0)
|
|
|
|
cs1 := C.CString(key)
|
|
|
|
|
|
|
|
defer C.free(unsafe.Pointer(cs1))
|
|
|
|
|
|
|
|
entry := C.av_dict_get(ff.options, cs1, nil, 0)
|
|
|
|
|
|
|
|
//entry := C.av_dict_get(ff.options, C.CString(key), nil, 0)
|
|
|
|
if entry == nil {
|
|
|
|
if entry == nil {
|
|
|
|
err = fmt.Errorf("ffmpeg: GetOption failed: `%s` not exists", key)
|
|
|
|
err = fmt.Errorf("ffmpeg: GetOption failed: `%s` not exists", key)
|
|
|
|
return
|
|
|
|
return
|
|
|
@ -401,6 +432,7 @@ func (self *AudioEncoder) Encode(frame av.AudioFrame) (pkts [][]byte, err error)
|
|
|
|
var pkt []byte
|
|
|
|
var pkt []byte
|
|
|
|
|
|
|
|
|
|
|
|
if frame.SampleFormat != self.SampleFormat || frame.ChannelLayout != self.ChannelLayout || frame.SampleRate != self.SampleRate {
|
|
|
|
if frame.SampleFormat != self.SampleFormat || frame.ChannelLayout != self.ChannelLayout || frame.SampleRate != self.SampleRate {
|
|
|
|
|
|
|
|
//fmt.Printf("%+v\n", self)
|
|
|
|
if frame, err = self.resample(frame); err != nil {
|
|
|
|
if frame, err = self.resample(frame); err != nil {
|
|
|
|
return
|
|
|
|
return
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -585,6 +617,11 @@ func (self *AudioDecoder) Decode(pkt []byte) (gotframe bool, frame av.AudioFrame
|
|
|
|
|
|
|
|
|
|
|
|
cgotframe := C.int(0)
|
|
|
|
cgotframe := C.int(0)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if ff.codecCtx == nil || &pkt[0] == nil {
|
|
|
|
|
|
|
|
err = fmt.Errorf("ffmpeg: Decode ff.codecCtx NULL or pkg NULL")
|
|
|
|
|
|
|
|
return
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
cerr := C.decode(ff.codecCtx, ff.frame, (*C.uchar)(unsafe.Pointer(&pkt[0])), C.int(len(pkt)), &cgotframe)
|
|
|
|
cerr := C.decode(ff.codecCtx, ff.frame, (*C.uchar)(unsafe.Pointer(&pkt[0])), C.int(len(pkt)), &cgotframe)
|
|
|
|
|
|
|
|
|
|
|
|
if cerr < C.int(0) {
|
|
|
|
if cerr < C.int(0) {
|
|
|
@ -615,6 +652,12 @@ func NewAudioEncoderByCodecType(typ av.CodecType) (enc *AudioEncoder, err error)
|
|
|
|
switch typ {
|
|
|
|
switch typ {
|
|
|
|
case av.AAC:
|
|
|
|
case av.AAC:
|
|
|
|
id = C.AV_CODEC_ID_AAC
|
|
|
|
id = C.AV_CODEC_ID_AAC
|
|
|
|
|
|
|
|
case av.PCM_ALAW:
|
|
|
|
|
|
|
|
id = C.AV_CODEC_ID_PCM_ALAW
|
|
|
|
|
|
|
|
case av.PCM_MULAW:
|
|
|
|
|
|
|
|
id = C.AV_CODEC_ID_PCM_MULAW
|
|
|
|
|
|
|
|
case av.G729:
|
|
|
|
|
|
|
|
id = C.AV_CODEC_ID_G729
|
|
|
|
|
|
|
|
|
|
|
|
default:
|
|
|
|
default:
|
|
|
|
err = fmt.Errorf("ffmpeg: cannot find encoder codecType=%d", typ)
|
|
|
|
err = fmt.Errorf("ffmpeg: cannot find encoder codecType=%d", typ)
|
|
|
@ -638,7 +681,10 @@ func NewAudioEncoderByCodecType(typ av.CodecType) (enc *AudioEncoder, err error)
|
|
|
|
func NewAudioEncoderByName(name string) (enc *AudioEncoder, err error) {
|
|
|
|
func NewAudioEncoderByName(name string) (enc *AudioEncoder, err error) {
|
|
|
|
_enc := &AudioEncoder{}
|
|
|
|
_enc := &AudioEncoder{}
|
|
|
|
|
|
|
|
|
|
|
|
codec := C.avcodec_find_encoder_by_name(C.CString(name))
|
|
|
|
cs1 := C.CString(name)
|
|
|
|
|
|
|
|
defer C.free(unsafe.Pointer(cs1))
|
|
|
|
|
|
|
|
codec := C.avcodec_find_encoder_by_name(cs1)
|
|
|
|
|
|
|
|
//codec := C.avcodec_find_encoder_by_name(C.CString(name))
|
|
|
|
if codec == nil || C.avcodec_get_type(codec.id) != C.AVMEDIA_TYPE_AUDIO {
|
|
|
|
if codec == nil || C.avcodec_get_type(codec.id) != C.AVMEDIA_TYPE_AUDIO {
|
|
|
|
err = fmt.Errorf("ffmpeg: cannot find audio encoder name=%s", name)
|
|
|
|
err = fmt.Errorf("ffmpeg: cannot find audio encoder name=%s", name)
|
|
|
|
return
|
|
|
|
return
|
|
|
|