add SPEEX codec
This commit is contained in:
parent
4b5f50e03f
commit
e3a02beada
@ -617,6 +617,9 @@ func NewAudioDecoder(codec av.AudioCodecData) (dec *AudioDecoder, err error) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case av.SPEEX:
|
||||||
|
id = C.AV_CODEC_ID_SPEEX
|
||||||
|
|
||||||
case av.PCM_MULAW:
|
case av.PCM_MULAW:
|
||||||
id = C.AV_CODEC_ID_PCM_MULAW
|
id = C.AV_CODEC_ID_PCM_MULAW
|
||||||
|
|
||||||
@ -680,17 +683,25 @@ func (self audioCodecData) ChannelLayout() av.ChannelLayout {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self audioCodecData) PacketDuration(data []byte) (dur time.Duration, err error) {
|
func (self audioCodecData) PacketDuration(data []byte) (dur time.Duration, err error) {
|
||||||
// TODO: implement it
|
// TODO: implement it: ffmpeg get_audio_frame_duration
|
||||||
err = fmt.Errorf("ffmpeg: cannot get packet duration")
|
err = fmt.Errorf("ffmpeg: cannot get packet duration")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func AudioCodecHandler(h *avutil.RegisterHandler) {
|
func AudioCodecHandler(h *avutil.RegisterHandler) {
|
||||||
h.AudioDecoder = func(codec av.AudioCodecData) (av.AudioDecoder, error) {
|
h.AudioDecoder = func(codec av.AudioCodecData) (av.AudioDecoder, error) {
|
||||||
return NewAudioDecoder(codec)
|
if dec, err := NewAudioDecoder(codec); err != nil {
|
||||||
|
return nil, nil
|
||||||
|
} else {
|
||||||
|
return dec, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
h.AudioEncoder = func(typ av.CodecType) (av.AudioEncoder, error) {
|
h.AudioEncoder = func(typ av.CodecType) (av.AudioEncoder, error) {
|
||||||
return NewAudioEncoderByCodecType(typ)
|
if enc, err := NewAudioEncoderByCodecType(typ); err != nil {
|
||||||
|
return nil, nil
|
||||||
|
} else {
|
||||||
|
return enc, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package codec
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/nareix/joy4/av"
|
"github.com/nareix/joy4/av"
|
||||||
|
"github.com/nareix/joy4/codec/fake"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -41,11 +42,23 @@ func NewPCMAlawCodecData() av.AudioCodecData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewNellyMoserCodecData() av.AudioCodecData {
|
type SpeexCodecData struct {
|
||||||
return PCMUCodecData{typ: av.NELLYMOSER}
|
fake.CodecData
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSpeexCodecData() av.AudioCodecData {
|
func (self SpeexCodecData) PacketDuration(data []byte) (time.Duration, error) {
|
||||||
return PCMUCodecData{typ: av.SPEEX}
|
// libavcodec/libspeexdec.c
|
||||||
|
// samples = samplerate/50
|
||||||
|
// duration = 0.02s
|
||||||
|
return time.Millisecond*20, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewSpeexCodecData(sr int, cl av.ChannelLayout) SpeexCodecData {
|
||||||
|
codec := SpeexCodecData{}
|
||||||
|
codec.CodecType_ = av.SPEEX
|
||||||
|
codec.SampleFormat_ = av.S16
|
||||||
|
codec.SampleRate_ = sr
|
||||||
|
codec.ChannelLayout_ = cl
|
||||||
|
return codec
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,10 +5,25 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type CodecData struct {
|
type CodecData struct {
|
||||||
Typ av.CodecType
|
CodecType_ av.CodecType
|
||||||
|
SampleRate_ int
|
||||||
|
SampleFormat_ av.SampleFormat
|
||||||
|
ChannelLayout_ av.ChannelLayout
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self CodecData) Type() av.CodecType {
|
func (self CodecData) Type() av.CodecType {
|
||||||
return self.Typ
|
return self.CodecType_
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self CodecData) SampleFormat() av.SampleFormat {
|
||||||
|
return self.SampleFormat_
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self CodecData) ChannelLayout() av.ChannelLayout {
|
||||||
|
return self.ChannelLayout_
|
||||||
|
}
|
||||||
|
|
||||||
|
func (self CodecData) SampleRate() int {
|
||||||
|
return self.SampleRate_
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"github.com/nareix/joy4/av/avutil"
|
"github.com/nareix/joy4/av/avutil"
|
||||||
"github.com/nareix/joy4/codec/h264parser"
|
"github.com/nareix/joy4/codec/h264parser"
|
||||||
"github.com/nareix/joy4/codec"
|
"github.com/nareix/joy4/codec"
|
||||||
|
"github.com/nareix/joy4/codec/fake"
|
||||||
"github.com/nareix/joy4/codec/aacparser"
|
"github.com/nareix/joy4/codec/aacparser"
|
||||||
"github.com/nareix/pio"
|
"github.com/nareix/pio"
|
||||||
"github.com/nareix/joy4/format/flv/flvio"
|
"github.com/nareix/joy4/format/flv/flvio"
|
||||||
@ -78,7 +79,7 @@ func (self *Prober) PushTag(_tag flvio.Tag, timestamp int32) (err error) {
|
|||||||
|
|
||||||
case flvio.SOUND_SPEEX:
|
case flvio.SOUND_SPEEX:
|
||||||
if !self.GotAudio {
|
if !self.GotAudio {
|
||||||
stream := codec.NewSpeexCodecData()
|
stream := codec.NewSpeexCodecData(16000, tag.ChannelLayout())
|
||||||
self.AudioStreamIdx = len(self.Streams)
|
self.AudioStreamIdx = len(self.Streams)
|
||||||
self.Streams = append(self.Streams, stream)
|
self.Streams = append(self.Streams, stream)
|
||||||
self.GotAudio = true
|
self.GotAudio = true
|
||||||
@ -87,7 +88,12 @@ func (self *Prober) PushTag(_tag flvio.Tag, timestamp int32) (err error) {
|
|||||||
|
|
||||||
case flvio.SOUND_NELLYMOSER:
|
case flvio.SOUND_NELLYMOSER:
|
||||||
if !self.GotAudio {
|
if !self.GotAudio {
|
||||||
stream := codec.NewNellyMoserCodecData()
|
stream := fake.CodecData{
|
||||||
|
CodecType_: av.NELLYMOSER,
|
||||||
|
SampleRate_: 16000,
|
||||||
|
SampleFormat_: av.S16,
|
||||||
|
ChannelLayout_: tag.ChannelLayout(),
|
||||||
|
}
|
||||||
self.AudioStreamIdx = len(self.Streams)
|
self.AudioStreamIdx = len(self.Streams)
|
||||||
self.Streams = append(self.Streams, stream)
|
self.Streams = append(self.Streams, stream)
|
||||||
self.GotAudio = true
|
self.GotAudio = true
|
||||||
@ -275,8 +281,10 @@ func NewMuxer(w io.Writer) *Muxer {
|
|||||||
return self
|
return self
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var SupportedCodecTypes = []av.CodecType{av.H264, av.AAC, av.SPEEX}
|
||||||
|
|
||||||
func (self *Muxer) SupportedCodecTypes() []av.CodecType {
|
func (self *Muxer) SupportedCodecTypes() []av.CodecType {
|
||||||
return []av.CodecType{av.H264, av.AAC, av.NELLYMOSER, av.SPEEX}
|
return SupportedCodecTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Muxer) WriteHeader(streams []av.CodecData) (err error) {
|
func (self *Muxer) WriteHeader(streams []av.CodecData) (err error) {
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/nareix/pio"
|
"github.com/nareix/pio"
|
||||||
|
"github.com/nareix/joy4/av"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TsToTime(ts int32) time.Duration {
|
func TsToTime(ts int32) time.Duration {
|
||||||
@ -144,6 +145,14 @@ func (self Audiodata) Type() uint8 {
|
|||||||
return TAG_AUDIO
|
return TAG_AUDIO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (self Audiodata) ChannelLayout() av.ChannelLayout {
|
||||||
|
if self.SoundType == SOUND_MONO {
|
||||||
|
return av.CH_MONO
|
||||||
|
} else {
|
||||||
|
return av.CH_STEREO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (self Audiodata) Len() int {
|
func (self Audiodata) Len() int {
|
||||||
if self.SoundFormat == SOUND_AAC {
|
if self.SoundFormat == SOUND_AAC {
|
||||||
return 2 + len(self.Data)
|
return 2 + len(self.Data)
|
||||||
|
@ -316,7 +316,7 @@ func createURL(tcurl, app, play string) (u *url.URL) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (self *Conn) SupportedCodecTypes() []av.CodecType {
|
func (self *Conn) SupportedCodecTypes() []av.CodecType {
|
||||||
return []av.CodecType{av.H264, av.AAC}
|
return flv.SupportedCodecTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
func (self *Conn) recvConnect() (err error) {
|
func (self *Conn) recvConnect() (err error) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user