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"
26 #include "refstruct.h"
27 #include "samplefmt.h"
28 #include "side_data.h"
29 #include "hwcontext.h"
31 static void get_frame_defaults(AVFrame
*frame
)
33 memset(frame
, 0, sizeof(*frame
));
36 frame
->pkt_dts
= AV_NOPTS_VALUE
;
37 frame
->best_effort_timestamp
= AV_NOPTS_VALUE
;
39 frame
->time_base
= (AVRational
){ 0, 1 };
40 frame
->sample_aspect_ratio
= (AVRational
){ 0, 1 };
41 frame
->format
= -1; /* unknown */
42 frame
->extended_data
= frame
->data
;
43 frame
->color_primaries
= AVCOL_PRI_UNSPECIFIED
;
44 frame
->color_trc
= AVCOL_TRC_UNSPECIFIED
;
45 frame
->colorspace
= AVCOL_SPC_UNSPECIFIED
;
46 frame
->color_range
= AVCOL_RANGE_UNSPECIFIED
;
47 frame
->chroma_location
= AVCHROMA_LOC_UNSPECIFIED
;
48 frame
->alpha_mode
= AVALPHA_MODE_UNSPECIFIED
;
52 AVFrame
*av_frame_alloc(void)
54 AVFrame
*frame
= av_malloc(sizeof(*frame
));
59 get_frame_defaults(frame
);
64 void av_frame_free(AVFrame
**frame
)
66 if (!frame
|| !*frame
)
69 av_frame_unref(*frame
);
73 #define ALIGN (HAVE_SIMD_ALIGN_64 ? 64 : 32)
75 static int get_video_buffer(AVFrame
*frame
, int align
)
77 const AVPixFmtDescriptor
*desc
= av_pix_fmt_desc_get(frame
->format
);
78 int ret
, padded_height
;
80 ptrdiff_t linesizes
[4];
81 size_t total_size
, sizes
[4];
84 return AVERROR(EINVAL
);
86 if ((ret
= av_image_check_size(frame
->width
, frame
->height
, 0, NULL
)) < 0)
91 plane_padding
= FFMAX(ALIGN
, align
);
93 if (!frame
->linesize
[0]) {
94 for (int i
= 1; i
<= align
; i
+= i
) {
95 ret
= av_image_fill_linesizes(frame
->linesize
, frame
->format
,
96 FFALIGN(frame
->width
, i
));
99 if (!(frame
->linesize
[0] & (align
-1)))
103 for (int i
= 0; i
< 4 && frame
->linesize
[i
]; i
++)
104 frame
->linesize
[i
] = FFALIGN(frame
->linesize
[i
], align
);
107 for (int i
= 0; i
< 4; i
++)
108 linesizes
[i
] = frame
->linesize
[i
];
110 padded_height
= FFALIGN(frame
->height
, 32);
111 if ((ret
= av_image_fill_plane_sizes(sizes
, frame
->format
,
112 padded_height
, linesizes
)) < 0)
115 total_size
= 4 * plane_padding
+ 4 * align
;
116 for (int i
= 0; i
< 4; i
++) {
117 if (sizes
[i
] > SIZE_MAX
- total_size
)
118 return AVERROR(EINVAL
);
119 total_size
+= sizes
[i
];
122 frame
->buf
[0] = av_buffer_alloc(total_size
);
123 if (!frame
->buf
[0]) {
124 ret
= AVERROR(ENOMEM
);
128 if ((ret
= av_image_fill_pointers(frame
->data
, frame
->format
, padded_height
,
129 frame
->buf
[0]->data
, frame
->linesize
)) < 0)
132 for (int i
= 1; i
< 4; i
++) {
134 frame
->data
[i
] += i
* plane_padding
;
135 frame
->data
[i
] = (uint8_t *)FFALIGN((uintptr_t)frame
->data
[i
], align
);
138 frame
->extended_data
= frame
->data
;
142 av_frame_unref(frame
);
146 static int get_audio_buffer(AVFrame
*frame
, int align
)
148 int planar
= av_sample_fmt_is_planar(frame
->format
);
149 int channels
, planes
;
153 channels
= frame
->ch_layout
.nb_channels
;
154 planes
= planar
? channels
: 1;
155 if (!frame
->linesize
[0]) {
156 ret
= av_samples_get_buffer_size(&frame
->linesize
[0], channels
,
157 frame
->nb_samples
, frame
->format
,
166 if (planes
> AV_NUM_DATA_POINTERS
) {
167 frame
->extended_data
= av_calloc(planes
,
168 sizeof(*frame
->extended_data
));
169 frame
->extended_buf
= av_calloc(planes
- AV_NUM_DATA_POINTERS
,
170 sizeof(*frame
->extended_buf
));
171 if (!frame
->extended_data
|| !frame
->extended_buf
) {
172 av_freep(&frame
->extended_data
);
173 av_freep(&frame
->extended_buf
);
174 return AVERROR(ENOMEM
);
176 frame
->nb_extended_buf
= planes
- AV_NUM_DATA_POINTERS
;
178 frame
->extended_data
= frame
->data
;
180 if (frame
->linesize
[0] > SIZE_MAX
- align
)
181 return AVERROR(EINVAL
);
182 size
= frame
->linesize
[0] + (size_t)align
;
184 for (int i
= 0; i
< FFMIN(planes
, AV_NUM_DATA_POINTERS
); i
++) {
185 frame
->buf
[i
] = av_buffer_alloc(size
);
186 if (!frame
->buf
[i
]) {
187 av_frame_unref(frame
);
188 return AVERROR(ENOMEM
);
190 frame
->extended_data
[i
] = frame
->data
[i
] =
191 (uint8_t *)FFALIGN((uintptr_t)frame
->buf
[i
]->data
, align
);
193 for (int i
= 0; i
< planes
- AV_NUM_DATA_POINTERS
; i
++) {
194 frame
->extended_buf
[i
] = av_buffer_alloc(size
);
195 if (!frame
->extended_buf
[i
]) {
196 av_frame_unref(frame
);
197 return AVERROR(ENOMEM
);
199 frame
->extended_data
[i
+ AV_NUM_DATA_POINTERS
] =
200 (uint8_t *)FFALIGN((uintptr_t)frame
->extended_buf
[i
]->data
, align
);
206 int av_frame_get_buffer(AVFrame
*frame
, int align
)
208 if (frame
->format
< 0)
209 return AVERROR(EINVAL
);
211 if (frame
->width
> 0 && frame
->height
> 0)
212 return get_video_buffer(frame
, align
);
213 else if (frame
->nb_samples
> 0 &&
214 (av_channel_layout_check(&frame
->ch_layout
)))
215 return get_audio_buffer(frame
, align
);
217 return AVERROR(EINVAL
);
220 static int frame_copy_props(AVFrame
*dst
, const AVFrame
*src
, int force_copy
)
222 dst
->pict_type
= src
->pict_type
;
223 dst
->sample_aspect_ratio
= src
->sample_aspect_ratio
;
224 dst
->crop_top
= src
->crop_top
;
225 dst
->crop_bottom
= src
->crop_bottom
;
226 dst
->crop_left
= src
->crop_left
;
227 dst
->crop_right
= src
->crop_right
;
229 dst
->duration
= src
->duration
;
230 dst
->repeat_pict
= src
->repeat_pict
;
231 dst
->sample_rate
= src
->sample_rate
;
232 dst
->opaque
= src
->opaque
;
233 dst
->pkt_dts
= src
->pkt_dts
;
234 dst
->time_base
= src
->time_base
;
235 dst
->quality
= src
->quality
;
236 dst
->best_effort_timestamp
= src
->best_effort_timestamp
;
237 dst
->flags
= src
->flags
;
238 dst
->decode_error_flags
= src
->decode_error_flags
;
239 dst
->color_primaries
= src
->color_primaries
;
240 dst
->color_trc
= src
->color_trc
;
241 dst
->colorspace
= src
->colorspace
;
242 dst
->color_range
= src
->color_range
;
243 dst
->chroma_location
= src
->chroma_location
;
244 dst
->alpha_mode
= src
->alpha_mode
;
246 av_dict_copy(&dst
->metadata
, src
->metadata
, 0);
248 for (int i
= 0; i
< src
->nb_side_data
; i
++) {
249 const AVFrameSideData
*sd_src
= src
->side_data
[i
];
250 AVFrameSideData
*sd_dst
;
251 if ( sd_src
->type
== AV_FRAME_DATA_PANSCAN
252 && (src
->width
!= dst
->width
|| src
->height
!= dst
->height
))
255 sd_dst
= av_frame_new_side_data(dst
, sd_src
->type
,
258 av_frame_side_data_free(&dst
->side_data
, &dst
->nb_side_data
);
259 return AVERROR(ENOMEM
);
261 memcpy(sd_dst
->data
, sd_src
->data
, sd_src
->size
);
263 AVBufferRef
*ref
= av_buffer_ref(sd_src
->buf
);
264 sd_dst
= av_frame_new_side_data_from_buf(dst
, sd_src
->type
, ref
);
266 av_buffer_unref(&ref
);
267 av_frame_side_data_free(&dst
->side_data
, &dst
->nb_side_data
);
268 return AVERROR(ENOMEM
);
271 av_dict_copy(&sd_dst
->metadata
, sd_src
->metadata
, 0);
274 av_refstruct_replace(&dst
->private_ref
, src
->private_ref
);
275 return av_buffer_replace(&dst
->opaque_ref
, src
->opaque_ref
);
278 int av_frame_ref(AVFrame
*dst
, const AVFrame
*src
)
282 av_assert1(dst
->width
== 0 && dst
->height
== 0);
283 av_assert1(dst
->ch_layout
.nb_channels
== 0 &&
284 dst
->ch_layout
.order
== AV_CHANNEL_ORDER_UNSPEC
);
286 dst
->format
= src
->format
;
287 dst
->width
= src
->width
;
288 dst
->height
= src
->height
;
289 dst
->nb_samples
= src
->nb_samples
;
291 ret
= frame_copy_props(dst
, src
, 0);
295 ret
= av_channel_layout_copy(&dst
->ch_layout
, &src
->ch_layout
);
299 /* duplicate the frame data if it's not refcounted */
301 ret
= av_frame_get_buffer(dst
, 0);
305 ret
= av_frame_copy(dst
, src
);
312 /* ref the buffers */
313 for (int i
= 0; i
< FF_ARRAY_ELEMS(src
->buf
); i
++) {
316 dst
->buf
[i
] = av_buffer_ref(src
->buf
[i
]);
318 ret
= AVERROR(ENOMEM
);
323 if (src
->extended_buf
) {
324 dst
->extended_buf
= av_calloc(src
->nb_extended_buf
,
325 sizeof(*dst
->extended_buf
));
326 if (!dst
->extended_buf
) {
327 ret
= AVERROR(ENOMEM
);
330 dst
->nb_extended_buf
= src
->nb_extended_buf
;
332 for (int i
= 0; i
< src
->nb_extended_buf
; i
++) {
333 dst
->extended_buf
[i
] = av_buffer_ref(src
->extended_buf
[i
]);
334 if (!dst
->extended_buf
[i
]) {
335 ret
= AVERROR(ENOMEM
);
341 if (src
->hw_frames_ctx
) {
342 dst
->hw_frames_ctx
= av_buffer_ref(src
->hw_frames_ctx
);
343 if (!dst
->hw_frames_ctx
) {
344 ret
= AVERROR(ENOMEM
);
349 /* duplicate extended data */
350 if (src
->extended_data
!= src
->data
) {
351 int ch
= dst
->ch_layout
.nb_channels
;
353 if (ch
<= 0 || ch
> SIZE_MAX
/ sizeof(*dst
->extended_data
)) {
354 ret
= AVERROR(EINVAL
);
358 dst
->extended_data
= av_memdup(src
->extended_data
, sizeof(*dst
->extended_data
) * ch
);
359 if (!dst
->extended_data
) {
360 ret
= AVERROR(ENOMEM
);
364 dst
->extended_data
= dst
->data
;
366 memcpy(dst
->data
, src
->data
, sizeof(src
->data
));
367 memcpy(dst
->linesize
, src
->linesize
, sizeof(src
->linesize
));
376 int av_frame_replace(AVFrame
*dst
, const AVFrame
*src
)
381 return AVERROR(EINVAL
);
386 /* duplicate the frame data if it's not refcounted */
387 if ( src
->data
[0] || src
->data
[1]
388 || src
->data
[2] || src
->data
[3])
389 return av_frame_ref(dst
, src
);
391 ret
= frame_copy_props(dst
, src
, 0);
396 dst
->format
= src
->format
;
397 dst
->width
= src
->width
;
398 dst
->height
= src
->height
;
399 dst
->nb_samples
= src
->nb_samples
;
401 ret
= av_channel_layout_copy(&dst
->ch_layout
, &src
->ch_layout
);
405 av_frame_side_data_free(&dst
->side_data
, &dst
->nb_side_data
);
406 av_dict_free(&dst
->metadata
);
407 ret
= frame_copy_props(dst
, src
, 0);
411 /* replace the buffers */
412 for (int i
= 0; i
< FF_ARRAY_ELEMS(src
->buf
); i
++) {
413 ret
= av_buffer_replace(&dst
->buf
[i
], src
->buf
[i
]);
418 if (src
->extended_buf
) {
419 if (dst
->nb_extended_buf
!= src
->nb_extended_buf
) {
420 int nb_extended_buf
= FFMIN(dst
->nb_extended_buf
, src
->nb_extended_buf
);
423 for (int i
= nb_extended_buf
; i
< dst
->nb_extended_buf
; i
++)
424 av_buffer_unref(&dst
->extended_buf
[i
]);
426 tmp
= av_realloc_array(dst
->extended_buf
, src
->nb_extended_buf
,
427 sizeof(*dst
->extended_buf
));
429 ret
= AVERROR(ENOMEM
);
432 dst
->extended_buf
= tmp
;
433 dst
->nb_extended_buf
= src
->nb_extended_buf
;
435 memset(&dst
->extended_buf
[nb_extended_buf
], 0,
436 (src
->nb_extended_buf
- nb_extended_buf
) * sizeof(*dst
->extended_buf
));
439 for (int i
= 0; i
< src
->nb_extended_buf
; i
++) {
440 ret
= av_buffer_replace(&dst
->extended_buf
[i
], src
->extended_buf
[i
]);
444 } else if (dst
->extended_buf
) {
445 for (int i
= 0; i
< dst
->nb_extended_buf
; i
++)
446 av_buffer_unref(&dst
->extended_buf
[i
]);
447 av_freep(&dst
->extended_buf
);
450 ret
= av_buffer_replace(&dst
->hw_frames_ctx
, src
->hw_frames_ctx
);
454 if (dst
->extended_data
!= dst
->data
)
455 av_freep(&dst
->extended_data
);
457 if (src
->extended_data
!= src
->data
) {
458 int ch
= dst
->ch_layout
.nb_channels
;
460 if (ch
<= 0 || ch
> SIZE_MAX
/ sizeof(*dst
->extended_data
)) {
461 ret
= AVERROR(EINVAL
);
465 dst
->extended_data
= av_memdup(src
->extended_data
, sizeof(*dst
->extended_data
) * ch
);
466 if (!dst
->extended_data
) {
467 ret
= AVERROR(ENOMEM
);
471 dst
->extended_data
= dst
->data
;
473 memcpy(dst
->data
, src
->data
, sizeof(src
->data
));
474 memcpy(dst
->linesize
, src
->linesize
, sizeof(src
->linesize
));
483 AVFrame
*av_frame_clone(const AVFrame
*src
)
485 AVFrame
*ret
= av_frame_alloc();
490 if (av_frame_ref(ret
, src
) < 0)
496 void av_frame_unref(AVFrame
*frame
)
501 av_frame_side_data_free(&frame
->side_data
, &frame
->nb_side_data
);
503 for (int i
= 0; i
< FF_ARRAY_ELEMS(frame
->buf
); i
++)
504 av_buffer_unref(&frame
->buf
[i
]);
505 for (int i
= 0; i
< frame
->nb_extended_buf
; i
++)
506 av_buffer_unref(&frame
->extended_buf
[i
]);
507 av_freep(&frame
->extended_buf
);
508 av_dict_free(&frame
->metadata
);
510 av_buffer_unref(&frame
->hw_frames_ctx
);
512 av_buffer_unref(&frame
->opaque_ref
);
513 av_refstruct_unref(&frame
->private_ref
);
515 if (frame
->extended_data
!= frame
->data
)
516 av_freep(&frame
->extended_data
);
518 av_channel_layout_uninit(&frame
->ch_layout
);
520 get_frame_defaults(frame
);
523 void av_frame_move_ref(AVFrame
*dst
, AVFrame
*src
)
525 av_assert1(dst
->width
== 0 && dst
->height
== 0);
526 av_assert1(dst
->ch_layout
.nb_channels
== 0 &&
527 dst
->ch_layout
.order
== AV_CHANNEL_ORDER_UNSPEC
);
530 if (src
->extended_data
== src
->data
)
531 dst
->extended_data
= dst
->data
;
532 get_frame_defaults(src
);
535 int av_frame_is_writable(AVFrame
*frame
)
539 /* assume non-refcounted frames are not writable */
543 for (int i
= 0; i
< FF_ARRAY_ELEMS(frame
->buf
); i
++)
545 ret
&= !!av_buffer_is_writable(frame
->buf
[i
]);
546 for (int i
= 0; i
< frame
->nb_extended_buf
; i
++)
547 ret
&= !!av_buffer_is_writable(frame
->extended_buf
[i
]);
552 int av_frame_make_writable(AVFrame
*frame
)
557 if (av_frame_is_writable(frame
))
560 memset(&tmp
, 0, sizeof(tmp
));
561 tmp
.format
= frame
->format
;
562 tmp
.width
= frame
->width
;
563 tmp
.height
= frame
->height
;
564 tmp
.nb_samples
= frame
->nb_samples
;
565 ret
= av_channel_layout_copy(&tmp
.ch_layout
, &frame
->ch_layout
);
567 av_frame_unref(&tmp
);
571 if (frame
->hw_frames_ctx
)
572 ret
= av_hwframe_get_buffer(frame
->hw_frames_ctx
, &tmp
, 0);
574 ret
= av_frame_get_buffer(&tmp
, 0);
578 ret
= av_frame_copy(&tmp
, frame
);
580 av_frame_unref(&tmp
);
584 ret
= av_frame_copy_props(&tmp
, frame
);
586 av_frame_unref(&tmp
);
590 av_frame_unref(frame
);
593 if (tmp
.data
== tmp
.extended_data
)
594 frame
->extended_data
= frame
->data
;
599 int av_frame_copy_props(AVFrame
*dst
, const AVFrame
*src
)
601 return frame_copy_props(dst
, src
, 1);
604 AVBufferRef
*av_frame_get_plane_buffer(const AVFrame
*frame
, int plane
)
609 if (frame
->nb_samples
) {
610 int channels
= frame
->ch_layout
.nb_channels
;
613 planes
= av_sample_fmt_is_planar(frame
->format
) ? channels
: 1;
617 if (plane
< 0 || plane
>= planes
|| !frame
->extended_data
[plane
])
619 data
= (uintptr_t)frame
->extended_data
[plane
];
621 for (int i
= 0; i
< FF_ARRAY_ELEMS(frame
->buf
) && frame
->buf
[i
]; i
++) {
622 AVBufferRef
*buf
= frame
->buf
[i
];
623 uintptr_t buf_begin
= (uintptr_t)buf
->data
;
625 if (data
>= buf_begin
&& data
< buf_begin
+ buf
->size
)
628 for (int i
= 0; i
< frame
->nb_extended_buf
; i
++) {
629 AVBufferRef
*buf
= frame
->extended_buf
[i
];
630 uintptr_t buf_begin
= (uintptr_t)buf
->data
;
632 if (data
>= buf_begin
&& data
< buf_begin
+ buf
->size
)
638 AVFrameSideData
*av_frame_new_side_data_from_buf(AVFrame
*frame
,
639 enum AVFrameSideDataType type
,
643 ff_frame_side_data_add_from_buf(
644 &frame
->side_data
, &frame
->nb_side_data
, type
, buf
);
647 AVFrameSideData
*av_frame_new_side_data(AVFrame
*frame
,
648 enum AVFrameSideDataType type
,
651 AVFrameSideData
*ret
;
652 AVBufferRef
*buf
= av_buffer_alloc(size
);
653 ret
= av_frame_new_side_data_from_buf(frame
, type
, buf
);
655 av_buffer_unref(&buf
);
659 AVFrameSideData
*av_frame_get_side_data(const AVFrame
*frame
,
660 enum AVFrameSideDataType type
)
662 return (AVFrameSideData
*)av_frame_side_data_get(
663 frame
->side_data
, frame
->nb_side_data
,
668 static int frame_copy_video(AVFrame
*dst
, const AVFrame
*src
)
672 if (dst
->width
< src
->width
||
673 dst
->height
< src
->height
)
674 return AVERROR(EINVAL
);
676 if (src
->hw_frames_ctx
|| dst
->hw_frames_ctx
)
677 return av_hwframe_transfer_data(dst
, src
, 0);
679 planes
= av_pix_fmt_count_planes(dst
->format
);
680 for (int i
= 0; i
< planes
; i
++)
681 if (!dst
->data
[i
] || !src
->data
[i
])
682 return AVERROR(EINVAL
);
684 av_image_copy2(dst
->data
, dst
->linesize
,
685 src
->data
, src
->linesize
,
686 dst
->format
, src
->width
, src
->height
);
691 static int frame_copy_audio(AVFrame
*dst
, const AVFrame
*src
)
693 int planar
= av_sample_fmt_is_planar(dst
->format
);
694 int channels
= dst
->ch_layout
.nb_channels
;
695 int planes
= planar
? channels
: 1;
697 if (dst
->nb_samples
!= src
->nb_samples
||
698 av_channel_layout_compare(&dst
->ch_layout
, &src
->ch_layout
))
699 return AVERROR(EINVAL
);
701 for (int i
= 0; i
< planes
; i
++)
702 if (!dst
->extended_data
[i
] || !src
->extended_data
[i
])
703 return AVERROR(EINVAL
);
705 av_samples_copy(dst
->extended_data
, src
->extended_data
, 0, 0,
706 dst
->nb_samples
, channels
, dst
->format
);
711 int av_frame_copy(AVFrame
*dst
, const AVFrame
*src
)
713 if (dst
->format
!= src
->format
|| dst
->format
< 0)
714 return AVERROR(EINVAL
);
716 if (dst
->width
> 0 && dst
->height
> 0)
717 return frame_copy_video(dst
, src
);
718 else if (dst
->nb_samples
> 0 &&
719 (av_channel_layout_check(&dst
->ch_layout
)))
720 return frame_copy_audio(dst
, src
);
722 return AVERROR(EINVAL
);
725 void av_frame_remove_side_data(AVFrame
*frame
, enum AVFrameSideDataType type
)
727 av_frame_side_data_remove(&frame
->side_data
, &frame
->nb_side_data
, type
);
730 static int calc_cropping_offsets(size_t offsets
[4], const AVFrame
*frame
,
731 const AVPixFmtDescriptor
*desc
)
733 for (int i
= 0; frame
->data
[i
]; i
++) {
734 const AVComponentDescriptor
*comp
= NULL
;
735 int shift_x
= (i
== 1 || i
== 2) ? desc
->log2_chroma_w
: 0;
736 int shift_y
= (i
== 1 || i
== 2) ? desc
->log2_chroma_h
: 0;
738 if (desc
->flags
& AV_PIX_FMT_FLAG_PAL
&& i
== 1) {
743 /* find any component descriptor for this plane */
744 for (int j
= 0; j
< desc
->nb_components
; j
++) {
745 if (desc
->comp
[j
].plane
== i
) {
746 comp
= &desc
->comp
[j
];
753 offsets
[i
] = (frame
->crop_top
>> shift_y
) * frame
->linesize
[i
] +
754 (frame
->crop_left
>> shift_x
) * comp
->step
;
760 int av_frame_apply_cropping(AVFrame
*frame
, int flags
)
762 const AVPixFmtDescriptor
*desc
;
766 if (!(frame
->width
> 0 && frame
->height
> 0))
767 return AVERROR(EINVAL
);
769 if (frame
->crop_left
>= INT_MAX
- frame
->crop_right
||
770 frame
->crop_top
>= INT_MAX
- frame
->crop_bottom
||
771 (frame
->crop_left
+ frame
->crop_right
) >= frame
->width
||
772 (frame
->crop_top
+ frame
->crop_bottom
) >= frame
->height
)
773 return AVERROR(ERANGE
);
775 desc
= av_pix_fmt_desc_get(frame
->format
);
779 /* Apply just the right/bottom cropping for hwaccel formats. Bitstream
780 * formats cannot be easily handled here either (and corresponding decoders
781 * should not export any cropping anyway), so do the same for those as well.
783 if (desc
->flags
& (AV_PIX_FMT_FLAG_BITSTREAM
| AV_PIX_FMT_FLAG_HWACCEL
)) {
784 frame
->width
-= frame
->crop_right
;
785 frame
->height
-= frame
->crop_bottom
;
786 frame
->crop_right
= 0;
787 frame
->crop_bottom
= 0;
791 /* calculate the offsets for each plane */
792 ret
= calc_cropping_offsets(offsets
, frame
, desc
);
796 /* adjust the offsets to avoid breaking alignment */
797 if (!(flags
& AV_FRAME_CROP_UNALIGNED
)) {
798 int log2_crop_align
= frame
->crop_left
? ff_ctz(frame
->crop_left
) : INT_MAX
;
799 int min_log2_align
= INT_MAX
;
801 for (int i
= 0; frame
->data
[i
]; i
++) {
802 int log2_align
= offsets
[i
] ? ff_ctz(offsets
[i
]) : INT_MAX
;
803 min_log2_align
= FFMIN(log2_align
, min_log2_align
);
806 /* we assume, and it should always be true, that the data alignment is
807 * related to the cropping alignment by a constant power-of-2 factor */
808 if (log2_crop_align
< min_log2_align
)
811 if (min_log2_align
< 5 && log2_crop_align
!= INT_MAX
) {
812 frame
->crop_left
&= ~((1 << (5 + log2_crop_align
- min_log2_align
)) - 1);
813 ret
= calc_cropping_offsets(offsets
, frame
, desc
);
819 for (int i
= 0; frame
->data
[i
]; i
++)
820 frame
->data
[i
] += offsets
[i
];
822 frame
->width
-= (frame
->crop_left
+ frame
->crop_right
);
823 frame
->height
-= (frame
->crop_top
+ frame
->crop_bottom
);
824 frame
->crop_left
= 0;
825 frame
->crop_right
= 0;
827 frame
->crop_bottom
= 0;