1
- package media
1
+ package ffmpeg
2
2
3
3
import (
4
4
"encoding/json"
@@ -17,8 +17,9 @@ import (
17
17
////////////////////////////////////////////////////////////////////////////////
18
18
// TYPES
19
19
20
- type frame struct {
21
- ctx * ff.AVFrame
20
+ type Frame struct {
21
+ ctx * ff.AVFrame
22
+ stream int
22
23
}
23
24
24
25
var (
@@ -40,27 +41,32 @@ var (
40
41
////////////////////////////////////////////////////////////////////////////////
41
42
// LIFECYCLE
42
43
43
- func NewFrame (ctx * ff.AVFrame ) * frame {
44
- return & frame {ctx }
44
+ func NewFrame (ctx * ff.AVFrame , stream int ) * Frame {
45
+ return & Frame {ctx , stream }
45
46
}
46
47
47
48
////////////////////////////////////////////////////////////////////////////////
48
49
// STRINGIFY
49
50
50
- func (frame * frame ) MarshalJSON () ([]byte , error ) {
51
+ func (frame * Frame ) MarshalJSON () ([]byte , error ) {
51
52
return json .Marshal (frame .ctx )
52
53
}
53
54
54
- func (frame * frame ) String () string {
55
+ func (frame * Frame ) String () string {
55
56
data , _ := json .MarshalIndent (frame , "" , " " )
56
57
return string (data )
57
58
}
58
59
59
60
////////////////////////////////////////////////////////////////////////////////
60
61
// PARAMETERS
61
62
63
+ // Return the context
64
+ func (frame * Frame ) AVFrame () * ff.AVFrame {
65
+ return frame .ctx
66
+ }
67
+
62
68
// Return the media type (AUDIO, VIDEO)
63
- func (frame * frame ) Type () media.MediaType {
69
+ func (frame * Frame ) Type () media.MediaType {
64
70
if frame .ctx .NumSamples () > 0 {
65
71
return media .AUDIO
66
72
}
@@ -70,13 +76,13 @@ func (frame *frame) Type() media.MediaType {
70
76
return media .NONE
71
77
}
72
78
73
- // Id is unused
74
- func (frame * frame ) Id () int {
75
- return 0
79
+ // Return the stream
80
+ func (frame * Frame ) Id () int {
81
+ return frame . stream
76
82
}
77
83
78
84
// Return the timestamp as a duration, or minus one if not set
79
- func (frame * frame ) Time () time.Duration {
85
+ func (frame * Frame ) Time () time.Duration {
80
86
pts := frame .ctx .Pts ()
81
87
if pts == ff .AV_NOPTS_VALUE {
82
88
return - 1
@@ -89,17 +95,17 @@ func (frame *frame) Time() time.Duration {
89
95
90
96
// Return the number of planes for a specific PixelFormat
91
97
// or SampleFormat and ChannelLayout combination
92
- func (frame * frame ) NumPlanes () int {
98
+ func (frame * Frame ) NumPlanes () int {
93
99
return ff .AVUtil_frame_get_num_planes (frame .ctx )
94
100
}
95
101
96
102
// Return the byte data for a plane
97
- func (frame * frame ) Bytes (plane int ) []byte {
103
+ func (frame * Frame ) Bytes (plane int ) []byte {
98
104
return frame .ctx .Bytes (plane )[:frame .ctx .Planesize (plane )]
99
105
}
100
106
101
107
// Return the int16 data for a plane
102
- func (frame * frame ) Int16 (plane int ) []int16 {
108
+ func (frame * Frame ) Int16 (plane int ) []int16 {
103
109
sz := frame .ctx .Planesize (plane ) >> 1
104
110
return frame .ctx .Int16 (plane )[:sz ]
105
111
}
@@ -108,15 +114,15 @@ func (frame *frame) Int16(plane int) []int16 {
108
114
// AUDIO PARAMETERS
109
115
110
116
// Return number of samples
111
- func (frame * frame ) NumSamples () int {
117
+ func (frame * Frame ) NumSamples () int {
112
118
if frame .Type () != media .AUDIO {
113
119
return 0
114
120
}
115
121
return frame .ctx .NumSamples ()
116
122
}
117
123
118
124
// Return channel layout
119
- func (frame * frame ) ChannelLayout () string {
125
+ func (frame * Frame ) ChannelLayout () string {
120
126
if frame .Type () != media .AUDIO {
121
127
return ""
122
128
}
@@ -129,15 +135,15 @@ func (frame *frame) ChannelLayout() string {
129
135
}
130
136
131
137
// Return the sample format
132
- func (frame * frame ) SampleFormat () string {
138
+ func (frame * Frame ) SampleFormat () string {
133
139
if frame .Type () != media .AUDIO {
134
140
return ""
135
141
}
136
142
return ff .AVUtil_get_sample_fmt_name (frame .ctx .SampleFormat ())
137
143
}
138
144
139
145
// Return the sample rate (Hz)
140
- func (frame * frame ) Samplerate () int {
146
+ func (frame * Frame ) Samplerate () int {
141
147
if frame .Type () != media .AUDIO {
142
148
return 0
143
149
}
@@ -149,7 +155,7 @@ func (frame *frame) Samplerate() int {
149
155
// VIDEO PARAMETERS
150
156
151
157
// Convert a frame into an image
152
- func (frame * frame ) Image () (image.Image , error ) {
158
+ func (frame * Frame ) Image () (image.Image , error ) {
153
159
if t := frame .Type (); t != media .VIDEO {
154
160
return nil , ErrBadParameter .With ("unsupported frame type" , t )
155
161
}
@@ -205,7 +211,7 @@ func (frame *frame) Image() (image.Image, error) {
205
211
}
206
212
207
213
// Return the number of bytes in a single row of the video frame
208
- func (frame * frame ) Stride (plane int ) int {
214
+ func (frame * Frame ) Stride (plane int ) int {
209
215
if frame .Type () == media .VIDEO {
210
216
return frame .ctx .Linesize (plane )
211
217
} else {
@@ -214,23 +220,23 @@ func (frame *frame) Stride(plane int) int {
214
220
}
215
221
216
222
// Return the width of the video frame
217
- func (frame * frame ) Width () int {
223
+ func (frame * Frame ) Width () int {
218
224
if frame .Type () != media .VIDEO {
219
225
return 0
220
226
}
221
227
return frame .ctx .Width ()
222
228
}
223
229
224
230
// Return the height of the video frame
225
- func (frame * frame ) Height () int {
231
+ func (frame * Frame ) Height () int {
226
232
if frame .Type () != media .VIDEO {
227
233
return 0
228
234
}
229
235
return frame .ctx .Height ()
230
236
}
231
237
232
238
// Return the pixel format
233
- func (frame * frame ) PixelFormat () string {
239
+ func (frame * Frame ) PixelFormat () string {
234
240
if frame .Type () != media .VIDEO {
235
241
return ""
236
242
}
0 commit comments