h264parser: remove old bits use

This commit is contained in:
nareix 2016-07-15 01:21:29 +08:00
parent b8afa6ca0c
commit 9feea9df46

View File

@ -4,7 +4,7 @@ package h264parser
import ( import (
"github.com/nareix/joy4/av" "github.com/nareix/joy4/av"
"github.com/nareix/bits" "github.com/nareix/bits"
"io" "github.com/nareix/pio"
"fmt" "fmt"
"bytes" "bytes"
) )
@ -199,26 +199,8 @@ Additionally, there is a new variable called NALULengthSizeMinusOne. This confus
An advantage to this format is the ability to configure the decoder at the start and jump into the middle of a stream. This is a common use case where the media is available on a random access medium such as a hard drive, and is therefore used in common container formats such as MP4 and MKV. An advantage to this format is the ability to configure the decoder at the start and jump into the middle of a stream. This is a common use case where the media is available on a random access medium such as a hard drive, and is therefore used in common container formats such as MP4 and MKV.
*/ */
func WalkNALUsAnnexb(nalus [][]byte, write func([]byte)) { var StartCodeBytes = []byte{0,0,1}
for i, nalu := range(nalus) { var AUDBytes = []byte{0,0,0,1,0x9,0xf0,0,0,0,1} // AUD
if i == 0 {
write([]byte{0,0,0,1,0x9,0xf0,0,0,0,1}) // AUD
} else {
write([]byte{0,0,1})
}
write(nalu)
}
return
}
func WalkNALUsAVCC(nalus [][]byte, write func([]byte)) {
for _, nalu := range(nalus) {
var b [4]byte
bits.PutUIntBE(b[:], uint(len(nalu)), 32)
write(b[:])
write(nalu)
}
}
func CheckNALUsType(b []byte) (typ int) { func CheckNALUsType(b []byte) (typ int) {
_, typ = SplitNALUs(b) _, typ = SplitNALUs(b)
@ -236,11 +218,11 @@ func SplitNALUs(b []byte) (nalus [][]byte, typ int) {
return [][]byte{b}, NALU_RAW return [][]byte{b}, NALU_RAW
} }
val3 := bits.GetUIntBE(b, 24) val3 := pio.U24BE(b)
val4 := bits.GetUIntBE(b, 32) val4 := pio.U32BE(b)
// maybe AVCC // maybe AVCC
if val4 <= uint(len(b)) { if val4 <= uint32(len(b)) {
_val4 := val4 _val4 := val4
_b := b[4:] _b := b[4:]
nalus := [][]byte{} nalus := [][]byte{}
@ -250,9 +232,9 @@ func SplitNALUs(b []byte) (nalus [][]byte, typ int) {
if len(_b) < 4 { if len(_b) < 4 {
break break
} }
_val4 = bits.GetUIntBE(_b, 32) _val4 = pio.U32BE(_b)
_b = _b[4:] _b = _b[4:]
if _val4 > uint(len(_b)) { if _val4 > uint32(len(_b)) {
break break
} }
} }
@ -284,10 +266,10 @@ func SplitNALUs(b []byte) (nalus [][]byte, typ int) {
_val4 = 0 _val4 = 0
for pos < len(b) { for pos < len(b) {
if pos+2 < len(b) && b[pos] == 0 { if pos+2 < len(b) && b[pos] == 0 {
_val3 = bits.GetUIntBE(b[pos:], 24) _val3 = pio.U24BE(b[pos:])
if _val3 == 0 { if _val3 == 0 {
if pos+3 < len(b) { if pos+3 < len(b) {
_val4 = uint(b[pos+3]) _val4 = uint32(b[pos+3])
if _val4 == 1 { if _val4 == 1 {
break break
} }
@ -516,50 +498,6 @@ func ParseSPS(data []byte) (self SPSInfo, err error) {
return return
} }
func WriteAVCDecoderConfRecord(w io.Writer, self AVCDecoderConfRecord) (err error) {
if err = bits.WriteUIntBE(w, 1, 8); err != nil {
return
}
if err = bits.WriteUIntBE(w, uint(self.AVCProfileIndication), 8); err != nil {
return
}
if err = bits.WriteUIntBE(w, uint(self.ProfileCompatibility), 8); err != nil {
return
}
if err = bits.WriteUIntBE(w, uint(self.AVCLevelIndication), 8); err != nil {
return
}
if err = bits.WriteUIntBE(w, uint(self.LengthSizeMinusOne|0xfc), 8); err != nil {
return
}
if err = bits.WriteUIntBE(w, uint(len(self.SPS)|0xe0), 8); err != nil {
return
}
for _, data := range self.SPS {
if err = bits.WriteUIntBE(w, uint(len(data)), 16); err != nil {
return
}
if err = bits.WriteBytes(w, data, len(data)); err != nil {
return
}
}
if err = bits.WriteUIntBE(w, uint(len(self.PPS)), 8); err != nil {
return
}
for _, data := range self.PPS {
if err = bits.WriteUIntBE(w, uint(len(data)), 16); err != nil {
return
}
if err = bits.WriteBytes(w, data, len(data)); err != nil {
return
}
}
return
}
type CodecData struct { type CodecData struct {
Record []byte Record []byte
RecordInfo AVCDecoderConfRecord RecordInfo AVCDecoderConfRecord
@ -592,7 +530,7 @@ func (self CodecData) Height() int {
func NewCodecDataFromAVCDecoderConfRecord(record []byte) (self CodecData, err error) { func NewCodecDataFromAVCDecoderConfRecord(record []byte) (self CodecData, err error) {
self.Record = record self.Record = record
if self.RecordInfo, err = ParseAVCDecoderConfRecord(record); err != nil { if _, err = (&self.RecordInfo).Unmarshal(record); err != nil {
return return
} }
if len(self.RecordInfo.SPS) == 0 { if len(self.RecordInfo.SPS) == 0 {
@ -612,18 +550,19 @@ func NewCodecDataFromAVCDecoderConfRecord(record []byte) (self CodecData, err er
func NewCodecDataFromSPSAndPPS(sps, pps []byte) (self CodecData, err error) { func NewCodecDataFromSPSAndPPS(sps, pps []byte) (self CodecData, err error) {
recordinfo := AVCDecoderConfRecord{} recordinfo := AVCDecoderConfRecord{}
recordinfo.AVCProfileIndication = uint(sps[1]) recordinfo.AVCProfileIndication = sps[1]
recordinfo.ProfileCompatibility = uint(sps[2]) recordinfo.ProfileCompatibility = sps[2]
recordinfo.AVCLevelIndication = uint(sps[3]) recordinfo.AVCLevelIndication = sps[3]
recordinfo.SPS = [][]byte{sps} recordinfo.SPS = [][]byte{sps}
recordinfo.PPS = [][]byte{pps} recordinfo.PPS = [][]byte{pps}
recordinfo.LengthSizeMinusOne = 3 recordinfo.LengthSizeMinusOne = 3
buf := &bytes.Buffer{}
if err = WriteAVCDecoderConfRecord(buf, recordinfo); err != nil { buf := make([]byte, recordinfo.Len())
return recordinfo.Marshal(buf)
}
self.RecordInfo = recordinfo self.RecordInfo = recordinfo
self.Record = buf.Bytes() self.Record = buf
if self.SPSInfo, err = ParseSPS(sps); err != nil { if self.SPSInfo, err = ParseSPS(sps); err != nil {
return return
} }
@ -631,66 +570,106 @@ func NewCodecDataFromSPSAndPPS(sps, pps []byte) (self CodecData, err error) {
} }
type AVCDecoderConfRecord struct { type AVCDecoderConfRecord struct {
AVCProfileIndication uint AVCProfileIndication uint8
ProfileCompatibility uint ProfileCompatibility uint8
AVCLevelIndication uint AVCLevelIndication uint8
LengthSizeMinusOne uint LengthSizeMinusOne uint8
SPS [][]byte SPS [][]byte
PPS [][]byte PPS [][]byte
} }
func ParseAVCDecoderConfRecord(config []byte) (self AVCDecoderConfRecord, err error) { var ErrDecconfInvalid = fmt.Errorf("h264parser: AVCDecoderConfRecord invalid")
r := bytes.NewReader(config)
if _, err = bits.ReadUIntBE(r, 8); err != nil { func (self *AVCDecoderConfRecord) Unmarshal(b []byte) (n int, err error) {
if len(b) < 7 {
err = ErrDecconfInvalid
return return
} }
if self.AVCProfileIndication, err = bits.ReadUIntBE(r, 8); err != nil {
return
}
if self.ProfileCompatibility, err = bits.ReadUIntBE(r, 8); err != nil {
return
}
if self.AVCLevelIndication, err = bits.ReadUIntBE(r, 8); err != nil {
return
}
if self.LengthSizeMinusOne, err = bits.ReadUIntBE(r, 8); err != nil {
return
}
self.LengthSizeMinusOne &= 0x03
var u uint
var n, length int
var data []byte
if u, err = bits.ReadUIntBE(r, 8); err != nil {
return
}
n = int(u&0x1f)
for i := 0; i < n; i++ {
if u, err = bits.ReadUIntBE(r, 16); err != nil {
return
}
length = int(u)
if data, err = bits.ReadBytes(r, length); err != nil {
return
}
self.SPS = append(self.SPS, data)
}
if u, err = bits.ReadUIntBE(r, 8); err != nil { self.AVCProfileIndication = b[1]
self.ProfileCompatibility = b[2]
self.AVCLevelIndication = b[3]
self.LengthSizeMinusOne = b[4]&0x03
spscount := int(b[5]&0x1f)
n += 6
for i := 0; i < spscount; i++ {
if len(b) < n+2 {
err = ErrDecconfInvalid
return
}
spslen := int(pio.U16BE(b[n:]))
n += 2
if len(b) < n+spslen {
err = ErrDecconfInvalid
return
}
self.SPS = append(self.SPS, b[n:n+spslen])
n += spslen
}
if len(b) < n+1 {
err = ErrDecconfInvalid
return return
} }
n = int(u) ppscount := int(b[n])
for i := 0; i < n; i++ { n++
if u, err = bits.ReadUIntBE(r, 16); err != nil {
for i := 0; i < ppscount; i++ {
if len(b) < n+2 {
err = ErrDecconfInvalid
return return
} }
length = int(u) ppslen := int(pio.U16BE(b[n:]))
if data, err = bits.ReadBytes(r, length); err != nil { n += 2
if len(b) < n+ppslen {
err = ErrDecconfInvalid
return return
} }
self.PPS = append(self.PPS, data) self.PPS = append(self.PPS, b[n:n+ppslen])
n += ppslen
}
return
}
func (self AVCDecoderConfRecord) Len() (n int) {
n = 7
for _, sps := range self.SPS {
n += 2+len(sps)
}
for _, pps := range self.PPS {
n += 2+len(pps)
}
return
}
func (self AVCDecoderConfRecord) Marshal(b []byte) (n int) {
b[0] = 1
b[1] = self.AVCProfileIndication
b[2] = self.ProfileCompatibility
b[3] = self.AVCLevelIndication
b[4] = self.LengthSizeMinusOne|0xfc
b[5] = uint8(len(self.SPS))|0xe0
n += 6
for _, sps := range self.SPS {
pio.PutU16BE(b[n:], uint16(len(sps)))
n += 2
copy(b[n:], sps)
n += len(sps)
}
b[n] = uint8(len(self.PPS))
n++
for _, pps := range self.PPS {
pio.PutU16BE(b[n:], uint16(len(pps)))
n += 2
copy(b[n:], pps)
n += len(pps)
} }
return return
@ -762,43 +741,3 @@ func ParseSliceHeaderFromNALU(packet []byte) (sliceType SliceType, err error) {
return 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
}
*/