FFmpeg coverage


Directory: ../../../ffmpeg/
File: src/libavutil/frame.c
Date: 2025-02-01 04:38:32
Exec Total Coverage
Lines: 450 670 67.2%
Functions: 40 42 95.2%
Branches: 233 428 54.4%

Line Branch Exec Source
1 /*
2 * This file is part of FFmpeg.
3 *
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.
8 *
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.
13 *
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
17 */
18
19 #include "channel_layout.h"
20 #include "avassert.h"
21 #include "buffer.h"
22 #include "common.h"
23 #include "cpu.h"
24 #include "dict.h"
25 #include "frame.h"
26 #include "imgutils.h"
27 #include "mem.h"
28 #include "samplefmt.h"
29 #include "hwcontext.h"
30
31 static const AVSideDataDescriptor sd_props[] = {
32 [AV_FRAME_DATA_PANSCAN] = { "AVPanScan", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
33 [AV_FRAME_DATA_A53_CC] = { "ATSC A53 Part 4 Closed Captions" },
34 [AV_FRAME_DATA_MATRIXENCODING] = { "AVMatrixEncoding", AV_SIDE_DATA_PROP_CHANNEL_DEPENDENT },
35 [AV_FRAME_DATA_DOWNMIX_INFO] = { "Metadata relevant to a downmix procedure", AV_SIDE_DATA_PROP_CHANNEL_DEPENDENT },
36 [AV_FRAME_DATA_AFD] = { "Active format description" },
37 [AV_FRAME_DATA_MOTION_VECTORS] = { "Motion vectors", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
38 [AV_FRAME_DATA_SKIP_SAMPLES] = { "Skip samples" },
39 [AV_FRAME_DATA_GOP_TIMECODE] = { "GOP timecode" },
40 [AV_FRAME_DATA_S12M_TIMECODE] = { "SMPTE 12-1 timecode" },
41 [AV_FRAME_DATA_DYNAMIC_HDR_PLUS] = { "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)", AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
42 [AV_FRAME_DATA_DYNAMIC_HDR_VIVID] = { "HDR Dynamic Metadata CUVA 005.1 2021 (Vivid)", AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
43 [AV_FRAME_DATA_REGIONS_OF_INTEREST] = { "Regions Of Interest", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
44 [AV_FRAME_DATA_VIDEO_ENC_PARAMS] = { "Video encoding parameters" },
45 [AV_FRAME_DATA_FILM_GRAIN_PARAMS] = { "Film grain parameters" },
46 [AV_FRAME_DATA_DETECTION_BBOXES] = { "Bounding boxes for object detection and classification", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
47 [AV_FRAME_DATA_DOVI_RPU_BUFFER] = { "Dolby Vision RPU Data", AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
48 [AV_FRAME_DATA_DOVI_METADATA] = { "Dolby Vision Metadata", AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
49 [AV_FRAME_DATA_LCEVC] = { "LCEVC NAL data", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
50 [AV_FRAME_DATA_VIEW_ID] = { "View ID" },
51 [AV_FRAME_DATA_STEREO3D] = { "Stereo 3D", AV_SIDE_DATA_PROP_GLOBAL },
52 [AV_FRAME_DATA_REPLAYGAIN] = { "AVReplayGain", AV_SIDE_DATA_PROP_GLOBAL },
53 [AV_FRAME_DATA_DISPLAYMATRIX] = { "3x3 displaymatrix", AV_SIDE_DATA_PROP_GLOBAL },
54 [AV_FRAME_DATA_AUDIO_SERVICE_TYPE] = { "Audio service type", AV_SIDE_DATA_PROP_GLOBAL },
55 [AV_FRAME_DATA_MASTERING_DISPLAY_METADATA] = { "Mastering display metadata", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
56 [AV_FRAME_DATA_CONTENT_LIGHT_LEVEL] = { "Content light level metadata", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
57 [AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT] = { "Ambient viewing environment", AV_SIDE_DATA_PROP_GLOBAL },
58 [AV_FRAME_DATA_SPHERICAL] = { "Spherical Mapping", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
59 [AV_FRAME_DATA_ICC_PROFILE] = { "ICC profile", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT },
60 [AV_FRAME_DATA_SEI_UNREGISTERED] = { "H.26[45] User Data Unregistered SEI message", AV_SIDE_DATA_PROP_MULTI },
61 [AV_FRAME_DATA_VIDEO_HINT] = { "Encoding video hint", AV_SIDE_DATA_PROP_SIZE_DEPENDENT },
62 };
63
64 12098916 static void get_frame_defaults(AVFrame *frame)
65 {
66 12098916 memset(frame, 0, sizeof(*frame));
67
68 12098916 frame->pts =
69 12098916 frame->pkt_dts = AV_NOPTS_VALUE;
70 12098916 frame->best_effort_timestamp = AV_NOPTS_VALUE;
71 12098916 frame->duration = 0;
72 #if FF_API_FRAME_PKT
73 FF_DISABLE_DEPRECATION_WARNINGS
74 12098916 frame->pkt_pos = -1;
75 12098916 frame->pkt_size = -1;
76 FF_ENABLE_DEPRECATION_WARNINGS
77 #endif
78 12098916 frame->time_base = (AVRational){ 0, 1 };
79 12098916 frame->sample_aspect_ratio = (AVRational){ 0, 1 };
80 12098916 frame->format = -1; /* unknown */
81 12098916 frame->extended_data = frame->data;
82 12098916 frame->color_primaries = AVCOL_PRI_UNSPECIFIED;
83 12098916 frame->color_trc = AVCOL_TRC_UNSPECIFIED;
84 12098916 frame->colorspace = AVCOL_SPC_UNSPECIFIED;
85 12098916 frame->color_range = AVCOL_RANGE_UNSPECIFIED;
86 12098916 frame->chroma_location = AVCHROMA_LOC_UNSPECIFIED;
87 12098916 frame->flags = 0;
88 12098916 }
89
90 50876 static void free_side_data(AVFrameSideData **ptr_sd)
91 {
92 50876 AVFrameSideData *sd = *ptr_sd;
93
94 50876 av_buffer_unref(&sd->buf);
95 50876 av_dict_free(&sd->metadata);
96 50876 av_freep(ptr_sd);
97 50876 }
98
99 7497869 static void wipe_side_data(AVFrameSideData ***sd, int *nb_side_data)
100 {
101
2/2
✓ Branch 0 taken 50634 times.
✓ Branch 1 taken 7497869 times.
7548503 for (int i = 0; i < *nb_side_data; i++) {
102 50634 free_side_data(&((*sd)[i]));
103 }
104 7497869 *nb_side_data = 0;
105
106 7497869 av_freep(sd);
107 7497869 }
108
109 7342660 static void frame_side_data_wipe(AVFrame *frame)
110 {
111 7342660 wipe_side_data(&frame->side_data, &frame->nb_side_data);
112 7342660 }
113
114 155209 void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd)
115 {
116 155209 wipe_side_data(sd, nb_sd);
117 155209 }
118
119 407186 static void remove_side_data(AVFrameSideData ***sd, int *nb_side_data,
120 const enum AVFrameSideDataType type)
121 {
122
2/2
✓ Branch 0 taken 12797 times.
✓ Branch 1 taken 407186 times.
419983 for (int i = *nb_side_data - 1; i >= 0; i--) {
123 12797 AVFrameSideData *entry = ((*sd)[i]);
124
2/2
✓ Branch 0 taken 12555 times.
✓ Branch 1 taken 242 times.
12797 if (entry->type != type)
125 12555 continue;
126
127 242 free_side_data(&entry);
128
129 242 ((*sd)[i]) = ((*sd)[*nb_side_data - 1]);
130 242 (*nb_side_data)--;
131 }
132 407186 }
133
134 static void remove_side_data_by_entry(AVFrameSideData ***sd, int *nb_sd,
135 const AVFrameSideData *target)
136 {
137 for (int i = *nb_sd - 1; i >= 0; i--) {
138 AVFrameSideData *entry = ((*sd)[i]);
139 if (entry != target)
140 continue;
141
142 free_side_data(&entry);
143
144 ((*sd)[i]) = ((*sd)[*nb_sd - 1]);
145 (*nb_sd)--;
146
147 return;
148 }
149 }
150
151 1293098 AVFrame *av_frame_alloc(void)
152 {
153 1293098 AVFrame *frame = av_malloc(sizeof(*frame));
154
155
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1293098 times.
1293098 if (!frame)
156 return NULL;
157
158 1293098 get_frame_defaults(frame);
159
160 1293098 return frame;
161 }
162
163 1551765 void av_frame_free(AVFrame **frame)
164 {
165
3/4
✓ Branch 0 taken 1551765 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 258593 times.
✓ Branch 3 taken 1293172 times.
1551765 if (!frame || !*frame)
166 258593 return;
167
168 1293172 av_frame_unref(*frame);
169 1293172 av_freep(frame);
170 }
171
172 #define ALIGN (HAVE_SIMD_ALIGN_64 ? 64 : 32)
173
174 394 static int get_video_buffer(AVFrame *frame, int align)
175 {
176 394 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format);
177 int ret, padded_height;
178 int plane_padding;
179 ptrdiff_t linesizes[4];
180 size_t total_size, sizes[4];
181
182
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 394 times.
394 if (!desc)
183 return AVERROR(EINVAL);
184
185
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 394 times.
394 if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0)
186 return ret;
187
188
2/2
✓ Branch 0 taken 370 times.
✓ Branch 1 taken 24 times.
394 if (align <= 0)
189 370 align = ALIGN;
190 394 plane_padding = FFMAX(ALIGN, align);
191
192
1/2
✓ Branch 0 taken 394 times.
✗ Branch 1 not taken.
394 if (!frame->linesize[0]) {
193
1/2
✓ Branch 0 taken 1075 times.
✗ Branch 1 not taken.
1075 for (int i = 1; i <= align; i += i) {
194 1075 ret = av_image_fill_linesizes(frame->linesize, frame->format,
195 1075 FFALIGN(frame->width, i));
196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1075 times.
1075 if (ret < 0)
197 return ret;
198
2/2
✓ Branch 0 taken 394 times.
✓ Branch 1 taken 681 times.
1075 if (!(frame->linesize[0] & (align-1)))
199 394 break;
200 }
201
202
3/4
✓ Branch 0 taken 990 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 596 times.
✓ Branch 3 taken 394 times.
990 for (int i = 0; i < 4 && frame->linesize[i]; i++)
203 596 frame->linesize[i] = FFALIGN(frame->linesize[i], align);
204 }
205
206
2/2
✓ Branch 0 taken 1576 times.
✓ Branch 1 taken 394 times.
1970 for (int i = 0; i < 4; i++)
207 1576 linesizes[i] = frame->linesize[i];
208
209 394 padded_height = FFALIGN(frame->height, 32);
210
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 394 times.
394 if ((ret = av_image_fill_plane_sizes(sizes, frame->format,
211 padded_height, linesizes)) < 0)
212 return ret;
213
214 394 total_size = 4 * plane_padding + 4 * align;
215
2/2
✓ Branch 0 taken 1576 times.
✓ Branch 1 taken 394 times.
1970 for (int i = 0; i < 4; i++) {
216
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1576 times.
1576 if (sizes[i] > SIZE_MAX - total_size)
217 return AVERROR(EINVAL);
218 1576 total_size += sizes[i];
219 }
220
221 394 frame->buf[0] = av_buffer_alloc(total_size);
222
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 394 times.
394 if (!frame->buf[0]) {
223 ret = AVERROR(ENOMEM);
224 goto fail;
225 }
226
227
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 394 times.
394 if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height,
228 394 frame->buf[0]->data, frame->linesize)) < 0)
229 goto fail;
230
231
2/2
✓ Branch 0 taken 1182 times.
✓ Branch 1 taken 394 times.
1576 for (int i = 1; i < 4; i++) {
232
2/2
✓ Branch 0 taken 202 times.
✓ Branch 1 taken 980 times.
1182 if (frame->data[i])
233 202 frame->data[i] += i * plane_padding;
234 1182 frame->data[i] = (uint8_t *)FFALIGN((uintptr_t)frame->data[i], align);
235 }
236
237 394 frame->extended_data = frame->data;
238
239 394 return 0;
240 fail:
241 av_frame_unref(frame);
242 return ret;
243 }
244
245 14451 static int get_audio_buffer(AVFrame *frame, int align)
246 {
247 14451 int planar = av_sample_fmt_is_planar(frame->format);
248 int channels, planes;
249 size_t size;
250 int ret;
251
252 14451 channels = frame->ch_layout.nb_channels;
253
2/2
✓ Branch 0 taken 1169 times.
✓ Branch 1 taken 13282 times.
14451 planes = planar ? channels : 1;
254
1/2
✓ Branch 0 taken 14451 times.
✗ Branch 1 not taken.
14451 if (!frame->linesize[0]) {
255 14451 ret = av_samples_get_buffer_size(&frame->linesize[0], channels,
256 14451 frame->nb_samples, frame->format,
257 align);
258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14451 times.
14451 if (ret < 0)
259 return ret;
260 }
261
262
2/2
✓ Branch 0 taken 14422 times.
✓ Branch 1 taken 29 times.
14451 if (align <= 0)
263 14422 align = ALIGN;
264
265
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14451 times.
14451 if (planes > AV_NUM_DATA_POINTERS) {
266 frame->extended_data = av_calloc(planes,
267 sizeof(*frame->extended_data));
268 frame->extended_buf = av_calloc(planes - AV_NUM_DATA_POINTERS,
269 sizeof(*frame->extended_buf));
270 if (!frame->extended_data || !frame->extended_buf) {
271 av_freep(&frame->extended_data);
272 av_freep(&frame->extended_buf);
273 return AVERROR(ENOMEM);
274 }
275 frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS;
276 } else
277 14451 frame->extended_data = frame->data;
278
279
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14451 times.
14451 if (frame->linesize[0] > SIZE_MAX - align)
280 return AVERROR(EINVAL);
281 14451 size = frame->linesize[0] + (size_t)align;
282
283
2/2
✓ Branch 0 taken 15246 times.
✓ Branch 1 taken 14451 times.
29697 for (int i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) {
284 15246 frame->buf[i] = av_buffer_alloc(size);
285
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15246 times.
15246 if (!frame->buf[i]) {
286 av_frame_unref(frame);
287 return AVERROR(ENOMEM);
288 }
289 15246 frame->extended_data[i] = frame->data[i] =
290 15246 (uint8_t *)FFALIGN((uintptr_t)frame->buf[i]->data, align);
291 }
292
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14451 times.
14451 for (int i = 0; i < planes - AV_NUM_DATA_POINTERS; i++) {
293 frame->extended_buf[i] = av_buffer_alloc(size);
294 if (!frame->extended_buf[i]) {
295 av_frame_unref(frame);
296 return AVERROR(ENOMEM);
297 }
298 frame->extended_data[i + AV_NUM_DATA_POINTERS] =
299 (uint8_t *)FFALIGN((uintptr_t)frame->extended_buf[i]->data, align);
300 }
301 14451 return 0;
302
303 }
304
305 14845 int av_frame_get_buffer(AVFrame *frame, int align)
306 {
307
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14845 times.
14845 if (frame->format < 0)
308 return AVERROR(EINVAL);
309
310
3/4
✓ Branch 0 taken 394 times.
✓ Branch 1 taken 14451 times.
✓ Branch 2 taken 394 times.
✗ Branch 3 not taken.
14845 if (frame->width > 0 && frame->height > 0)
311 394 return get_video_buffer(frame, align);
312
2/4
✓ Branch 0 taken 14451 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 14451 times.
✗ Branch 3 not taken.
28902 else if (frame->nb_samples > 0 &&
313 14451 (av_channel_layout_check(&frame->ch_layout)))
314 14451 return get_audio_buffer(frame, align);
315
316 return AVERROR(EINVAL);
317 }
318
319 1139916 static int frame_copy_props(AVFrame *dst, const AVFrame *src, int force_copy)
320 {
321 int ret;
322
323 #if FF_API_FRAME_KEY
324 FF_DISABLE_DEPRECATION_WARNINGS
325 1139916 dst->key_frame = src->key_frame;
326 FF_ENABLE_DEPRECATION_WARNINGS
327 #endif
328 1139916 dst->pict_type = src->pict_type;
329 1139916 dst->sample_aspect_ratio = src->sample_aspect_ratio;
330 1139916 dst->crop_top = src->crop_top;
331 1139916 dst->crop_bottom = src->crop_bottom;
332 1139916 dst->crop_left = src->crop_left;
333 1139916 dst->crop_right = src->crop_right;
334 1139916 dst->pts = src->pts;
335 1139916 dst->duration = src->duration;
336 1139916 dst->repeat_pict = src->repeat_pict;
337 #if FF_API_INTERLACED_FRAME
338 FF_DISABLE_DEPRECATION_WARNINGS
339 1139916 dst->interlaced_frame = src->interlaced_frame;
340 1139916 dst->top_field_first = src->top_field_first;
341 FF_ENABLE_DEPRECATION_WARNINGS
342 #endif
343 #if FF_API_PALETTE_HAS_CHANGED
344 FF_DISABLE_DEPRECATION_WARNINGS
345 1139916 dst->palette_has_changed = src->palette_has_changed;
346 FF_ENABLE_DEPRECATION_WARNINGS
347 #endif
348 1139916 dst->sample_rate = src->sample_rate;
349 1139916 dst->opaque = src->opaque;
350 1139916 dst->pkt_dts = src->pkt_dts;
351 #if FF_API_FRAME_PKT
352 FF_DISABLE_DEPRECATION_WARNINGS
353 1139916 dst->pkt_pos = src->pkt_pos;
354 1139916 dst->pkt_size = src->pkt_size;
355 FF_ENABLE_DEPRECATION_WARNINGS
356 #endif
357 1139916 dst->time_base = src->time_base;
358 1139916 dst->quality = src->quality;
359 1139916 dst->best_effort_timestamp = src->best_effort_timestamp;
360 1139916 dst->flags = src->flags;
361 1139916 dst->decode_error_flags = src->decode_error_flags;
362 1139916 dst->color_primaries = src->color_primaries;
363 1139916 dst->color_trc = src->color_trc;
364 1139916 dst->colorspace = src->colorspace;
365 1139916 dst->color_range = src->color_range;
366 1139916 dst->chroma_location = src->chroma_location;
367
368 1139916 av_dict_copy(&dst->metadata, src->metadata, 0);
369
370
2/2
✓ Branch 0 taken 36132 times.
✓ Branch 1 taken 1139916 times.
1176048 for (int i = 0; i < src->nb_side_data; i++) {
371 36132 const AVFrameSideData *sd_src = src->side_data[i];
372 AVFrameSideData *sd_dst;
373
2/2
✓ Branch 0 taken 13392 times.
✓ Branch 1 taken 22740 times.
36132 if ( sd_src->type == AV_FRAME_DATA_PANSCAN
374
2/4
✓ Branch 0 taken 13392 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 13392 times.
13392 && (src->width != dst->width || src->height != dst->height))
375 continue;
376
2/2
✓ Branch 0 taken 4762 times.
✓ Branch 1 taken 31370 times.
36132 if (force_copy) {
377 4762 sd_dst = av_frame_new_side_data(dst, sd_src->type,
378 4762 sd_src->size);
379
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4762 times.
4762 if (!sd_dst) {
380 frame_side_data_wipe(dst);
381 return AVERROR(ENOMEM);
382 }
383 4762 memcpy(sd_dst->data, sd_src->data, sd_src->size);
384 } else {
385 31370 AVBufferRef *ref = av_buffer_ref(sd_src->buf);
386 31370 sd_dst = av_frame_new_side_data_from_buf(dst, sd_src->type, ref);
387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 31370 times.
31370 if (!sd_dst) {
388 av_buffer_unref(&ref);
389 frame_side_data_wipe(dst);
390 return AVERROR(ENOMEM);
391 }
392 }
393 36132 av_dict_copy(&sd_dst->metadata, sd_src->metadata, 0);
394 }
395
396 1139916 ret = av_buffer_replace(&dst->opaque_ref, src->opaque_ref);
397 1139916 ret |= av_buffer_replace(&dst->private_ref, src->private_ref);
398 1139916 return ret;
399 }
400
401 784273 int av_frame_ref(AVFrame *dst, const AVFrame *src)
402 {
403 784273 int ret = 0;
404
405 av_assert1(dst->width == 0 && dst->height == 0);
406 av_assert1(dst->ch_layout.nb_channels == 0 &&
407 dst->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC);
408
409 784273 dst->format = src->format;
410 784273 dst->width = src->width;
411 784273 dst->height = src->height;
412 784273 dst->nb_samples = src->nb_samples;
413
414 784273 ret = frame_copy_props(dst, src, 0);
415
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 784273 times.
784273 if (ret < 0)
416 goto fail;
417
418 784273 ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
419
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 784273 times.
784273 if (ret < 0)
420 goto fail;
421
422 /* duplicate the frame data if it's not refcounted */
423
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 784273 times.
784273 if (!src->buf[0]) {
424 ret = av_frame_get_buffer(dst, 0);
425 if (ret < 0)
426 goto fail;
427
428 ret = av_frame_copy(dst, src);
429 if (ret < 0)
430 goto fail;
431
432 return 0;
433 }
434
435 /* ref the buffers */
436
2/2
✓ Branch 0 taken 6274184 times.
✓ Branch 1 taken 784273 times.
7058457 for (int i = 0; i < FF_ARRAY_ELEMS(src->buf); i++) {
437
2/2
✓ Branch 0 taken 4762550 times.
✓ Branch 1 taken 1511634 times.
6274184 if (!src->buf[i])
438 4762550 continue;
439 1511634 dst->buf[i] = av_buffer_ref(src->buf[i]);
440
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1511634 times.
1511634 if (!dst->buf[i]) {
441 ret = AVERROR(ENOMEM);
442 goto fail;
443 }
444 }
445
446
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 784207 times.
784273 if (src->extended_buf) {
447 66 dst->extended_buf = av_calloc(src->nb_extended_buf,
448 sizeof(*dst->extended_buf));
449
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if (!dst->extended_buf) {
450 ret = AVERROR(ENOMEM);
451 goto fail;
452 }
453 66 dst->nb_extended_buf = src->nb_extended_buf;
454
455
2/2
✓ Branch 0 taken 3828 times.
✓ Branch 1 taken 66 times.
3894 for (int i = 0; i < src->nb_extended_buf; i++) {
456 3828 dst->extended_buf[i] = av_buffer_ref(src->extended_buf[i]);
457
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3828 times.
3828 if (!dst->extended_buf[i]) {
458 ret = AVERROR(ENOMEM);
459 goto fail;
460 }
461 }
462 }
463
464
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 784273 times.
784273 if (src->hw_frames_ctx) {
465 dst->hw_frames_ctx = av_buffer_ref(src->hw_frames_ctx);
466 if (!dst->hw_frames_ctx) {
467 ret = AVERROR(ENOMEM);
468 goto fail;
469 }
470 }
471
472 /* duplicate extended data */
473
2/2
✓ Branch 0 taken 66 times.
✓ Branch 1 taken 784207 times.
784273 if (src->extended_data != src->data) {
474 66 int ch = dst->ch_layout.nb_channels;
475
476
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if (!ch) {
477 ret = AVERROR(EINVAL);
478 goto fail;
479 }
480
481 66 dst->extended_data = av_malloc_array(sizeof(*dst->extended_data), ch);
482
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 66 times.
66 if (!dst->extended_data) {
483 ret = AVERROR(ENOMEM);
484 goto fail;
485 }
486 66 memcpy(dst->extended_data, src->extended_data, sizeof(*src->extended_data) * ch);
487 } else
488 784207 dst->extended_data = dst->data;
489
490 784273 memcpy(dst->data, src->data, sizeof(src->data));
491 784273 memcpy(dst->linesize, src->linesize, sizeof(src->linesize));
492
493 784273 return 0;
494
495 fail:
496 av_frame_unref(dst);
497 return ret;
498 }
499
500 4347 int av_frame_replace(AVFrame *dst, const AVFrame *src)
501 {
502 4347 int ret = 0;
503
504
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4347 times.
4347 if (dst == src)
505 return AVERROR(EINVAL);
506
507
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4347 times.
4347 if (!src->buf[0]) {
508 av_frame_unref(dst);
509
510 /* duplicate the frame data if it's not refcounted */
511 if ( src->data[0] || src->data[1]
512 || src->data[2] || src->data[3])
513 return av_frame_ref(dst, src);
514
515 ret = frame_copy_props(dst, src, 0);
516 if (ret < 0)
517 goto fail;
518 }
519
520 4347 dst->format = src->format;
521 4347 dst->width = src->width;
522 4347 dst->height = src->height;
523 4347 dst->nb_samples = src->nb_samples;
524
525 4347 ret = av_channel_layout_copy(&dst->ch_layout, &src->ch_layout);
526
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4347 times.
4347 if (ret < 0)
527 goto fail;
528
529 4347 frame_side_data_wipe(dst);
530 4347 av_dict_free(&dst->metadata);
531 4347 ret = frame_copy_props(dst, src, 0);
532
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4347 times.
4347 if (ret < 0)
533 goto fail;
534
535 /* replace the buffers */
536
2/2
✓ Branch 0 taken 34776 times.
✓ Branch 1 taken 4347 times.
39123 for (int i = 0; i < FF_ARRAY_ELEMS(src->buf); i++) {
537 34776 ret = av_buffer_replace(&dst->buf[i], src->buf[i]);
538
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 34776 times.
34776 if (ret < 0)
539 goto fail;
540 }
541
542
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4347 times.
4347 if (src->extended_buf) {
543 if (dst->nb_extended_buf != src->nb_extended_buf) {
544 int nb_extended_buf = FFMIN(dst->nb_extended_buf, src->nb_extended_buf);
545 void *tmp;
546
547 for (int i = nb_extended_buf; i < dst->nb_extended_buf; i++)
548 av_buffer_unref(&dst->extended_buf[i]);
549
550 tmp = av_realloc_array(dst->extended_buf, sizeof(*dst->extended_buf),
551 src->nb_extended_buf);
552 if (!tmp) {
553 ret = AVERROR(ENOMEM);
554 goto fail;
555 }
556 dst->extended_buf = tmp;
557 dst->nb_extended_buf = src->nb_extended_buf;
558
559 memset(&dst->extended_buf[nb_extended_buf], 0,
560 (src->nb_extended_buf - nb_extended_buf) * sizeof(*dst->extended_buf));
561 }
562
563 for (int i = 0; i < src->nb_extended_buf; i++) {
564 ret = av_buffer_replace(&dst->extended_buf[i], src->extended_buf[i]);
565 if (ret < 0)
566 goto fail;
567 }
568
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4347 times.
4347 } else if (dst->extended_buf) {
569 for (int i = 0; i < dst->nb_extended_buf; i++)
570 av_buffer_unref(&dst->extended_buf[i]);
571 av_freep(&dst->extended_buf);
572 }
573
574 4347 ret = av_buffer_replace(&dst->hw_frames_ctx, src->hw_frames_ctx);
575
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4347 times.
4347 if (ret < 0)
576 goto fail;
577
578
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4347 times.
4347 if (dst->extended_data != dst->data)
579 av_freep(&dst->extended_data);
580
581
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4347 times.
4347 if (src->extended_data != src->data) {
582 int ch = dst->ch_layout.nb_channels;
583
584 if (!ch) {
585 ret = AVERROR(EINVAL);
586 goto fail;
587 }
588
589 if (ch > SIZE_MAX / sizeof(*dst->extended_data))
590 goto fail;
591
592 dst->extended_data = av_memdup(src->extended_data, sizeof(*dst->extended_data) * ch);
593 if (!dst->extended_data) {
594 ret = AVERROR(ENOMEM);
595 goto fail;
596 }
597 } else
598 4347 dst->extended_data = dst->data;
599
600 4347 memcpy(dst->data, src->data, sizeof(src->data));
601 4347 memcpy(dst->linesize, src->linesize, sizeof(src->linesize));
602
603 4347 return 0;
604
605 fail:
606 av_frame_unref(dst);
607 return ret;
608 }
609
610 39075 AVFrame *av_frame_clone(const AVFrame *src)
611 {
612 39075 AVFrame *ret = av_frame_alloc();
613
614
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 39075 times.
39075 if (!ret)
615 return NULL;
616
617
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 39075 times.
39075 if (av_frame_ref(ret, src) < 0)
618 av_frame_free(&ret);
619
620 39075 return ret;
621 }
622
623 7338317 void av_frame_unref(AVFrame *frame)
624 {
625
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 7338313 times.
7338317 if (!frame)
626 4 return;
627
628 7338313 frame_side_data_wipe(frame);
629
630
2/2
✓ Branch 0 taken 58706504 times.
✓ Branch 1 taken 7338313 times.
66044817 for (int i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++)
631 58706504 av_buffer_unref(&frame->buf[i]);
632
2/2
✓ Branch 0 taken 5720 times.
✓ Branch 1 taken 7338313 times.
7344033 for (int i = 0; i < frame->nb_extended_buf; i++)
633 5720 av_buffer_unref(&frame->extended_buf[i]);
634 7338313 av_freep(&frame->extended_buf);
635 7338313 av_dict_free(&frame->metadata);
636
637 7338313 av_buffer_unref(&frame->hw_frames_ctx);
638
639 7338313 av_buffer_unref(&frame->opaque_ref);
640 7338313 av_buffer_unref(&frame->private_ref);
641
642
2/2
✓ Branch 0 taken 584 times.
✓ Branch 1 taken 7337729 times.
7338313 if (frame->extended_data != frame->data)
643 584 av_freep(&frame->extended_data);
644
645 7338313 av_channel_layout_uninit(&frame->ch_layout);
646
647 7338313 get_frame_defaults(frame);
648 }
649
650 3467505 void av_frame_move_ref(AVFrame *dst, AVFrame *src)
651 {
652 av_assert1(dst->width == 0 && dst->height == 0);
653 av_assert1(dst->ch_layout.nb_channels == 0 &&
654 dst->ch_layout.order == AV_CHANNEL_ORDER_UNSPEC);
655
656 3467505 *dst = *src;
657
1/2
✓ Branch 0 taken 3467505 times.
✗ Branch 1 not taken.
3467505 if (src->extended_data == src->data)
658 3467505 dst->extended_data = dst->data;
659 3467505 get_frame_defaults(src);
660 3467505 }
661
662 18142 int av_frame_is_writable(AVFrame *frame)
663 {
664 18142 int ret = 1;
665
666 /* assume non-refcounted frames are not writable */
667
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 18142 times.
18142 if (!frame->buf[0])
668 return 0;
669
670
2/2
✓ Branch 0 taken 145136 times.
✓ Branch 1 taken 18142 times.
163278 for (int i = 0; i < FF_ARRAY_ELEMS(frame->buf); i++)
671
2/2
✓ Branch 0 taken 36427 times.
✓ Branch 1 taken 108709 times.
145136 if (frame->buf[i])
672 36427 ret &= !!av_buffer_is_writable(frame->buf[i]);
673
2/2
✓ Branch 0 taken 1834 times.
✓ Branch 1 taken 18142 times.
19976 for (int i = 0; i < frame->nb_extended_buf; i++)
674 1834 ret &= !!av_buffer_is_writable(frame->extended_buf[i]);
675
676 18142 return ret;
677 }
678
679 3200 int av_frame_make_writable(AVFrame *frame)
680 {
681 AVFrame tmp;
682 int ret;
683
684
1/2
✓ Branch 1 taken 3200 times.
✗ Branch 2 not taken.
3200 if (av_frame_is_writable(frame))
685 3200 return 0;
686
687 memset(&tmp, 0, sizeof(tmp));
688 tmp.format = frame->format;
689 tmp.width = frame->width;
690 tmp.height = frame->height;
691 tmp.nb_samples = frame->nb_samples;
692 ret = av_channel_layout_copy(&tmp.ch_layout, &frame->ch_layout);
693 if (ret < 0) {
694 av_frame_unref(&tmp);
695 return ret;
696 }
697
698 if (frame->hw_frames_ctx)
699 ret = av_hwframe_get_buffer(frame->hw_frames_ctx, &tmp, 0);
700 else
701 ret = av_frame_get_buffer(&tmp, 0);
702 if (ret < 0)
703 return ret;
704
705 ret = av_frame_copy(&tmp, frame);
706 if (ret < 0) {
707 av_frame_unref(&tmp);
708 return ret;
709 }
710
711 ret = av_frame_copy_props(&tmp, frame);
712 if (ret < 0) {
713 av_frame_unref(&tmp);
714 return ret;
715 }
716
717 av_frame_unref(frame);
718
719 *frame = tmp;
720 if (tmp.data == tmp.extended_data)
721 frame->extended_data = frame->data;
722
723 return 0;
724 }
725
726 351296 int av_frame_copy_props(AVFrame *dst, const AVFrame *src)
727 {
728 351296 return frame_copy_props(dst, src, 1);
729 }
730
731 5540 AVBufferRef *av_frame_get_plane_buffer(const AVFrame *frame, int plane)
732 {
733 uint8_t *data;
734 int planes;
735
736
2/2
✓ Branch 0 taken 457 times.
✓ Branch 1 taken 5083 times.
5540 if (frame->nb_samples) {
737 457 int channels = frame->ch_layout.nb_channels;
738
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 457 times.
457 if (!channels)
739 return NULL;
740
1/2
✓ Branch 1 taken 457 times.
✗ Branch 2 not taken.
457 planes = av_sample_fmt_is_planar(frame->format) ? channels : 1;
741 } else
742 5083 planes = 4;
743
744
3/6
✓ Branch 0 taken 5540 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 5540 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 5540 times.
5540 if (plane < 0 || plane >= planes || !frame->extended_data[plane])
745 return NULL;
746 5540 data = frame->extended_data[plane];
747
748
2/4
✓ Branch 0 taken 12932 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 12932 times.
✗ Branch 3 not taken.
12932 for (int i = 0; i < FF_ARRAY_ELEMS(frame->buf) && frame->buf[i]; i++) {
749 12932 AVBufferRef *buf = frame->buf[i];
750
4/4
✓ Branch 0 taken 11866 times.
✓ Branch 1 taken 1066 times.
✓ Branch 2 taken 5540 times.
✓ Branch 3 taken 6326 times.
12932 if (data >= buf->data && data < buf->data + buf->size)
751 5540 return buf;
752 }
753 for (int i = 0; i < frame->nb_extended_buf; i++) {
754 AVBufferRef *buf = frame->extended_buf[i];
755 if (data >= buf->data && data < buf->data + buf->size)
756 return buf;
757 }
758 return NULL;
759 }
760
761 50876 static AVFrameSideData *add_side_data_from_buf_ext(AVFrameSideData ***sd,
762 int *nb_sd,
763 enum AVFrameSideDataType type,
764 AVBufferRef *buf, uint8_t *data,
765 size_t size)
766 {
767 AVFrameSideData *ret, **tmp;
768
769 // *nb_sd + 1 needs to fit into an int and a size_t.
770
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50876 times.
50876 if ((unsigned)*nb_sd >= FFMIN(INT_MAX, SIZE_MAX))
771 return NULL;
772
773 50876 tmp = av_realloc_array(*sd, sizeof(**sd), *nb_sd + 1);
774
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50876 times.
50876 if (!tmp)
775 return NULL;
776 50876 *sd = tmp;
777
778 50876 ret = av_mallocz(sizeof(*ret));
779
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 50876 times.
50876 if (!ret)
780 return NULL;
781
782 50876 ret->buf = buf;
783 50876 ret->data = data;
784 50876 ret->size = size;
785 50876 ret->type = type;
786
787 50876 (*sd)[(*nb_sd)++] = ret;
788
789 50876 return ret;
790 }
791
792 49421 static AVFrameSideData *add_side_data_from_buf(AVFrameSideData ***sd,
793 int *nb_sd,
794 enum AVFrameSideDataType type,
795 AVBufferRef *buf)
796 {
797
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 49421 times.
49421 if (!buf)
798 return NULL;
799
800 49421 return add_side_data_from_buf_ext(sd, nb_sd, type, buf, buf->data, buf->size);
801 }
802
803 47757 AVFrameSideData *av_frame_new_side_data_from_buf(AVFrame *frame,
804 enum AVFrameSideDataType type,
805 AVBufferRef *buf)
806 {
807 return
808 47757 add_side_data_from_buf(
809 &frame->side_data, &frame->nb_side_data, type, buf);
810 }
811
812 16318 AVFrameSideData *av_frame_new_side_data(AVFrame *frame,
813 enum AVFrameSideDataType type,
814 size_t size)
815 {
816 AVFrameSideData *ret;
817 16318 AVBufferRef *buf = av_buffer_alloc(size);
818 16318 ret = av_frame_new_side_data_from_buf(frame, type, buf);
819
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16318 times.
16318 if (!ret)
820 av_buffer_unref(&buf);
821 16318 return ret;
822 }
823
824 2 static AVFrameSideData *replace_side_data_from_buf(AVFrameSideData *dst,
825 AVBufferRef *buf, int flags)
826 {
827
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE))
828 return NULL;
829
830 2 av_dict_free(&dst->metadata);
831 2 av_buffer_unref(&dst->buf);
832 2 dst->buf = buf;
833 2 dst->data = buf->data;
834 2 dst->size = buf->size;
835 2 return dst;
836 }
837
838 570 AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd,
839 enum AVFrameSideDataType type,
840 size_t size, unsigned int flags)
841 {
842 570 const AVSideDataDescriptor *desc = av_frame_side_data_desc(type);
843 570 AVBufferRef *buf = av_buffer_alloc(size);
844 570 AVFrameSideData *ret = NULL;
845
846
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 569 times.
570 if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
847 1 remove_side_data(sd, nb_sd, type);
848
5/6
✓ Branch 0 taken 570 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 563 times.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 561 times.
1133 if ((!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) &&
849 563 (ret = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, type))) {
850 2 ret = replace_side_data_from_buf(ret, buf, flags);
851
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (!ret)
852 av_buffer_unref(&buf);
853 2 return ret;
854 }
855
856 568 ret = add_side_data_from_buf(sd, nb_sd, type, buf);
857
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 568 times.
568 if (!ret)
858 av_buffer_unref(&buf);
859
860 568 return ret;
861 }
862
863 1096 AVFrameSideData *av_frame_side_data_add(AVFrameSideData ***sd, int *nb_sd,
864 enum AVFrameSideDataType type,
865 AVBufferRef **pbuf, unsigned int flags)
866 {
867 1096 const AVSideDataDescriptor *desc = av_frame_side_data_desc(type);
868 1096 AVFrameSideData *sd_dst = NULL;
869 1096 AVBufferRef *buf = *pbuf;
870
871
3/4
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1094 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
1096 if ((flags & AV_FRAME_SIDE_DATA_FLAG_NEW_REF) && !(buf = av_buffer_ref(*pbuf)))
872 return NULL;
873
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1096 times.
1096 if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
874 remove_side_data(sd, nb_sd, type);
875
4/6
✓ Branch 0 taken 1096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 787 times.
✓ Branch 3 taken 309 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 787 times.
1883 if ((!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) &&
876 787 (sd_dst = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, type))) {
877 sd_dst = replace_side_data_from_buf(sd_dst, buf, flags);
878 } else
879 1096 sd_dst = add_side_data_from_buf(sd, nb_sd, type, buf);
880
881
3/4
✓ Branch 0 taken 1096 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1094 times.
✓ Branch 3 taken 2 times.
1096 if (sd_dst && !(flags & AV_FRAME_SIDE_DATA_FLAG_NEW_REF))
882 1094 *pbuf = NULL;
883
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 else if (!sd_dst && (flags & AV_FRAME_SIDE_DATA_FLAG_NEW_REF))
884 av_buffer_unref(&buf);
885 1096 return sd_dst;
886 }
887
888 1455 int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd,
889 const AVFrameSideData *src, unsigned int flags)
890 {
891 const AVSideDataDescriptor *desc;
892 1455 AVBufferRef *buf = NULL;
893 1455 AVFrameSideData *sd_dst = NULL;
894 1455 int ret = AVERROR_BUG;
895
896
6/10
✓ Branch 0 taken 1455 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1455 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1455 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 32 times.
✓ Branch 7 taken 1423 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 32 times.
1455 if (!sd || !src || !nb_sd || (*nb_sd && !*sd))
897 return AVERROR(EINVAL);
898
899 1455 desc = av_frame_side_data_desc(src->type);
900
2/2
✓ Branch 0 taken 232 times.
✓ Branch 1 taken 1223 times.
1455 if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE)
901 232 remove_side_data(sd, nb_sd, src->type);
902
4/6
✓ Branch 0 taken 1455 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1405 times.
✓ Branch 3 taken 50 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1405 times.
2860 if ((!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) &&
903 1405 (sd_dst = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, src->type))) {
904 AVDictionary *dict = NULL;
905
906 if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE))
907 return AVERROR(EEXIST);
908
909 ret = av_dict_copy(&dict, src->metadata, 0);
910 if (ret < 0)
911 return ret;
912
913 ret = av_buffer_replace(&sd_dst->buf, src->buf);
914 if (ret < 0) {
915 av_dict_free(&dict);
916 return ret;
917 }
918
919 av_dict_free(&sd_dst->metadata);
920 sd_dst->metadata = dict;
921 sd_dst->data = src->data;
922 sd_dst->size = src->size;
923 return 0;
924 }
925
926 1455 buf = av_buffer_ref(src->buf);
927
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1455 times.
1455 if (!buf)
928 return AVERROR(ENOMEM);
929
930 1455 sd_dst = add_side_data_from_buf_ext(sd, nb_sd, src->type, buf,
931 1455 src->data, src->size);
932
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1455 times.
1455 if (!sd_dst) {
933 av_buffer_unref(&buf);
934 return AVERROR(ENOMEM);
935 }
936
937 1455 ret = av_dict_copy(&sd_dst->metadata, src->metadata, 0);
938
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1455 times.
1455 if (ret < 0) {
939 remove_side_data_by_entry(sd, nb_sd, sd_dst);
940 return ret;
941 }
942
943 1455 return 0;
944 }
945
946 2221416 const AVFrameSideData *av_frame_side_data_get_c(const AVFrameSideData * const *sd,
947 const int nb_sd,
948 enum AVFrameSideDataType type)
949 {
950
2/2
✓ Branch 0 taken 40382 times.
✓ Branch 1 taken 2218961 times.
2259343 for (int i = 0; i < nb_sd; i++) {
951
2/2
✓ Branch 0 taken 2455 times.
✓ Branch 1 taken 37927 times.
40382 if (sd[i]->type == type)
952 2455 return sd[i];
953 }
954 2218961 return NULL;
955 }
956
957 15 void av_frame_side_data_remove(AVFrameSideData ***sd, int *nb_sd,
958 enum AVFrameSideDataType type)
959 {
960 15 remove_side_data(sd, nb_sd, type);
961 15 }
962
963 6436 void av_frame_side_data_remove_by_props(AVFrameSideData ***sd, int *nb_sd,
964 int props)
965 {
966
2/2
✓ Branch 0 taken 111 times.
✓ Branch 1 taken 6436 times.
6547 for (int i = *nb_sd - 1; i >= 0; i--) {
967 111 AVFrameSideData *entry = ((*sd)[i]);
968 111 const AVSideDataDescriptor *desc = av_frame_side_data_desc(entry->type);
969
2/4
✓ Branch 0 taken 111 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 111 times.
✗ Branch 3 not taken.
111 if (!desc || !(desc->props & props))
970 111 continue;
971
972 free_side_data(&entry);
973
974 ((*sd)[i]) = ((*sd)[*nb_sd - 1]);
975 (*nb_sd)--;
976 }
977 6436 }
978
979 2023022 AVFrameSideData *av_frame_get_side_data(const AVFrame *frame,
980 enum AVFrameSideDataType type)
981 {
982 4046044 return (AVFrameSideData *)av_frame_side_data_get(
983 2023022 frame->side_data, frame->nb_side_data,
984 type
985 );
986 }
987
988 9940 static int frame_copy_video(AVFrame *dst, const AVFrame *src)
989 {
990 int planes;
991
992
1/2
✓ Branch 0 taken 9940 times.
✗ Branch 1 not taken.
9940 if (dst->width < src->width ||
993
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9940 times.
9940 dst->height < src->height)
994 return AVERROR(EINVAL);
995
996
2/4
✓ Branch 0 taken 9940 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9940 times.
9940 if (src->hw_frames_ctx || dst->hw_frames_ctx)
997 return av_hwframe_transfer_data(dst, src, 0);
998
999 9940 planes = av_pix_fmt_count_planes(dst->format);
1000
2/2
✓ Branch 0 taken 16149 times.
✓ Branch 1 taken 9940 times.
26089 for (int i = 0; i < planes; i++)
1001
2/4
✓ Branch 0 taken 16149 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 16149 times.
16149 if (!dst->data[i] || !src->data[i])
1002 return AVERROR(EINVAL);
1003
1004 9940 av_image_copy2(dst->data, dst->linesize,
1005 9940 src->data, src->linesize,
1006 9940 dst->format, src->width, src->height);
1007
1008 9940 return 0;
1009 }
1010
1011 static int frame_copy_audio(AVFrame *dst, const AVFrame *src)
1012 {
1013 int planar = av_sample_fmt_is_planar(dst->format);
1014 int channels = dst->ch_layout.nb_channels;
1015 int planes = planar ? channels : 1;
1016
1017 if (dst->nb_samples != src->nb_samples ||
1018 av_channel_layout_compare(&dst->ch_layout, &src->ch_layout))
1019 return AVERROR(EINVAL);
1020
1021 for (int i = 0; i < planes; i++)
1022 if (!dst->extended_data[i] || !src->extended_data[i])
1023 return AVERROR(EINVAL);
1024
1025 av_samples_copy(dst->extended_data, src->extended_data, 0, 0,
1026 dst->nb_samples, channels, dst->format);
1027
1028 return 0;
1029 }
1030
1031 9940 int av_frame_copy(AVFrame *dst, const AVFrame *src)
1032 {
1033
2/4
✓ Branch 0 taken 9940 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 9940 times.
9940 if (dst->format != src->format || dst->format < 0)
1034 return AVERROR(EINVAL);
1035
1036
2/4
✓ Branch 0 taken 9940 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 9940 times.
✗ Branch 3 not taken.
9940 if (dst->width > 0 && dst->height > 0)
1037 9940 return frame_copy_video(dst, src);
1038 else if (dst->nb_samples > 0 &&
1039 (av_channel_layout_check(&dst->ch_layout)))
1040 return frame_copy_audio(dst, src);
1041
1042 return AVERROR(EINVAL);
1043 }
1044
1045 406938 void av_frame_remove_side_data(AVFrame *frame, enum AVFrameSideDataType type)
1046 {
1047 406938 remove_side_data(&frame->side_data, &frame->nb_side_data, type);
1048 406938 }
1049
1050 4694 const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType type)
1051 {
1052 4694 unsigned t = type;
1053
2/4
✓ Branch 0 taken 4694 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4694 times.
✗ Branch 3 not taken.
4694 if (t < FF_ARRAY_ELEMS(sd_props) && sd_props[t].name)
1054 4694 return &sd_props[t];
1055 return NULL;
1056 }
1057
1058 483 const char *av_frame_side_data_name(enum AVFrameSideDataType type)
1059 {
1060 483 const AVSideDataDescriptor *desc = av_frame_side_data_desc(type);
1061
1/2
✓ Branch 0 taken 483 times.
✗ Branch 1 not taken.
483 return desc ? desc->name : NULL;
1062 }
1063
1064 144806 static int calc_cropping_offsets(size_t offsets[4], const AVFrame *frame,
1065 const AVPixFmtDescriptor *desc)
1066 {
1067
2/2
✓ Branch 0 taken 408255 times.
✓ Branch 1 taken 140059 times.
548314 for (int i = 0; frame->data[i]; i++) {
1068 408255 const AVComponentDescriptor *comp = NULL;
1069
4/4
✓ Branch 0 taken 274501 times.
✓ Branch 1 taken 133754 times.
✓ Branch 2 taken 129004 times.
✓ Branch 3 taken 145497 times.
408255 int shift_x = (i == 1 || i == 2) ? desc->log2_chroma_w : 0;
1070
4/4
✓ Branch 0 taken 274501 times.
✓ Branch 1 taken 133754 times.
✓ Branch 2 taken 129004 times.
✓ Branch 3 taken 145497 times.
408255 int shift_y = (i == 1 || i == 2) ? desc->log2_chroma_h : 0;
1071
1072
4/4
✓ Branch 0 taken 9494 times.
✓ Branch 1 taken 398761 times.
✓ Branch 2 taken 4747 times.
✓ Branch 3 taken 4747 times.
408255 if (desc->flags & AV_PIX_FMT_FLAG_PAL && i == 1) {
1073 4747 offsets[i] = 0;
1074 4747 break;
1075 }
1076
1077 /* find any component descriptor for this plane */
1078
1/2
✓ Branch 0 taken 792596 times.
✗ Branch 1 not taken.
792596 for (int j = 0; j < desc->nb_components; j++) {
1079
2/2
✓ Branch 0 taken 403508 times.
✓ Branch 1 taken 389088 times.
792596 if (desc->comp[j].plane == i) {
1080 403508 comp = &desc->comp[j];
1081 403508 break;
1082 }
1083 }
1084
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 403508 times.
403508 if (!comp)
1085 return AVERROR_BUG;
1086
1087 403508 offsets[i] = (frame->crop_top >> shift_y) * frame->linesize[i] +
1088 403508 (frame->crop_left >> shift_x) * comp->step;
1089 }
1090
1091 144806 return 0;
1092 }
1093
1094 145110 int av_frame_apply_cropping(AVFrame *frame, int flags)
1095 {
1096 const AVPixFmtDescriptor *desc;
1097 size_t offsets[4];
1098 int ret;
1099
1100
2/4
✓ Branch 0 taken 145110 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 145110 times.
145110 if (!(frame->width > 0 && frame->height > 0))
1101 return AVERROR(EINVAL);
1102
1103
1/2
✓ Branch 0 taken 145110 times.
✗ Branch 1 not taken.
145110 if (frame->crop_left >= INT_MAX - frame->crop_right ||
1104
1/2
✓ Branch 0 taken 145110 times.
✗ Branch 1 not taken.
145110 frame->crop_top >= INT_MAX - frame->crop_bottom ||
1105
1/2
✓ Branch 0 taken 145110 times.
✗ Branch 1 not taken.
145110 (frame->crop_left + frame->crop_right) >= frame->width ||
1106
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 145110 times.
145110 (frame->crop_top + frame->crop_bottom) >= frame->height)
1107 return AVERROR(ERANGE);
1108
1109 145110 desc = av_pix_fmt_desc_get(frame->format);
1110
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 145110 times.
145110 if (!desc)
1111 return AVERROR_BUG;
1112
1113 /* Apply just the right/bottom cropping for hwaccel formats. Bitstream
1114 * formats cannot be easily handled here either (and corresponding decoders
1115 * should not export any cropping anyway), so do the same for those as well.
1116 * */
1117
2/2
✓ Branch 0 taken 318 times.
✓ Branch 1 taken 144792 times.
145110 if (desc->flags & (AV_PIX_FMT_FLAG_BITSTREAM | AV_PIX_FMT_FLAG_HWACCEL)) {
1118 318 frame->width -= frame->crop_right;
1119 318 frame->height -= frame->crop_bottom;
1120 318 frame->crop_right = 0;
1121 318 frame->crop_bottom = 0;
1122 318 return 0;
1123 }
1124
1125 /* calculate the offsets for each plane */
1126 144792 ret = calc_cropping_offsets(offsets, frame, desc);
1127
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 144792 times.
144792 if (ret < 0)
1128 return ret;
1129
1130 /* adjust the offsets to avoid breaking alignment */
1131
2/2
✓ Branch 0 taken 7338 times.
✓ Branch 1 taken 137454 times.
144792 if (!(flags & AV_FRAME_CROP_UNALIGNED)) {
1132
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 7324 times.
7338 int log2_crop_align = frame->crop_left ? ff_ctz(frame->crop_left) : INT_MAX;
1133 7338 int min_log2_align = INT_MAX;
1134
1135
2/2
✓ Branch 0 taken 21532 times.
✓ Branch 1 taken 7338 times.
28870 for (int i = 0; frame->data[i]; i++) {
1136
2/2
✓ Branch 0 taken 42 times.
✓ Branch 1 taken 21490 times.
21532 int log2_align = offsets[i] ? ff_ctz(offsets[i]) : INT_MAX;
1137 21532 min_log2_align = FFMIN(log2_align, min_log2_align);
1138 }
1139
1140 /* we assume, and it should always be true, that the data alignment is
1141 * related to the cropping alignment by a constant power-of-2 factor */
1142
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 7338 times.
7338 if (log2_crop_align < min_log2_align)
1143 return AVERROR_BUG;
1144
1145
3/4
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 7324 times.
✓ Branch 2 taken 14 times.
✗ Branch 3 not taken.
7338 if (min_log2_align < 5 && log2_crop_align != INT_MAX) {
1146 14 frame->crop_left &= ~((1 << (5 + log2_crop_align - min_log2_align)) - 1);
1147 14 ret = calc_cropping_offsets(offsets, frame, desc);
1148
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (ret < 0)
1149 return ret;
1150 }
1151 }
1152
1153
2/2
✓ Branch 0 taken 408213 times.
✓ Branch 1 taken 144792 times.
553005 for (int i = 0; frame->data[i]; i++)
1154 408213 frame->data[i] += offsets[i];
1155
1156 144792 frame->width -= (frame->crop_left + frame->crop_right);
1157 144792 frame->height -= (frame->crop_top + frame->crop_bottom);
1158 144792 frame->crop_left = 0;
1159 144792 frame->crop_right = 0;
1160 144792 frame->crop_top = 0;
1161 144792 frame->crop_bottom = 0;
1162
1163 144792 return 0;
1164 }
1165