forked from PyAV-Org/PyAV
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcodec.pyx
More file actions
211 lines (172 loc) · 7 KB
/
Copy pathcodec.pyx
File metadata and controls
211 lines (172 loc) · 7 KB
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
from libc.stdint cimport uint64_t
from av.audio.format cimport get_audio_format
from av.descriptor cimport wrap_avclass
from av.utils cimport media_type_to_string
from av.video.format cimport get_video_format
cdef object _cinit_sentinel = object()
cdef Codec wrap_codec(lib.AVCodec *ptr):
cdef Codec codec = Codec(_cinit_sentinel)
codec.ptr = ptr
codec.is_encoder = lib.av_codec_is_encoder(ptr)
codec._init()
return codec
cdef flag_in_bitfield(uint64_t bitfield, uint64_t flag):
# Not every flag exists in every version of FFMpeg and LibAV, so we
# define them to 0.
if not flag:
return None
return bool(bitfield & flag)
class UnknownCodecError(ValueError):
pass
cdef class Codec(object):
def __cinit__(self, name, mode='r'):
if name is _cinit_sentinel:
return
if mode == 'w':
self.ptr = lib.avcodec_find_encoder_by_name(name)
self.is_encoder = True
elif mode == 'r':
self.ptr = lib.avcodec_find_decoder_by_name(name)
self.is_encoder = False
else:
raise ValueError('Invalid mode; must be "r" or "w".', mode)
self._init(name)
cdef _init(self, name=None):
if not self.ptr:
raise UnknownCodecError(name)
self.desc = lib.avcodec_descriptor_get(self.ptr.id)
if not self.desc:
raise RuntimeError('No codec descriptor for %r.' % name)
def create(self):
from .context import CodecContext
return CodecContext.create(self)
property is_decoder:
def __get__(self): return not self.is_encoder
property descriptor:
def __get__(self): return wrap_avclass(self.ptr.priv_class)
property name:
def __get__(self): return self.ptr.name or ''
property long_name:
def __get__(self): return self.ptr.long_name or ''
property type:
def __get__(self): return media_type_to_string(self.ptr.type)
property id:
def __get__(self): return self.ptr.id
property frame_rates:
def __get__(self): return <int>self.ptr.supported_framerates
property audio_rates:
def __get__(self): return <int>self.ptr.supported_samplerates
property video_formats:
def __get__(self):
if not self.ptr.pix_fmts:
return
ret = []
cdef lib.AVPixelFormat *ptr = self.ptr.pix_fmts
while ptr[0] != -1:
ret.append(get_video_format(ptr[0], 0, 0))
ptr += 1
return ret
property audio_formats:
def __get__(self):
if not self.ptr.sample_fmts:
return
ret = []
cdef lib.AVSampleFormat *ptr = self.ptr.sample_fmts
while ptr[0] != -1:
ret.append(get_audio_format(ptr[0]))
ptr += 1
return ret
# Capabilities.
property draw_horiz_band:
def __get__(self): return flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_DRAW_HORIZ_BAND)
property dr1:
def __get__(self): return flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_DR1)
property truncated:
def __get__(self): return flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_TRUNCATED)
property hwaccel:
def __get__(self): return flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_HWACCEL)
property delay:
def __get__(self): return flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_DELAY)
property small_last_frame:
def __get__(self): return flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_SMALL_LAST_FRAME)
property hwaccel_vdpau:
def __get__(self): return flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_HWACCEL_VDPAU)
property subframes:
def __get__(self): return flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_SUBFRAMES)
property experimental:
def __get__(self): return flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_EXPERIMENTAL)
property channel_conf:
def __get__(self): return flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_CHANNEL_CONF)
property neg_linesizes:
def __get__(self): return flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_NEG_LINESIZES)
property frame_threads:
def __get__(self): return flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_FRAME_THREADS)
property slice_threads:
def __get__(self): return flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_SLICE_THREADS)
property param_change:
def __get__(self): return flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_PARAM_CHANGE)
property auto_threads:
def __get__(self): return flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_AUTO_THREADS)
property variable_frame_size:
def __get__(self): return flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_VARIABLE_FRAME_SIZE)
# Capabilities and properties overlap.
# TODO: Is this really the right way to combine these things?
property intra_only:
def __get__(self): return (
flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_INTRA_ONLY) or
flag_in_bitfield(self.desc.props, lib.AV_CODEC_PROP_INTRA_ONLY)
)
property lossless:
def __get__(self): return (
flag_in_bitfield(self.ptr.capabilities, lib.CODEC_CAP_LOSSLESS) or
flag_in_bitfield(self.desc.props, lib.AV_CODEC_PROP_LOSSLESS)
)
property lossy:
def __get__(self): return (
flag_in_bitfield(self.desc.props, lib.AV_CODEC_PROP_LOSSY) or
not self.lossless
)
# Properties.
property reorder:
def __get__(self): return flag_in_bitfield(self.desc.props, lib.AV_CODEC_PROP_REORDER)
property bitmap_sub:
def __get__(self): return flag_in_bitfield(self.desc.props, lib.AV_CODEC_PROP_BITMAP_SUB)
property text_sub:
def __get__(self): return flag_in_bitfield(self.desc.props, lib.AV_CODEC_PROP_TEXT_SUB)
codecs_availible = set()
cdef lib.AVCodec *ptr = lib.av_codec_next(NULL)
while ptr:
codecs_availible.add(ptr.name)
ptr = lib.av_codec_next(ptr)
def dump_codecs():
"""Print information about availible codecs."""
print '''Codecs:
D..... = Decoding supported
.E.... = Encoding supported
..V... = Video codec
..A... = Audio codec
..S... = Subtitle codec
...I.. = Intra frame-only codec
....L. = Lossy compression
.....S = Lossless compression
------'''
for name in sorted(codecs_availible):
try:
e_codec = Codec(name, 'w')
except ValueError:
e_codec = None
try:
d_codec = Codec(name, 'r')
except ValueError:
d_codec = None
codec = e_codec or d_codec
print ' %s%s%s%s%s%s %-18s %s' % (
'.D'[bool(d_codec)],
'.E'[bool(e_codec)],
codec.type[0].upper(),
'.I'[codec.intra_only],
'L.'[codec.lossless],
'.S'[codec.lossless],
codec.name,
codec.long_name
)