-
Notifications
You must be signed in to change notification settings - Fork 45
/
codec_context.go
450 lines (374 loc) · 14.2 KB
/
codec_context.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
package astiav
//#include "codec_context.h"
import "C"
import (
"sync"
"unsafe"
)
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html
type CodecContext struct {
c *C.AVCodecContext
// We need to store this to unref it properly
hdc *HardwareDeviceContext
hfc *HardwareFrameContext
}
func newCodecContextFromC(c *C.AVCodecContext) *CodecContext {
if c == nil {
return nil
}
cc := &CodecContext{c: c}
classers.set(cc)
return cc
}
var _ Classer = (*CodecContext)(nil)
// https://ffmpeg.org/doxygen/7.0/group__lavc__core.html#gae80afec6f26df6607eaacf39b561c315
func AllocCodecContext(c *Codec) *CodecContext {
var cc *C.AVCodec
if c != nil {
cc = c.c
}
return newCodecContextFromC(C.avcodec_alloc_context3(cc))
}
// https://ffmpeg.org/doxygen/7.0/group__lavc__core.html#gaf869d0829ed607cec3a4a02a1c7026b3
func (cc *CodecContext) Free() {
if cc.hdc != nil {
C.av_buffer_unref(&cc.hdc.c)
cc.hdc = nil
}
if cc.hfc != nil {
C.av_buffer_unref(&cc.hfc.c)
cc.hfc = nil
}
if cc.c != nil {
// Make sure to clone the classer before freeing the object since
// the C free method may reset the pointer
c := newClonedClasser(cc)
C.avcodec_free_context(&cc.c)
// Make sure to remove from classers after freeing the object since
// the C free method may use methods needing the classer
if c != nil {
classers.del(c)
}
}
}
func (cc *CodecContext) String() string {
s, _ := stringFromC(255, func(buf *C.char, size C.size_t) error {
C.avcodec_string(buf, C.int(size), cc.c, C.int(0))
return nil
})
return s
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a6b53fda85ad61baa345edbd96cb8a33c
func (cc *CodecContext) BitRate() int64 {
return int64(cc.c.bit_rate)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a6b53fda85ad61baa345edbd96cb8a33c
func (cc *CodecContext) SetBitRate(bitRate int64) {
cc.c.bit_rate = C.int64_t(bitRate)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a167ff73c67960acf2d5ca73d93e13f64
func (cc *CodecContext) ChannelLayout() ChannelLayout {
l, _ := newChannelLayoutFromC(&cc.c.ch_layout).clone()
return l
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a167ff73c67960acf2d5ca73d93e13f64
func (cc *CodecContext) SetChannelLayout(l ChannelLayout) {
l.copy(&cc.c.ch_layout) //nolint: errcheck
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#ac60a0209642b5d74068cab0ac35a78b2
func (cc *CodecContext) ChromaLocation() ChromaLocation {
return ChromaLocation(cc.c.chroma_sample_location)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a90622d3af2a9abba986a1c9f7ca21b16
func (cc *CodecContext) Class() *Class {
return newClassFromC(unsafe.Pointer(cc.c))
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#adc5f65d6099fd8339c1580c091777223
func (cc *CodecContext) CodecID() CodecID {
return CodecID(cc.c.codec_id)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a3a41b3e5bde23b877799f6e72dac8ef3
func (cc *CodecContext) ColorPrimaries() ColorPrimaries {
return ColorPrimaries(cc.c.color_primaries)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a255bf7100a4ba6dcb6ee5d87740a4f35
func (cc *CodecContext) ColorRange() ColorRange {
return ColorRange(cc.c.color_range)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a8cd8caa7d40319324ce3d879a2edbd9f
func (cc *CodecContext) ColorSpace() ColorSpace {
return ColorSpace(cc.c.colorspace)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#ab649e8c599f5a0e2a30448e67a36deb6
func (cc *CodecContext) ColorTransferCharacteristic() ColorTransferCharacteristic {
return ColorTransferCharacteristic(cc.c.color_trc)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#abe964316aaaa61967b012efdcced79c4
func (cc *CodecContext) ExtraData() []byte {
return bytesFromC(func(size *C.size_t) *C.uint8_t {
*size = C.size_t(cc.c.extradata_size)
return cc.c.extradata
})
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#abe964316aaaa61967b012efdcced79c4
func (cc *CodecContext) SetExtraData(b []byte) error {
return setBytesWithIntSizeInC(b, &cc.c.extradata, &cc.c.extradata_size)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#abb01e291550fa3fb96188af4d494587e
func (cc *CodecContext) Flags() CodecContextFlags {
return CodecContextFlags(cc.c.flags)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#abb01e291550fa3fb96188af4d494587e
func (cc *CodecContext) SetFlags(fs CodecContextFlags) {
cc.c.flags = C.int(fs)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a1944f9a4f8f2e123c087e1fe7613d571
func (cc *CodecContext) Flags2() CodecContextFlags2 {
return CodecContextFlags2(cc.c.flags2)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a1944f9a4f8f2e123c087e1fe7613d571
func (cc *CodecContext) SetFlags2(fs CodecContextFlags2) {
cc.c.flags2 = C.int(fs)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a4d08b297e97eefd66c714df4fff493c8
func (cc *CodecContext) Framerate() Rational {
return newRationalFromC(cc.c.framerate)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a4d08b297e97eefd66c714df4fff493c8
func (cc *CodecContext) SetFramerate(f Rational) {
cc.c.framerate = f.c
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#aec57f0d859a6df8b479cd93ca3a44a33
func (cc *CodecContext) FrameSize() int {
return int(cc.c.frame_size)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a9b6b3f1fcbdcc2ad9f4dbb4370496e38
func (cc *CodecContext) GopSize() int {
return int(cc.c.gop_size)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a9b6b3f1fcbdcc2ad9f4dbb4370496e38
func (cc *CodecContext) SetGopSize(gopSize int) {
cc.c.gop_size = C.int(gopSize)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a0449afd803eb107bd4dbc8b5ea22e363
func (cc *CodecContext) Height() int {
return int(cc.c.height)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a0449afd803eb107bd4dbc8b5ea22e363
func (cc *CodecContext) SetHeight(height int) {
cc.c.height = C.int(height)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a6927dc652ae6241f1dfdbad4e12d3a40
func (cc *CodecContext) Level() Level {
return Level(cc.c.level)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a6927dc652ae6241f1dfdbad4e12d3a40
func (cc *CodecContext) SetLevel(l Level) {
cc.c.level = C.int(l)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a3f99ca3115c44e6d7772c9384faf15e6
func (cc *CodecContext) MediaType() MediaType {
return MediaType(cc.c.codec_type)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a0425c77b3d06d71e5db88b1d7e1b37f2
func (cc *CodecContext) PixelFormat() PixelFormat {
return PixelFormat(cc.c.pix_fmt)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a0425c77b3d06d71e5db88b1d7e1b37f2
func (cc *CodecContext) SetPixelFormat(pixFmt PixelFormat) {
cc.c.pix_fmt = C.enum_AVPixelFormat(pixFmt)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a7abe7095de73df98df4895bf9e25fc6b
func (cc *CodecContext) Profile() Profile {
return Profile(cc.c.profile)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a7abe7095de73df98df4895bf9e25fc6b
func (cc *CodecContext) SetProfile(p Profile) {
cc.c.profile = C.int(p)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a3f63bc9141e25bf7f1cda0cef7cd4a60
func (cc *CodecContext) Qmin() int {
return int(cc.c.qmin)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a3f63bc9141e25bf7f1cda0cef7cd4a60
func (cc *CodecContext) SetQmin(qmin int) {
cc.c.qmin = C.int(qmin)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a5252d34fbce300228d4dbda19a8c3293
func (cc *CodecContext) SampleAspectRatio() Rational {
return newRationalFromC(cc.c.sample_aspect_ratio)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a5252d34fbce300228d4dbda19a8c3293
func (cc *CodecContext) SetSampleAspectRatio(r Rational) {
cc.c.sample_aspect_ratio = r.c
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a1bdba69ea111e2a9d03fdaa7a46a4c45
func (cc *CodecContext) SampleFormat() SampleFormat {
return SampleFormat(cc.c.sample_fmt)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a1bdba69ea111e2a9d03fdaa7a46a4c45
func (cc *CodecContext) SetSampleFormat(f SampleFormat) {
cc.c.sample_fmt = C.enum_AVSampleFormat(f)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a8ff0b000c463361e234af48d03aadfc0
func (cc *CodecContext) SampleRate() int {
return int(cc.c.sample_rate)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a8ff0b000c463361e234af48d03aadfc0
func (cc *CodecContext) SetSampleRate(sampleRate int) {
cc.c.sample_rate = C.int(sampleRate)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a3090804569341ca235e3adbdc03318d2
func (cc *CodecContext) StrictStdCompliance() StrictStdCompliance {
return StrictStdCompliance(cc.c.strict_std_compliance)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a3090804569341ca235e3adbdc03318d2
func (cc *CodecContext) SetStrictStdCompliance(c StrictStdCompliance) {
cc.c.strict_std_compliance = C.int(c)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#ab7bfeb9fa5840aac090e2b0bd0ef7589
func (cc *CodecContext) TimeBase() Rational {
return newRationalFromC(cc.c.time_base)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#ab7bfeb9fa5840aac090e2b0bd0ef7589
func (cc *CodecContext) SetTimeBase(r Rational) {
cc.c.time_base = r.c
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#aa852b6227d0778b62e9cc4034ad3720c
func (cc *CodecContext) ThreadCount() int {
return int(cc.c.thread_count)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#aa852b6227d0778b62e9cc4034ad3720c
func (cc *CodecContext) SetThreadCount(threadCount int) {
cc.c.thread_count = C.int(threadCount)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a7651614f4309122981d70e06a4b42fcb
func (cc *CodecContext) ThreadType() ThreadType {
return ThreadType(cc.c.thread_type)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a7651614f4309122981d70e06a4b42fcb
func (cc *CodecContext) SetThreadType(t ThreadType) {
cc.c.thread_type = C.int(t)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a0d8f46461754e8abea0847dcbc41b956
func (cc *CodecContext) Width() int {
return int(cc.c.width)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a0d8f46461754e8abea0847dcbc41b956
func (cc *CodecContext) SetWidth(width int) {
cc.c.width = C.int(width)
}
// https://ffmpeg.org/doxygen/7.0/group__lavc__core.html#ga11f785a188d7d9df71621001465b0f1d
func (cc *CodecContext) Open(c *Codec, d *Dictionary) error {
var dc **C.AVDictionary
if d != nil {
dc = &d.c
}
return newError(C.avcodec_open2(cc.c, c.c, dc))
}
// https://ffmpeg.org/doxygen/7.0/group__lavc__decoding.html#ga5b8eff59cf259747cf0b31563e38ded6
func (cc *CodecContext) ReceivePacket(p *Packet) error {
var pc *C.AVPacket
if p != nil {
pc = p.c
}
return newError(C.avcodec_receive_packet(cc.c, pc))
}
// https://ffmpeg.org/doxygen/7.0/group__lavc__decoding.html#ga58bc4bf1e0ac59e27362597e467efff3
func (cc *CodecContext) SendPacket(p *Packet) error {
var pc *C.AVPacket
if p != nil {
pc = p.c
}
return newError(C.avcodec_send_packet(cc.c, pc))
}
// https://ffmpeg.org/doxygen/7.0/group__lavc__decoding.html#ga11e6542c4e66d3028668788a1a74217c
func (cc *CodecContext) ReceiveFrame(f *Frame) error {
var fc *C.AVFrame
if f != nil {
fc = f.c
}
return newError(C.avcodec_receive_frame(cc.c, fc))
}
// https://ffmpeg.org/doxygen/7.0/group__lavc__decoding.html#ga9395cb802a5febf1f00df31497779169
func (cc *CodecContext) SendFrame(f *Frame) error {
var fc *C.AVFrame
if f != nil {
fc = f.c
}
return newError(C.avcodec_send_frame(cc.c, fc))
}
func (cc *CodecContext) ToCodecParameters(cp *CodecParameters) error {
return cp.FromCodecContext(cc)
}
func (cc *CodecContext) FromCodecParameters(cp *CodecParameters) error {
return cp.ToCodecContext(cc)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#acf8113e490f9e7b57465e65af9c0c75c
func (cc *CodecContext) SetHardwareDeviceContext(hdc *HardwareDeviceContext) {
if cc.hdc != nil {
C.av_buffer_unref(&cc.hdc.c)
}
cc.hdc = hdc
if cc.hdc != nil {
cc.c.hw_device_ctx = C.av_buffer_ref(cc.hdc.c)
}
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a3bac44bb0b016ab838780cc19ac277d6
func (cc *CodecContext) SetHardwareFrameContext(hfc *HardwareFrameContext) {
if cc.hfc != nil {
C.av_buffer_unref(&cc.hfc.c)
}
cc.hfc = hfc
if cc.hfc != nil {
cc.c.hw_frames_ctx = C.av_buffer_ref(cc.hfc.c)
}
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#ad2f772bd948d8f3be4d674a3a52ee00e
func (cc *CodecContext) ExtraHardwareFrames() int {
return int(cc.c.extra_hw_frames)
}
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#ad2f772bd948d8f3be4d674a3a52ee00e
func (cc *CodecContext) SetExtraHardwareFrames(n int) {
cc.c.extra_hw_frames = C.int(n)
}
func (cc *CodecContext) UnsafePointer() unsafe.Pointer {
return unsafe.Pointer(cc.c)
}
type CodecContextPixelFormatCallback func(pfs []PixelFormat) PixelFormat
var (
codecContextPixelFormatCallbacks = make(map[*C.AVCodecContext]CodecContextPixelFormatCallback)
codecContextPixelFormatCallbacksMutex = &sync.Mutex{}
)
// https://ffmpeg.org/doxygen/7.0/structAVCodecContext.html#a360a2b8508a67c4234d97f4c13ba1bb5
func (cc *CodecContext) SetPixelFormatCallback(c CodecContextPixelFormatCallback) {
// Lock
codecContextPixelFormatCallbacksMutex.Lock()
defer codecContextPixelFormatCallbacksMutex.Unlock()
// Update callback
if c == nil {
C.astiavResetCodecContextGetFormat(cc.c)
delete(codecContextPixelFormatCallbacks, cc.c)
} else {
C.astiavSetCodecContextGetFormat(cc.c)
codecContextPixelFormatCallbacks[cc.c] = c
}
}
//export goAstiavCodecContextGetFormat
func goAstiavCodecContextGetFormat(cc *C.AVCodecContext, pfsCPtr *C.enum_AVPixelFormat, pfsCSize C.int) C.enum_AVPixelFormat {
// Lock
codecContextPixelFormatCallbacksMutex.Lock()
defer codecContextPixelFormatCallbacksMutex.Unlock()
// Get callback
c, ok := codecContextPixelFormatCallbacks[cc]
if !ok {
return C.enum_AVPixelFormat(PixelFormatNone)
}
// Get pixel formats
var pfs []PixelFormat
for _, v := range unsafe.Slice(pfsCPtr, pfsCSize) {
pfs = append(pfs, PixelFormat(v))
}
// Callback
return C.enum_AVPixelFormat(c(pfs))
}