Skip to content

Commit 158af38

Browse files
authored
Merge pull request #29 from danielpaulus/simplyFy
simplify asyn code
2 parents a4e8d50 + 9b2621b commit 158af38

38 files changed

+352
-342
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
.vscode
2+
quicktime_video_hack
23
# Binaries for programs and plugins
34
main
45
*.exe

screencapture/messageprocessor.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ func (mp *MessageProcessor) handleAsyncPacket(data []byte) {
167167
switch binary.LittleEndian.Uint32(data[12:]) {
168168
case packet.EAT:
169169
mp.audioSamplesReceived++
170-
eatPacket, err := packet.NewAsynEatPacketFromBytes(data)
170+
eatPacket, err := packet.NewAsynCmSampleBufPacketFromBytes(data)
171171
if err != nil {
172172
log.Warn("unknown eat")
173173
return
@@ -181,7 +181,7 @@ func (mp *MessageProcessor) handleAsyncPacket(data []byte) {
181181
log.Debugf("RCV Audio Samples:%d", mp.audioSamplesReceived)
182182
}
183183
case packet.FEED:
184-
feedPacket, err := packet.NewAsynFeedPacketFromBytes(data)
184+
feedPacket, err := packet.NewAsynCmSampleBufPacketFromBytes(data)
185185
if err != nil {
186186
//log.Errorf("Error parsing FEED packet: %x %s", data, err)
187187
log.Warn("unknown feed")
@@ -237,6 +237,8 @@ func (mp *MessageProcessor) handleAsyncPacket(data []byte) {
237237
}
238238
}
239239

240+
//CloseSession shuts down the streams on the device by sending HPA0 and HPD0
241+
//messages and waiting for RELS messages.
240242
func (mp *MessageProcessor) CloseSession() {
241243
log.Info("Telling device to stop streaming..")
242244
mp.usbWriter.WriteDataToUsb(packet.NewAsynHPA0(mp.deviceAudioClockRef))

screencapture/packet/asyn.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,3 +122,25 @@ func CreateHpa1DeviceInfoDict() coremedia.StringKeyDict {
122122
}
123123
return resultDict
124124
}
125+
126+
//NewAsynHPD0 creates the bytes needed for stopping video streaming
127+
func NewAsynHPD0() []byte {
128+
length := 20
129+
data := make([]byte, length)
130+
binary.LittleEndian.PutUint32(data, uint32(length))
131+
binary.LittleEndian.PutUint32(data[4:], AsynPacketMagic)
132+
binary.LittleEndian.PutUint64(data[8:], EmptyCFType)
133+
binary.LittleEndian.PutUint32(data[16:], HPD0)
134+
return data
135+
}
136+
137+
//NewAsynHPA0 creates the bytes needed for stopping audio streaming
138+
func NewAsynHPA0(clockRef uint64) []byte {
139+
length := 20
140+
data := make([]byte, length)
141+
binary.LittleEndian.PutUint32(data, uint32(length))
142+
binary.LittleEndian.PutUint32(data[4:], AsynPacketMagic)
143+
binary.LittleEndian.PutUint64(data[8:], clockRef)
144+
binary.LittleEndian.PutUint32(data[16:], HPA0)
145+
return data
146+
}

screencapture/packet/asyn_feed.go

Lines changed: 14 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -7,53 +7,30 @@ import (
77
"github.com/danielpaulus/quicktime_video_hack/screencapture/coremedia"
88
)
99

10-
//AsynFeedPacket contains a CMSampleBuffer and there the actual video data
11-
type AsynFeedPacket struct {
12-
AsyncMagic uint32
10+
//AsynCmSampleBufPacket contains a CMSampleBuffer with audio or video data
11+
type AsynCmSampleBufPacket struct {
1312
ClockRef CFTypeID
14-
MessageType uint32
1513
CMSampleBuf coremedia.CMSampleBuffer
1614
}
1715

18-
//AsynEatPacket contains a CMSampleBuffer with audio data
19-
type AsynEatPacket struct {
20-
AsyncMagic uint32
21-
ClockRef CFTypeID
22-
MessageType uint32
23-
CMSampleBuf coremedia.CMSampleBuffer
24-
}
25-
26-
//NewAsynEatPacketFromBytes parses a new AsynEatPacket from bytes
27-
func NewAsynEatPacketFromBytes(data []byte) (AsynEatPacket, error) {
28-
clockRef, sBuf, err := newAsynCmSampleBufferPacketFromBytes(data, EAT)
16+
//NewAsynCmSampleBufPacketFromBytes parses a new AsynCmSampleBufPacket from bytes
17+
func NewAsynCmSampleBufPacketFromBytes(data []byte) (AsynCmSampleBufPacket, error) {
18+
clockRef, sBuf, err := newAsynCmSampleBufferPacketFromBytes(data)
2919
if err != nil {
30-
return AsynEatPacket{}, err
20+
return AsynCmSampleBufPacket{}, err
3121
}
32-
return AsynEatPacket{AsyncMagic: AsynPacketMagic, ClockRef: clockRef, MessageType: EAT, CMSampleBuf: sBuf}, nil
22+
return AsynCmSampleBufPacket{ClockRef: clockRef, CMSampleBuf: sBuf}, nil
3323
}
3424

35-
//NewAsynFeedPacketFromBytes parses a new AsynFeedPacket from bytes
36-
func NewAsynFeedPacketFromBytes(data []byte) (AsynFeedPacket, error) {
37-
clockRef, sBuf, err := newAsynCmSampleBufferPacketFromBytes(data, FEED)
25+
func newAsynCmSampleBufferPacketFromBytes(data []byte) (CFTypeID, coremedia.CMSampleBuffer, error) {
26+
magic := binary.LittleEndian.Uint32(data[12:])
27+
_, clockRef, err := ParseAsynHeader(data, magic)
3828
if err != nil {
39-
return AsynFeedPacket{}, err
29+
return 0, coremedia.CMSampleBuffer{}, err
4030
}
41-
return AsynFeedPacket{AsyncMagic: AsynPacketMagic, ClockRef: clockRef, MessageType: FEED, CMSampleBuf: sBuf}, nil
42-
}
43-
44-
func newAsynCmSampleBufferPacketFromBytes(data []byte, magic uint32) (CFTypeID, coremedia.CMSampleBuffer, error) {
4531

46-
asyncMagic := binary.LittleEndian.Uint32(data)
47-
if asyncMagic != AsynPacketMagic {
48-
return 0, coremedia.CMSampleBuffer{}, fmt.Errorf("invalid asyn magic: %x", data)
49-
}
50-
clockRef := binary.LittleEndian.Uint64(data[4:])
51-
messageType := binary.LittleEndian.Uint32(data[12:])
52-
if messageType != magic {
53-
return 0, coremedia.CMSampleBuffer{}, fmt.Errorf("invalid packet type in asyn cmsamplebufferpacket:%x", data)
54-
}
5532
var cMSampleBuf coremedia.CMSampleBuffer
56-
var err error
33+
5734
if magic == FEED {
5835
cMSampleBuf, err = coremedia.NewCMSampleBufferFromBytesVideo(data[16:])
5936
if err != nil {
@@ -69,10 +46,6 @@ func newAsynCmSampleBufferPacketFromBytes(data []byte, magic uint32) (CFTypeID,
6946
return clockRef, cMSampleBuf, nil
7047
}
7148

72-
func (sp AsynFeedPacket) String() string {
73-
return fmt.Sprintf("ASYN_FEED{ClockRef:%x, sBuf:%s}", sp.ClockRef, sp.CMSampleBuf.String())
74-
}
75-
76-
func (sp AsynEatPacket) String() string {
77-
return fmt.Sprintf("ASYN_EAT!{ClockRef:%x, sBuf:%s}", sp.ClockRef, sp.CMSampleBuf.String())
49+
func (sp AsynCmSampleBufPacket) String() string {
50+
return fmt.Sprintf("ASYN_SBUF{ClockRef:%x, sBuf:%s}", sp.ClockRef, sp.CMSampleBuf.String())
7851
}

screencapture/packet/asyn_feed_test.go

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,23 @@ import (
55
"log"
66
"testing"
77

8+
"github.com/danielpaulus/quicktime_video_hack/screencapture/coremedia"
89
"github.com/danielpaulus/quicktime_video_hack/screencapture/packet"
910
"github.com/stretchr/testify/assert"
1011
)
1112

13+
const expectedString = `ASYN_SBUF{ClockRef:7ffb5cc32f60, sBuf:{OutputPresentationTS:CMTime{95911997690984/1000000000, flags:KCMTimeFlagsHasBeenRounded, epoch:0}, NumSamples:1, Nalus:[{len:30 type:SEI},{len:90712 type:IDR},], fdsc:fdsc:{MediaType:Video, VideoDimension:(1126x2436), Codec:AVC-1, PPS:27640033ac5680470133e69e6e04040404, SPS:28ee3cb0, Extensions:IndexKeyDict:[{49 : IndexKeyDict:[{105 : 0x01640033ffe1001127640033ac5680470133e69e6e0404040401000428ee3cb0fdf8f800},]},{52 : H.264},]}, attach:IndexKeyDict:[{28 : IndexKeyDict:[{46 : Float64[2436.000000]},{47 : Float64[2436.000000]},]},{29 : Int32[0]},{26 : IndexKeyDict:[{46 : Float64[1126.000000]},{47 : Float64[2436.000000]},{45 : Float64[0.000000]},{44 : Float64[0.000000]},]},{27 : IndexKeyDict:[{46 : Float64[1126.000000]},{47 : Float64[2436.000000]},{45 : Float64[0.000000]},{44 : Float64[0.000000]},]},], sary:IndexKeyDict:[{4 : %!s(bool=false)},], SampleTimingInfoArray:{Duration:CMTime{1/60, flags:KCMTimeFlagsHasBeenRounded, epoch:0}, PresentationTS:CMTime{95911997690984/1000000000, flags:KCMTimeFlagsHasBeenRounded, epoch:0}, DecodeTS:CMTime{0/0, flags:KCMTimeFlagsValid, epoch:0}}}}`
14+
1215
func TestFeed(t *testing.T) {
1316
dat, err := ioutil.ReadFile("fixtures/asyn-feed")
1417
if err != nil {
1518
log.Fatal(err)
1619
}
17-
feedPacket, err := packet.NewAsynFeedPacketFromBytes(dat[4:])
20+
feedPacket, err := packet.NewAsynCmSampleBufPacketFromBytes(dat[4:])
1821
if assert.NoError(t, err) {
1922
assert.Equal(t, uint64(0x7ffb5cc32f60), feedPacket.ClockRef)
20-
assert.Equal(t, packet.AsynPacketMagic, feedPacket.AsyncMagic)
21-
assert.Equal(t, packet.FEED, feedPacket.MessageType)
23+
assert.Equal(t, expectedString, feedPacket.String())
24+
assert.Equal(t, coremedia.MediaTypeVideo, feedPacket.CMSampleBuf.MediaType)
2225
}
2326
}
2427

@@ -27,10 +30,9 @@ func TestEat(t *testing.T) {
2730
if err != nil {
2831
log.Fatal(err)
2932
}
30-
feedPacket, err := packet.NewAsynEatPacketFromBytes(dat)
33+
feedPacket, err := packet.NewAsynCmSampleBufPacketFromBytes(dat)
3134
if assert.NoError(t, err) {
3235
assert.Equal(t, uint64(0x133959728), feedPacket.ClockRef)
33-
assert.Equal(t, packet.AsynPacketMagic, feedPacket.AsyncMagic)
34-
assert.Equal(t, packet.EAT, feedPacket.MessageType)
36+
assert.Equal(t, coremedia.MediaTypeSound, feedPacket.CMSampleBuf.MediaType)
3537
}
3638
}

screencapture/packet/asyn_hp.go

Lines changed: 0 additions & 25 deletions
This file was deleted.

screencapture/packet/asyn_hp_test.go

Lines changed: 0 additions & 25 deletions
This file was deleted.

screencapture/packet/asyn_rels.go

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,22 @@
11
package packet
22

33
import (
4-
"encoding/binary"
54
"fmt"
65
)
76

87
//AsynRelsPacket tells us that a clock was released
98
type AsynRelsPacket struct {
10-
AsyncMagic uint32
11-
ClockRef CFTypeID
12-
MessageType uint32
9+
ClockRef CFTypeID
1310
}
1411

1512
//NewAsynRelsPacketFromBytes creates a new AsynRelsPacket from bytes
1613
func NewAsynRelsPacketFromBytes(data []byte) (AsynRelsPacket, error) {
1714
var packet = AsynRelsPacket{}
18-
packet.AsyncMagic = binary.LittleEndian.Uint32(data)
19-
if packet.AsyncMagic != AsynPacketMagic {
20-
return packet, fmt.Errorf("invalid asyn magic: %x", data)
21-
}
22-
packet.ClockRef = binary.LittleEndian.Uint64(data[4:])
23-
packet.MessageType = binary.LittleEndian.Uint32(data[12:])
24-
if packet.MessageType != RELS {
25-
return packet, fmt.Errorf("invalid packet type in asyn rels:%x", data)
15+
_, clockRef, err := ParseAsynHeader(data, RELS)
16+
if err != nil {
17+
return packet, err
2618
}
19+
packet.ClockRef = clockRef
2720

2821
return packet, nil
2922
}

screencapture/packet/asyn_rels_test.go

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,6 @@ func TestRels(t *testing.T) {
1717
relsPacket, err := packet.NewAsynRelsPacketFromBytes(dat[4:])
1818
if assert.NoError(t, err) {
1919
assert.Equal(t, uint64(0x7fba35608a00), relsPacket.ClockRef)
20-
assert.Equal(t, packet.AsynPacketMagic, relsPacket.AsyncMagic)
21-
assert.Equal(t, packet.RELS, relsPacket.MessageType)
2220
assert.Equal(t, "ASYN_RELS{ClockRef:7fba35608a00}", relsPacket.String())
2321
}
2422
}

screencapture/packet/asyn_sprp.go

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,26 @@
11
package packet
22

33
import (
4-
"encoding/binary"
54
"fmt"
5+
66
"github.com/danielpaulus/quicktime_video_hack/screencapture/coremedia"
77
)
88

99
//AsynSprpPacket seems to be a set property packet sent by the device.
1010
type AsynSprpPacket struct {
11-
AsyncMagic uint32
12-
ClockRef CFTypeID
13-
MessageType uint32
14-
Property coremedia.StringKeyEntry
11+
ClockRef CFTypeID
12+
Property coremedia.StringKeyEntry
1513
}
1614

1715
//NewAsynSprpPacketFromBytes creates a new AsynSprpPacket from bytes
1816
func NewAsynSprpPacketFromBytes(data []byte) (AsynSprpPacket, error) {
1917
var packet = AsynSprpPacket{}
20-
packet.AsyncMagic = binary.LittleEndian.Uint32(data)
21-
if packet.AsyncMagic != AsynPacketMagic {
22-
return packet, fmt.Errorf("invalid asyn magic: %x", data)
23-
}
24-
packet.ClockRef = binary.LittleEndian.Uint64(data[4:])
25-
packet.MessageType = binary.LittleEndian.Uint32(data[12:])
26-
if packet.MessageType != SPRP {
27-
return packet, fmt.Errorf("invalid packet type in asyn sprp:%x", data)
18+
remainingBytes, clockRef, err := ParseAsynHeader(data, SPRP)
19+
if err != nil {
20+
return packet, err
2821
}
29-
entry, err := coremedia.ParseKeyValueEntry(data[16:])
22+
packet.ClockRef = clockRef
23+
entry, err := coremedia.ParseKeyValueEntry(remainingBytes)
3024
if err != nil {
3125
return packet, err
3226
}

0 commit comments

Comments
 (0)