| 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 "avassert.h" | ||
| 20 | #include "buffer.h" | ||
| 21 | #include "common.h" | ||
| 22 | #include "dict.h" | ||
| 23 | #include "frame.h" | ||
| 24 | #include "mem.h" | ||
| 25 | #include "side_data.h" | ||
| 26 | |||
| 27 | static const AVSideDataDescriptor sd_props[] = { | ||
| 28 | [AV_FRAME_DATA_PANSCAN] = { "AVPanScan", AV_SIDE_DATA_PROP_SIZE_DEPENDENT }, | ||
| 29 | [AV_FRAME_DATA_A53_CC] = { "ATSC A53 Part 4 Closed Captions" }, | ||
| 30 | [AV_FRAME_DATA_MATRIXENCODING] = { "AVMatrixEncoding", AV_SIDE_DATA_PROP_CHANNEL_DEPENDENT }, | ||
| 31 | [AV_FRAME_DATA_DOWNMIX_INFO] = { "Metadata relevant to a downmix procedure", AV_SIDE_DATA_PROP_CHANNEL_DEPENDENT }, | ||
| 32 | [AV_FRAME_DATA_AFD] = { "Active format description" }, | ||
| 33 | [AV_FRAME_DATA_MOTION_VECTORS] = { "Motion vectors", AV_SIDE_DATA_PROP_SIZE_DEPENDENT }, | ||
| 34 | [AV_FRAME_DATA_SKIP_SAMPLES] = { "Skip samples" }, | ||
| 35 | [AV_FRAME_DATA_GOP_TIMECODE] = { "GOP timecode" }, | ||
| 36 | [AV_FRAME_DATA_S12M_TIMECODE] = { "SMPTE 12-1 timecode" }, | ||
| 37 | [AV_FRAME_DATA_DYNAMIC_HDR_PLUS] = { "HDR Dynamic Metadata SMPTE2094-40 (HDR10+)", AV_SIDE_DATA_PROP_COLOR_DEPENDENT }, | ||
| 38 | [AV_FRAME_DATA_DYNAMIC_HDR_VIVID] = { "HDR Dynamic Metadata CUVA 005.1 2021 (Vivid)", AV_SIDE_DATA_PROP_COLOR_DEPENDENT }, | ||
| 39 | [AV_FRAME_DATA_DYNAMIC_HDR_SMPTE_2094_APP5] = { "HDR Dynamic Metadata SMPTE2094-50", AV_SIDE_DATA_PROP_COLOR_DEPENDENT }, | ||
| 40 | [AV_FRAME_DATA_REGIONS_OF_INTEREST] = { "Regions Of Interest", AV_SIDE_DATA_PROP_SIZE_DEPENDENT }, | ||
| 41 | [AV_FRAME_DATA_VIDEO_ENC_PARAMS] = { "Video encoding parameters" }, | ||
| 42 | [AV_FRAME_DATA_FILM_GRAIN_PARAMS] = { "Film grain parameters" }, | ||
| 43 | [AV_FRAME_DATA_DETECTION_BBOXES] = { "Bounding boxes for object detection and classification", AV_SIDE_DATA_PROP_SIZE_DEPENDENT }, | ||
| 44 | [AV_FRAME_DATA_DOVI_RPU_BUFFER] = { "Dolby Vision RPU Data", AV_SIDE_DATA_PROP_COLOR_DEPENDENT }, | ||
| 45 | [AV_FRAME_DATA_DOVI_METADATA] = { "Dolby Vision Metadata", AV_SIDE_DATA_PROP_COLOR_DEPENDENT }, | ||
| 46 | [AV_FRAME_DATA_LCEVC] = { "LCEVC NAL data", AV_SIDE_DATA_PROP_SIZE_DEPENDENT }, | ||
| 47 | [AV_FRAME_DATA_VIEW_ID] = { "View ID" }, | ||
| 48 | [AV_FRAME_DATA_STEREO3D] = { "Stereo 3D", AV_SIDE_DATA_PROP_GLOBAL }, | ||
| 49 | [AV_FRAME_DATA_REPLAYGAIN] = { "AVReplayGain", AV_SIDE_DATA_PROP_GLOBAL }, | ||
| 50 | [AV_FRAME_DATA_DISPLAYMATRIX] = { "3x3 displaymatrix", AV_SIDE_DATA_PROP_GLOBAL }, | ||
| 51 | [AV_FRAME_DATA_AUDIO_SERVICE_TYPE] = { "Audio service type", AV_SIDE_DATA_PROP_GLOBAL }, | ||
| 52 | [AV_FRAME_DATA_MASTERING_DISPLAY_METADATA] = { "Mastering display metadata", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT }, | ||
| 53 | [AV_FRAME_DATA_CONTENT_LIGHT_LEVEL] = { "Content light level metadata", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT }, | ||
| 54 | [AV_FRAME_DATA_AMBIENT_VIEWING_ENVIRONMENT] = { "Ambient viewing environment", AV_SIDE_DATA_PROP_GLOBAL }, | ||
| 55 | [AV_FRAME_DATA_SPHERICAL] = { "Spherical Mapping", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_SIZE_DEPENDENT }, | ||
| 56 | [AV_FRAME_DATA_ICC_PROFILE] = { "ICC profile", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT }, | ||
| 57 | [AV_FRAME_DATA_EXIF] = { "EXIF metadata", AV_SIDE_DATA_PROP_GLOBAL }, | ||
| 58 | [AV_FRAME_DATA_SEI_UNREGISTERED] = { "H.26[45] User Data Unregistered SEI message", AV_SIDE_DATA_PROP_MULTI }, | ||
| 59 | [AV_FRAME_DATA_VIDEO_HINT] = { "Encoding video hint", AV_SIDE_DATA_PROP_SIZE_DEPENDENT }, | ||
| 60 | [AV_FRAME_DATA_3D_REFERENCE_DISPLAYS] = { "3D Reference Displays Information", AV_SIDE_DATA_PROP_GLOBAL }, | ||
| 61 | [AV_FRAME_DATA_IAMF_MIX_GAIN_PARAM] = { "IAMF Mix Gain Parameter Data" }, | ||
| 62 | [AV_FRAME_DATA_IAMF_DEMIXING_INFO_PARAM] = { "IAMF Demixing Info Parameter Data", AV_SIDE_DATA_PROP_CHANNEL_DEPENDENT }, | ||
| 63 | [AV_FRAME_DATA_IAMF_RECON_GAIN_INFO_PARAM] = { "IAMF Recon Gain Info Parameter Data" }, | ||
| 64 | [AV_FRAME_DATA_RAW_COLOR_PARAMS] = { "RAW camera color parameters", AV_SIDE_DATA_PROP_GLOBAL | AV_SIDE_DATA_PROP_COLOR_DEPENDENT }, | ||
| 65 | [AV_FRAME_DATA_DOWNMIX_MATRIX] = { "Downmix Matrix", AV_SIDE_DATA_PROP_CHANNEL_DEPENDENT }, | ||
| 66 | }; | ||
| 67 | |||
| 68 | 6110 | const AVSideDataDescriptor *av_frame_side_data_desc(enum AVFrameSideDataType type) | |
| 69 | { | ||
| 70 | 6110 | unsigned t = type; | |
| 71 |
2/4✓ Branch 0 taken 6110 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 6110 times.
✗ Branch 3 not taken.
|
6110 | if (t < FF_ARRAY_ELEMS(sd_props) && sd_props[t].name) |
| 72 | 6110 | return &sd_props[t]; | |
| 73 | ✗ | return NULL; | |
| 74 | } | ||
| 75 | |||
| 76 | 592 | const char *av_frame_side_data_name(enum AVFrameSideDataType type) | |
| 77 | { | ||
| 78 | 592 | const AVSideDataDescriptor *desc = av_frame_side_data_desc(type); | |
| 79 |
1/2✓ Branch 0 taken 592 times.
✗ Branch 1 not taken.
|
592 | return desc ? desc->name : NULL; |
| 80 | } | ||
| 81 | |||
| 82 | 63313 | static void free_side_data_entry(AVFrameSideData **ptr_sd) | |
| 83 | { | ||
| 84 | 63313 | AVFrameSideData *sd = *ptr_sd; | |
| 85 | |||
| 86 | 63313 | av_buffer_unref(&sd->buf); | |
| 87 | 63313 | av_dict_free(&sd->metadata); | |
| 88 | 63313 | av_freep(ptr_sd); | |
| 89 | 63313 | } | |
| 90 | |||
| 91 | ✗ | static void remove_side_data_by_entry(AVFrameSideData ***sd, int *nb_sd, | |
| 92 | const AVFrameSideData *target) | ||
| 93 | { | ||
| 94 | ✗ | for (int i = *nb_sd - 1; i >= 0; i--) { | |
| 95 | ✗ | AVFrameSideData *entry = ((*sd)[i]); | |
| 96 | ✗ | if (entry != target) | |
| 97 | ✗ | continue; | |
| 98 | |||
| 99 | ✗ | free_side_data_entry(&entry); | |
| 100 | |||
| 101 | ✗ | ((*sd)[i]) = ((*sd)[*nb_sd - 1]); | |
| 102 | ✗ | (*nb_sd)--; | |
| 103 | |||
| 104 | ✗ | return; | |
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | 465700 | void av_frame_side_data_remove(AVFrameSideData ***sd, int *nb_sd, | |
| 109 | enum AVFrameSideDataType type) | ||
| 110 | { | ||
| 111 |
2/2✓ Branch 0 taken 15952 times.
✓ Branch 1 taken 465700 times.
|
481652 | for (int i = *nb_sd - 1; i >= 0; i--) { |
| 112 | 15952 | AVFrameSideData *entry = ((*sd)[i]); | |
| 113 |
2/2✓ Branch 0 taken 15286 times.
✓ Branch 1 taken 666 times.
|
15952 | if (entry->type != type) |
| 114 | 15286 | continue; | |
| 115 | |||
| 116 | 666 | free_side_data_entry(&entry); | |
| 117 | |||
| 118 | 666 | ((*sd)[i]) = ((*sd)[*nb_sd - 1]); | |
| 119 | 666 | (*nb_sd)--; | |
| 120 | } | ||
| 121 | 465700 | } | |
| 122 | |||
| 123 | 7339 | void av_frame_side_data_remove_by_props(AVFrameSideData ***sd, int *nb_sd, | |
| 124 | int props) | ||
| 125 | { | ||
| 126 |
2/2✓ Branch 0 taken 135 times.
✓ Branch 1 taken 7339 times.
|
7474 | for (int i = *nb_sd - 1; i >= 0; i--) { |
| 127 | 135 | AVFrameSideData *entry = ((*sd)[i]); | |
| 128 | 135 | const AVSideDataDescriptor *desc = av_frame_side_data_desc(entry->type); | |
| 129 |
3/4✓ Branch 0 taken 135 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 113 times.
✓ Branch 3 taken 22 times.
|
135 | if (!desc || !(desc->props & props)) |
| 130 | 113 | continue; | |
| 131 | |||
| 132 | 22 | free_side_data_entry(&entry); | |
| 133 | |||
| 134 | 22 | ((*sd)[i]) = ((*sd)[*nb_sd - 1]); | |
| 135 | 22 | (*nb_sd)--; | |
| 136 | } | ||
| 137 | 7339 | } | |
| 138 | |||
| 139 | 10886687 | void av_frame_side_data_free(AVFrameSideData ***sd, int *nb_sd) | |
| 140 | { | ||
| 141 |
2/2✓ Branch 0 taken 62625 times.
✓ Branch 1 taken 10886687 times.
|
10949312 | for (int i = 0; i < *nb_sd; i++) |
| 142 | 62625 | free_side_data_entry(&((*sd)[i])); | |
| 143 | 10886687 | *nb_sd = 0; | |
| 144 | |||
| 145 | 10886687 | av_freep(sd); | |
| 146 | 10886687 | } | |
| 147 | |||
| 148 | 63313 | static AVFrameSideData *add_side_data_from_buf_ext(AVFrameSideData ***sd, | |
| 149 | int *nb_sd, | ||
| 150 | enum AVFrameSideDataType type, | ||
| 151 | AVBufferRef *buf, uint8_t *data, | ||
| 152 | size_t size) | ||
| 153 | { | ||
| 154 | AVFrameSideData *ret, **tmp; | ||
| 155 | |||
| 156 | // *nb_sd + 1 needs to fit into an int and a size_t. | ||
| 157 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 63313 times.
|
63313 | if ((unsigned)*nb_sd >= FFMIN(INT_MAX, SIZE_MAX)) |
| 158 | ✗ | return NULL; | |
| 159 | |||
| 160 | 63313 | tmp = av_realloc_array(*sd, *nb_sd + 1, sizeof(**sd)); | |
| 161 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 63313 times.
|
63313 | if (!tmp) |
| 162 | ✗ | return NULL; | |
| 163 | 63313 | *sd = tmp; | |
| 164 | |||
| 165 | 63313 | ret = av_mallocz(sizeof(*ret)); | |
| 166 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 63313 times.
|
63313 | if (!ret) |
| 167 | ✗ | return NULL; | |
| 168 | |||
| 169 | 63313 | ret->buf = buf; | |
| 170 | 63313 | ret->data = data; | |
| 171 | 63313 | ret->size = size; | |
| 172 | 63313 | ret->type = type; | |
| 173 | |||
| 174 | 63313 | (*sd)[(*nb_sd)++] = ret; | |
| 175 | |||
| 176 | 63313 | return ret; | |
| 177 | } | ||
| 178 | |||
| 179 | 60899 | AVFrameSideData *ff_frame_side_data_add_from_buf(AVFrameSideData ***sd, | |
| 180 | int *nb_sd, | ||
| 181 | enum AVFrameSideDataType type, | ||
| 182 | AVBufferRef *buf) | ||
| 183 | { | ||
| 184 |
2/2✓ Branch 0 taken 4 times.
✓ Branch 1 taken 60895 times.
|
60899 | if (!buf) |
| 185 | 4 | return NULL; | |
| 186 | |||
| 187 | 60895 | return add_side_data_from_buf_ext(sd, nb_sd, type, buf, buf->data, buf->size); | |
| 188 | } | ||
| 189 | |||
| 190 | 2 | static AVFrameSideData *replace_side_data_from_buf(AVFrameSideData *dst, | |
| 191 | AVBufferRef *buf, int flags) | ||
| 192 | { | ||
| 193 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE)) |
| 194 | ✗ | return NULL; | |
| 195 | |||
| 196 | 2 | av_dict_free(&dst->metadata); | |
| 197 | 2 | av_buffer_unref(&dst->buf); | |
| 198 | 2 | dst->buf = buf; | |
| 199 | 2 | dst->data = buf->data; | |
| 200 | 2 | dst->size = buf->size; | |
| 201 | 2 | return dst; | |
| 202 | } | ||
| 203 | |||
| 204 | 697 | AVFrameSideData *av_frame_side_data_new(AVFrameSideData ***sd, int *nb_sd, | |
| 205 | enum AVFrameSideDataType type, | ||
| 206 | size_t size, unsigned int flags) | ||
| 207 | { | ||
| 208 | 697 | const AVSideDataDescriptor *desc = av_frame_side_data_desc(type); | |
| 209 | 697 | AVBufferRef *buf = av_buffer_alloc(size); | |
| 210 | 697 | AVFrameSideData *ret = NULL; | |
| 211 | |||
| 212 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 696 times.
|
697 | if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE) |
| 213 | 1 | av_frame_side_data_remove(sd, nb_sd, type); | |
| 214 |
5/6✓ Branch 0 taken 697 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 690 times.
✓ Branch 3 taken 7 times.
✓ Branch 4 taken 2 times.
✓ Branch 5 taken 688 times.
|
1387 | if ((!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) && |
| 215 | 690 | (ret = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, type))) { | |
| 216 | 2 | ret = replace_side_data_from_buf(ret, buf, flags); | |
| 217 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (!ret) |
| 218 | ✗ | av_buffer_unref(&buf); | |
| 219 | 2 | return ret; | |
| 220 | } | ||
| 221 | |||
| 222 | 695 | ret = ff_frame_side_data_add_from_buf(sd, nb_sd, type, buf); | |
| 223 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 695 times.
|
695 | if (!ret) |
| 224 | ✗ | av_buffer_unref(&buf); | |
| 225 | |||
| 226 | 695 | return ret; | |
| 227 | } | ||
| 228 | |||
| 229 | 1641 | AVFrameSideData *av_frame_side_data_add(AVFrameSideData ***sd, int *nb_sd, | |
| 230 | enum AVFrameSideDataType type, | ||
| 231 | AVBufferRef **pbuf, unsigned int flags) | ||
| 232 | { | ||
| 233 | 1641 | const AVSideDataDescriptor *desc = av_frame_side_data_desc(type); | |
| 234 | 1641 | AVFrameSideData *sd_dst = NULL; | |
| 235 | 1641 | AVBufferRef *buf = *pbuf; | |
| 236 | |||
| 237 |
3/4✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1639 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2 times.
|
1641 | if ((flags & AV_FRAME_SIDE_DATA_FLAG_NEW_REF) && !(buf = av_buffer_ref(*pbuf))) |
| 238 | ✗ | return NULL; | |
| 239 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1641 times.
|
1641 | if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE) |
| 240 | ✗ | av_frame_side_data_remove(sd, nb_sd, type); | |
| 241 |
4/6✓ Branch 0 taken 1641 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1301 times.
✓ Branch 3 taken 340 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 1301 times.
|
2942 | if ((!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) && |
| 242 | 1301 | (sd_dst = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, type))) { | |
| 243 | ✗ | sd_dst = replace_side_data_from_buf(sd_dst, buf, flags); | |
| 244 | } else | ||
| 245 | 1641 | sd_dst = ff_frame_side_data_add_from_buf(sd, nb_sd, type, buf); | |
| 246 | |||
| 247 |
3/4✓ Branch 0 taken 1641 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1639 times.
✓ Branch 3 taken 2 times.
|
1641 | if (sd_dst && !(flags & AV_FRAME_SIDE_DATA_FLAG_NEW_REF)) |
| 248 | 1639 | *pbuf = NULL; | |
| 249 |
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)) |
| 250 | ✗ | av_buffer_unref(&buf); | |
| 251 | 1641 | return sd_dst; | |
| 252 | } | ||
| 253 | |||
| 254 | 2418 | int av_frame_side_data_clone(AVFrameSideData ***sd, int *nb_sd, | |
| 255 | const AVFrameSideData *src, unsigned int flags) | ||
| 256 | { | ||
| 257 | const AVSideDataDescriptor *desc; | ||
| 258 | 2418 | AVBufferRef *buf = NULL; | |
| 259 | 2418 | AVFrameSideData *sd_dst = NULL; | |
| 260 | 2418 | int ret = AVERROR_BUG; | |
| 261 | |||
| 262 |
6/10✓ Branch 0 taken 2418 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2418 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 2418 times.
✗ Branch 5 not taken.
✓ Branch 6 taken 244 times.
✓ Branch 7 taken 2174 times.
✗ Branch 8 not taken.
✓ Branch 9 taken 244 times.
|
2418 | if (!sd || !src || !nb_sd || (*nb_sd && !*sd)) |
| 263 | ✗ | return AVERROR(EINVAL); | |
| 264 | |||
| 265 | 2418 | desc = av_frame_side_data_desc(src->type); | |
| 266 |
2/2✓ Branch 0 taken 280 times.
✓ Branch 1 taken 2138 times.
|
2418 | if (flags & AV_FRAME_SIDE_DATA_FLAG_UNIQUE) |
| 267 | 280 | av_frame_side_data_remove(sd, nb_sd, src->type); | |
| 268 |
4/6✓ Branch 0 taken 2418 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 2366 times.
✓ Branch 3 taken 52 times.
✗ Branch 4 not taken.
✓ Branch 5 taken 2366 times.
|
4784 | if ((!desc || !(desc->props & AV_SIDE_DATA_PROP_MULTI)) && |
| 269 | 2366 | (sd_dst = (AVFrameSideData *)av_frame_side_data_get(*sd, *nb_sd, src->type))) { | |
| 270 | ✗ | AVDictionary *dict = NULL; | |
| 271 | |||
| 272 | ✗ | if (!(flags & AV_FRAME_SIDE_DATA_FLAG_REPLACE)) | |
| 273 | ✗ | return AVERROR(EEXIST); | |
| 274 | |||
| 275 | ✗ | ret = av_dict_copy(&dict, src->metadata, 0); | |
| 276 | ✗ | if (ret < 0) | |
| 277 | ✗ | return ret; | |
| 278 | |||
| 279 | ✗ | ret = av_buffer_replace(&sd_dst->buf, src->buf); | |
| 280 | ✗ | if (ret < 0) { | |
| 281 | ✗ | av_dict_free(&dict); | |
| 282 | ✗ | return ret; | |
| 283 | } | ||
| 284 | |||
| 285 | ✗ | av_dict_free(&sd_dst->metadata); | |
| 286 | ✗ | sd_dst->metadata = dict; | |
| 287 | ✗ | sd_dst->data = src->data; | |
| 288 | ✗ | sd_dst->size = src->size; | |
| 289 | ✗ | return 0; | |
| 290 | } | ||
| 291 | |||
| 292 | 2418 | buf = av_buffer_ref(src->buf); | |
| 293 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2418 times.
|
2418 | if (!buf) |
| 294 | ✗ | return AVERROR(ENOMEM); | |
| 295 | |||
| 296 | 2418 | sd_dst = add_side_data_from_buf_ext(sd, nb_sd, src->type, buf, | |
| 297 | 2418 | src->data, src->size); | |
| 298 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2418 times.
|
2418 | if (!sd_dst) { |
| 299 | ✗ | av_buffer_unref(&buf); | |
| 300 | ✗ | return AVERROR(ENOMEM); | |
| 301 | } | ||
| 302 | |||
| 303 | 2418 | ret = av_dict_copy(&sd_dst->metadata, src->metadata, 0); | |
| 304 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2418 times.
|
2418 | if (ret < 0) { |
| 305 | ✗ | remove_side_data_by_entry(sd, nb_sd, sd_dst); | |
| 306 | ✗ | return ret; | |
| 307 | } | ||
| 308 | |||
| 309 | 2418 | return 0; | |
| 310 | } | ||
| 311 | |||
| 312 | 4008976 | const AVFrameSideData *av_frame_side_data_get_c(const AVFrameSideData * const *sd, | |
| 313 | const int nb_sd, | ||
| 314 | enum AVFrameSideDataType type) | ||
| 315 | { | ||
| 316 |
2/2✓ Branch 0 taken 73085 times.
✓ Branch 1 taken 4004391 times.
|
4077476 | for (int i = 0; i < nb_sd; i++) { |
| 317 |
2/2✓ Branch 0 taken 4585 times.
✓ Branch 1 taken 68500 times.
|
73085 | if (sd[i]->type == type) |
| 318 | 4585 | return sd[i]; | |
| 319 | } | ||
| 320 | 4004391 | return NULL; | |
| 321 | } | ||
| 322 |