mirror of https://bitbucket.org/ausocean/av.git
container/mts: filled Clip.Bytes
writing Clip.Bytes required a change to the Clip type. The Clip type now possess a slice that references the memory in which the Frames should reference for the media. Appropriate changes have been made to Extract and TestExtract to accomidate this change.
This commit is contained in:
parent
8f434e9703
commit
1323cbcae3
|
@ -8,18 +8,16 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
// Extract extracts the media from an MPEG-TS clip given by p.
|
// Extract extracts the media from an MPEG-TS clip given by p.
|
||||||
func Extract(p []byte) (Clip, error) {
|
func Extract(p []byte) (*Clip, error) {
|
||||||
l := len(p)
|
l := len(p)
|
||||||
// Check that clip is divisible by 188, i.e. contains a series of full MPEG-TS clips.
|
// Check that clip is divisible by 188, i.e. contains a series of full MPEG-TS clips.
|
||||||
if l%PacketSize != 0 {
|
if l%PacketSize != 0 {
|
||||||
return nil, errors.New("MTS clip is not of valid size")
|
return nil, errors.New("MTS clip is not of valid size")
|
||||||
}
|
}
|
||||||
|
|
||||||
// This will hold a copy of all the media in the MPEG-TS clip.
|
|
||||||
buf := make([]byte, 0, l/PacketSize)
|
|
||||||
|
|
||||||
var (
|
var (
|
||||||
clip Clip // The data that will be returned.
|
frameStart int // Index used to indicate the start of current frame in backing slice.
|
||||||
|
clip = &Clip{} // The data that will be returned.
|
||||||
meta map[string]string // Holds the most recently extracted meta.
|
meta map[string]string // Holds the most recently extracted meta.
|
||||||
lenOfFrame int // Len of current frame.
|
lenOfFrame int // Len of current frame.
|
||||||
dataLen int // Len of data from MPEG-TS packet.
|
dataLen int // Len of data from MPEG-TS packet.
|
||||||
|
@ -29,6 +27,9 @@ func Extract(p []byte) (Clip, error) {
|
||||||
err error
|
err error
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// This will hold a copy of all the media in the MPEG-TS clip.
|
||||||
|
clip.backing = make([]byte, 0, l/PacketSize)
|
||||||
|
|
||||||
// Go through the MPEGT-TS packets.
|
// Go through the MPEGT-TS packets.
|
||||||
var pkt packet.Packet
|
var pkt packet.Packet
|
||||||
for i := 0; i < l; i += PacketSize {
|
for i := 0; i < l; i += PacketSize {
|
||||||
|
@ -61,40 +62,42 @@ func Extract(p []byte) (Clip, error) {
|
||||||
// Extract the PTS and ID, then add a new frame to the clip.
|
// Extract the PTS and ID, then add a new frame to the clip.
|
||||||
curPTS = _pes.PTS()
|
curPTS = _pes.PTS()
|
||||||
curStreamID = _pes.StreamId()
|
curStreamID = _pes.StreamId()
|
||||||
clip = append(clip, Frame{
|
clip.frames = append(clip.frames, Frame{
|
||||||
PTS: curPTS,
|
PTS: curPTS,
|
||||||
ID: curStreamID,
|
ID: curStreamID,
|
||||||
Meta: meta,
|
Meta: meta,
|
||||||
})
|
})
|
||||||
|
|
||||||
// Append the data to the underlying buffer and get appended lenghth.
|
// Append the data to the underlying buffer and get appended lenghth.
|
||||||
buf = append(buf, _pes.Data()...)
|
clip.backing = append(clip.backing, _pes.Data()...)
|
||||||
dataLen = len(_pes.Data())
|
dataLen = len(_pes.Data())
|
||||||
|
|
||||||
// If we haven't hit the first PUSI, then we know we have a full frame
|
// If we haven't hit the first PUSI, then we know we have a full frame
|
||||||
// and can add this data to the frame pertaining to the finish frame.
|
// and can add this data to the frame pertaining to the finish frame.
|
||||||
if !firstPUSI {
|
if !firstPUSI {
|
||||||
clip[len(clip)-2].Media = buf[:lenOfFrame]
|
clip.frames[len(clip.frames)-2].Media = clip.backing[frameStart:lenOfFrame]
|
||||||
buf = buf[lenOfFrame:]
|
frameStart = lenOfFrame
|
||||||
lenOfFrame = 0
|
|
||||||
}
|
}
|
||||||
firstPUSI = false
|
firstPUSI = false
|
||||||
} else {
|
} else {
|
||||||
// We're not at the start of the frame, so we don't have a PES header.
|
// We're not at the start of the frame, so we don't have a PES header.
|
||||||
// We can append the MPEG-TS data directly to the underlying buf.
|
// We can append the MPEG-TS data directly to the underlying buf.
|
||||||
dataLen = len(payload)
|
dataLen = len(payload)
|
||||||
buf = append(buf, payload...)
|
clip.backing = append(clip.backing, payload...)
|
||||||
}
|
}
|
||||||
lenOfFrame += dataLen
|
lenOfFrame += dataLen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// We're finished up with media frames, so give the final Frame it's data.
|
// We're finished up with media frames, so give the final Frame it's data.
|
||||||
clip[len(clip)-1].Media = buf[:lenOfFrame]
|
clip.frames[len(clip.frames)-1].Media = clip.backing[frameStart:lenOfFrame]
|
||||||
return clip, nil
|
return clip, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clip represents a clip of media, i.e. a sequence of media frames.
|
// Clip represents a clip of media, i.e. a sequence of media frames.
|
||||||
type Clip []Frame
|
type Clip struct {
|
||||||
|
frames []Frame
|
||||||
|
backing []byte
|
||||||
|
}
|
||||||
|
|
||||||
// Frame describes a media frame that may be extracted from a PES packet.
|
// Frame describes a media frame that may be extracted from a PES packet.
|
||||||
type Frame struct {
|
type Frame struct {
|
||||||
|
@ -106,5 +109,8 @@ type Frame struct {
|
||||||
|
|
||||||
// Bytes returns the concatentated media bytes from each frame in the Clip c.
|
// Bytes returns the concatentated media bytes from each frame in the Clip c.
|
||||||
func (c *Clip) Bytes() []byte {
|
func (c *Clip) Bytes() []byte {
|
||||||
return nil
|
if c.backing == nil {
|
||||||
|
panic("the clip backing array cannot be nil")
|
||||||
|
}
|
||||||
|
return c.backing
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,7 +73,7 @@ func TestExtract(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create an equivalent Frame and append to our Clip want.
|
// Create an equivalent Frame and append to our Clip want.
|
||||||
want = append(want, Frame{
|
want.frames = append(want.frames, Frame{
|
||||||
Media: frame,
|
Media: frame,
|
||||||
PTS: nextPTS,
|
PTS: nextPTS,
|
||||||
ID: H264ID,
|
ID: H264ID,
|
||||||
|
@ -88,14 +88,14 @@ func TestExtract(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check length of got and want.
|
// Check length of got and want.
|
||||||
if len(want) != len(got) {
|
if len(want.frames) != len(got.frames) {
|
||||||
t.Fatalf("did not get expected length for got.\nGot: %v\n, Want: %v\n", len(got), len(want))
|
t.Fatalf("did not get expected length for got.\nGot: %v\n, Want: %v\n", len(got.frames), len(want.frames))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check frames individually.
|
// Check frames individually.
|
||||||
for i, frame := range want {
|
for i, frame := range want.frames {
|
||||||
if !reflect.DeepEqual(frame, got[i]) {
|
if !reflect.DeepEqual(frame, got.frames[i]) {
|
||||||
t.Fatalf("did not get expected result.\nGot: %v\n, Want: %v\n", got[i], frame)
|
t.Fatalf("did not get expected result.\nGot: %v\n, Want: %v\n", got.frames[i], frame)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue