Libav
Main Page
Related Pages
Modules
Data Structures
Files
Examples
File List
Globals
libavutil
frame.c
Go to the documentation of this file.
1
/*
2
*
3
* This file is part of Libav.
4
*
5
* Libav is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU Lesser General Public
7
* License as published by the Free Software Foundation; either
8
* version 2.1 of the License, or (at your option) any later version.
9
*
10
* Libav is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* Lesser General Public License for more details.
14
*
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with Libav; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18
*/
19
20
#include "
channel_layout.h
"
21
#include "
buffer.h
"
22
#include "
common.h
"
23
#include "
dict.h
"
24
#include "
frame.h
"
25
#include "
imgutils.h
"
26
#include "
mem.h
"
27
#include "
samplefmt.h
"
28
29
static
void
get_frame_defaults
(
AVFrame
*frame)
30
{
31
if
(frame->
extended_data
!= frame->
data
)
32
av_freep
(&frame->
extended_data
);
33
34
memset(frame, 0,
sizeof
(*frame));
35
36
frame->
pts
=
AV_NOPTS_VALUE
;
37
frame->
key_frame
= 1;
38
frame->
sample_aspect_ratio
= (
AVRational
){ 0, 1 };
39
frame->
format
= -1;
/* unknown */
40
frame->
extended_data
= frame->
data
;
41
}
42
43
AVFrame
*
av_frame_alloc
(
void
)
44
{
45
AVFrame
*frame =
av_mallocz
(
sizeof
(*frame));
46
47
if
(!frame)
48
return
NULL
;
49
50
get_frame_defaults
(frame);
51
52
return
frame;
53
}
54
55
void
av_frame_free
(
AVFrame
**frame)
56
{
57
if
(!frame || !*frame)
58
return
;
59
60
av_frame_unref
(*frame);
61
av_freep
(frame);
62
}
63
64
static
int
get_video_buffer
(
AVFrame
*frame,
int
align)
65
{
66
const
AVPixFmtDescriptor
*desc =
av_pix_fmt_desc_get
(frame->
format
);
67
int
ret, i;
68
69
if
(!desc)
70
return
AVERROR
(EINVAL);
71
72
if
((ret =
av_image_check_size
(frame->
width
, frame->
height
, 0,
NULL
)) < 0)
73
return
ret;
74
75
if
(!frame->
linesize
[0]) {
76
ret =
av_image_fill_linesizes
(frame->
linesize
, frame->
format
,
77
frame->
width
);
78
if
(ret < 0)
79
return
ret;
80
81
for
(i = 0; i < 4 && frame->
linesize
[i]; i++)
82
frame->
linesize
[i] =
FFALIGN
(frame->
linesize
[i], align);
83
}
84
85
for
(i = 0; i < 4 && frame->
linesize
[i]; i++) {
86
int
h = frame->
height
;
87
if
(i == 1 || i == 2)
88
h = -((-h) >> desc->
log2_chroma_h
);
89
90
frame->
buf
[i] =
av_buffer_alloc
(frame->
linesize
[i] * h);
91
if
(!frame->
buf
[i])
92
goto
fail;
93
94
frame->
data
[i] = frame->
buf
[i]->
data
;
95
}
96
if
(desc->
flags
&
AV_PIX_FMT_FLAG_PAL
|| desc->
flags
&
AV_PIX_FMT_FLAG_PSEUDOPAL
) {
97
av_buffer_unref
(&frame->
buf
[1]);
98
frame->
buf
[1] =
av_buffer_alloc
(1024);
99
if
(!frame->
buf
[1])
100
goto
fail;
101
frame->
data
[1] = frame->
buf
[1]->
data
;
102
}
103
104
frame->
extended_data
= frame->
data
;
105
106
return
0;
107
fail:
108
av_frame_unref
(frame);
109
return
AVERROR
(ENOMEM);
110
}
111
112
static
int
get_audio_buffer
(
AVFrame
*frame,
int
align)
113
{
114
int
channels =
av_get_channel_layout_nb_channels
(frame->
channel_layout
);
115
int
planar =
av_sample_fmt_is_planar
(frame->
format
);
116
int
planes = planar ? channels : 1;
117
int
ret, i;
118
119
if
(!frame->
linesize
[0]) {
120
ret =
av_samples_get_buffer_size
(&frame->
linesize
[0], channels,
121
frame->
nb_samples
, frame->
format
,
122
align);
123
if
(ret < 0)
124
return
ret;
125
}
126
127
if
(planes >
AV_NUM_DATA_POINTERS
) {
128
frame->
extended_data
=
av_mallocz
(planes *
129
sizeof
(*frame->
extended_data
));
130
frame->
extended_buf
=
av_mallocz
((planes -
AV_NUM_DATA_POINTERS
) *
131
sizeof
(*frame->
extended_buf
));
132
if
(!frame->
extended_data
|| !frame->
extended_buf
) {
133
av_freep
(&frame->
extended_data
);
134
av_freep
(&frame->
extended_buf
);
135
return
AVERROR
(ENOMEM);
136
}
137
frame->
nb_extended_buf
= planes -
AV_NUM_DATA_POINTERS
;
138
}
else
139
frame->
extended_data
= frame->
data
;
140
141
for
(i = 0; i <
FFMIN
(planes,
AV_NUM_DATA_POINTERS
); i++) {
142
frame->
buf
[i] =
av_buffer_alloc
(frame->
linesize
[0]);
143
if
(!frame->
buf
[i]) {
144
av_frame_unref
(frame);
145
return
AVERROR
(ENOMEM);
146
}
147
frame->
extended_data
[i] = frame->
data
[i] = frame->
buf
[i]->
data
;
148
}
149
for
(i = 0; i < planes -
AV_NUM_DATA_POINTERS
; i++) {
150
frame->
extended_buf
[i] =
av_buffer_alloc
(frame->
linesize
[0]);
151
if
(!frame->
extended_buf
[i]) {
152
av_frame_unref
(frame);
153
return
AVERROR
(ENOMEM);
154
}
155
frame->
extended_data
[i +
AV_NUM_DATA_POINTERS
] = frame->
extended_buf
[i]->
data
;
156
}
157
return
0;
158
159
}
160
161
int
av_frame_get_buffer
(
AVFrame
*frame,
int
align)
162
{
163
if
(frame->
format
< 0)
164
return
AVERROR
(EINVAL);
165
166
if
(frame->
width
> 0 && frame->
height
> 0)
167
return
get_video_buffer
(frame, align);
168
else
if
(frame->
nb_samples
> 0 && frame->
channel_layout
)
169
return
get_audio_buffer
(frame, align);
170
171
return
AVERROR
(EINVAL);
172
}
173
174
int
av_frame_ref
(
AVFrame
*dst,
const
AVFrame
*src)
175
{
176
int
i, ret = 0;
177
178
dst->
format
= src->
format
;
179
dst->
width
= src->
width
;
180
dst->
height
= src->
height
;
181
dst->
channel_layout
= src->
channel_layout
;
182
dst->
nb_samples
= src->
nb_samples
;
183
184
ret =
av_frame_copy_props
(dst, src);
185
if
(ret < 0)
186
return
ret;
187
188
/* duplicate the frame data if it's not refcounted */
189
if
(!src->
buf
[0]) {
190
ret =
av_frame_get_buffer
(dst, 32);
191
if
(ret < 0)
192
return
ret;
193
194
if
(src->
nb_samples
) {
195
int
ch =
av_get_channel_layout_nb_channels
(src->
channel_layout
);
196
av_samples_copy
(dst->
extended_data
, src->
extended_data
, 0, 0,
197
dst->
nb_samples
, ch, dst->
format
);
198
}
else
{
199
av_image_copy
(dst->
data
, dst->
linesize
, src->
data
, src->
linesize
,
200
dst->
format
, dst->
width
, dst->
height
);
201
}
202
return
0;
203
}
204
205
/* ref the buffers */
206
for
(i = 0; i <
FF_ARRAY_ELEMS
(src->
buf
) && src->
buf
[i]; i++) {
207
dst->
buf
[i] =
av_buffer_ref
(src->
buf
[i]);
208
if
(!dst->
buf
[i]) {
209
ret =
AVERROR
(ENOMEM);
210
goto
fail;
211
}
212
}
213
214
if
(src->
extended_buf
) {
215
dst->
extended_buf
=
av_mallocz
(
sizeof
(*dst->
extended_buf
) *
216
src->
nb_extended_buf
);
217
if
(!dst->
extended_buf
) {
218
ret =
AVERROR
(ENOMEM);
219
goto
fail;
220
}
221
dst->
nb_extended_buf
= src->
nb_extended_buf
;
222
223
for
(i = 0; i < src->
nb_extended_buf
; i++) {
224
dst->
extended_buf
[i] =
av_buffer_ref
(src->
extended_buf
[i]);
225
if
(!dst->
extended_buf
[i]) {
226
ret =
AVERROR
(ENOMEM);
227
goto
fail;
228
}
229
}
230
}
231
232
/* duplicate extended data */
233
if
(src->
extended_data
!= src->
data
) {
234
int
ch =
av_get_channel_layout_nb_channels
(src->
channel_layout
);
235
236
if
(!ch) {
237
ret =
AVERROR
(EINVAL);
238
goto
fail;
239
}
240
241
dst->
extended_data
=
av_malloc
(
sizeof
(*dst->
extended_data
) * ch);
242
if
(!dst->
extended_data
) {
243
ret =
AVERROR
(ENOMEM);
244
goto
fail;
245
}
246
memcpy(dst->
extended_data
, src->
extended_data
,
sizeof
(*src->
extended_data
) * ch);
247
}
else
248
dst->
extended_data
= dst->
data
;
249
250
memcpy(dst->
data
, src->
data
,
sizeof
(src->
data
));
251
memcpy(dst->
linesize
, src->
linesize
,
sizeof
(src->
linesize
));
252
253
return
0;
254
255
fail:
256
av_frame_unref
(dst);
257
return
ret;
258
}
259
260
AVFrame
*
av_frame_clone
(
const
AVFrame
*src)
261
{
262
AVFrame
*ret =
av_frame_alloc
();
263
264
if
(!ret)
265
return
NULL
;
266
267
if
(
av_frame_ref
(ret, src) < 0)
268
av_frame_free
(&ret);
269
270
return
ret;
271
}
272
273
void
av_frame_unref
(
AVFrame
*frame)
274
{
275
int
i;
276
277
for
(i = 0; i < frame->
nb_side_data
; i++) {
278
av_freep
(&frame->
side_data
[i]->
data
);
279
av_dict_free
(&frame->
side_data
[i]->
metadata
);
280
av_freep
(&frame->
side_data
[i]);
281
}
282
av_freep
(&frame->
side_data
);
283
284
for
(i = 0; i <
FF_ARRAY_ELEMS
(frame->
buf
); i++)
285
av_buffer_unref
(&frame->
buf
[i]);
286
for
(i = 0; i < frame->
nb_extended_buf
; i++)
287
av_buffer_unref
(&frame->
extended_buf
[i]);
288
av_freep
(&frame->
extended_buf
);
289
get_frame_defaults
(frame);
290
}
291
292
void
av_frame_move_ref
(
AVFrame
*dst,
AVFrame
*src)
293
{
294
*dst = *src;
295
if
(src->
extended_data
== src->
data
)
296
dst->
extended_data
= dst->
data
;
297
memset(src, 0,
sizeof
(*src));
298
get_frame_defaults
(src);
299
}
300
301
int
av_frame_is_writable
(
AVFrame
*frame)
302
{
303
int
i, ret = 1;
304
305
/* assume non-refcounted frames are not writable */
306
if
(!frame->
buf
[0])
307
return
0;
308
309
for
(i = 0; i <
FF_ARRAY_ELEMS
(frame->
buf
) && frame->
buf
[i]; i++)
310
ret &= !!
av_buffer_is_writable
(frame->
buf
[i]);
311
for
(i = 0; i < frame->
nb_extended_buf
; i++)
312
ret &= !!
av_buffer_is_writable
(frame->
extended_buf
[i]);
313
314
return
ret;
315
}
316
317
int
av_frame_make_writable
(
AVFrame
*frame)
318
{
319
AVFrame
tmp;
320
int
ret;
321
322
if
(!frame->
buf
[0])
323
return
AVERROR
(EINVAL);
324
325
if
(
av_frame_is_writable
(frame))
326
return
0;
327
328
memset(&tmp, 0,
sizeof
(tmp));
329
tmp.
format
= frame->
format
;
330
tmp.
width
= frame->
width
;
331
tmp.
height
= frame->
height
;
332
tmp.
channel_layout
= frame->
channel_layout
;
333
tmp.
nb_samples
= frame->
nb_samples
;
334
ret =
av_frame_get_buffer
(&tmp, 32);
335
if
(ret < 0)
336
return
ret;
337
338
if
(tmp.
nb_samples
) {
339
int
ch =
av_get_channel_layout_nb_channels
(tmp.
channel_layout
);
340
av_samples_copy
(tmp.
extended_data
, frame->
extended_data
, 0, 0,
341
frame->
nb_samples
, ch, frame->
format
);
342
}
else
{
343
av_image_copy
(tmp.
data
, tmp.
linesize
, frame->
data
, frame->
linesize
,
344
frame->
format
, frame->
width
, frame->
height
);
345
}
346
347
ret =
av_frame_copy_props
(&tmp, frame);
348
if
(ret < 0) {
349
av_frame_unref
(&tmp);
350
return
ret;
351
}
352
353
av_frame_unref
(frame);
354
355
*frame = tmp;
356
if
(tmp.
data
== tmp.
extended_data
)
357
frame->
extended_data
= frame->
data
;
358
359
return
0;
360
}
361
362
int
av_frame_copy_props
(
AVFrame
*dst,
const
AVFrame
*src)
363
{
364
int
i;
365
366
dst->
key_frame
= src->
key_frame
;
367
dst->
pict_type
= src->
pict_type
;
368
dst->
sample_aspect_ratio
= src->
sample_aspect_ratio
;
369
dst->
pts
= src->
pts
;
370
dst->
repeat_pict
= src->
repeat_pict
;
371
dst->
interlaced_frame
= src->
interlaced_frame
;
372
dst->
top_field_first
= src->
top_field_first
;
373
dst->
palette_has_changed
= src->
palette_has_changed
;
374
dst->
sample_rate
= src->
sample_rate
;
375
dst->
opaque
= src->
opaque
;
376
dst->
pkt_pts
= src->
pkt_pts
;
377
dst->
pkt_dts
= src->
pkt_dts
;
378
dst->
reordered_opaque
= src->
reordered_opaque
;
379
dst->
quality
= src->
quality
;
380
dst->
coded_picture_number
= src->
coded_picture_number
;
381
dst->
display_picture_number
= src->
display_picture_number
;
382
dst->
flags
= src->
flags
;
383
384
memcpy(dst->
error
, src->
error
,
sizeof
(dst->
error
));
385
386
for
(i = 0; i < src->
nb_side_data
; i++) {
387
const
AVFrameSideData
*sd_src = src->
side_data
[i];
388
AVFrameSideData
*sd_dst =
av_frame_new_side_data
(dst, sd_src->
type
,
389
sd_src->
size
);
390
if
(!sd_dst) {
391
for
(i = 0; i < dst->
nb_side_data
; i++) {
392
av_freep
(&dst->
side_data
[i]->
data
);
393
av_freep
(&dst->
side_data
[i]);
394
av_dict_free
(&dst->
side_data
[i]->
metadata
);
395
}
396
av_freep
(&dst->
side_data
);
397
return
AVERROR
(ENOMEM);
398
}
399
memcpy(sd_dst->
data
, sd_src->
data
, sd_src->
size
);
400
av_dict_copy
(&sd_dst->
metadata
, sd_src->
metadata
, 0);
401
}
402
403
return
0;
404
}
405
406
AVBufferRef
*
av_frame_get_plane_buffer
(
AVFrame
*frame,
int
plane)
407
{
408
uint8_t
*
data
;
409
int
planes, i;
410
411
if
(frame->
nb_samples
) {
412
int
channels =
av_get_channel_layout_nb_channels
(frame->
channel_layout
);
413
if
(!channels)
414
return
NULL
;
415
planes =
av_sample_fmt_is_planar
(frame->
format
) ? channels : 1;
416
}
else
417
planes = 4;
418
419
if
(plane < 0 || plane >= planes || !frame->
extended_data
[plane])
420
return
NULL
;
421
data = frame->
extended_data
[plane];
422
423
for
(i = 0; i <
FF_ARRAY_ELEMS
(frame->
buf
) && frame->
buf
[i]; i++) {
424
AVBufferRef
*buf = frame->
buf
[i];
425
if
(data >= buf->
data
&& data < buf->data + buf->
size
)
426
return
buf;
427
}
428
for
(i = 0; i < frame->
nb_extended_buf
; i++) {
429
AVBufferRef
*buf = frame->
extended_buf
[i];
430
if
(data >= buf->
data
&& data < buf->data + buf->
size
)
431
return
buf;
432
}
433
return
NULL
;
434
}
435
436
AVFrameSideData
*
av_frame_new_side_data
(
AVFrame
*frame,
437
enum
AVFrameSideDataType
type,
438
int
size
)
439
{
440
AVFrameSideData
*ret, **tmp;
441
442
if
(frame->
nb_side_data
> INT_MAX /
sizeof
(*frame->
side_data
) - 1)
443
return
NULL
;
444
445
tmp =
av_realloc
(frame->
side_data
,
446
(frame->
nb_side_data
+ 1) *
sizeof
(*frame->
side_data
));
447
if
(!tmp)
448
return
NULL
;
449
frame->
side_data
= tmp;
450
451
ret =
av_mallocz
(
sizeof
(*ret));
452
if
(!ret)
453
return
NULL
;
454
455
ret->
data
=
av_malloc
(size);
456
if
(!ret->
data
) {
457
av_freep
(&ret);
458
return
NULL
;
459
}
460
461
ret->
size
=
size
;
462
ret->
type
= type;
463
464
frame->
side_data
[frame->
nb_side_data
++] = ret;
465
466
return
ret;
467
}
468
469
AVFrameSideData
*
av_frame_get_side_data
(
const
AVFrame
*frame,
470
enum
AVFrameSideDataType
type)
471
{
472
int
i;
473
474
for
(i = 0; i < frame->
nb_side_data
; i++) {
475
if
(frame->
side_data
[i]->
type
== type)
476
return
frame->
side_data
[i];
477
}
478
return
NULL
;
479
}
Generated on Sun Jun 1 2014 17:55:37 for Libav by
1.8.1.2