2 * This file is part of FFmpeg.
4 * FFmpeg is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * FFmpeg is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with FFmpeg; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 #include "channel_layout.h"
28 #include "samplefmt.h"
29 #include "hwcontext.h"
31 #if FF_API_OLD_CHANNEL_LAYOUT
32 #define CHECK_CHANNELS_CONSISTENCY(frame) \
33 av_assert2(!(frame)->channel_layout || \
34 (frame)->channels == \
35 av_get_channel_layout_nb_channels((frame)->channel_layout))
38 #if FF_API_COLORSPACE_NAME
39 const char *av_get_colorspace_name(enum AVColorSpace val
)
41 static const char * const name
[] = {
42 [AVCOL_SPC_RGB
] = "GBR",
43 [AVCOL_SPC_BT709
] = "bt709",
44 [AVCOL_SPC_FCC
] = "fcc",
45 [AVCOL_SPC_BT470BG
] = "bt470bg",
46 [AVCOL_SPC_SMPTE170M
] = "smpte170m",
47 [AVCOL_SPC_SMPTE240M
] = "smpte240m",
48 [AVCOL_SPC_YCOCG
] = "YCgCo",
50 if ((unsigned)val
>= FF_ARRAY_ELEMS(name
))
55 static void get_frame_defaults(AVFrame
*frame
)
57 memset(frame
, 0, sizeof(*frame
));
60 frame
->pkt_dts
= AV_NOPTS_VALUE
;
61 frame
->best_effort_timestamp
= AV_NOPTS_VALUE
;
62 frame
->pkt_duration
= 0;
65 frame
->time_base
= (AVRational
){ 0, 1 };
67 frame
->sample_aspect_ratio
= (AVRational
){ 0, 1 };
68 frame
->format
= -1; /* unknown */
69 frame
->extended_data
= frame
->data
;
70 frame
->color_primaries
= AVCOL_PRI_UNSPECIFIED
;
71 frame
->color_trc
= AVCOL_TRC_UNSPECIFIED
;
72 frame
->colorspace
= AVCOL_SPC_UNSPECIFIED
;
73 frame
->color_range
= AVCOL_RANGE_UNSPECIFIED
;
74 frame
->chroma_location
= AVCHROMA_LOC_UNSPECIFIED
;
78 static void free_side_data(AVFrameSideData
**ptr_sd
)
80 AVFrameSideData
*sd
= *ptr_sd
;
82 av_buffer_unref(&sd
->buf
);
83 av_dict_free(&sd
->metadata
);
87 static void wipe_side_data(AVFrame
*frame
)
91 for (i
= 0; i
< frame
->nb_side_data
; i
++) {
92 free_side_data(&frame
->side_data
[i
]);
94 frame
->nb_side_data
= 0;
96 av_freep(&frame
->side_data
);
99 AVFrame
*av_frame_alloc(void)
101 AVFrame
*frame
= av_malloc(sizeof(*frame
));
106 get_frame_defaults(frame
);
111 void av_frame_free(AVFrame
**frame
)
113 if (!frame
|| !*frame
)
116 av_frame_unref(*frame
);
120 static int get_video_buffer(AVFrame
*frame
, int align
)
122 const AVPixFmtDescriptor
*desc
= av_pix_fmt_desc_get(frame
->format
);
123 int ret
, i
, padded_height
, total_size
;
124 int plane_padding
= FFMAX(16 + 16/*STRIDE_ALIGN*/, align
);
125 ptrdiff_t linesizes
[4];
129 return AVERROR(EINVAL
);
131 if ((ret
= av_image_check_size(frame
->width
, frame
->height
, 0, NULL
)) < 0)
134 if (!frame
->linesize
[0]) {
136 align
= 32; /* STRIDE_ALIGN. Should be av_cpu_max_align() */
138 for(i
=1; i
<=align
; i
+=i
) {
139 ret
= av_image_fill_linesizes(frame
->linesize
, frame
->format
,
140 FFALIGN(frame
->width
, i
));
143 if (!(frame
->linesize
[0] & (align
-1)))
147 for (i
= 0; i
< 4 && frame
->linesize
[i
]; i
++)
148 frame
->linesize
[i
] = FFALIGN(frame
->linesize
[i
], align
);
151 for (i
= 0; i
< 4; i
++)
152 linesizes
[i
] = frame
->linesize
[i
];
154 padded_height
= FFALIGN(frame
->height
, 32);
155 if ((ret
= av_image_fill_plane_sizes(sizes
, frame
->format
,
156 padded_height
, linesizes
)) < 0)
159 total_size
= 4*plane_padding
;
160 for (i
= 0; i
< 4; i
++) {
161 if (sizes
[i
] > INT_MAX
- total_size
)
162 return AVERROR(EINVAL
);
163 total_size
+= sizes
[i
];
166 frame
->buf
[0] = av_buffer_alloc(total_size
);
167 if (!frame
->buf
[0]) {
168 ret
= AVERROR(ENOMEM
);
172 if ((ret
= av_image_fill_pointers(frame
->data
, frame
->format
, padded_height
,
173 frame
->buf
[0]->data
, frame
->linesize
)) < 0)
176 for (i
= 1; i
< 4; i
++) {
178 frame
->data
[i
] += i
* plane_padding
;
181 frame
->extended_data
= frame
->data
;
185 av_frame_unref(frame
);
189 static int get_audio_buffer(AVFrame
*frame
, int align
)
191 int planar
= av_sample_fmt_is_planar(frame
->format
);
192 int channels
, planes
;
195 #if FF_API_OLD_CHANNEL_LAYOUT
196 FF_DISABLE_DEPRECATION_WARNINGS
197 if (!frame
->ch_layout
.nb_channels
) {
198 if (frame
->channel_layout
) {
199 av_channel_layout_from_mask(&frame
->ch_layout
, frame
->channel_layout
);
201 frame
->ch_layout
.nb_channels
= frame
->channels
;
202 frame
->ch_layout
.order
= AV_CHANNEL_ORDER_UNSPEC
;
205 frame
->channels
= frame
->ch_layout
.nb_channels
;
206 frame
->channel_layout
= frame
->ch_layout
.order
== AV_CHANNEL_ORDER_NATIVE
?
207 frame
->ch_layout
.u
.mask
: 0;
208 FF_ENABLE_DEPRECATION_WARNINGS
210 channels
= frame
->ch_layout
.nb_channels
;
211 planes
= planar
? channels
: 1;
212 if (!frame
->linesize
[0]) {
213 ret
= av_samples_get_buffer_size(&frame
->linesize
[0], channels
,
214 frame
->nb_samples
, frame
->format
,
220 if (planes
> AV_NUM_DATA_POINTERS
) {
221 frame
->extended_data
= av_calloc(planes
,
222 sizeof(*frame
->extended_data
));
223 frame
->extended_buf
= av_calloc(planes
- AV_NUM_DATA_POINTERS
,
224 sizeof(*frame
->extended_buf
));
225 if (!frame
->extended_data
|| !frame
->extended_buf
) {
226 av_freep(&frame
->extended_data
);
227 av_freep(&frame
->extended_buf
);
228 return AVERROR(ENOMEM
);
230 frame
->nb_extended_buf
= planes
- AV_NUM_DATA_POINTERS
;
232 frame
->extended_data
= frame
->data
;
234 for (i
= 0; i
< FFMIN(planes
, AV_NUM_DATA_POINTERS
); i
++) {
235 frame
->buf
[i
] = av_buffer_alloc(frame
->linesize
[0]);
236 if (!frame
->buf
[i
]) {
237 av_frame_unref(frame
);
238 return AVERROR(ENOMEM
);
240 frame
->extended_data
[i
] = frame
->data
[i
] = frame
->buf
[i
]->data
;
242 for (i
= 0; i
< planes
- AV_NUM_DATA_POINTERS
; i
++) {
243 frame
->extended_buf
[i
] = av_buffer_alloc(frame
->linesize
[0]);
244 if (!frame
->extended_buf
[i
]) {
245 av_frame_unref(frame
);
246 return AVERROR(ENOMEM
);
248 frame
->extended_data
[i
+ AV_NUM_DATA_POINTERS
] = frame
->extended_buf
[i
]->data
;
254 int av_frame_get_buffer(AVFrame
*frame
, int align
)
256 if (frame
->format
< 0)
257 return AVERROR(EINVAL
);
259 FF_DISABLE_DEPRECATION_WARNINGS
260 if (frame
->width
> 0 && frame
->height
> 0)
261 return get_video_buffer(frame
, align
);
262 else if (frame
->nb_samples
> 0 &&
263 (av_channel_layout_check(&frame
->ch_layout
)
264 #if FF_API_OLD_CHANNEL_LAYOUT
265 || frame
->channel_layout
|| frame
->channels
> 0
268 return get_audio_buffer(frame
, align
);
269 FF_ENABLE_DEPRECATION_WARNINGS
271 return AVERROR(EINVAL
);
274 static int frame_copy_props(AVFrame
*dst
, const AVFrame
*src
, int force_copy
)
278 dst
->key_frame
= src
->key_frame
;
279 dst
->pict_type
= src
->pict_type
;
280 dst
->sample_aspect_ratio
= src
->sample_aspect_ratio
;
281 dst
->crop_top
= src
->crop_top
;
282 dst
->crop_bottom
= src
->crop_bottom
;
283 dst
->crop_left
= src
->crop_left
;
284 dst
->crop_right
= src
->crop_right
;
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 dst
->pkt_dts
= src
->pkt_dts
;
293 dst
->pkt_pos
= src
->pkt_pos
;
294 dst
->pkt_size
= src
->pkt_size
;
295 dst
->pkt_duration
= src
->pkt_duration
;
296 dst
->time_base
= src
->time_base
;
297 dst
->reordered_opaque
= src
->reordered_opaque
;
298 dst
->quality
= src
->quality
;
299 dst
->best_effort_timestamp
= src
->best_effort_timestamp
;
300 dst
->coded_picture_number
= src
->coded_picture_number
;
301 dst
->display_picture_number
= src
->display_picture_number
;
302 dst
->flags
= src
->flags
;
303 dst
->decode_error_flags
= src
->decode_error_flags
;
304 dst
->color_primaries
= src
->color_primaries
;
305 dst
->color_trc
= src
->color_trc
;
306 dst
->colorspace
= src
->colorspace
;
307 dst
->color_range
= src
->color_range
;
308 dst
->chroma_location
= src
->chroma_location
;
310 av_dict_copy(&dst
->metadata
, src
->metadata
, 0);
312 for (i
= 0; i
< src
->nb_side_data
; i
++) {
313 const AVFrameSideData
*sd_src
= src
->side_data
[i
];
314 AVFrameSideData
*sd_dst
;
315 if ( sd_src
->type
== AV_FRAME_DATA_PANSCAN
316 && (src
->width
!= dst
->width
|| src
->height
!= dst
->height
))
319 sd_dst
= av_frame_new_side_data(dst
, sd_src
->type
,
323 return AVERROR(ENOMEM
);
325 memcpy(sd_dst
->data
, sd_src
->data
, sd_src
->size
);
327 AVBufferRef
*ref
= av_buffer_ref(sd_src
->buf
);
328 sd_dst
= av_frame_new_side_data_from_buf(dst
, sd_src
->type
, ref
);
330 av_buffer_unref(&ref
);
332 return AVERROR(ENOMEM
);
335 av_dict_copy(&sd_dst
->metadata
, sd_src
->metadata
, 0);
338 ret
= av_buffer_replace(&dst
->opaque_ref
, src
->opaque_ref
);
339 ret
|= av_buffer_replace(&dst
->private_ref
, src
->private_ref
);
343 int av_frame_ref(AVFrame
*dst
, const AVFrame
*src
)
347 av_assert1(dst
->width
== 0 && dst
->height
== 0);
348 #if FF_API_OLD_CHANNEL_LAYOUT
349 FF_DISABLE_DEPRECATION_WARNINGS
350 av_assert1(dst
->channels
== 0);
351 FF_ENABLE_DEPRECATION_WARNINGS
353 av_assert1(dst
->ch_layout
.nb_channels
== 0 &&
354 dst
->ch_layout
.order
== AV_CHANNEL_ORDER_UNSPEC
);
356 dst
->format
= src
->format
;
357 dst
->width
= src
->width
;
358 dst
->height
= src
->height
;
359 dst
->nb_samples
= src
->nb_samples
;
360 #if FF_API_OLD_CHANNEL_LAYOUT
361 FF_DISABLE_DEPRECATION_WARNINGS
362 dst
->channels
= src
->channels
;
363 dst
->channel_layout
= src
->channel_layout
;
364 if (!av_channel_layout_check(&src
->ch_layout
)) {
365 if (src
->channel_layout
)
366 av_channel_layout_from_mask(&dst
->ch_layout
, src
->channel_layout
);
368 dst
->ch_layout
.nb_channels
= src
->channels
;
369 dst
->ch_layout
.order
= AV_CHANNEL_ORDER_UNSPEC
;
372 FF_ENABLE_DEPRECATION_WARNINGS
375 ret
= frame_copy_props(dst
, src
, 0);
379 // this check is needed only until FF_API_OLD_CHANNEL_LAYOUT is out
380 if (av_channel_layout_check(&src
->ch_layout
)) {
381 ret
= av_channel_layout_copy(&dst
->ch_layout
, &src
->ch_layout
);
386 /* duplicate the frame data if it's not refcounted */
388 ret
= av_frame_get_buffer(dst
, 0);
392 ret
= av_frame_copy(dst
, src
);
399 /* ref the buffers */
400 for (i
= 0; i
< FF_ARRAY_ELEMS(src
->buf
); i
++) {
403 dst
->buf
[i
] = av_buffer_ref(src
->buf
[i
]);
405 ret
= AVERROR(ENOMEM
);
410 if (src
->extended_buf
) {
411 dst
->extended_buf
= av_calloc(src
->nb_extended_buf
,
412 sizeof(*dst
->extended_buf
));
413 if (!dst
->extended_buf
) {
414 ret
= AVERROR(ENOMEM
);
417 dst
->nb_extended_buf
= src
->nb_extended_buf
;
419 for (i
= 0; i
< src
->nb_extended_buf
; i
++) {
420 dst
->extended_buf
[i
] = av_buffer_ref(src
->extended_buf
[i
]);
421 if (!dst
->extended_buf
[i
]) {
422 ret
= AVERROR(ENOMEM
);
428 if (src
->hw_frames_ctx
) {
429 dst
->hw_frames_ctx
= av_buffer_ref(src
->hw_frames_ctx
);
430 if (!dst
->hw_frames_ctx
) {
431 ret
= AVERROR(ENOMEM
);
436 /* duplicate extended data */
437 if (src
->extended_data
!= src
->data
) {
438 int ch
= dst
->ch_layout
.nb_channels
;
441 ret
= AVERROR(EINVAL
);
445 dst
->extended_data
= av_malloc_array(sizeof(*dst
->extended_data
), ch
);
446 if (!dst
->extended_data
) {
447 ret
= AVERROR(ENOMEM
);
450 memcpy(dst
->extended_data
, src
->extended_data
, sizeof(*src
->extended_data
) * ch
);
452 dst
->extended_data
= dst
->data
;
454 memcpy(dst
->data
, src
->data
, sizeof(src
->data
));
455 memcpy(dst
->linesize
, src
->linesize
, sizeof(src
->linesize
));
464 AVFrame
*av_frame_clone(const AVFrame
*src
)
466 AVFrame
*ret
= av_frame_alloc();
471 if (av_frame_ref(ret
, src
) < 0)
477 void av_frame_unref(AVFrame
*frame
)
484 wipe_side_data(frame
);
486 for (i
= 0; i
< FF_ARRAY_ELEMS(frame
->buf
); i
++)
487 av_buffer_unref(&frame
->buf
[i
]);
488 for (i
= 0; i
< frame
->nb_extended_buf
; i
++)
489 av_buffer_unref(&frame
->extended_buf
[i
]);
490 av_freep(&frame
->extended_buf
);
491 av_dict_free(&frame
->metadata
);
493 av_buffer_unref(&frame
->hw_frames_ctx
);
495 av_buffer_unref(&frame
->opaque_ref
);
496 av_buffer_unref(&frame
->private_ref
);
498 if (frame
->extended_data
!= frame
->data
)
499 av_freep(&frame
->extended_data
);
501 av_channel_layout_uninit(&frame
->ch_layout
);
503 get_frame_defaults(frame
);
506 void av_frame_move_ref(AVFrame
*dst
, AVFrame
*src
)
508 av_assert1(dst
->width
== 0 && dst
->height
== 0);
509 #if FF_API_OLD_CHANNEL_LAYOUT
510 FF_DISABLE_DEPRECATION_WARNINGS
511 av_assert1(dst
->channels
== 0);
512 FF_ENABLE_DEPRECATION_WARNINGS
514 av_assert1(dst
->ch_layout
.nb_channels
== 0 &&
515 dst
->ch_layout
.order
== AV_CHANNEL_ORDER_UNSPEC
);
518 if (src
->extended_data
== src
->data
)
519 dst
->extended_data
= dst
->data
;
520 get_frame_defaults(src
);
523 int av_frame_is_writable(AVFrame
*frame
)
527 /* assume non-refcounted frames are not writable */
531 for (i
= 0; i
< FF_ARRAY_ELEMS(frame
->buf
); i
++)
533 ret
&= !!av_buffer_is_writable(frame
->buf
[i
]);
534 for (i
= 0; i
< frame
->nb_extended_buf
; i
++)
535 ret
&= !!av_buffer_is_writable(frame
->extended_buf
[i
]);
540 int av_frame_make_writable(AVFrame
*frame
)
546 return AVERROR(EINVAL
);
548 if (av_frame_is_writable(frame
))
551 memset(&tmp
, 0, sizeof(tmp
));
552 tmp
.format
= frame
->format
;
553 tmp
.width
= frame
->width
;
554 tmp
.height
= frame
->height
;
555 #if FF_API_OLD_CHANNEL_LAYOUT
556 FF_DISABLE_DEPRECATION_WARNINGS
557 tmp
.channels
= frame
->channels
;
558 tmp
.channel_layout
= frame
->channel_layout
;
559 FF_ENABLE_DEPRECATION_WARNINGS
561 tmp
.nb_samples
= frame
->nb_samples
;
562 ret
= av_channel_layout_copy(&tmp
.ch_layout
, &frame
->ch_layout
);
564 av_frame_unref(&tmp
);
568 if (frame
->hw_frames_ctx
)
569 ret
= av_hwframe_get_buffer(frame
->hw_frames_ctx
, &tmp
, 0);
571 ret
= av_frame_get_buffer(&tmp
, 0);
575 ret
= av_frame_copy(&tmp
, frame
);
577 av_frame_unref(&tmp
);
581 ret
= av_frame_copy_props(&tmp
, frame
);
583 av_frame_unref(&tmp
);
587 av_frame_unref(frame
);
590 if (tmp
.data
== tmp
.extended_data
)
591 frame
->extended_data
= frame
->data
;
596 int av_frame_copy_props(AVFrame
*dst
, const AVFrame
*src
)
598 return frame_copy_props(dst
, src
, 1);
601 AVBufferRef
*av_frame_get_plane_buffer(AVFrame
*frame
, int plane
)
606 if (frame
->nb_samples
) {
607 int channels
= frame
->ch_layout
.nb_channels
;
609 #if FF_API_OLD_CHANNEL_LAYOUT
610 FF_DISABLE_DEPRECATION_WARNINGS
612 channels
= frame
->channels
;
613 CHECK_CHANNELS_CONSISTENCY(frame
);
615 FF_ENABLE_DEPRECATION_WARNINGS
619 planes
= av_sample_fmt_is_planar(frame
->format
) ? channels
: 1;
623 if (plane
< 0 || plane
>= planes
|| !frame
->extended_data
[plane
])
625 data
= frame
->extended_data
[plane
];
627 for (i
= 0; i
< FF_ARRAY_ELEMS(frame
->buf
) && frame
->buf
[i
]; i
++) {
628 AVBufferRef
*buf
= frame
->buf
[i
];
629 if (data
>= buf
->data
&& data
< buf
->data
+ buf
->size
)
632 for (i
= 0; i
< frame
->nb_extended_buf
; i
++) {
633 AVBufferRef
*buf
= frame
->extended_buf
[i
];
634 if (data
>= buf
->data
&& data
< buf
->data
+ buf
->size
)
640 AVFrameSideData
*av_frame_new_side_data_from_buf(AVFrame
*frame
,
641 enum AVFrameSideDataType type
,
644 AVFrameSideData
*ret
, **tmp
;
649 if (frame
->nb_side_data
> INT_MAX
/ sizeof(*frame
->side_data
) - 1)
652 tmp
= av_realloc(frame
->side_data
,
653 (frame
->nb_side_data
+ 1) * sizeof(*frame
->side_data
));
656 frame
->side_data
= tmp
;
658 ret
= av_mallocz(sizeof(*ret
));
663 ret
->data
= ret
->buf
->data
;
664 ret
->size
= buf
->size
;
667 frame
->side_data
[frame
->nb_side_data
++] = ret
;
672 AVFrameSideData
*av_frame_new_side_data(AVFrame
*frame
,
673 enum AVFrameSideDataType type
,
676 AVFrameSideData
*ret
;
677 AVBufferRef
*buf
= av_buffer_alloc(size
);
678 ret
= av_frame_new_side_data_from_buf(frame
, type
, buf
);
680 av_buffer_unref(&buf
);
684 AVFrameSideData
*av_frame_get_side_data(const AVFrame
*frame
,
685 enum AVFrameSideDataType type
)
689 for (i
= 0; i
< frame
->nb_side_data
; i
++) {
690 if (frame
->side_data
[i
]->type
== type
)
691 return frame
->side_data
[i
];
696 static int frame_copy_video(AVFrame
*dst
, const AVFrame
*src
)
698 const uint8_t *src_data
[4];
701 if (dst
->width
< src
->width
||
702 dst
->height
< src
->height
)
703 return AVERROR(EINVAL
);
705 if (src
->hw_frames_ctx
|| dst
->hw_frames_ctx
)
706 return av_hwframe_transfer_data(dst
, src
, 0);
708 planes
= av_pix_fmt_count_planes(dst
->format
);
709 for (i
= 0; i
< planes
; i
++)
710 if (!dst
->data
[i
] || !src
->data
[i
])
711 return AVERROR(EINVAL
);
713 memcpy(src_data
, src
->data
, sizeof(src_data
));
714 av_image_copy(dst
->data
, dst
->linesize
,
715 src_data
, src
->linesize
,
716 dst
->format
, src
->width
, src
->height
);
721 static int frame_copy_audio(AVFrame
*dst
, const AVFrame
*src
)
723 int planar
= av_sample_fmt_is_planar(dst
->format
);
724 int channels
= dst
->ch_layout
.nb_channels
;
725 int planes
= planar
? channels
: 1;
728 #if FF_API_OLD_CHANNEL_LAYOUT
729 FF_DISABLE_DEPRECATION_WARNINGS
730 if (!channels
|| !src
->ch_layout
.nb_channels
) {
731 if (dst
->channels
!= src
->channels
||
732 dst
->channel_layout
!= src
->channel_layout
)
733 return AVERROR(EINVAL
);
734 CHECK_CHANNELS_CONSISTENCY(src
);
737 channels
= dst
->channels
;
738 planes
= planar
? channels
: 1;
740 FF_ENABLE_DEPRECATION_WARNINGS
743 if (dst
->nb_samples
!= src
->nb_samples
||
744 #if FF_API_OLD_CHANNEL_LAYOUT
745 (av_channel_layout_check(&dst
->ch_layout
) &&
746 av_channel_layout_check(&src
->ch_layout
) &&
748 av_channel_layout_compare(&dst
->ch_layout
, &src
->ch_layout
))
749 #if FF_API_OLD_CHANNEL_LAYOUT
752 return AVERROR(EINVAL
);
754 for (i
= 0; i
< planes
; i
++)
755 if (!dst
->extended_data
[i
] || !src
->extended_data
[i
])
756 return AVERROR(EINVAL
);
758 av_samples_copy(dst
->extended_data
, src
->extended_data
, 0, 0,
759 dst
->nb_samples
, channels
, dst
->format
);
764 int av_frame_copy(AVFrame
*dst
, const AVFrame
*src
)
766 if (dst
->format
!= src
->format
|| dst
->format
< 0)
767 return AVERROR(EINVAL
);
769 FF_DISABLE_DEPRECATION_WARNINGS
770 if (dst
->width
> 0 && dst
->height
> 0)
771 return frame_copy_video(dst
, src
);
772 else if (dst
->nb_samples
> 0 &&
773 (av_channel_layout_check(&dst
->ch_layout
)
774 #if FF_API_OLD_CHANNEL_LAYOUT
778 return frame_copy_audio(dst
, src
);
779 FF_ENABLE_DEPRECATION_WARNINGS
781 return AVERROR(EINVAL
);
784 void av_frame_remove_side_data(AVFrame
*frame
, enum AVFrameSideDataType type
)
788 for (i
= frame
->nb_side_data
- 1; i
>= 0; i
--) {
789 AVFrameSideData
*sd
= frame
->side_data
[i
];
790 if (sd
->type
== type
) {
791 free_side_data(&frame
->side_data
[i
]);
792 frame
->side_data
[i
] = frame
->side_data
[frame
->nb_side_data
- 1];
793 frame
->nb_side_data
--;
798 const char *av_frame_side_data_name(enum AVFrameSideDataType type
)
801 case AV_FRAME_DATA_PANSCAN
: return "AVPanScan";
802 case AV_FRAME_DATA_A53_CC
: return "ATSC A53 Part 4 Closed Captions";
803 case AV_FRAME_DATA_STEREO3D
: return "Stereo 3D";
804 case AV_FRAME_DATA_MATRIXENCODING
: return "AVMatrixEncoding";
805 case AV_FRAME_DATA_DOWNMIX_INFO
: return "Metadata relevant to a downmix procedure";
806 case AV_FRAME_DATA_REPLAYGAIN
: return "AVReplayGain";
807 case AV_FRAME_DATA_DISPLAYMATRIX
: return "3x3 displaymatrix";
808 case AV_FRAME_DATA_AFD
: return "Active format description";
809 case AV_FRAME_DATA_MOTION_VECTORS
: return "Motion vectors";
810 case AV_FRAME_DATA_SKIP_SAMPLES
: return "Skip samples";
811 case AV_FRAME_DATA_AUDIO_SERVICE_TYPE
: return "Audio service type";
812 case AV_FRAME_DATA_MASTERING_DISPLAY_METADATA
: return "Mastering display metadata";
813 case AV_FRAME_DATA_CONTENT_LIGHT_LEVEL
: return "Content light level metadata";
814 case AV_FRAME_DATA_GOP_TIMECODE
: return "GOP timecode";
815 case AV_FRAME_DATA_S12M_TIMECODE
: return "SMPTE 12-1 timecode";
816 case AV_FRAME_DATA_SPHERICAL
: return "Spherical Mapping";
817 case AV_FRAME_DATA_ICC_PROFILE
: return "ICC profile";
818 case AV_FRAME_DATA_DYNAMIC_HDR_PLUS
: return "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)";
819 case AV_FRAME_DATA_DYNAMIC_HDR_VIVID
: return "HDR Dynamic Metadata CUVA 005.1 2021 (Vivid)";
820 case AV_FRAME_DATA_REGIONS_OF_INTEREST
: return "Regions Of Interest";
821 case AV_FRAME_DATA_VIDEO_ENC_PARAMS
: return "Video encoding parameters";
822 case AV_FRAME_DATA_SEI_UNREGISTERED
: return "H.26[45] User Data Unregistered SEI message";
823 case AV_FRAME_DATA_FILM_GRAIN_PARAMS
: return "Film grain parameters";
824 case AV_FRAME_DATA_DETECTION_BBOXES
: return "Bounding boxes for object detection and classification";
825 case AV_FRAME_DATA_DOVI_RPU_BUFFER
: return "Dolby Vision RPU Data";
826 case AV_FRAME_DATA_DOVI_METADATA
: return "Dolby Vision Metadata";
831 static int calc_cropping_offsets(size_t offsets
[4], const AVFrame
*frame
,
832 const AVPixFmtDescriptor
*desc
)
836 for (i
= 0; frame
->data
[i
]; i
++) {
837 const AVComponentDescriptor
*comp
= NULL
;
838 int shift_x
= (i
== 1 || i
== 2) ? desc
->log2_chroma_w
: 0;
839 int shift_y
= (i
== 1 || i
== 2) ? desc
->log2_chroma_h
: 0;
841 if (desc
->flags
& AV_PIX_FMT_FLAG_PAL
&& i
== 1) {
846 /* find any component descriptor for this plane */
847 for (j
= 0; j
< desc
->nb_components
; j
++) {
848 if (desc
->comp
[j
].plane
== i
) {
849 comp
= &desc
->comp
[j
];
856 offsets
[i
] = (frame
->crop_top
>> shift_y
) * frame
->linesize
[i
] +
857 (frame
->crop_left
>> shift_x
) * comp
->step
;
863 int av_frame_apply_cropping(AVFrame
*frame
, int flags
)
865 const AVPixFmtDescriptor
*desc
;
869 if (!(frame
->width
> 0 && frame
->height
> 0))
870 return AVERROR(EINVAL
);
872 if (frame
->crop_left
>= INT_MAX
- frame
->crop_right
||
873 frame
->crop_top
>= INT_MAX
- frame
->crop_bottom
||
874 (frame
->crop_left
+ frame
->crop_right
) >= frame
->width
||
875 (frame
->crop_top
+ frame
->crop_bottom
) >= frame
->height
)
876 return AVERROR(ERANGE
);
878 desc
= av_pix_fmt_desc_get(frame
->format
);
882 /* Apply just the right/bottom cropping for hwaccel formats. Bitstream
883 * formats cannot be easily handled here either (and corresponding decoders
884 * should not export any cropping anyway), so do the same for those as well.
886 if (desc
->flags
& (AV_PIX_FMT_FLAG_BITSTREAM
| AV_PIX_FMT_FLAG_HWACCEL
)) {
887 frame
->width
-= frame
->crop_right
;
888 frame
->height
-= frame
->crop_bottom
;
889 frame
->crop_right
= 0;
890 frame
->crop_bottom
= 0;
894 /* calculate the offsets for each plane */
895 calc_cropping_offsets(offsets
, frame
, desc
);
897 /* adjust the offsets to avoid breaking alignment */
898 if (!(flags
& AV_FRAME_CROP_UNALIGNED
)) {
899 int log2_crop_align
= frame
->crop_left
? ff_ctz(frame
->crop_left
) : INT_MAX
;
900 int min_log2_align
= INT_MAX
;
902 for (i
= 0; frame
->data
[i
]; i
++) {
903 int log2_align
= offsets
[i
] ? ff_ctz(offsets
[i
]) : INT_MAX
;
904 min_log2_align
= FFMIN(log2_align
, min_log2_align
);
907 /* we assume, and it should always be true, that the data alignment is
908 * related to the cropping alignment by a constant power-of-2 factor */
909 if (log2_crop_align
< min_log2_align
)
912 if (min_log2_align
< 5 && log2_crop_align
!= INT_MAX
) {
913 frame
->crop_left
&= ~((1 << (5 + log2_crop_align
- min_log2_align
)) - 1);
914 calc_cropping_offsets(offsets
, frame
, desc
);
918 for (i
= 0; frame
->data
[i
]; i
++)
919 frame
->data
[i
] += offsets
[i
];
921 frame
->width
-= (frame
->crop_left
+ frame
->crop_right
);
922 frame
->height
-= (frame
->crop_top
+ frame
->crop_bottom
);
923 frame
->crop_left
= 0;
924 frame
->crop_right
= 0;
926 frame
->crop_bottom
= 0;