av.go multi changes

This commit is contained in:
nareix 2016-06-22 19:21:01 +08:00
parent 9b9965cca0
commit 1420483262

124
av.go
View File

@ -2,12 +2,13 @@ package av
import ( import (
"fmt" "fmt"
"time"
) )
type SampleFormat int type SampleFormat uint8
const ( const (
U8 = SampleFormat(iota+1) U8 = SampleFormat(iota + 1)
S16 S16
S32 S32
FLT FLT
@ -22,13 +23,13 @@ const (
func (self SampleFormat) BytesPerSample() int { func (self SampleFormat) BytesPerSample() int {
switch self { switch self {
case U8,U8P: case U8, U8P:
return 1 return 1
case S16,S16P: case S16, S16P:
return 2 return 2
case FLT,FLTP,S32,S32P,U32: case FLT, FLTP, S32, S32P, U32:
return 4 return 4
case DBL,DBLP: case DBL, DBLP:
return 8 return 8
default: default:
return 0 return 0
@ -64,21 +65,21 @@ func (self SampleFormat) String() string {
func (self SampleFormat) IsPlanar() bool { func (self SampleFormat) IsPlanar() bool {
switch self { switch self {
case S16P,S32P,FLTP,DBLP: case S16P, S32P, FLTP, DBLP:
return true return true
default: default:
return false return false
} }
} }
type ChannelLayout uint64 type ChannelLayout uint16
func (self ChannelLayout) String() string { func (self ChannelLayout) String() string {
return fmt.Sprintf("%dch", self.Count()) return fmt.Sprintf("%dch", self.Count())
} }
const ( const (
CH_FRONT_CENTER = ChannelLayout(1<<iota) CH_FRONT_CENTER = ChannelLayout(1 << iota)
CH_FRONT_LEFT CH_FRONT_LEFT
CH_FRONT_RIGHT CH_FRONT_RIGHT
CH_BACK_CENTER CH_BACK_CENTER
@ -89,34 +90,72 @@ const (
CH_LOW_FREQ CH_LOW_FREQ
CH_NR CH_NR
CH_MONO = ChannelLayout(CH_FRONT_CENTER) CH_MONO = ChannelLayout(CH_FRONT_CENTER)
CH_STEREO = ChannelLayout(CH_FRONT_LEFT|CH_FRONT_RIGHT) CH_STEREO = ChannelLayout(CH_FRONT_LEFT | CH_FRONT_RIGHT)
CH_2_1 = ChannelLayout(CH_STEREO|CH_BACK_CENTER) CH_2_1 = ChannelLayout(CH_STEREO | CH_BACK_CENTER)
CH_2POINT1 = ChannelLayout(CH_STEREO|CH_LOW_FREQ) CH_2POINT1 = ChannelLayout(CH_STEREO | CH_LOW_FREQ)
CH_SURROUND = ChannelLayout(CH_STEREO|CH_FRONT_CENTER) CH_SURROUND = ChannelLayout(CH_STEREO | CH_FRONT_CENTER)
CH_3POINT1 = ChannelLayout(CH_SURROUND|CH_LOW_FREQ) CH_3POINT1 = ChannelLayout(CH_SURROUND | CH_LOW_FREQ)
// TODO: add all channel_layout in ffmpeg // TODO: add all channel_layout in ffmpeg
) )
func (self ChannelLayout) Count() (n int) { func (self ChannelLayout) Count() (n int) {
for self != 0 { for self != 0 {
n++ n++
self = (self-1)&self self = (self - 1) & self
} }
return return
} }
const ( type CodecType uint32
H264 = iota+0x264
AAC const codecTypeAudioBit = 0x1
PCM_MULAW const codecTypeOtherBits = 1
PCM_ALAW
func (self CodecType) String() string {
switch self {
case H264:
return "H264"
case AAC:
return "AAC"
case PCM_MULAW:
return "PCM_MULAW"
case PCM_ALAW:
return "PCM_ALAW"
}
return ""
}
func (self CodecType) IsAudio() bool {
return self&codecTypeAudioBit != 0
}
func (self CodecType) IsVideo() bool {
return self&codecTypeAudioBit == 0
}
func MakeAudioCodecType(base uint32) (c CodecType) {
c = CodecType(base)<<codecTypeOtherBits | CodecType(codecTypeAudioBit)
return
}
func MakeVideoCodecType(base uint32) (c CodecType) {
c = CodecType(base) << codecTypeOtherBits
return
}
const avCodecTypeMagic = 16531653
var (
H264 = MakeVideoCodecType(avCodecTypeMagic + 1)
AAC = MakeAudioCodecType(avCodecTypeMagic + 1)
PCM_MULAW = MakeAudioCodecType(avCodecTypeMagic + 2)
PCM_ALAW = MakeAudioCodecType(avCodecTypeMagic + 3)
) )
type CodecData interface { type CodecData interface {
IsVideo() bool Type() CodecType
IsAudio() bool
Type() int
} }
type VideoCodecData interface { type VideoCodecData interface {
@ -130,32 +169,46 @@ type AudioCodecData interface {
SampleFormat() SampleFormat SampleFormat() SampleFormat
SampleRate() int SampleRate() int
ChannelLayout() ChannelLayout ChannelLayout() ChannelLayout
PacketDuration([]byte) (time.Duration, error)
}
type PacketWriter interface {
WritePacket(Packet) error
}
type PacketReader interface {
ReadPacket() (Packet,error)
} }
type Muxer interface { type Muxer interface {
PacketWriter
WriteHeader([]CodecData) error WriteHeader([]CodecData) error
WritePacket(int, Packet) error
WriteTrailer() error WriteTrailer() error
} }
type Demuxer interface { type Demuxer interface {
ReadPacket() (int, Packet, error) PacketReader
Streams() ([]CodecData, error) Streams() ([]CodecData, error)
} }
type Packet struct { type Packet struct {
IsKeyFrame bool IsKeyFrame bool
Idx int8
CompositionTime time.Duration
Time time.Duration
Data []byte Data []byte
Duration float64
CompositionTime float64
} }
type AudioFrame struct { type AudioFrame struct {
SampleRate int SampleFormat SampleFormat
SampleFormat SampleFormat
ChannelLayout ChannelLayout ChannelLayout ChannelLayout
SampleCount int SampleCount int
Data [][]byte SampleRate int
Data [][]byte
}
func (self AudioFrame) Duration() time.Duration {
return time.Second * time.Duration(self.SampleCount) / time.Duration(self.SampleRate)
} }
func (self AudioFrame) HasSameFormat(other AudioFrame) bool { func (self AudioFrame) HasSameFormat(other AudioFrame) bool {
@ -174,10 +227,10 @@ func (self AudioFrame) HasSameFormat(other AudioFrame) bool {
func (self AudioFrame) Slice(start int, end int) (out AudioFrame) { func (self AudioFrame) Slice(start int, end int) (out AudioFrame) {
out = self out = self
out.Data = append([][]byte(nil), out.Data...) out.Data = append([][]byte(nil), out.Data...)
out.SampleCount = end-start out.SampleCount = end - start
size := self.SampleFormat.BytesPerSample() size := self.SampleFormat.BytesPerSample()
for i := range out.Data { for i := range out.Data {
out.Data[i] = out.Data[i][start*size:end*size] out.Data[i] = out.Data[i][start*size : end*size]
} }
return return
} }
@ -194,7 +247,7 @@ func (self AudioFrame) Concat(in AudioFrame) (out AudioFrame) {
type AudioEncoder interface { type AudioEncoder interface {
CodecData() AudioCodecData CodecData() AudioCodecData
Encode(AudioFrame) ([]Packet, error) Encode(AudioFrame) ([][]byte, error)
Close() Close()
//Flush() ([]Packet, error) //Flush() ([]Packet, error)
} }
@ -208,4 +261,3 @@ type AudioDecoder interface {
type AudioResampler interface { type AudioResampler interface {
Resample(AudioFrame) (AudioFrame, error) Resample(AudioFrame) (AudioFrame, error)
} }