update
This commit is contained in:
parent
8e14c48c2a
commit
790569a35a
16
aacenc.go
16
aacenc.go
@ -17,7 +17,7 @@ import (
|
||||
} aacenc_t ;
|
||||
|
||||
static int aacenc_new(aacenc_t *m) {
|
||||
m->c = avcodec_find_encoder(CODEC_ID_AAC);
|
||||
m->c = avcodec_find_encoder_by_name("aac");
|
||||
m->ctx = avcodec_alloc_context3(m->c);
|
||||
m->ctx->sample_fmt = AV_SAMPLE_FMT_FLTP;
|
||||
m->ctx->sample_rate = m->samplerate;
|
||||
@ -26,7 +26,7 @@ import (
|
||||
m->ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL;
|
||||
m->f = av_frame_alloc();
|
||||
int r = avcodec_open2(m->ctx, m->c, 0);
|
||||
av_log(m->ctx, AV_LOG_DEBUG, "extra %d\n", m->ctx->extradata_size);
|
||||
//av_log(m->ctx, AV_LOG_DEBUG, "extra %d\n", m->ctx->extradata_size);
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -37,7 +37,8 @@ import (
|
||||
pkt.size = sizeof(m->buf);
|
||||
m->f->nb_samples = 1024;
|
||||
m->f->extended_data = m->f->data;
|
||||
m->f->linesize[0] = 4096;
|
||||
m->f->linesize[0] = 1024*4;
|
||||
//m->f->linesize[1] = 1024*4;
|
||||
avcodec_encode_audio2(m->ctx, &pkt, m->f, &m->got);
|
||||
av_log(m->ctx, AV_LOG_DEBUG, "got %d size %d\n", m->got, pkt.size);
|
||||
m->size = pkt.size;
|
||||
@ -53,12 +54,12 @@ type AACEncoder struct {
|
||||
Header []byte
|
||||
}
|
||||
|
||||
// only supported fltp,stereo,44100khz. If you need other config, it's easy to modify code
|
||||
// only supported fltp,stereo,44100HZ. If you need other config, it's easy to modify code
|
||||
func NewAACEncoder() (m *AACEncoder, err error) {
|
||||
m = &AACEncoder{}
|
||||
m.m.samplerate = 44100
|
||||
m.m.bitrate = 50000
|
||||
m.m.channels = 2
|
||||
m.m.channels = 1
|
||||
r := C.aacenc_new(&m.m)
|
||||
if int(r) != 0 {
|
||||
err = errors.New("open codec failed")
|
||||
@ -67,7 +68,7 @@ func NewAACEncoder() (m *AACEncoder, err error) {
|
||||
m.Header = make([]byte, (int)(m.m.ctx.extradata_size))
|
||||
C.memcpy(
|
||||
unsafe.Pointer(&m.Header[0]),
|
||||
unsafe.Pointer(&m.m.ctx.extradata),
|
||||
unsafe.Pointer(m.m.ctx.extradata),
|
||||
(C.size_t)(len(m.Header)),
|
||||
)
|
||||
return
|
||||
@ -75,7 +76,7 @@ func NewAACEncoder() (m *AACEncoder, err error) {
|
||||
|
||||
func (m *AACEncoder) Encode(sample []byte) (ret []byte, err error) {
|
||||
m.m.f.data[0] = (*C.uint8_t)(unsafe.Pointer(&sample[0]))
|
||||
m.m.f.data[1] = (*C.uint8_t)(unsafe.Pointer(&sample[4096]))
|
||||
//m.m.f.data[1] = (*C.uint8_t)(unsafe.Pointer(&sample[1024*4]))
|
||||
C.aacenc_encode(&m.m)
|
||||
if int(m.m.got) == 0 {
|
||||
err = errors.New("no data")
|
||||
@ -89,3 +90,4 @@ func (m *AACEncoder) Encode(sample []byte) (ret []byte, err error) {
|
||||
)
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@ package aacparser
|
||||
|
||||
import (
|
||||
"github.com/nareix/bits"
|
||||
"github.com/nareix/av"
|
||||
"fmt"
|
||||
"bytes"
|
||||
"io"
|
||||
@ -247,6 +248,16 @@ func (self MPEG4AudioConfig) Complete() (config MPEG4AudioConfig) {
|
||||
return
|
||||
}
|
||||
|
||||
func ParseMPEG4AudioConfig(data []byte) (config MPEG4AudioConfig, err error) {
|
||||
r := bytes.NewReader(data)
|
||||
if config, err = ReadMPEG4AudioConfig(r); err != nil {
|
||||
err = fmt.Errorf("CodecData invalid: parse MPEG4AudioConfig failed(%s)", err)
|
||||
return
|
||||
}
|
||||
config = config.Complete()
|
||||
return
|
||||
}
|
||||
|
||||
func ReadMPEG4AudioConfig(r io.Reader) (config MPEG4AudioConfig, err error) {
|
||||
// copied from libavcodec/mpeg4audio.c avpriv_mpeg4audio_get_config()
|
||||
br := &bits.Reader{R: r}
|
||||
@ -298,17 +309,51 @@ func WriteMPEG4AudioConfig(w io.Writer, config MPEG4AudioConfig) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
type CodecInfo struct {
|
||||
MPEG4AudioConfig
|
||||
type CodecData struct {
|
||||
Config []byte
|
||||
ConfigInfo MPEG4AudioConfig
|
||||
}
|
||||
|
||||
func ParseCodecData(config []byte) (info CodecInfo, err error) {
|
||||
r := bytes.NewReader(config)
|
||||
if info.MPEG4AudioConfig, err = ReadMPEG4AudioConfig(r); err != nil {
|
||||
err = fmt.Errorf("CodecData invalid: parse MPEG4AudioConfig failed(%s)", err)
|
||||
func (self CodecData) IsVideo() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self CodecData) IsAudio() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self CodecData) Type() int {
|
||||
return av.AAC
|
||||
}
|
||||
|
||||
func (self CodecData) MPEG4AudioConfigBytes() []byte {
|
||||
return self.Config
|
||||
}
|
||||
|
||||
func (self CodecData) ChannelCount() int {
|
||||
return self.ConfigInfo.ChannelCount
|
||||
}
|
||||
|
||||
func (self CodecData) SampleRate() int {
|
||||
return self.ConfigInfo.SampleRate
|
||||
}
|
||||
|
||||
func (self CodecData) SampleFormat() av.SampleFormat {
|
||||
return av.FLTP
|
||||
}
|
||||
|
||||
func (self CodecData) MakeADTSHeader(samples int, payloadLength int) []byte {
|
||||
return MakeADTSHeader(self.ConfigInfo, samples, payloadLength)
|
||||
}
|
||||
|
||||
func NewCodecDataFromMPEG4AudioConfigBytes(config []byte) (codec av.AACCodecData, err error) {
|
||||
self := CodecData{}
|
||||
self.Config = config
|
||||
if self.ConfigInfo, err = ParseMPEG4AudioConfig(config); err != nil {
|
||||
err = fmt.Errorf("parse MPEG4AudioConfig failed(%s)", err)
|
||||
return
|
||||
}
|
||||
info.MPEG4AudioConfig = info.MPEG4AudioConfig.Complete()
|
||||
codec = self
|
||||
return
|
||||
}
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
package h264parser
|
||||
|
||||
import (
|
||||
"github.com/nareix/av"
|
||||
"github.com/nareix/bits"
|
||||
"io"
|
||||
"fmt"
|
||||
@ -492,25 +493,6 @@ func ParseSPS(data []byte) (self SPSInfo, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
func MakeAVCDecoderConfRecord(
|
||||
SPS []byte,
|
||||
PPS []byte,
|
||||
) (self AVCDecoderConfRecord, err error) {
|
||||
if len(SPS) < 4 {
|
||||
err = fmt.Errorf("invalid SPS data")
|
||||
return
|
||||
}
|
||||
self.AVCProfileIndication = int(SPS[1])
|
||||
self.ProfileCompatibility = int(SPS[2])
|
||||
self.AVCLevelIndication = int(SPS[3])
|
||||
self.SPS = [][]byte{SPS}
|
||||
self.PPS = [][]byte{PPS}
|
||||
self.LengthSizeMinusOne = 3
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
func WriteAVCDecoderConfRecord(w io.Writer, self AVCDecoderConfRecord) (err error) {
|
||||
if err = bits.WriteUIntBE(w, 1, 8); err != nil {
|
||||
return
|
||||
@ -555,42 +537,85 @@ func WriteAVCDecoderConfRecord(w io.Writer, self AVCDecoderConfRecord) (err erro
|
||||
return
|
||||
}
|
||||
|
||||
type CodecInfo struct {
|
||||
Record AVCDecoderConfRecord
|
||||
type CodecData struct {
|
||||
Record []byte
|
||||
RecordInfo AVCDecoderConfRecord
|
||||
SPSInfo SPSInfo
|
||||
}
|
||||
|
||||
// CodecData is AVCDecoderConfRecord
|
||||
func ParseCodecData(config []byte) (info CodecInfo, err error) {
|
||||
if info.Record, err = ParseAVCDecoderConfRecord(config); err != nil {
|
||||
func (self CodecData) Type() int {
|
||||
return av.H264
|
||||
}
|
||||
|
||||
func (self CodecData) IsVideo() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (self CodecData) AVCDecoderConfRecordBytes() []byte {
|
||||
return self.Record
|
||||
}
|
||||
|
||||
func (self CodecData) SPS() []byte {
|
||||
return self.RecordInfo.SPS[0]
|
||||
}
|
||||
|
||||
func (self CodecData) PPS() []byte {
|
||||
return self.RecordInfo.PPS[0]
|
||||
}
|
||||
|
||||
func (self CodecData) IsAudio() bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func (self CodecData) Width() int {
|
||||
return int(self.SPSInfo.Width)
|
||||
}
|
||||
|
||||
func (self CodecData) Height() int {
|
||||
return int(self.SPSInfo.Height)
|
||||
}
|
||||
|
||||
func NewCodecDataFromAVCDecoderConfRecord(record []byte) (codec av.H264CodecData, err error) {
|
||||
self := CodecData{}
|
||||
self.Record = record
|
||||
if self.RecordInfo, err = ParseAVCDecoderConfRecord(record); err != nil {
|
||||
return
|
||||
}
|
||||
if len(info.Record.SPS) < 1 {
|
||||
err = fmt.Errorf("CodecData invalid: no SPS found in AVCDecoderConfRecord")
|
||||
if len(self.RecordInfo.SPS) == 0 {
|
||||
err = fmt.Errorf("no SPS found in AVCDecoderConfRecord")
|
||||
return
|
||||
}
|
||||
if info.SPSInfo, err = ParseSPS(info.Record.SPS[0]); err != nil {
|
||||
err = fmt.Errorf("CodecData invalid: parse SPS failed(%s)", err)
|
||||
if len(self.RecordInfo.PPS) == 0 {
|
||||
err = fmt.Errorf("no PPS found in AVCDecoderConfRecord")
|
||||
return
|
||||
}
|
||||
if self.SPSInfo, err = ParseSPS(self.RecordInfo.SPS[0]); err != nil {
|
||||
err = fmt.Errorf("parse SPS failed(%s)", err)
|
||||
return
|
||||
}
|
||||
codec = self
|
||||
return
|
||||
}
|
||||
|
||||
func CreateCodecDataBySPSAndPPS(SPS, PPS []byte) (codecData []byte, err error) {
|
||||
self := AVCDecoderConfRecord{}
|
||||
self.AVCProfileIndication = uint(SPS[1])
|
||||
self.ProfileCompatibility = uint(SPS[2])
|
||||
self.AVCLevelIndication = uint(SPS[3])
|
||||
self.SPS = [][]byte{SPS}
|
||||
self.PPS = [][]byte{PPS}
|
||||
self.LengthSizeMinusOne = 3
|
||||
|
||||
func NewCodecDataFromSPSAndPPS(sps, pps []byte) (codec av.H264CodecData, err error) {
|
||||
recordinfo := AVCDecoderConfRecord{}
|
||||
recordinfo.AVCProfileIndication = uint(sps[1])
|
||||
recordinfo.ProfileCompatibility = uint(sps[2])
|
||||
recordinfo.AVCLevelIndication = uint(sps[3])
|
||||
recordinfo.SPS = [][]byte{sps}
|
||||
recordinfo.PPS = [][]byte{pps}
|
||||
recordinfo.LengthSizeMinusOne = 3
|
||||
buf := &bytes.Buffer{}
|
||||
if err = WriteAVCDecoderConfRecord(buf, self); err != nil {
|
||||
if err = WriteAVCDecoderConfRecord(buf, recordinfo); err != nil {
|
||||
return
|
||||
}
|
||||
codecData = buf.Bytes()
|
||||
|
||||
self := CodecData{}
|
||||
self.RecordInfo = recordinfo
|
||||
self.Record = buf.Bytes()
|
||||
if self.SPSInfo, err = ParseSPS(sps); err != nil {
|
||||
return
|
||||
}
|
||||
codec = self
|
||||
return
|
||||
}
|
||||
|
||||
@ -726,3 +751,43 @@ func ParseSliceHeaderFromNALU(packet []byte) (sliceType SliceType, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
/*
|
||||
type CodecInfo struct {
|
||||
Record AVCDecoderConfRecord
|
||||
SPSInfo SPSInfo
|
||||
}
|
||||
|
||||
func ParseCodecData(config []byte) (info CodecInfo, err error) {
|
||||
if info.Record, err = ParseAVCDecoderConfRecord(config); err != nil {
|
||||
return
|
||||
}
|
||||
if len(info.Record.SPS) < 1 {
|
||||
err = fmt.Errorf("CodecData invalid: no SPS found in AVCDecoderConfRecord")
|
||||
return
|
||||
}
|
||||
if info.SPSInfo, err = ParseSPS(info.Record.SPS[0]); err != nil {
|
||||
err = fmt.Errorf("CodecData invalid: parse SPS failed(%s)", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func CreateCodecDataBySPSAndPPS(SPS, PPS []byte) (codecData []byte, err error) {
|
||||
self := AVCDecoderConfRecord{}
|
||||
self.AVCProfileIndication = uint(SPS[1])
|
||||
self.ProfileCompatibility = uint(SPS[2])
|
||||
self.AVCLevelIndication = uint(SPS[3])
|
||||
self.SPS = [][]byte{SPS}
|
||||
self.PPS = [][]byte{PPS}
|
||||
self.LengthSizeMinusOne = 3
|
||||
|
||||
buf := &bytes.Buffer{}
|
||||
if err = WriteAVCDecoderConfRecord(buf, self); err != nil {
|
||||
return
|
||||
}
|
||||
codecData = buf.Bytes()
|
||||
|
||||
return
|
||||
}
|
||||
*/
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user