• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

asticode / go-astiav / 7728604914

31 Jan 2024 03:34PM UTC coverage: 88.266% (-0.2%) from 88.453%
7728604914

push

github

asticode
Fixed hard device context unref

1 of 9 new or added lines in 1 file covered. (11.11%)

1 existing line in 1 file now uncovered.

1670 of 1892 relevant lines covered (88.27%)

39.78 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.88
/codec_context.go
1
package astiav
2

3
//#cgo pkg-config: libavcodec libavutil
4
//#include <libavcodec/avcodec.h>
5
//#include <libavutil/frame.h>
6
/*
7
extern enum AVPixelFormat goAstiavCodecContextGetFormat(AVCodecContext *ctx, enum AVPixelFormat *pix_fmts, int pix_fmts_size);
8

9
static inline enum AVPixelFormat astiavCodecContextGetFormat(AVCodecContext *ctx, const enum AVPixelFormat *pix_fmts)
10
{
11
        int pix_fmts_size = 0;
12
        while (*pix_fmts != AV_PIX_FMT_NONE) {
13
                pix_fmts_size++;
14
                pix_fmts++;
15
        }
16
        pix_fmts -= pix_fmts_size;
17
        return goAstiavCodecContextGetFormat(ctx, (enum AVPixelFormat*)(pix_fmts), pix_fmts_size);
18
}
19
static inline void astiavSetCodecContextGetFormat(AVCodecContext *ctx)
20
{
21
        ctx->get_format = astiavCodecContextGetFormat;
22
}
23
static inline void astiavResetCodecContextGetFormat(AVCodecContext *ctx)
24
{
25
        ctx->get_format = NULL;
26
}
27

28
*/
29
import "C"
30
import (
31
        "sync"
32
        "unsafe"
33
)
34

35
// https://github.com/FFmpeg/FFmpeg/blob/n5.0/libavcodec/avcodec.h#L383
36
type CodecContext struct {
37
        c *C.struct_AVCodecContext
38
        // We need to store this to unref it properly
39
        hdc *HardwareDeviceContext
40
}
41

42
func AllocCodecContext(c *Codec) *CodecContext {
21✔
43
        var cc *C.struct_AVCodec
21✔
44
        if c != nil {
36✔
45
                cc = c.c
15✔
46
        }
15✔
47
        return newCodecContextFromC(C.avcodec_alloc_context3(cc))
21✔
48
}
49

50
func newCodecContextFromC(c *C.struct_AVCodecContext) *CodecContext {
21✔
51
        if c == nil {
21✔
52
                return nil
×
53
        }
×
54
        return &CodecContext{c: c}
21✔
55
}
56

57
func (cc *CodecContext) Free() {
15✔
58
        if cc.hdc != nil {
15✔
NEW
59
                C.av_buffer_unref(&cc.hdc.c)
×
NEW
60
                cc.hdc = nil
×
UNCOV
61
        }
×
62
        C.avcodec_free_context(&cc.c)
15✔
63
}
64

65
func (cc *CodecContext) String() string {
6✔
66
        s, _ := stringFromC(255, func(buf *C.char, size C.size_t) error {
12✔
67
                C.avcodec_string(buf, C.int(size), cc.c, C.int(0))
6✔
68
                return nil
6✔
69
        })
6✔
70
        return s
6✔
71
}
72

73
func (cc *CodecContext) BitRate() int64 {
9✔
74
        return int64(cc.c.bit_rate)
9✔
75
}
9✔
76

77
func (cc *CodecContext) SetBitRate(bitRate int64) {
3✔
78
        cc.c.bit_rate = C.int64_t(bitRate)
3✔
79
}
3✔
80

81
func (cc *CodecContext) Channels() int {
9✔
82
        return int(cc.c.channels)
9✔
83
}
9✔
84

85
func (cc *CodecContext) SetChannels(channels int) {
3✔
86
        cc.c.channels = C.int(channels)
3✔
87
}
3✔
88

89
func (cc *CodecContext) ChannelLayout() ChannelLayout {
6✔
90
        l, _ := newChannelLayoutFromC(&cc.c.ch_layout).clone()
6✔
91
        return l
6✔
92
}
6✔
93

94
func (cc *CodecContext) SetChannelLayout(l ChannelLayout) {
3✔
95
        l.copy(&cc.c.ch_layout) //nolint: errcheck
3✔
96
}
3✔
97

98
func (cc *CodecContext) ChromaLocation() ChromaLocation {
3✔
99
        return ChromaLocation(cc.c.chroma_sample_location)
3✔
100
}
3✔
101

102
func (cc *CodecContext) CodecID() CodecID {
6✔
103
        return CodecID(cc.c.codec_id)
6✔
104
}
6✔
105

106
func (cc *CodecContext) ColorPrimaries() ColorPrimaries {
3✔
107
        return ColorPrimaries(cc.c.color_primaries)
3✔
108
}
3✔
109

110
func (cc *CodecContext) ColorRange() ColorRange {
3✔
111
        return ColorRange(cc.c.color_range)
3✔
112
}
3✔
113

114
func (cc *CodecContext) ColorSpace() ColorSpace {
3✔
115
        return ColorSpace(cc.c.colorspace)
3✔
116
}
3✔
117

118
func (cc *CodecContext) ColorTransferCharacteristic() ColorTransferCharacteristic {
3✔
119
        return ColorTransferCharacteristic(cc.c.color_trc)
3✔
120
}
3✔
121

122
func (cc *CodecContext) Flags() CodecContextFlags {
3✔
123
        return CodecContextFlags(cc.c.flags)
3✔
124
}
3✔
125

126
func (cc *CodecContext) SetFlags(fs CodecContextFlags) {
3✔
127
        cc.c.flags = C.int(fs)
3✔
128
}
3✔
129

130
func (cc *CodecContext) Flags2() CodecContextFlags2 {
3✔
131
        return CodecContextFlags2(cc.c.flags2)
3✔
132
}
3✔
133

134
func (cc *CodecContext) SetFlags2(fs CodecContextFlags2) {
3✔
135
        cc.c.flags2 = C.int(fs)
3✔
136
}
3✔
137

138
func (cc *CodecContext) Framerate() Rational {
3✔
139
        return newRationalFromC(cc.c.framerate)
3✔
140
}
3✔
141

142
func (cc *CodecContext) SetFramerate(f Rational) {
3✔
143
        cc.c.framerate = f.c
3✔
144
}
3✔
145

146
func (cc *CodecContext) FrameSize() int {
3✔
147
        return int(cc.c.frame_size)
3✔
148
}
3✔
149

150
func (cc *CodecContext) GopSize() int {
6✔
151
        return int(cc.c.gop_size)
6✔
152
}
6✔
153

154
func (cc *CodecContext) SetGopSize(gopSize int) {
3✔
155
        cc.c.gop_size = C.int(gopSize)
3✔
156
}
3✔
157

158
func (cc *CodecContext) Height() int {
6✔
159
        return int(cc.c.height)
6✔
160
}
6✔
161

162
func (cc *CodecContext) SetHeight(height int) {
6✔
163
        cc.c.height = C.int(height)
6✔
164
}
6✔
165

166
func (cc *CodecContext) Level() Level {
3✔
167
        return Level(cc.c.level)
3✔
168
}
3✔
169

170
func (cc *CodecContext) MediaType() MediaType {
6✔
171
        return MediaType(cc.c.codec_type)
6✔
172
}
6✔
173

174
func (cc *CodecContext) PixelFormat() PixelFormat {
6✔
175
        return PixelFormat(cc.c.pix_fmt)
6✔
176
}
6✔
177

178
func (cc *CodecContext) SetPixelFormat(pixFmt PixelFormat) {
6✔
179
        cc.c.pix_fmt = C.enum_AVPixelFormat(pixFmt)
6✔
180
}
6✔
181

182
func (cc *CodecContext) Profile() Profile {
3✔
183
        return Profile(cc.c.profile)
3✔
184
}
3✔
185

186
func (cc *CodecContext) Qmin() int {
3✔
187
        return int(cc.c.qmin)
3✔
188
}
3✔
189

190
func (cc *CodecContext) SetQmin(qmin int) {
3✔
191
        cc.c.qmin = C.int(qmin)
3✔
192
}
3✔
193

194
func (cc *CodecContext) SampleAspectRatio() Rational {
6✔
195
        return newRationalFromC(cc.c.sample_aspect_ratio)
6✔
196
}
6✔
197

198
func (cc *CodecContext) SetSampleAspectRatio(r Rational) {
3✔
199
        cc.c.sample_aspect_ratio = r.c
3✔
200
}
3✔
201

202
func (cc *CodecContext) SampleFormat() SampleFormat {
6✔
203
        return SampleFormat(cc.c.sample_fmt)
6✔
204
}
6✔
205

206
func (cc *CodecContext) SetSampleFormat(f SampleFormat) {
3✔
207
        cc.c.sample_fmt = C.enum_AVSampleFormat(f)
3✔
208
}
3✔
209

210
func (cc *CodecContext) SampleRate() int {
6✔
211
        return int(cc.c.sample_rate)
6✔
212
}
6✔
213

214
func (cc *CodecContext) SetSampleRate(sampleRate int) {
3✔
215
        cc.c.sample_rate = C.int(sampleRate)
3✔
216
}
3✔
217

218
func (cc *CodecContext) StrictStdCompliance() StrictStdCompliance {
9✔
219
        return StrictStdCompliance(cc.c.strict_std_compliance)
9✔
220
}
9✔
221

222
func (cc *CodecContext) SetStrictStdCompliance(c StrictStdCompliance) {
3✔
223
        cc.c.strict_std_compliance = C.int(c)
3✔
224
}
3✔
225

226
func (cc *CodecContext) TimeBase() Rational {
3✔
227
        return newRationalFromC(cc.c.time_base)
3✔
228
}
3✔
229

230
func (cc *CodecContext) SetTimeBase(r Rational) {
6✔
231
        cc.c.time_base = r.c
6✔
232
}
6✔
233

234
func (cc *CodecContext) ThreadCount() int {
9✔
235
        return int(cc.c.thread_count)
9✔
236
}
9✔
237

238
func (cc *CodecContext) SetThreadCount(threadCount int) {
3✔
239
        cc.c.thread_count = C.int(threadCount)
3✔
240
}
3✔
241

242
func (cc *CodecContext) ThreadType() ThreadType {
9✔
243
        return ThreadType(cc.c.thread_type)
9✔
244
}
9✔
245

246
func (cc *CodecContext) SetThreadType(t ThreadType) {
3✔
247
        cc.c.thread_type = C.int(t)
3✔
248
}
3✔
249

250
func (cc *CodecContext) Width() int {
6✔
251
        return int(cc.c.width)
6✔
252
}
6✔
253

254
func (cc *CodecContext) SetWidth(width int) {
6✔
255
        cc.c.width = C.int(width)
6✔
256
}
6✔
257

258
func (cc *CodecContext) Open(c *Codec, d *Dictionary) error {
9✔
259
        var dc **C.struct_AVDictionary
9✔
260
        if d != nil {
9✔
261
                dc = &d.c
×
262
        }
×
263
        return newError(C.avcodec_open2(cc.c, c.c, dc))
9✔
264
}
265

266
func (cc *CodecContext) ReceivePacket(p *Packet) error {
×
267
        var pc *C.struct_AVPacket
×
268
        if p != nil {
×
269
                pc = p.c
×
270
        }
×
271
        return newError(C.avcodec_receive_packet(cc.c, pc))
×
272
}
273

274
func (cc *CodecContext) SendPacket(p *Packet) error {
363✔
275
        var pc *C.struct_AVPacket
363✔
276
        if p != nil {
726✔
277
                pc = p.c
363✔
278
        }
363✔
279
        return newError(C.avcodec_send_packet(cc.c, pc))
363✔
280
}
281

282
func (cc *CodecContext) ReceiveFrame(f *Frame) error {
726✔
283
        var fc *C.struct_AVFrame
726✔
284
        if f != nil {
1,452✔
285
                fc = f.c
726✔
286
        }
726✔
287
        return newError(C.avcodec_receive_frame(cc.c, fc))
726✔
288
}
289

290
func (cc *CodecContext) SendFrame(f *Frame) error {
×
291
        var fc *C.struct_AVFrame
×
292
        if f != nil {
×
293
                fc = f.c
×
294
        }
×
295
        return newError(C.avcodec_send_frame(cc.c, fc))
×
296
}
297

298
func (cc *CodecContext) SetHardwareDeviceContext(hdc *HardwareDeviceContext) {
×
NEW
299
        if cc.hdc != nil {
×
NEW
300
                C.av_buffer_unref(&cc.hdc.c)
×
NEW
301
        }
×
NEW
302
        cc.hdc = hdc
×
NEW
303
        if cc.hdc != nil {
×
NEW
304
                cc.c.hw_device_ctx = C.av_buffer_ref(cc.hdc.c)
×
305
        }
×
306
}
307

308
type CodecContextPixelFormatCallback func(pfs []PixelFormat) PixelFormat
309

310
var (
311
        codecContextPixelFormatCallbacks      = make(map[*C.struct_AVCodecContext]CodecContextPixelFormatCallback)
312
        codecContextPixelFormatCallbacksMutex = &sync.Mutex{}
313
)
314

315
func (cc *CodecContext) SetPixelFormatCallback(c CodecContextPixelFormatCallback) {
×
316
        // Lock
×
317
        codecContextPixelFormatCallbacksMutex.Lock()
×
318
        defer codecContextPixelFormatCallbacksMutex.Unlock()
×
319

×
320
        // Update callback
×
321
        if c == nil {
×
322
                C.astiavResetCodecContextGetFormat(cc.c)
×
323
                delete(codecContextPixelFormatCallbacks, cc.c)
×
324
        } else {
×
325
                C.astiavSetCodecContextGetFormat(cc.c)
×
326
                codecContextPixelFormatCallbacks[cc.c] = c
×
327
        }
×
328
}
329

330
//export goAstiavCodecContextGetFormat
331
func goAstiavCodecContextGetFormat(cc *C.struct_AVCodecContext, pfsCPtr *C.enum_AVPixelFormat, pfsCSize C.int) C.enum_AVPixelFormat {
×
332
        // Lock
×
333
        codecContextPixelFormatCallbacksMutex.Lock()
×
334
        defer codecContextPixelFormatCallbacksMutex.Unlock()
×
335

×
336
        // Get callback
×
337
        c, ok := codecContextPixelFormatCallbacks[cc]
×
338
        if !ok {
×
339
                return C.enum_AVPixelFormat(PixelFormatNone)
×
340
        }
×
341

342
        // Get pixel formats
343
        var pfs []PixelFormat
×
344
        for _, v := range unsafe.Slice(pfsCPtr, pfsCSize) {
×
345
                pfs = append(pfs, PixelFormat(v))
×
346
        }
×
347

348
        // Callback
349
        return C.enum_AVPixelFormat(c(pfs))
×
350

351
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc