Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
6147 | serge | 1 | /* |
2 | * |
||
3 | * This file is part of FFmpeg. |
||
4 | * |
||
5 | * FFmpeg 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 | * FFmpeg 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 FFmpeg; 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 "avassert.h" |
||
22 | #include "buffer.h" |
||
23 | #include "common.h" |
||
24 | #include "dict.h" |
||
25 | #include "frame.h" |
||
26 | #include "imgutils.h" |
||
27 | #include "mem.h" |
||
28 | #include "samplefmt.h" |
||
29 | |||
30 | MAKE_ACCESSORS(AVFrame, frame, int64_t, best_effort_timestamp) |
||
31 | MAKE_ACCESSORS(AVFrame, frame, int64_t, pkt_duration) |
||
32 | MAKE_ACCESSORS(AVFrame, frame, int64_t, pkt_pos) |
||
33 | MAKE_ACCESSORS(AVFrame, frame, int64_t, channel_layout) |
||
34 | MAKE_ACCESSORS(AVFrame, frame, int, channels) |
||
35 | MAKE_ACCESSORS(AVFrame, frame, int, sample_rate) |
||
36 | MAKE_ACCESSORS(AVFrame, frame, AVDictionary *, metadata) |
||
37 | MAKE_ACCESSORS(AVFrame, frame, int, decode_error_flags) |
||
38 | MAKE_ACCESSORS(AVFrame, frame, int, pkt_size) |
||
39 | MAKE_ACCESSORS(AVFrame, frame, enum AVColorSpace, colorspace) |
||
40 | MAKE_ACCESSORS(AVFrame, frame, enum AVColorRange, color_range) |
||
41 | |||
42 | #define CHECK_CHANNELS_CONSISTENCY(frame) \ |
||
43 | av_assert2(!(frame)->channel_layout || \ |
||
44 | (frame)->channels == \ |
||
45 | av_get_channel_layout_nb_channels((frame)->channel_layout)) |
||
46 | |||
47 | AVDictionary **avpriv_frame_get_metadatap(AVFrame *frame) {return &frame->metadata;}; |
||
48 | |||
49 | int av_frame_set_qp_table(AVFrame *f, AVBufferRef *buf, int stride, int qp_type) |
||
50 | { |
||
51 | av_buffer_unref(&f->qp_table_buf); |
||
52 | |||
53 | f->qp_table_buf = buf; |
||
54 | |||
55 | f->qscale_table = buf->data; |
||
56 | f->qstride = stride; |
||
57 | f->qscale_type = qp_type; |
||
58 | |||
59 | return 0; |
||
60 | } |
||
61 | |||
62 | int8_t *av_frame_get_qp_table(AVFrame *f, int *stride, int *type) |
||
63 | { |
||
64 | *stride = f->qstride; |
||
65 | *type = f->qscale_type; |
||
66 | |||
67 | if (!f->qp_table_buf) |
||
68 | return NULL; |
||
69 | |||
70 | return f->qp_table_buf->data; |
||
71 | } |
||
72 | |||
73 | const char *av_get_colorspace_name(enum AVColorSpace val) |
||
74 | { |
||
75 | static const char * const name[] = { |
||
76 | [AVCOL_SPC_RGB] = "GBR", |
||
77 | [AVCOL_SPC_BT709] = "bt709", |
||
78 | [AVCOL_SPC_FCC] = "fcc", |
||
79 | [AVCOL_SPC_BT470BG] = "bt470bg", |
||
80 | [AVCOL_SPC_SMPTE170M] = "smpte170m", |
||
81 | [AVCOL_SPC_SMPTE240M] = "smpte240m", |
||
82 | [AVCOL_SPC_YCOCG] = "YCgCo", |
||
83 | }; |
||
84 | if ((unsigned)val >= FF_ARRAY_ELEMS(name)) |
||
85 | return NULL; |
||
86 | return name[val]; |
||
87 | } |
||
88 | |||
89 | static void get_frame_defaults(AVFrame *frame) |
||
90 | { |
||
91 | if (frame->extended_data != frame->data) |
||
92 | av_freep(&frame->extended_data); |
||
93 | |||
94 | memset(frame, 0, sizeof(*frame)); |
||
95 | |||
96 | frame->pts = |
||
97 | frame->pkt_dts = |
||
98 | frame->pkt_pts = AV_NOPTS_VALUE; |
||
99 | av_frame_set_best_effort_timestamp(frame, AV_NOPTS_VALUE); |
||
100 | av_frame_set_pkt_duration (frame, 0); |
||
101 | av_frame_set_pkt_pos (frame, -1); |
||
102 | av_frame_set_pkt_size (frame, -1); |
||
103 | frame->key_frame = 1; |
||
104 | frame->sample_aspect_ratio = (AVRational){ 0, 1 }; |
||
105 | frame->format = -1; /* unknown */ |
||
106 | frame->extended_data = frame->data; |
||
107 | frame->color_primaries = AVCOL_PRI_UNSPECIFIED; |
||
108 | frame->color_trc = AVCOL_TRC_UNSPECIFIED; |
||
109 | frame->colorspace = AVCOL_SPC_UNSPECIFIED; |
||
110 | frame->color_range = AVCOL_RANGE_UNSPECIFIED; |
||
111 | frame->chroma_location = AVCHROMA_LOC_UNSPECIFIED; |
||
112 | } |
||
113 | |||
114 | static void free_side_data(AVFrameSideData **ptr_sd) |
||
115 | { |
||
116 | AVFrameSideData *sd = *ptr_sd; |
||
117 | |||
118 | av_buffer_unref(&sd->buf); |
||
119 | av_dict_free(&sd->metadata); |
||
120 | av_freep(ptr_sd); |
||
121 | } |
||
122 | |||
123 | static void wipe_side_data(AVFrame *frame) |
||
124 | { |
||
125 | int i; |
||
126 | |||
127 | for (i = 0; i < frame->nb_side_data; i++) { |
||
128 | free_side_data(&frame->side_data[i]); |
||
129 | } |
||
130 | frame->nb_side_data = 0; |
||
131 | |||
132 | av_freep(&frame->side_data); |
||
133 | } |
||
134 | |||
135 | AVFrame *av_frame_alloc(void) |
||
136 | { |
||
137 | AVFrame *frame = av_mallocz(sizeof(*frame)); |
||
138 | |||
139 | if (!frame) |
||
140 | return NULL; |
||
141 | |||
142 | frame->extended_data = NULL; |
||
143 | get_frame_defaults(frame); |
||
144 | |||
145 | return frame; |
||
146 | } |
||
147 | |||
148 | void av_frame_free(AVFrame **frame) |
||
149 | { |
||
150 | if (!frame || !*frame) |
||
151 | return; |
||
152 | |||
153 | av_frame_unref(*frame); |
||
154 | av_freep(frame); |
||
155 | } |
||
156 | |||
157 | static int get_video_buffer(AVFrame *frame, int align) |
||
158 | { |
||
159 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); |
||
160 | int ret, i; |
||
161 | |||
162 | if (!desc) |
||
163 | return AVERROR(EINVAL); |
||
164 | |||
165 | if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0) |
||
166 | return ret; |
||
167 | |||
168 | if (!frame->linesize[0]) { |
||
169 | for(i=1; i<=align; i+=i) { |
||
170 | ret = av_image_fill_linesizes(frame->linesize, frame->format, |
||
171 | FFALIGN(frame->width, i)); |
||
172 | if (ret < 0) |
||
173 | return ret; |
||
174 | if (!(frame->linesize[0] & (align-1))) |
||
175 | break; |
||
176 | } |
||
177 | |||
178 | for (i = 0; i < 4 && frame->linesize[i]; i++) |
||
179 | frame->linesize[i] = FFALIGN(frame->linesize[i], align); |
||
180 | } |
||
181 | |||
182 | for (i = 0; i < 4 && frame->linesize[i]; i++) { |
||
183 | int h = FFALIGN(frame->height, 32); |
||
184 | if (i == 1 || i == 2) |
||
185 | h = FF_CEIL_RSHIFT(h, desc->log2_chroma_h); |
||
186 | |||
187 | frame->buf[i] = av_buffer_alloc(frame->linesize[i] * h + 16 + 16/*STRIDE_ALIGN*/ - 1); |
||
188 | if (!frame->buf[i]) |
||
189 | goto fail; |
||
190 | |||
191 | frame->data[i] = frame->buf[i]->data; |
||
192 | } |
||
193 | if (desc->flags & AV_PIX_FMT_FLAG_PAL || desc->flags & AV_PIX_FMT_FLAG_PSEUDOPAL) { |
||
194 | av_buffer_unref(&frame->buf[1]); |
||
195 | frame->buf[1] = av_buffer_alloc(1024); |
||
196 | if (!frame->buf[1]) |
||
197 | goto fail; |
||
198 | frame->data[1] = frame->buf[1]->data; |
||
199 | } |
||
200 | |||
201 | frame->extended_data = frame->data; |
||
202 | |||
203 | return 0; |
||
204 | fail: |
||
205 | av_frame_unref(frame); |
||
206 | return AVERROR(ENOMEM); |
||
207 | } |
||
208 | |||
209 | static int get_audio_buffer(AVFrame *frame, int align) |
||
210 | { |
||
211 | int channels; |
||
212 | int planar = av_sample_fmt_is_planar(frame->format); |
||
213 | int planes; |
||
214 | int ret, i; |
||
215 | |||
216 | if (!frame->channels) |
||
217 | frame->channels = av_get_channel_layout_nb_channels(frame->channel_layout); |
||
218 | |||
219 | channels = frame->channels; |
||
220 | planes = planar ? channels : 1; |
||
221 | |||
222 | CHECK_CHANNELS_CONSISTENCY(frame); |
||
223 | if (!frame->linesize[0]) { |
||
224 | ret = av_samples_get_buffer_size(&frame->linesize[0], channels, |
||
225 | frame->nb_samples, frame->format, |
||
226 | align); |
||
227 | if (ret < 0) |
||
228 | return ret; |
||
229 | } |
||
230 | |||
231 | if (planes > AV_NUM_DATA_POINTERS) { |
||
232 | frame->extended_data = av_mallocz_array(planes, |
||
233 | sizeof(*frame->extended_data)); |
||
234 | frame->extended_buf = av_mallocz_array((planes - AV_NUM_DATA_POINTERS), |
||
235 | sizeof(*frame->extended_buf)); |
||
236 | if (!frame->extended_data || !frame->extended_buf) { |
||
237 | av_freep(&frame->extended_data); |
||
238 | av_freep(&frame->extended_buf); |
||
239 | return AVERROR(ENOMEM); |
||
240 | } |
||
241 | frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS; |
||
242 | } else |
||
243 | frame->extended_data = frame->data; |
||
244 | |||
245 | for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) { |
||
246 | frame->buf[i] = av_buffer_alloc(frame->linesize[0]); |
||
247 | if (!frame->buf[i]) { |
||
248 | av_frame_unref(frame); |
||
249 | return AVERROR(ENOMEM); |
||
250 | } |
||
251 | frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; |
||
252 | } |
||
253 | for (i = 0; i < planes - AV_NUM_DATA_POINTERS; i++) { |
||
254 | frame->extended_buf[i] = av_buffer_alloc(frame->linesize[0]); |
||
255 | if (!frame->extended_buf[i]) { |
||
256 | av_frame_unref(frame); |
||
257 | return AVERROR(ENOMEM); |
||
258 | } |
||
259 | frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data; |
||
260 | } |
||
261 | return 0; |
||
262 | |||
263 | } |
||
264 | |||
265 | int av_frame_get_buffer(AVFrame *frame, int align) |
||
266 | { |
||
267 | if (frame->format < 0) |
||
268 | return AVERROR(EINVAL); |
||
269 | |||
270 | if (frame->width > 0 && frame->height > 0) |
||
271 | return get_video_buffer(frame, align); |
||
272 | else if (frame->nb_samples > 0 && (frame->channel_layout || frame->channels > 0)) |
||
273 | return get_audio_buffer(frame, align); |
||
274 | |||
275 | return AVERROR(EINVAL); |
||
276 | } |
||
277 | |||
278 | static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy) |
||
279 | { |
||
280 | int i; |
||
281 | |||
282 | dst->key_frame = src->key_frame; |
||
283 | dst->pict_type = src->pict_type; |
||
284 | dst->sample_aspect_ratio = src->sample_aspect_ratio; |
||
285 | dst->pts = src->pts; |
||
286 | dst->repeat_pict = src->repeat_pict; |
||
287 | dst->interlaced_frame = src->interlaced_frame; |
||
288 | dst->top_field_first = src->top_field_first; |
||
289 | dst->palette_has_changed = src->palette_has_changed; |
||
290 | dst->sample_rate = src->sample_rate; |
||
291 | dst->opaque = src->opaque; |
||
292 | #if FF_API_AVFRAME_LAVC |
||
293 | FF_DISABLE_DEPRECATION_WARNINGS |
||
294 | dst->type = src->type; |
||
295 | FF_ENABLE_DEPRECATION_WARNINGS |
||
296 | #endif |
||
297 | dst->pkt_pts = src->pkt_pts; |
||
298 | dst->pkt_dts = src->pkt_dts; |
||
299 | dst->pkt_pos = src->pkt_pos; |
||
300 | dst->pkt_size = src->pkt_size; |
||
301 | dst->pkt_duration = src->pkt_duration; |
||
302 | dst->reordered_opaque = src->reordered_opaque; |
||
303 | dst->quality = src->quality; |
||
304 | dst->best_effort_timestamp = src->best_effort_timestamp; |
||
305 | dst->coded_picture_number = src->coded_picture_number; |
||
306 | dst->display_picture_number = src->display_picture_number; |
||
307 | dst->flags = src->flags; |
||
308 | dst->decode_error_flags = src->decode_error_flags; |
||
309 | dst->color_primaries = src->color_primaries; |
||
310 | dst->color_trc = src->color_trc; |
||
311 | dst->colorspace = src->colorspace; |
||
312 | dst->color_range = src->color_range; |
||
313 | dst->chroma_location = src->chroma_location; |
||
314 | |||
315 | av_dict_copy(&dst->metadata, src->metadata, 0); |
||
316 | |||
317 | memcpy(dst->error, src->error, sizeof(dst->error)); |
||
318 | |||
319 | for (i = 0; i < src->nb_side_data; i++) { |
||
320 | const AVFrameSideData *sd_src = src->side_data[i]; |
||
321 | AVFrameSideData *sd_dst; |
||
322 | if ( sd_src->type == AV_FRAME_DATA_PANSCAN |
||
323 | && (src->width != dst->width || src->height != dst->height)) |
||
324 | continue; |
||
325 | if (force_copy) { |
||
326 | sd_dst = av_frame_new_side_data(dst, sd_src->type, |
||
327 | sd_src->size); |
||
328 | if (!sd_dst) { |
||
329 | wipe_side_data(dst); |
||
330 | return AVERROR(ENOMEM); |
||
331 | } |
||
332 | memcpy(sd_dst->data, sd_src->data, sd_src->size); |
||
333 | } else { |
||
334 | sd_dst = av_frame_new_side_data(dst, sd_src->type, 0); |
||
335 | if (!sd_dst) { |
||
336 | wipe_side_data(dst); |
||
337 | return AVERROR(ENOMEM); |
||
338 | } |
||
339 | sd_dst->buf = av_buffer_ref(sd_src->buf); |
||
340 | if (!sd_dst->buf) { |
||
341 | wipe_side_data(dst); |
||
342 | return AVERROR(ENOMEM); |
||
343 | } |
||
344 | sd_dst->data = sd_dst->buf->data; |
||
345 | sd_dst->size = sd_dst->buf->size; |
||
346 | } |
||
347 | av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0); |
||
348 | } |
||
349 | |||
350 | dst->qscale_table = NULL; |
||
351 | dst->qstride = 0; |
||
352 | dst->qscale_type = 0; |
||
353 | if (src->qp_table_buf) { |
||
354 | dst->qp_table_buf = av_buffer_ref(src->qp_table_buf); |
||
355 | if (dst->qp_table_buf) { |
||
356 | dst->qscale_table = dst->qp_table_buf->data; |
||
357 | dst->qstride = src->qstride; |
||
358 | dst->qscale_type = src->qscale_type; |
||
359 | } |
||
360 | } |
||
361 | |||
362 | return 0; |
||
363 | } |
||
364 | |||
365 | int av_frame_ref(AVFrame *dst, const AVFrame *src) |
||
366 | { |
||
367 | int i, ret = 0; |
||
368 | |||
369 | dst->format = src->format; |
||
370 | dst->width = src->width; |
||
371 | dst->height = src->height; |
||
372 | dst->channels = src->channels; |
||
373 | dst->channel_layout = src->channel_layout; |
||
374 | dst->nb_samples = src->nb_samples; |
||
375 | |||
376 | ret = frame_copy_props(dst, src, 0); |
||
377 | if (ret < 0) |
||
378 | return ret; |
||
379 | |||
380 | /* duplicate the frame data if it's not refcounted */ |
||
381 | if (!src->buf[0]) { |
||
382 | ret = av_frame_get_buffer(dst, 32); |
||
383 | if (ret < 0) |
||
384 | return ret; |
||
385 | |||
386 | ret = av_frame_copy(dst, src); |
||
387 | if (ret < 0) |
||
388 | av_frame_unref(dst); |
||
389 | |||
390 | return ret; |
||
391 | } |
||
392 | |||
393 | /* ref the buffers */ |
||
394 | for (i = 0; i < FF_ARRAY_ELEMS(src->buf); i++) { |
||
395 | if (!src->buf[i]) |
||
396 | continue; |
||
397 | dst->buf[i] = av_buffer_ref(src->buf[i]); |
||
398 | if (!dst->buf[i]) { |
||
399 | ret = AVERROR(ENOMEM); |
||
400 | goto fail; |
||
401 | } |
||
402 | } |
||
403 | |||
404 | if (src->extended_buf) { |
||
405 | dst->extended_buf = av_mallocz_array(sizeof(*dst->extended_buf), |
||
406 | src->nb_extended_buf); |
||
407 | if (!dst->extended_buf) { |
||
408 | ret = AVERROR(ENOMEM); |
||
409 | goto fail; |
||
410 | } |
||
411 | dst->nb_extended_buf = src->nb_extended_buf; |
||
412 | |||
413 | for (i = 0; i < src->nb_extended_buf; i++) { |
||
414 | dst->extended_buf[i] = av_buffer_ref(src->extended_buf[i]); |
||
415 | if (!dst->extended_buf[i]) { |
||
416 | ret = AVERROR(ENOMEM); |
||
417 | goto fail; |
||
418 | } |
||
419 | } |
||
420 | } |
||
421 | |||
422 | /* duplicate extended data */ |
||
423 | if (src->extended_data != src->data) { |
||
424 | int ch = src->channels; |
||
425 | |||
426 | if (!ch) { |
||
427 | ret = AVERROR(EINVAL); |
||
428 | goto fail; |
||
429 | } |
||
430 | CHECK_CHANNELS_CONSISTENCY(src); |
||
431 | |||
432 | dst->extended_data = av_malloc_array(sizeof(*dst->extended_data), ch); |
||
433 | if (!dst->extended_data) { |
||
434 | ret = AVERROR(ENOMEM); |
||
435 | goto fail; |
||
436 | } |
||
437 | memcpy(dst->extended_data, src->extended_data, sizeof(*src->extended_data) * ch); |
||
438 | } else |
||
439 | dst->extended_data = dst->data; |
||
440 | |||
441 | memcpy(dst->data, src->data, sizeof(src->data)); |
||
442 | memcpy(dst->linesize, src->linesize, sizeof(src->linesize)); |
||
443 | |||
444 | return 0; |
||
445 | |||
446 | fail: |
||
447 | av_frame_unref(dst); |
||
448 | return ret; |
||
449 | } |
||
450 | |||
451 | AVFrame *av_frame_clone(const AVFrame *src) |
||
452 | { |
||
453 | AVFrame *ret = av_frame_alloc(); |
||
454 | |||
455 | if (!ret) |
||
456 | return NULL; |
||
457 | |||
458 | if (av_frame_ref(ret, src) < 0) |
||
459 | av_frame_free(&ret); |
||
460 | |||
461 | return ret; |
||
462 | } |
||
463 | |||
464 | void av_frame_unref(AVFrame *frame) |
||
465 | { |
||
466 | int i; |
||
467 | |||
468 | if (!frame) |
||
469 | return; |
||
470 | |||
471 | wipe_side_data(frame); |
||
472 | |||
473 | for (i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++) |
||
474 | av_buffer_unref(&frame->buf[i]); |
||
475 | for (i = 0; i < frame->nb_extended_buf; i++) |
||
476 | av_buffer_unref(&frame->extended_buf[i]); |
||
477 | av_freep(&frame->extended_buf); |
||
478 | av_dict_free(&frame->metadata); |
||
479 | av_buffer_unref(&frame->qp_table_buf); |
||
480 | |||
481 | get_frame_defaults(frame); |
||
482 | } |
||
483 | |||
484 | void av_frame_move_ref(AVFrame *dst, AVFrame *src) |
||
485 | { |
||
486 | *dst = *src; |
||
487 | if (src->extended_data == src->data) |
||
488 | dst->extended_data = dst->data; |
||
489 | memset(src, 0, sizeof(*src)); |
||
490 | get_frame_defaults(src); |
||
491 | } |
||
492 | |||
493 | int av_frame_is_writable(AVFrame *frame) |
||
494 | { |
||
495 | int i, ret = 1; |
||
496 | |||
497 | /* assume non-refcounted frames are not writable */ |
||
498 | if (!frame->buf[0]) |
||
499 | return 0; |
||
500 | |||
501 | for (i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++) |
||
502 | if (frame->buf[i]) |
||
503 | ret &= !!av_buffer_is_writable(frame->buf[i]); |
||
504 | for (i = 0; i < frame->nb_extended_buf; i++) |
||
505 | ret &= !!av_buffer_is_writable(frame->extended_buf[i]); |
||
506 | |||
507 | return ret; |
||
508 | } |
||
509 | |||
510 | int av_frame_make_writable(AVFrame *frame) |
||
511 | { |
||
512 | AVFrame tmp; |
||
513 | int ret; |
||
514 | |||
515 | if (!frame->buf[0]) |
||
516 | return AVERROR(EINVAL); |
||
517 | |||
518 | if (av_frame_is_writable(frame)) |
||
519 | return 0; |
||
520 | |||
521 | memset(&tmp, 0, sizeof(tmp)); |
||
522 | tmp.format = frame->format; |
||
523 | tmp.width = frame->width; |
||
524 | tmp.height = frame->height; |
||
525 | tmp.channels = frame->channels; |
||
526 | tmp.channel_layout = frame->channel_layout; |
||
527 | tmp.nb_samples = frame->nb_samples; |
||
528 | ret = av_frame_get_buffer(&tmp, 32); |
||
529 | if (ret < 0) |
||
530 | return ret; |
||
531 | |||
532 | ret = av_frame_copy(&tmp, frame); |
||
533 | if (ret < 0) { |
||
534 | av_frame_unref(&tmp); |
||
535 | return ret; |
||
536 | } |
||
537 | |||
538 | ret = av_frame_copy_props(&tmp, frame); |
||
539 | if (ret < 0) { |
||
540 | av_frame_unref(&tmp); |
||
541 | return ret; |
||
542 | } |
||
543 | |||
544 | av_frame_unref(frame); |
||
545 | |||
546 | *frame = tmp; |
||
547 | if (tmp.data == tmp.extended_data) |
||
548 | frame->extended_data = frame->data; |
||
549 | |||
550 | return 0; |
||
551 | } |
||
552 | |||
553 | int av_frame_copy_props(AVFrame *dst, const AVFrame *src) |
||
554 | { |
||
555 | return frame_copy_props(dst, src, 1); |
||
556 | } |
||
557 | |||
558 | AVBufferRef *av_frame_get_plane_buffer(AVFrame *frame, int plane) |
||
559 | { |
||
560 | uint8_t *data; |
||
561 | int planes, i; |
||
562 | |||
563 | if (frame->nb_samples) { |
||
564 | int channels = frame->channels; |
||
565 | if (!channels) |
||
566 | return NULL; |
||
567 | CHECK_CHANNELS_CONSISTENCY(frame); |
||
568 | planes = av_sample_fmt_is_planar(frame->format) ? channels : 1; |
||
569 | } else |
||
570 | planes = 4; |
||
571 | |||
572 | if (plane < 0 || plane >= planes || !frame->extended_data[plane]) |
||
573 | return NULL; |
||
574 | data = frame->extended_data[plane]; |
||
575 | |||
576 | for (i = 0; i < FF_ARRAY_ELEMS(frame->buf) && frame->buf[i]; i++) { |
||
577 | AVBufferRef *buf = frame->buf[i]; |
||
578 | if (data >= buf->data && data < buf->data + buf->size) |
||
579 | return buf; |
||
580 | } |
||
581 | for (i = 0; i < frame->nb_extended_buf; i++) { |
||
582 | AVBufferRef *buf = frame->extended_buf[i]; |
||
583 | if (data >= buf->data && data < buf->data + buf->size) |
||
584 | return buf; |
||
585 | } |
||
586 | return NULL; |
||
587 | } |
||
588 | |||
589 | AVFrameSideData *av_frame_new_side_data(AVFrame *frame, |
||
590 | enum AVFrameSideDataType type, |
||
591 | int size) |
||
592 | { |
||
593 | AVFrameSideData *ret, **tmp; |
||
594 | |||
595 | if (frame->nb_side_data > INT_MAX / sizeof(*frame->side_data) - 1) |
||
596 | return NULL; |
||
597 | |||
598 | tmp = av_realloc(frame->side_data, |
||
599 | (frame->nb_side_data + 1) * sizeof(*frame->side_data)); |
||
600 | if (!tmp) |
||
601 | return NULL; |
||
602 | frame->side_data = tmp; |
||
603 | |||
604 | ret = av_mallocz(sizeof(*ret)); |
||
605 | if (!ret) |
||
606 | return NULL; |
||
607 | |||
608 | if (size > 0) { |
||
609 | ret->buf = av_buffer_alloc(size); |
||
610 | if (!ret->buf) { |
||
611 | av_freep(&ret); |
||
612 | return NULL; |
||
613 | } |
||
614 | |||
615 | ret->data = ret->buf->data; |
||
616 | ret->size = size; |
||
617 | } |
||
618 | ret->type = type; |
||
619 | |||
620 | frame->side_data[frame->nb_side_data++] = ret; |
||
621 | |||
622 | return ret; |
||
623 | } |
||
624 | |||
625 | AVFrameSideData *av_frame_get_side_data(const AVFrame *frame, |
||
626 | enum AVFrameSideDataType type) |
||
627 | { |
||
628 | int i; |
||
629 | |||
630 | for (i = 0; i < frame->nb_side_data; i++) { |
||
631 | if (frame->side_data[i]->type == type) |
||
632 | return frame->side_data[i]; |
||
633 | } |
||
634 | return NULL; |
||
635 | } |
||
636 | |||
637 | static int frame_copy_video(AVFrame *dst, const AVFrame *src) |
||
638 | { |
||
639 | const uint8_t *src_data[4]; |
||
640 | int i, planes; |
||
641 | |||
642 | if (dst->width < src->width || |
||
643 | dst->height < src->height) |
||
644 | return AVERROR(EINVAL); |
||
645 | |||
646 | planes = av_pix_fmt_count_planes(dst->format); |
||
647 | for (i = 0; i < planes; i++) |
||
648 | if (!dst->data[i] || !src->data[i]) |
||
649 | return AVERROR(EINVAL); |
||
650 | |||
651 | memcpy(src_data, src->data, sizeof(src_data)); |
||
652 | av_image_copy(dst->data, dst->linesize, |
||
653 | src_data, src->linesize, |
||
654 | dst->format, src->width, src->height); |
||
655 | |||
656 | return 0; |
||
657 | } |
||
658 | |||
659 | static int frame_copy_audio(AVFrame *dst, const AVFrame *src) |
||
660 | { |
||
661 | int planar = av_sample_fmt_is_planar(dst->format); |
||
662 | int channels = dst->channels; |
||
663 | int planes = planar ? channels : 1; |
||
664 | int i; |
||
665 | |||
666 | if (dst->nb_samples != src->nb_samples || |
||
667 | dst->channels != src->channels || |
||
668 | dst->channel_layout != src->channel_layout) |
||
669 | return AVERROR(EINVAL); |
||
670 | |||
671 | CHECK_CHANNELS_CONSISTENCY(src); |
||
672 | |||
673 | for (i = 0; i < planes; i++) |
||
674 | if (!dst->extended_data[i] || !src->extended_data[i]) |
||
675 | return AVERROR(EINVAL); |
||
676 | |||
677 | av_samples_copy(dst->extended_data, src->extended_data, 0, 0, |
||
678 | dst->nb_samples, channels, dst->format); |
||
679 | |||
680 | return 0; |
||
681 | } |
||
682 | |||
683 | int av_frame_copy(AVFrame *dst, const AVFrame *src) |
||
684 | { |
||
685 | if (dst->format != src->format || dst->format < 0) |
||
686 | return AVERROR(EINVAL); |
||
687 | |||
688 | if (dst->width > 0 && dst->height > 0) |
||
689 | return frame_copy_video(dst, src); |
||
690 | else if (dst->nb_samples > 0 && dst->channel_layout) |
||
691 | return frame_copy_audio(dst, src); |
||
692 | |||
693 | return AVERROR(EINVAL); |
||
694 | } |
||
695 | |||
696 | void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type) |
||
697 | { |
||
698 | int i; |
||
699 | |||
700 | for (i = 0; i < frame->nb_side_data; i++) { |
||
701 | AVFrameSideData *sd = frame->side_data[i]; |
||
702 | if (sd->type == type) { |
||
703 | free_side_data(&frame->side_data[i]); |
||
704 | frame->side_data[i] = frame->side_data[frame->nb_side_data - 1]; |
||
705 | frame->nb_side_data--; |
||
706 | } |
||
707 | } |
||
708 | } |
||
709 | |||
710 | const char *av_frame_side_data_name(enum AVFrameSideDataType type) |
||
711 | { |
||
712 | switch(type) { |
||
713 | case AV_FRAME_DATA_PANSCAN: return "AVPanScan"; |
||
714 | case AV_FRAME_DATA_A53_CC: return "ATSC A53 Part 4 Closed Captions"; |
||
715 | case AV_FRAME_DATA_STEREO3D: return "Stereoscopic 3d metadata"; |
||
716 | case AV_FRAME_DATA_MATRIXENCODING: return "AVMatrixEncoding"; |
||
717 | case AV_FRAME_DATA_DOWNMIX_INFO: return "Metadata relevant to a downmix procedure"; |
||
718 | case AV_FRAME_DATA_REPLAYGAIN: return "AVReplayGain"; |
||
719 | case AV_FRAME_DATA_DISPLAYMATRIX: return "3x3 displaymatrix"; |
||
720 | case AV_FRAME_DATA_MOTION_VECTORS: return "Motion vectors"; |
||
721 | } |
||
722 | return NULL; |
||
723 | }>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>=align;>>> |