Skip to content

Commit 2dcb74b

Browse files
committed
Generalize SideData more.
1 parent 0c49ff2 commit 2dcb74b

File tree

11 files changed

+229
-19
lines changed

11 files changed

+229
-19
lines changed

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@ deploy-docs: docs
6969

7070

7171

72-
clean: clean-build
7372

7473
clean-build:
7574
- rm -rf build
@@ -87,4 +86,5 @@ clean-docs:
8786
- rm tmp/tagfile.xml
8887
- make -C docs clean
8988

89+
clean: clean-build clean-sandbox clean-src
9090
clean-all: clean-build clean-sandbox clean-src clean-docs

av/frame.pxd

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
cimport libav as lib
22

33
from av.packet cimport Packet
4-
4+
from av.sidedata.sidedata cimport _SideDataContainer
55

66
cdef class Frame(object):
77

@@ -11,6 +11,8 @@ cdef class Frame(object):
1111
cdef lib.AVRational _time_base
1212
cdef _rebase_time(self, lib.AVRational)
1313

14+
cdef _SideDataContainer _side_data
15+
1416
cdef readonly int index
1517

1618
cdef _copy_internal_attributes(self, Frame source, bint data_layout=?)

av/frame.pyx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from av.utils cimport avrational_to_fraction, to_avrational
22

3+
from av.sidedata.sidedata import SideDataContainer
4+
35
from fractions import Fraction
46

57

@@ -128,3 +130,9 @@ cdef class Frame(object):
128130
:type: bool
129131
"""
130132
def __get__(self): return self.ptr.decode_error_flags != 0 or bool(self.ptr.flags & lib.AV_FRAME_FLAG_CORRUPT)
133+
134+
@property
135+
def side_data(self):
136+
if self._side_data is None:
137+
self._side_data = SideDataContainer(self)
138+
return self._side_data

av/sidedata/__init__.py

Whitespace-only changes.

av/sidedata/motionvectors.pyx

Whitespace-only changes.

av/sidedata/sidedata.pxd

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
2+
from av.frame cimport Frame
3+
from av.buffer cimport Buffer
4+
cimport libav as lib
5+
6+
7+
cdef class SideData(Buffer):
8+
9+
cdef Frame frame
10+
cdef lib.AVFrameSideData *ptr
11+
12+
13+
cdef SideData wrap_side_data(Frame frame, int index)
14+
15+
cdef class _SideDataContainer(object):
16+
17+
cdef Frame frame
18+
19+
cdef list _by_index
20+
cdef dict _by_type
21+

av/sidedata/sidedata.pyx

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
2+
from av.enums cimport define_enum
3+
4+
import collections
5+
6+
7+
cdef object _cinit_bypass_sentinel = object()
8+
9+
10+
SideDataType = define_enum('SideDataType', (
11+
('PANSCAN', lib.AV_FRAME_DATA_PANSCAN),
12+
('A53_CC', lib.AV_FRAME_DATA_A53_CC),
13+
('STEREO3D', lib.AV_FRAME_DATA_STEREO3D),
14+
('MATRIXENCODING', lib.AV_FRAME_DATA_MATRIXENCODING),
15+
('DOWNMIX_INFO', lib.AV_FRAME_DATA_DOWNMIX_INFO),
16+
('REPLAYGAIN', lib.AV_FRAME_DATA_REPLAYGAIN),
17+
('DISPLAYMATRIX', lib.AV_FRAME_DATA_DISPLAYMATRIX),
18+
('AFD', lib.AV_FRAME_DATA_AFD),
19+
('MOTION_VECTORS', lib.AV_FRAME_DATA_MOTION_VECTORS),
20+
('SKIP_SAMPLES', lib.AV_FRAME_DATA_SKIP_SAMPLES),
21+
('AUDIO_SERVICE_TYPE', lib.AV_FRAME_DATA_AUDIO_SERVICE_TYPE),
22+
('MASTERING_DISPLAY_METADATA', lib.AV_FRAME_DATA_MASTERING_DISPLAY_METADATA),
23+
('GOP_TIMECODE', lib.AV_FRAME_DATA_GOP_TIMECODE),
24+
('SPHERICAL', lib.AV_FRAME_DATA_SPHERICAL),
25+
('CONTENT_LIGHT_LEVEL', lib.AV_FRAME_DATA_CONTENT_LIGHT_LEVEL),
26+
('ICC_PROFILE', lib.AV_FRAME_DATA_ICC_PROFILE),
27+
('QP_TABLE_PROPERTIES', lib.AV_FRAME_DATA_QP_TABLE_PROPERTIES),
28+
('QP_TABLE_DATA', lib.AV_FRAME_DATA_QP_TABLE_DATA),
29+
))
30+
31+
32+
cdef SideData wrap_side_data(Frame frame, int index):
33+
return SideData(_cinit_bypass_sentinel, frame, index)
34+
35+
36+
cdef class SideData(Buffer):
37+
38+
def __init__(self, sentinel, Frame frame, int index):
39+
if sentinel is not _cinit_bypass_sentinel:
40+
raise RuntimeError('cannot manually instatiate SideData')
41+
self.frame = frame
42+
self.ptr = frame.ptr.side_data[index]
43+
44+
cdef size_t _buffer_size(self):
45+
return self.ptr.size
46+
47+
cdef void* _buffer_ptr(self):
48+
return self.ptr.data
49+
50+
cdef bint _buffer_writable(self):
51+
return False
52+
53+
def __repr__(self):
54+
return f'<av.sidedata.SideData {self.ptr.size} bytes of {self.type} at 0x{<unsigned int>self.ptr.data:0x}>'
55+
56+
@property
57+
def type(self):
58+
return SideDataType.get(self.ptr.type) or self.ptr.type
59+
60+
61+
cdef class _SideDataContainer(object):
62+
63+
def __init__(self, Frame frame):
64+
65+
self.frame = frame
66+
self._by_index = []
67+
self._by_type = {}
68+
69+
cdef int i
70+
cdef SideData data
71+
for i in range(self.frame.ptr.nb_side_data):
72+
data = wrap_side_data(frame, i)
73+
self._by_index.append(data)
74+
self._by_type[data.type] = data
75+
76+
def __len__(self):
77+
return len(self._by_index)
78+
79+
def __iter__(self):
80+
return iter(self._by_index)
81+
82+
def __getitem__(self, key):
83+
84+
if isinstance(key, int):
85+
return self._by_index[key]
86+
87+
type_ = SideDataType.get(key)
88+
return self._by_type(type_)
89+
90+
91+
class SideDataContainer(_SideDataContainer, collections.Mapping):
92+
pass
93+
94+

av/video/codeccontext.pyx

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ from libc.stdint cimport int64_t
33
cimport libav as lib
44

55
from av.codec.context cimport CodecContext
6+
from av.enums cimport define_enum
67
from av.frame cimport Frame
78
from av.packet cimport Packet
89
from av.utils cimport avrational_to_fraction, to_avrational
@@ -12,6 +13,41 @@ from av.video.frame cimport VideoFrame, alloc_video_frame
1213
from av.video.reformatter cimport VideoReformatter
1314

1415

16+
CodecContextFlags = define_enum('CodecContextFlags', (
17+
('UNALIGNED', lib.AV_CODEC_FLAG_UNALIGNED),
18+
('QSCALE', lib.AV_CODEC_FLAG_QSCALE),
19+
('4MV', lib.AV_CODEC_FLAG_4MV),
20+
('OUTPUT_CORRUPT', lib.AV_CODEC_FLAG_OUTPUT_CORRUPT),
21+
('QPEL', lib.AV_CODEC_FLAG_QPEL),
22+
('PASS1', lib.AV_CODEC_FLAG_PASS1),
23+
('PASS2', lib.AV_CODEC_FLAG_PASS2),
24+
('LOOP_FILTER', lib.AV_CODEC_FLAG_LOOP_FILTER),
25+
('GRAY', lib.AV_CODEC_FLAG_GRAY),
26+
('PSNR', lib.AV_CODEC_FLAG_PSNR),
27+
('TRUNCATED', lib.AV_CODEC_FLAG_TRUNCATED),
28+
('INTERLACED_DCT', lib.AV_CODEC_FLAG_INTERLACED_DCT),
29+
('LOW_DELAY', lib.AV_CODEC_FLAG_LOW_DELAY),
30+
('GLOBAL_HEADER', lib.AV_CODEC_FLAG_GLOBAL_HEADER),
31+
('BITEXACT', lib.AV_CODEC_FLAG_BITEXACT),
32+
('AC_PRED', lib.AV_CODEC_FLAG_AC_PRED),
33+
('INTERLACED_ME', lib.AV_CODEC_FLAG_INTERLACED_ME),
34+
('CLOSED_GOP', lib.AV_CODEC_FLAG_CLOSED_GOP),
35+
), is_flags=True)
36+
37+
CodecContextFlags2 = define_enum('CodecContextFlags2', (
38+
('FAST', lib.AV_CODEC_FLAG2_FAST),
39+
('NO_OUTPUT', lib.AV_CODEC_FLAG2_NO_OUTPUT),
40+
('LOCAL_HEADER', lib.AV_CODEC_FLAG2_LOCAL_HEADER),
41+
('DROP_FRAME_TIMECODE', lib.AV_CODEC_FLAG2_DROP_FRAME_TIMECODE),
42+
('CHUNKS', lib.AV_CODEC_FLAG2_CHUNKS),
43+
('IGNORE_CROP', lib.AV_CODEC_FLAG2_IGNORE_CROP),
44+
('SHOW_ALL', lib.AV_CODEC_FLAG2_SHOW_ALL),
45+
('EXPORT_MVS', lib.AV_CODEC_FLAG2_EXPORT_MVS),
46+
('SKIP_MANUAL', lib.AV_CODEC_FLAG2_SKIP_MANUAL),
47+
('RO_FLUSH_NOOP', lib.AV_CODEC_FLAG2_RO_FLUSH_NOOP),
48+
), is_flags=True)
49+
50+
1551
cdef class VideoCodecContext(CodecContext):
1652

1753
def __cinit__(self, *args, **kwargs):
@@ -71,6 +107,22 @@ cdef class VideoCodecContext(CodecContext):
71107
cdef _build_format(self):
72108
self._format = get_video_format(<lib.AVPixelFormat>self.ptr.pix_fmt, self.ptr.width, self.ptr.height)
73109

110+
@property
111+
def flags(self):
112+
return CodecContextFlags.get(self.ptr.flags)
113+
@flags.setter
114+
def flags(self, value):
115+
enum = CodecContextFlags.get(value)
116+
self.ptr.flags = enum.value
117+
118+
@property
119+
def flags2(self):
120+
return CodecContextFlags.get(self.ptr.flags2)
121+
@flags2.setter
122+
def flags2(self, value):
123+
enum = CodecContextFlags2.get(value)
124+
self.ptr.flags2 = enum.value
125+
74126
property format:
75127
def __get__(self):
76128
return self._format

av/video/frame.pyx

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -32,22 +32,6 @@ PictureType = define_enum('PictureType', (
3232
('BI', lib.AV_PICTURE_TYPE_BI),
3333
))
3434

35-
SideDataType = define_enum('SideDataType', (
36-
('PANSCAN', lib.AV_FRAME_DATA_PANSCAN),
37-
('A53_CC', lib.AV_FRAME_DATA_A53_CC),
38-
('STEREO3D', lib.AV_FRAME_DATA_STEREO3D),
39-
('MATRIXENCODING', lib.AV_FRAME_DATA_MATRIXENCODING),
40-
('DOWNMIX_INFO', lib.AV_FRAME_DATA_DOWNMIX_INFO),
41-
('REPLAYGAIN', lib.AV_FRAME_DATA_REPLAYGAIN),
42-
('DISPLAYMATRIX', lib.AV_FRAME_DATA_DISPLAYMATRIX),
43-
('AFD', lib.AV_FRAME_DATA_AFD),
44-
('MOTION_VECTORS', lib.AV_FRAME_DATA_MOTION_VECTORS),
45-
('SKIP_SAMPLES', lib.AV_FRAME_DATA_SKIP_SAMPLES),
46-
('AUDIO_SERVICE_TYPE', lib.AV_FRAME_DATA_AUDIO_SERVICE_TYPE),
47-
('MASTERING_DISPLAY_METADATA', lib.AV_FRAME_DATA_MASTERING_DISPLAY_METADATA),
48-
('GOP_TIMECODE', lib.AV_FRAME_DATA_GOP_TIMECODE),
49-
))
50-
5135

5236
cdef copy_array_to_plane(array, VideoPlane plane, unsigned int bytes_per_pixel):
5337
cdef bytes imgbytes = array.tobytes()

include/libavcodec/avcodec.pxd

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,36 @@ cdef extern from "libavcodec/avcodec.pyav.h" nogil:
4747
FF_THREAD_SLICE
4848

4949
cdef enum:
50-
AV_CODEC_FLAG_GLOBAL_HEADER
50+
AV_CODEC_FLAG_UNALIGNED
5151
AV_CODEC_FLAG_QSCALE
52+
AV_CODEC_FLAG_4MV
53+
AV_CODEC_FLAG_OUTPUT_CORRUPT
54+
AV_CODEC_FLAG_QPEL
55+
AV_CODEC_FLAG_PASS1
56+
AV_CODEC_FLAG_PASS2
57+
AV_CODEC_FLAG_LOOP_FILTER
58+
AV_CODEC_FLAG_GRAY
59+
AV_CODEC_FLAG_PSNR
5260
AV_CODEC_FLAG_TRUNCATED
61+
AV_CODEC_FLAG_INTERLACED_DCT
62+
AV_CODEC_FLAG_LOW_DELAY
63+
AV_CODEC_FLAG_GLOBAL_HEADER
64+
AV_CODEC_FLAG_BITEXACT
65+
AV_CODEC_FLAG_AC_PRED
66+
AV_CODEC_FLAG_INTERLACED_ME
67+
AV_CODEC_FLAG_CLOSED_GOP
68+
69+
cdef enum:
70+
AV_CODEC_FLAG2_FAST
71+
AV_CODEC_FLAG2_NO_OUTPUT
72+
AV_CODEC_FLAG2_LOCAL_HEADER
73+
AV_CODEC_FLAG2_DROP_FRAME_TIMECODE
74+
AV_CODEC_FLAG2_CHUNKS
75+
AV_CODEC_FLAG2_IGNORE_CROP
76+
AV_CODEC_FLAG2_SHOW_ALL
77+
AV_CODEC_FLAG2_EXPORT_MVS
78+
AV_CODEC_FLAG2_SKIP_MANUAL
79+
AV_CODEC_FLAG2_RO_FLUSH_NOOP
5380

5481
cdef enum:
5582
AV_PKT_FLAG_KEY
@@ -119,6 +146,8 @@ cdef extern from "libavcodec/avcodec.pyav.h" nogil:
119146
AVCodecID codec_id
120147

121148
int flags
149+
int flags2
150+
122151
int thread_count
123152
int thread_type
124153

@@ -236,6 +265,8 @@ cdef extern from "libavcodec/avcodec.pyav.h" nogil:
236265
AV_FRAME_DATA_SPHERICAL
237266
AV_FRAME_DATA_CONTENT_LIGHT_LEVEL
238267
AV_FRAME_DATA_ICC_PROFILE
268+
AV_FRAME_DATA_QP_TABLE_PROPERTIES
269+
AV_FRAME_DATA_QP_TABLE_DATA
239270

240271
cdef struct AVFrameSideData:
241272
AVFrameSideDataType type
@@ -258,6 +289,9 @@ cdef extern from "libavcodec/avcodec.pyav.h" nogil:
258289
int width
259290
int height
260291

292+
int nb_side_data
293+
AVFrameSideData **side_data
294+
261295
int nb_samples # Audio samples
262296
int sample_rate # Audio Sample rate
263297
int channels # Number of audio channels

0 commit comments

Comments
 (0)