1 /*
2  * This file is part of mpv.
3  *
4  * mpv 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  * mpv 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
12  * GNU 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 mpv.  If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include <limits.h>
19 #include <pthread.h>
20 #include <assert.h>
21 
22 #include <libavutil/mem.h>
23 #include <libavutil/common.h>
24 #include <libavutil/bswap.h>
25 #include <libavutil/hwcontext.h>
26 #include <libavutil/intreadwrite.h>
27 #include <libavutil/rational.h>
28 #include <libavcodec/avcodec.h>
29 #include <libavutil/mastering_display_metadata.h>
30 
31 #include "mpv_talloc.h"
32 
33 #include "config.h"
34 #include "common/av_common.h"
35 #include "common/common.h"
36 #include "hwdec.h"
37 #include "mp_image.h"
38 #include "sws_utils.h"
39 #include "fmt-conversion.h"
40 
41 // Determine strides, plane sizes, and total required size for an image
42 // allocation. Returns total size on success, <0 on error. Unused planes
43 // have out_stride/out_plane_size to 0, and out_plane_offset set to -1 up
44 // until MP_MAX_PLANES-1.
mp_image_layout(int imgfmt,int w,int h,int stride_align,int out_stride[MP_MAX_PLANES],int out_plane_offset[MP_MAX_PLANES],int out_plane_size[MP_MAX_PLANES])45 static int mp_image_layout(int imgfmt, int w, int h, int stride_align,
46                            int out_stride[MP_MAX_PLANES],
47                            int out_plane_offset[MP_MAX_PLANES],
48                            int out_plane_size[MP_MAX_PLANES])
49 {
50     struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(imgfmt);
51 
52     w = MP_ALIGN_UP(w, desc.align_x);
53     h = MP_ALIGN_UP(h, desc.align_y);
54 
55     struct mp_image_params params = {.imgfmt = imgfmt, .w = w, .h = h};
56 
57     if (!mp_image_params_valid(&params) || desc.flags & MP_IMGFLAG_HWACCEL)
58         return -1;
59 
60     // Note: for non-mod-2 4:2:0 YUV frames, we have to allocate an additional
61     //       top/right border. This is needed for correct handling of such
62     //       images in filter and VO code (e.g. vo_vdpau or vo_gpu).
63 
64     for (int n = 0; n < MP_MAX_PLANES; n++) {
65         int alloc_w = mp_chroma_div_up(w, desc.xs[n]);
66         int alloc_h = MP_ALIGN_UP(h, 32) >> desc.ys[n];
67         int line_bytes = (alloc_w * desc.bpp[n] + 7) / 8;
68         out_stride[n] = MP_ALIGN_UP(line_bytes, stride_align);
69         out_plane_size[n] = out_stride[n] * alloc_h;
70     }
71     if (desc.flags & MP_IMGFLAG_PAL)
72         out_plane_size[1] = AVPALETTE_SIZE;
73 
74     int sum = 0;
75     for (int n = 0; n < MP_MAX_PLANES; n++) {
76         out_plane_offset[n] = out_plane_size[n] ? sum : -1;
77         sum += out_plane_size[n];
78     }
79 
80     return sum;
81 }
82 
83 // Return the total size needed for an image allocation of the given
84 // configuration (imgfmt, w, h must be set). Returns -1 on error.
85 // Assumes the allocation is already aligned on stride_align (otherwise you
86 // need to add padding yourself).
mp_image_get_alloc_size(int imgfmt,int w,int h,int stride_align)87 int mp_image_get_alloc_size(int imgfmt, int w, int h, int stride_align)
88 {
89     int stride[MP_MAX_PLANES];
90     int plane_offset[MP_MAX_PLANES];
91     int plane_size[MP_MAX_PLANES];
92     return mp_image_layout(imgfmt, w, h, stride_align, stride, plane_offset,
93                            plane_size);
94 }
95 
96 // Fill the mpi->planes and mpi->stride fields of the given mpi with data
97 // from buffer according to the mpi's w/h/imgfmt fields. See mp_image_from_buffer
98 // aboud remarks how to allocate/use buffer/buffer_size.
99 // This does not free the data. You are expected to setup refcounting by
100 // setting mp_image.bufs before or after this function is called.
101 // Returns true on success, false on failure.
mp_image_fill_alloc(struct mp_image * mpi,int stride_align,void * buffer,int buffer_size)102 static bool mp_image_fill_alloc(struct mp_image *mpi, int stride_align,
103                                 void *buffer, int buffer_size)
104 {
105     int stride[MP_MAX_PLANES];
106     int plane_offset[MP_MAX_PLANES];
107     int plane_size[MP_MAX_PLANES];
108     int size = mp_image_layout(mpi->imgfmt, mpi->w, mpi->h, stride_align,
109                                stride, plane_offset, plane_size);
110     if (size < 0 || size > buffer_size)
111         return false;
112 
113     int align = MP_ALIGN_UP((uintptr_t)buffer, stride_align) - (uintptr_t)buffer;
114     if (buffer_size - size < align)
115         return false;
116     uint8_t *s = buffer;
117     s += align;
118 
119     for (int n = 0; n < MP_MAX_PLANES; n++) {
120         mpi->planes[n] = plane_offset[n] >= 0 ? s + plane_offset[n] : NULL;
121         mpi->stride[n] = stride[n];
122     }
123 
124     return true;
125 }
126 
127 // Create a mp_image from the provided buffer. The mp_image is filled according
128 // to the imgfmt/w/h parameters, and respecting the stride_align parameter to
129 // align the plane start pointers and strides. Once the last reference to the
130 // returned image is destroyed, free(free_opaque, buffer) is called. (Be aware
131 // that this can happen from any thread.)
132 // The allocated size of buffer must be given by buffer_size. buffer_size should
133 // be at least the value returned by mp_image_get_alloc_size(). If buffer is not
134 // already aligned to stride_align, the function will attempt to align the
135 // pointer itself by incrementing the buffer pointer until ther alignment is
136 // achieved (if buffer_size is not large enough to allow aligning the buffer
137 // safely, the function fails). To be safe, you may want to overallocate the
138 // buffer by stride_align bytes, and include the overallocation in buffer_size.
139 // Returns NULL on failure. On failure, the free() callback is not called.
mp_image_from_buffer(int imgfmt,int w,int h,int stride_align,uint8_t * buffer,int buffer_size,void * free_opaque,void (* free)(void * opaque,uint8_t * data))140 struct mp_image *mp_image_from_buffer(int imgfmt, int w, int h, int stride_align,
141                                       uint8_t *buffer, int buffer_size,
142                                       void *free_opaque,
143                                       void (*free)(void *opaque, uint8_t *data))
144 {
145     struct mp_image *mpi = mp_image_new_dummy_ref(NULL);
146     mp_image_setfmt(mpi, imgfmt);
147     mp_image_set_size(mpi, w, h);
148 
149     if (!mp_image_fill_alloc(mpi, stride_align, buffer, buffer_size))
150         goto fail;
151 
152     mpi->bufs[0] = av_buffer_create(buffer, buffer_size, free, free_opaque, 0);
153     if (!mpi->bufs[0])
154         goto fail;
155 
156     return mpi;
157 
158 fail:
159     talloc_free(mpi);
160     return NULL;
161 }
162 
mp_image_alloc_planes(struct mp_image * mpi)163 static bool mp_image_alloc_planes(struct mp_image *mpi)
164 {
165     assert(!mpi->planes[0]);
166     assert(!mpi->bufs[0]);
167 
168     int align = MP_IMAGE_BYTE_ALIGN;
169 
170     int size = mp_image_get_alloc_size(mpi->imgfmt, mpi->w, mpi->h, align);
171     if (size < 0)
172         return false;
173 
174     // Note: mp_image_pool assumes this creates only 1 AVBufferRef.
175     mpi->bufs[0] = av_buffer_alloc(size + align);
176     if (!mpi->bufs[0])
177         return false;
178 
179     if (!mp_image_fill_alloc(mpi, align, mpi->bufs[0]->data, mpi->bufs[0]->size)) {
180         av_buffer_unref(&mpi->bufs[0]);
181         return false;
182     }
183 
184     return true;
185 }
186 
mp_image_setfmt(struct mp_image * mpi,int out_fmt)187 void mp_image_setfmt(struct mp_image *mpi, int out_fmt)
188 {
189     struct mp_image_params params = mpi->params;
190     struct mp_imgfmt_desc fmt = mp_imgfmt_get_desc(out_fmt);
191     params.imgfmt = fmt.id;
192     mpi->fmt = fmt;
193     mpi->imgfmt = fmt.id;
194     mpi->num_planes = fmt.num_planes;
195     mpi->params = params;
196 }
197 
mp_image_destructor(void * ptr)198 static void mp_image_destructor(void *ptr)
199 {
200     mp_image_t *mpi = ptr;
201     for (int p = 0; p < MP_MAX_PLANES; p++)
202         av_buffer_unref(&mpi->bufs[p]);
203     av_buffer_unref(&mpi->hwctx);
204     av_buffer_unref(&mpi->icc_profile);
205     av_buffer_unref(&mpi->a53_cc);
206     for (int n = 0; n < mpi->num_ff_side_data; n++)
207         av_buffer_unref(&mpi->ff_side_data[n].buf);
208     talloc_free(mpi->ff_side_data);
209 }
210 
mp_chroma_div_up(int size,int shift)211 int mp_chroma_div_up(int size, int shift)
212 {
213     return (size + (1 << shift) - 1) >> shift;
214 }
215 
216 // Return the storage width in pixels of the given plane.
mp_image_plane_w(struct mp_image * mpi,int plane)217 int mp_image_plane_w(struct mp_image *mpi, int plane)
218 {
219     return mp_chroma_div_up(MP_ALIGN_UP(mpi->w, mpi->fmt.align_x),
220                             mpi->fmt.xs[plane]);
221 }
222 
223 // Return the storage height in pixels of the given plane.
mp_image_plane_h(struct mp_image * mpi,int plane)224 int mp_image_plane_h(struct mp_image *mpi, int plane)
225 {
226     return mp_chroma_div_up(MP_ALIGN_UP(mpi->h, mpi->fmt.align_y),
227                             mpi->fmt.ys[plane]);
228 }
229 
230 // Caller has to make sure this doesn't exceed the allocated plane data/strides.
mp_image_set_size(struct mp_image * mpi,int w,int h)231 void mp_image_set_size(struct mp_image *mpi, int w, int h)
232 {
233     assert(w >= 0 && h >= 0);
234     mpi->w = mpi->params.w = w;
235     mpi->h = mpi->params.h = h;
236 }
237 
mp_image_set_params(struct mp_image * image,const struct mp_image_params * params)238 void mp_image_set_params(struct mp_image *image,
239                          const struct mp_image_params *params)
240 {
241     // possibly initialize other stuff
242     mp_image_setfmt(image, params->imgfmt);
243     mp_image_set_size(image, params->w, params->h);
244     image->params = *params;
245 }
246 
mp_image_alloc(int imgfmt,int w,int h)247 struct mp_image *mp_image_alloc(int imgfmt, int w, int h)
248 {
249     struct mp_image *mpi = talloc_zero(NULL, struct mp_image);
250     talloc_set_destructor(mpi, mp_image_destructor);
251 
252     mp_image_set_size(mpi, w, h);
253     mp_image_setfmt(mpi, imgfmt);
254     if (!mp_image_alloc_planes(mpi)) {
255         talloc_free(mpi);
256         return NULL;
257     }
258     return mpi;
259 }
260 
mp_image_approx_byte_size(struct mp_image * img)261 int mp_image_approx_byte_size(struct mp_image *img)
262 {
263     int total = sizeof(*img);
264 
265     for (int n = 0; n < MP_MAX_PLANES; n++) {
266         struct AVBufferRef *buf = img->bufs[n];
267         if (buf)
268             total += buf->size;
269     }
270 
271     return total;
272 }
273 
mp_image_new_copy(struct mp_image * img)274 struct mp_image *mp_image_new_copy(struct mp_image *img)
275 {
276     struct mp_image *new = mp_image_alloc(img->imgfmt, img->w, img->h);
277     if (!new)
278         return NULL;
279     mp_image_copy(new, img);
280     mp_image_copy_attributes(new, img);
281     return new;
282 }
283 
284 // Make dst take over the image data of src, and free src.
285 // This is basically a safe version of *dst = *src; free(src);
286 // Only works with ref-counted images, and can't change image size/format.
mp_image_steal_data(struct mp_image * dst,struct mp_image * src)287 void mp_image_steal_data(struct mp_image *dst, struct mp_image *src)
288 {
289     assert(dst->imgfmt == src->imgfmt && dst->w == src->w && dst->h == src->h);
290     assert(dst->bufs[0] && src->bufs[0]);
291 
292     mp_image_destructor(dst); // unref old
293     talloc_free_children(dst);
294 
295     *dst = *src;
296 
297     *src = (struct mp_image){0};
298     talloc_free(src);
299 }
300 
301 // Unref most data buffer (and clear the data array), but leave other fields
302 // allocated. In particular, mp_image.hwctx is preserved.
mp_image_unref_data(struct mp_image * img)303 void mp_image_unref_data(struct mp_image *img)
304 {
305     for (int n = 0; n < MP_MAX_PLANES; n++) {
306         img->planes[n] = NULL;
307         img->stride[n] = 0;
308         av_buffer_unref(&img->bufs[n]);
309     }
310 }
311 
ref_buffer(bool * ok,AVBufferRef ** dst)312 static void ref_buffer(bool *ok, AVBufferRef **dst)
313 {
314     if (*dst) {
315         *dst = av_buffer_ref(*dst);
316         if (!*dst)
317             *ok = false;
318     }
319 }
320 
321 // Return a new reference to img. The returned reference is owned by the caller,
322 // while img is left untouched.
mp_image_new_ref(struct mp_image * img)323 struct mp_image *mp_image_new_ref(struct mp_image *img)
324 {
325     if (!img)
326         return NULL;
327 
328     if (!img->bufs[0])
329         return mp_image_new_copy(img);
330 
331     struct mp_image *new = talloc_ptrtype(NULL, new);
332     talloc_set_destructor(new, mp_image_destructor);
333     *new = *img;
334 
335     bool ok = true;
336     for (int p = 0; p < MP_MAX_PLANES; p++)
337         ref_buffer(&ok, &new->bufs[p]);
338 
339     ref_buffer(&ok, &new->hwctx);
340     ref_buffer(&ok, &new->icc_profile);
341     ref_buffer(&ok, &new->a53_cc);
342 
343     new->ff_side_data = talloc_memdup(NULL, new->ff_side_data,
344                         new->num_ff_side_data * sizeof(new->ff_side_data[0]));
345     for (int n = 0; n < new->num_ff_side_data; n++)
346         ref_buffer(&ok, &new->ff_side_data[n].buf);
347 
348     if (ok)
349         return new;
350 
351     // Do this after _all_ bufs were changed; we don't want it to free bufs
352     // from the original image if this fails.
353     talloc_free(new);
354     return NULL;
355 }
356 
357 struct free_args {
358     void *arg;
359     void (*free)(void *arg);
360 };
361 
call_free(void * opaque,uint8_t * data)362 static void call_free(void *opaque, uint8_t *data)
363 {
364     struct free_args *args = opaque;
365     args->free(args->arg);
366     talloc_free(args);
367 }
368 
369 // Create a new mp_image based on img, but don't set any buffers.
370 // Using this is only valid until the original img is unreferenced (including
371 // implicit unreferencing of the data by mp_image_make_writeable()), unless
372 // a new reference is set.
mp_image_new_dummy_ref(struct mp_image * img)373 struct mp_image *mp_image_new_dummy_ref(struct mp_image *img)
374 {
375     struct mp_image *new = talloc_ptrtype(NULL, new);
376     talloc_set_destructor(new, mp_image_destructor);
377     *new = img ? *img : (struct mp_image){0};
378     for (int p = 0; p < MP_MAX_PLANES; p++)
379         new->bufs[p] = NULL;
380     new->hwctx = NULL;
381     new->icc_profile = NULL;
382     new->a53_cc = NULL;
383     new->num_ff_side_data = 0;
384     new->ff_side_data = NULL;
385     return new;
386 }
387 
388 // Return a reference counted reference to img. If the reference count reaches
389 // 0, call free(free_arg). The data passed by img must not be free'd before
390 // that. The new reference will be writeable.
391 // On allocation failure, unref the frame and return NULL.
392 // This is only used for hw decoding; this is important, because libav* expects
393 // all plane data to be accounted for by AVBufferRefs.
mp_image_new_custom_ref(struct mp_image * img,void * free_arg,void (* free)(void * arg))394 struct mp_image *mp_image_new_custom_ref(struct mp_image *img, void *free_arg,
395                                          void (*free)(void *arg))
396 {
397     struct mp_image *new = mp_image_new_dummy_ref(img);
398 
399     struct free_args *args = talloc_ptrtype(NULL, args);
400     *args = (struct free_args){free_arg, free};
401     new->bufs[0] = av_buffer_create(NULL, 0, call_free, args,
402                                     AV_BUFFER_FLAG_READONLY);
403     if (new->bufs[0])
404         return new;
405     talloc_free(new);
406     return NULL;
407 }
408 
mp_image_is_writeable(struct mp_image * img)409 bool mp_image_is_writeable(struct mp_image *img)
410 {
411     if (!img->bufs[0])
412         return true; // not ref-counted => always considered writeable
413     for (int p = 0; p < MP_MAX_PLANES; p++) {
414         if (!img->bufs[p])
415             break;
416         if (!av_buffer_is_writable(img->bufs[p]))
417             return false;
418     }
419     return true;
420 }
421 
422 // Make the image data referenced by img writeable. This allocates new data
423 // if the data wasn't already writeable, and img->planes[] and img->stride[]
424 // will be set to the copy.
425 // Returns success; if false is returned, the image could not be made writeable.
mp_image_make_writeable(struct mp_image * img)426 bool mp_image_make_writeable(struct mp_image *img)
427 {
428     if (mp_image_is_writeable(img))
429         return true;
430 
431     struct mp_image *new = mp_image_new_copy(img);
432     if (!new)
433         return false;
434     mp_image_steal_data(img, new);
435     assert(mp_image_is_writeable(img));
436     return true;
437 }
438 
439 // Helper function: unrefs *p_img, and sets *p_img to a new ref of new_value.
440 // Only unrefs *p_img and sets it to NULL if out of memory.
mp_image_setrefp(struct mp_image ** p_img,struct mp_image * new_value)441 void mp_image_setrefp(struct mp_image **p_img, struct mp_image *new_value)
442 {
443     if (*p_img != new_value) {
444         talloc_free(*p_img);
445         *p_img = new_value ? mp_image_new_ref(new_value) : NULL;
446     }
447 }
448 
449 // Mere helper function (mp_image can be directly free'd with talloc_free)
mp_image_unrefp(struct mp_image ** p_img)450 void mp_image_unrefp(struct mp_image **p_img)
451 {
452     talloc_free(*p_img);
453     *p_img = NULL;
454 }
455 
memcpy_pic(void * dst,const void * src,int bytesPerLine,int height,int dstStride,int srcStride)456 void memcpy_pic(void *dst, const void *src, int bytesPerLine, int height,
457                 int dstStride, int srcStride)
458 {
459     if (bytesPerLine == dstStride && dstStride == srcStride && height) {
460         if (srcStride < 0) {
461             src = (uint8_t*)src + (height - 1) * srcStride;
462             dst = (uint8_t*)dst + (height - 1) * dstStride;
463             srcStride = -srcStride;
464         }
465 
466         memcpy(dst, src, srcStride * (height - 1) + bytesPerLine);
467     } else {
468         for (int i = 0; i < height; i++) {
469             memcpy(dst, src, bytesPerLine);
470             src = (uint8_t*)src + srcStride;
471             dst = (uint8_t*)dst + dstStride;
472         }
473     }
474 }
475 
mp_image_copy(struct mp_image * dst,struct mp_image * src)476 void mp_image_copy(struct mp_image *dst, struct mp_image *src)
477 {
478     assert(dst->imgfmt == src->imgfmt);
479     assert(dst->w == src->w && dst->h == src->h);
480     assert(mp_image_is_writeable(dst));
481     for (int n = 0; n < dst->num_planes; n++) {
482         int line_bytes = (mp_image_plane_w(dst, n) * dst->fmt.bpp[n] + 7) / 8;
483         int plane_h = mp_image_plane_h(dst, n);
484         memcpy_pic(dst->planes[n], src->planes[n], line_bytes, plane_h,
485                    dst->stride[n], src->stride[n]);
486     }
487     if (dst->fmt.flags & MP_IMGFLAG_PAL)
488         memcpy(dst->planes[1], src->planes[1], AVPALETTE_SIZE);
489 }
490 
mp_image_params_get_forced_csp(struct mp_image_params * params)491 static enum mp_csp mp_image_params_get_forced_csp(struct mp_image_params *params)
492 {
493     int imgfmt = params->hw_subfmt ? params->hw_subfmt : params->imgfmt;
494     return mp_imgfmt_get_forced_csp(imgfmt);
495 }
496 
assign_bufref(AVBufferRef ** dst,AVBufferRef * new)497 static void assign_bufref(AVBufferRef **dst, AVBufferRef *new)
498 {
499     av_buffer_unref(dst);
500     if (new) {
501         *dst = av_buffer_ref(new);
502         MP_HANDLE_OOM(*dst);
503     }
504 }
505 
mp_image_copy_attributes(struct mp_image * dst,struct mp_image * src)506 void mp_image_copy_attributes(struct mp_image *dst, struct mp_image *src)
507 {
508     dst->pict_type = src->pict_type;
509     dst->fields = src->fields;
510     dst->pts = src->pts;
511     dst->dts = src->dts;
512     dst->pkt_duration = src->pkt_duration;
513     dst->params.rotate = src->params.rotate;
514     dst->params.stereo3d = src->params.stereo3d;
515     dst->params.p_w = src->params.p_w;
516     dst->params.p_h = src->params.p_h;
517     dst->params.color = src->params.color;
518     dst->params.chroma_location = src->params.chroma_location;
519     dst->params.alpha = src->params.alpha;
520     dst->nominal_fps = src->nominal_fps;
521     // ensure colorspace consistency
522     if (mp_image_params_get_forced_csp(&dst->params) !=
523         mp_image_params_get_forced_csp(&src->params))
524         dst->params.color = (struct mp_colorspace){0};
525     if ((dst->fmt.flags & MP_IMGFLAG_PAL) && (src->fmt.flags & MP_IMGFLAG_PAL)) {
526         if (dst->planes[1] && src->planes[1]) {
527             if (mp_image_make_writeable(dst))
528                 memcpy(dst->planes[1], src->planes[1], AVPALETTE_SIZE);
529         }
530     }
531     assign_bufref(&dst->icc_profile, src->icc_profile);
532     assign_bufref(&dst->a53_cc, src->a53_cc);
533 }
534 
535 // Crop the given image to (x0, y0)-(x1, y1) (bottom/right border exclusive)
536 // x0/y0 must be naturally aligned.
mp_image_crop(struct mp_image * img,int x0,int y0,int x1,int y1)537 void mp_image_crop(struct mp_image *img, int x0, int y0, int x1, int y1)
538 {
539     assert(x0 >= 0 && y0 >= 0);
540     assert(x0 <= x1 && y0 <= y1);
541     assert(x1 <= img->w && y1 <= img->h);
542     assert(!(x0 & (img->fmt.align_x - 1)));
543     assert(!(y0 & (img->fmt.align_y - 1)));
544 
545     for (int p = 0; p < img->num_planes; ++p) {
546         img->planes[p] += (y0 >> img->fmt.ys[p]) * img->stride[p] +
547                           (x0 >> img->fmt.xs[p]) * img->fmt.bpp[p] / 8;
548     }
549     mp_image_set_size(img, x1 - x0, y1 - y0);
550 }
551 
mp_image_crop_rc(struct mp_image * img,struct mp_rect rc)552 void mp_image_crop_rc(struct mp_image *img, struct mp_rect rc)
553 {
554     mp_image_crop(img, rc.x0, rc.y0, rc.x1, rc.y1);
555 }
556 
557 // Repeatedly write count patterns of src[0..src_size] to p.
memset_pattern(void * p,size_t count,uint8_t * src,size_t src_size)558 static void memset_pattern(void *p, size_t count, uint8_t *src, size_t src_size)
559 {
560     assert(src_size >= 1);
561 
562     if (src_size == 1) {
563         memset(p, src[0], count);
564     } else if (src_size == 2) { // >8 bit YUV => common, be slightly less naive
565         uint16_t val;
566         memcpy(&val, src, 2);
567         uint16_t *p16 = p;
568         while (count--)
569             *p16++ = val;
570     } else {
571         while (count--) {
572             memcpy(p, src, src_size);
573             p = (char *)p + src_size;
574         }
575     }
576 }
577 
endian_swap_bytes(void * d,size_t bytes,size_t word_size)578 static bool endian_swap_bytes(void *d, size_t bytes, size_t word_size)
579 {
580     if (word_size != 2 && word_size != 4)
581         return false;
582 
583     size_t num_words = bytes / word_size;
584     uint8_t *ud = d;
585 
586     switch (word_size) {
587     case 2:
588         for (size_t x = 0; x < num_words; x++)
589             AV_WL16(ud + x * 2, AV_RB16(ud + x * 2));
590         break;
591     case 4:
592         for (size_t x = 0; x < num_words; x++)
593             AV_WL32(ud + x * 2, AV_RB32(ud + x * 2));
594         break;
595     default:
596         assert(0);
597     }
598 
599     return true;
600 }
601 
602 // Bottom/right border is allowed not to be aligned, but it might implicitly
603 // overwrite pixel data until the alignment (align_x/align_y) is reached.
604 // Alpha is cleared to 0 (fully transparent).
mp_image_clear(struct mp_image * img,int x0,int y0,int x1,int y1)605 void mp_image_clear(struct mp_image *img, int x0, int y0, int x1, int y1)
606 {
607     assert(x0 >= 0 && y0 >= 0);
608     assert(x0 <= x1 && y0 <= y1);
609     assert(x1 <= img->w && y1 <= img->h);
610     assert(!(x0 & (img->fmt.align_x - 1)));
611     assert(!(y0 & (img->fmt.align_y - 1)));
612 
613     struct mp_image area = *img;
614     struct mp_imgfmt_desc *fmt = &area.fmt;
615     mp_image_crop(&area, x0, y0, x1, y1);
616 
617     // "Black" color for each plane.
618     uint8_t plane_clear[MP_MAX_PLANES][8] = {0};
619     int plane_size[MP_MAX_PLANES] = {0};
620     int misery = 1; // pixel group width
621 
622     // YUV integer chroma needs special consideration, and technically luma is
623     // usually not 0 either.
624     if ((fmt->flags & (MP_IMGFLAG_HAS_COMPS | MP_IMGFLAG_PACKED_SS_YUV)) &&
625         (fmt->flags & MP_IMGFLAG_TYPE_MASK) == MP_IMGFLAG_TYPE_UINT &&
626         (fmt->flags & MP_IMGFLAG_COLOR_MASK) == MP_IMGFLAG_COLOR_YUV)
627     {
628         uint64_t plane_clear_i[MP_MAX_PLANES] = {0};
629 
630         // Need to handle "multiple" pixels with packed YUV.
631         uint8_t luma_offsets[4] = {0};
632         if (fmt->flags & MP_IMGFLAG_PACKED_SS_YUV) {
633             misery = fmt->align_x;
634             if (misery <= MP_ARRAY_SIZE(luma_offsets)) // ignore if out of bounds
635                 mp_imgfmt_get_packed_yuv_locations(fmt->id, luma_offsets);
636         }
637 
638         for (int c = 0; c < 4; c++) {
639             struct mp_imgfmt_comp_desc *cd = &fmt->comps[c];
640             int plane_bits = fmt->bpp[cd->plane] * misery;
641             if (plane_bits <= 64 && plane_bits % 8u == 0 && cd->size) {
642                 plane_size[cd->plane] = plane_bits / 8u;
643                 int depth = cd->size + MPMIN(cd->pad, 0);
644                 double m, o;
645                 mp_get_csp_uint_mul(area.params.color.space,
646                                     area.params.color.levels,
647                                     depth, c + 1, &m, &o);
648                 uint64_t val = MPCLAMP(lrint((0 - o) / m), 0, 1ull << depth);
649                 plane_clear_i[cd->plane] |= val << cd->offset;
650                 for (int x = 1; x < (c ? 0 : misery); x++)
651                     plane_clear_i[cd->plane] |= val << luma_offsets[x];
652             }
653         }
654 
655         for (int p = 0; p < MP_MAX_PLANES; p++) {
656             if (!plane_clear_i[p])
657                 plane_size[p] = 0;
658             memcpy(&plane_clear[p][0], &plane_clear_i[p], 8); // endian dependent
659 
660             if (fmt->endian_shift) {
661                 endian_swap_bytes(&plane_clear[p][0], plane_size[p],
662                                   1 << fmt->endian_shift);
663             }
664         }
665     }
666 
667     for (int p = 0; p < area.num_planes; p++) {
668         int p_h = mp_image_plane_h(&area, p);
669         int p_w = mp_image_plane_w(&area, p);
670         for (int y = 0; y < p_h; y++) {
671             void *ptr = area.planes[p] + (ptrdiff_t)area.stride[p] * y;
672             if (plane_size[p] && plane_clear[p]) {
673                 memset_pattern(ptr, p_w / misery, plane_clear[p], plane_size[p]);
674             } else {
675                 memset(ptr, 0, mp_image_plane_bytes(&area, p, 0, area.w));
676             }
677         }
678     }
679 }
680 
mp_image_clear_rc(struct mp_image * mpi,struct mp_rect rc)681 void mp_image_clear_rc(struct mp_image *mpi, struct mp_rect rc)
682 {
683     mp_image_clear(mpi, rc.x0, rc.y0, rc.x1, rc.y1);
684 }
685 
686 // Clear the are of the image _not_ covered by rc.
mp_image_clear_rc_inv(struct mp_image * mpi,struct mp_rect rc)687 void mp_image_clear_rc_inv(struct mp_image *mpi, struct mp_rect rc)
688 {
689     struct mp_rect clr[4];
690     int cnt = mp_rect_subtract(&(struct mp_rect){0, 0, mpi->w, mpi->h}, &rc, clr);
691     for (int n = 0; n < cnt; n++)
692         mp_image_clear_rc(mpi, clr[n]);
693 }
694 
mp_image_vflip(struct mp_image * img)695 void mp_image_vflip(struct mp_image *img)
696 {
697     for (int p = 0; p < img->num_planes; p++) {
698         int plane_h = mp_image_plane_h(img, p);
699         img->planes[p] = img->planes[p] + img->stride[p] * (plane_h - 1);
700         img->stride[p] = -img->stride[p];
701     }
702 }
703 
704 // Display size derived from image size and pixel aspect ratio.
mp_image_params_get_dsize(const struct mp_image_params * p,int * d_w,int * d_h)705 void mp_image_params_get_dsize(const struct mp_image_params *p,
706                                int *d_w, int *d_h)
707 {
708     *d_w = p->w;
709     *d_h = p->h;
710     if (p->p_w > p->p_h && p->p_h >= 1)
711         *d_w = MPCLAMP(*d_w * (int64_t)p->p_w / p->p_h, 1, INT_MAX);
712     if (p->p_h > p->p_w && p->p_w >= 1)
713         *d_h = MPCLAMP(*d_h * (int64_t)p->p_h / p->p_w, 1, INT_MAX);
714 }
715 
mp_image_params_set_dsize(struct mp_image_params * p,int d_w,int d_h)716 void mp_image_params_set_dsize(struct mp_image_params *p, int d_w, int d_h)
717 {
718     AVRational ds = av_div_q((AVRational){d_w, d_h}, (AVRational){p->w, p->h});
719     p->p_w = ds.num;
720     p->p_h = ds.den;
721 }
722 
mp_image_params_to_str_buf(char * b,size_t bs,const struct mp_image_params * p)723 char *mp_image_params_to_str_buf(char *b, size_t bs,
724                                  const struct mp_image_params *p)
725 {
726     if (p && p->imgfmt) {
727         snprintf(b, bs, "%dx%d", p->w, p->h);
728         if (p->p_w != p->p_h || !p->p_w)
729             mp_snprintf_cat(b, bs, " [%d:%d]", p->p_w, p->p_h);
730         mp_snprintf_cat(b, bs, " %s", mp_imgfmt_to_name(p->imgfmt));
731         if (p->hw_subfmt)
732             mp_snprintf_cat(b, bs, "[%s]", mp_imgfmt_to_name(p->hw_subfmt));
733         mp_snprintf_cat(b, bs, " %s/%s/%s/%s/%s",
734                         m_opt_choice_str(mp_csp_names, p->color.space),
735                         m_opt_choice_str(mp_csp_prim_names, p->color.primaries),
736                         m_opt_choice_str(mp_csp_trc_names, p->color.gamma),
737                         m_opt_choice_str(mp_csp_levels_names, p->color.levels),
738                         m_opt_choice_str(mp_csp_light_names, p->color.light));
739         if (p->color.sig_peak)
740             mp_snprintf_cat(b, bs, " SP=%f", p->color.sig_peak);
741         mp_snprintf_cat(b, bs, " CL=%s",
742                         m_opt_choice_str(mp_chroma_names, p->chroma_location));
743         if (p->rotate)
744             mp_snprintf_cat(b, bs, " rot=%d", p->rotate);
745         if (p->stereo3d > 0) {
746             mp_snprintf_cat(b, bs, " stereo=%s",
747                             MP_STEREO3D_NAME_DEF(p->stereo3d, "?"));
748         }
749         if (p->alpha) {
750             mp_snprintf_cat(b, bs, " A=%s",
751                             m_opt_choice_str(mp_alpha_names, p->alpha));
752         }
753     } else {
754         snprintf(b, bs, "???");
755     }
756     return b;
757 }
758 
759 // Return whether the image parameters are valid.
760 // Some non-essential fields are allowed to be unset (like colorspace flags).
mp_image_params_valid(const struct mp_image_params * p)761 bool mp_image_params_valid(const struct mp_image_params *p)
762 {
763     // av_image_check_size has similar checks and triggers around 16000*16000
764     // It's mostly needed to deal with the fact that offsets are sometimes
765     // ints. We also should (for now) do the same as FFmpeg, to be sure large
766     // images don't crash with libswscale or when wrapping with AVFrame and
767     // passing the result to filters.
768     if (p->w <= 0 || p->h <= 0 || (p->w + 128LL) * (p->h + 128LL) >= INT_MAX / 8)
769         return false;
770 
771     if (p->p_w < 0 || p->p_h < 0)
772         return false;
773 
774     if (p->rotate < 0 || p->rotate >= 360)
775         return false;
776 
777     struct mp_imgfmt_desc desc = mp_imgfmt_get_desc(p->imgfmt);
778     if (!desc.id)
779         return false;
780 
781     if (p->hw_subfmt && !(desc.flags & MP_IMGFLAG_HWACCEL))
782         return false;
783 
784     return true;
785 }
786 
mp_image_params_equal(const struct mp_image_params * p1,const struct mp_image_params * p2)787 bool mp_image_params_equal(const struct mp_image_params *p1,
788                            const struct mp_image_params *p2)
789 {
790     return p1->imgfmt == p2->imgfmt &&
791            p1->hw_subfmt == p2->hw_subfmt &&
792            p1->w == p2->w && p1->h == p2->h &&
793            p1->p_w == p2->p_w && p1->p_h == p2->p_h &&
794            mp_colorspace_equal(p1->color, p2->color) &&
795            p1->chroma_location == p2->chroma_location &&
796            p1->rotate == p2->rotate &&
797            p1->stereo3d == p2->stereo3d &&
798            p1->alpha == p2->alpha;
799 }
800 
801 // Set most image parameters, but not image format or size.
802 // Display size is used to set the PAR.
mp_image_set_attributes(struct mp_image * image,const struct mp_image_params * params)803 void mp_image_set_attributes(struct mp_image *image,
804                              const struct mp_image_params *params)
805 {
806     struct mp_image_params nparams = *params;
807     nparams.imgfmt = image->imgfmt;
808     nparams.w = image->w;
809     nparams.h = image->h;
810     if (nparams.imgfmt != params->imgfmt)
811         nparams.color = (struct mp_colorspace){0};
812     mp_image_set_params(image, &nparams);
813 }
814 
815 // If details like params->colorspace/colorlevels are missing, guess them from
816 // the other settings. Also, even if they are set, make them consistent with
817 // the colorspace as implied by the pixel format.
mp_image_params_guess_csp(struct mp_image_params * params)818 void mp_image_params_guess_csp(struct mp_image_params *params)
819 {
820     enum mp_csp forced_csp = mp_image_params_get_forced_csp(params);
821     if (forced_csp == MP_CSP_AUTO) { // YUV/other
822         if (params->color.space != MP_CSP_BT_601 &&
823             params->color.space != MP_CSP_BT_709 &&
824             params->color.space != MP_CSP_BT_2020_NC &&
825             params->color.space != MP_CSP_BT_2020_C &&
826             params->color.space != MP_CSP_SMPTE_240M &&
827             params->color.space != MP_CSP_YCGCO)
828         {
829             // Makes no sense, so guess instead
830             // YCGCO should be separate, but libavcodec disagrees
831             params->color.space = MP_CSP_AUTO;
832         }
833         if (params->color.space == MP_CSP_AUTO)
834             params->color.space = mp_csp_guess_colorspace(params->w, params->h);
835         if (params->color.levels == MP_CSP_LEVELS_AUTO) {
836             if (params->color.gamma == MP_CSP_TRC_V_LOG) {
837                 params->color.levels = MP_CSP_LEVELS_PC;
838             } else {
839                 params->color.levels = MP_CSP_LEVELS_TV;
840             }
841         }
842         if (params->color.primaries == MP_CSP_PRIM_AUTO) {
843             // Guess based on the colormatrix as a first priority
844             if (params->color.space == MP_CSP_BT_2020_NC ||
845                 params->color.space == MP_CSP_BT_2020_C) {
846                 params->color.primaries = MP_CSP_PRIM_BT_2020;
847             } else if (params->color.space == MP_CSP_BT_709) {
848                 params->color.primaries = MP_CSP_PRIM_BT_709;
849             } else {
850                 // Ambiguous colormatrix for BT.601, guess based on res
851                 params->color.primaries = mp_csp_guess_primaries(params->w, params->h);
852             }
853         }
854         if (params->color.gamma == MP_CSP_TRC_AUTO)
855             params->color.gamma = MP_CSP_TRC_BT_1886;
856     } else if (forced_csp == MP_CSP_RGB) {
857         params->color.space = MP_CSP_RGB;
858         params->color.levels = MP_CSP_LEVELS_PC;
859 
860         // The majority of RGB content is either sRGB or (rarely) some other
861         // color space which we don't even handle, like AdobeRGB or
862         // ProPhotoRGB. The only reasonable thing we can do is assume it's
863         // sRGB and hope for the best, which should usually just work out fine.
864         // Note: sRGB primaries = BT.709 primaries
865         if (params->color.primaries == MP_CSP_PRIM_AUTO)
866             params->color.primaries = MP_CSP_PRIM_BT_709;
867         if (params->color.gamma == MP_CSP_TRC_AUTO)
868             params->color.gamma = MP_CSP_TRC_SRGB;
869     } else if (forced_csp == MP_CSP_XYZ) {
870         params->color.space = MP_CSP_XYZ;
871         params->color.levels = MP_CSP_LEVELS_PC;
872 
873         // In theory, XYZ data does not really need a concept of 'primaries' to
874         // function, but this field can still be relevant for guiding gamut
875         // mapping optimizations, and it's also used by `mp_get_csp_matrix`
876         // when deciding what RGB space to map XYZ to for VOs that don't want
877         // to directly ingest XYZ into their color pipeline. BT.709 would be a
878         // sane default here, but it runs the risk of clipping any wide gamut
879         // content, so we pick BT.2020 instead to be on the safer side.
880         if (params->color.primaries == MP_CSP_PRIM_AUTO)
881             params->color.primaries = MP_CSP_PRIM_BT_2020;
882         if (params->color.gamma == MP_CSP_TRC_AUTO)
883             params->color.gamma = MP_CSP_TRC_LINEAR;
884     } else {
885         // We have no clue.
886         params->color.space = MP_CSP_AUTO;
887         params->color.levels = MP_CSP_LEVELS_AUTO;
888         params->color.primaries = MP_CSP_PRIM_AUTO;
889         params->color.gamma = MP_CSP_TRC_AUTO;
890     }
891 
892     if (!params->color.sig_peak) {
893         if (params->color.gamma == MP_CSP_TRC_HLG) {
894             params->color.sig_peak = 1000 / MP_REF_WHITE; // reference display
895         } else {
896             // If the signal peak is unknown, we're forced to pick the TRC's
897             // nominal range as the signal peak to prevent clipping
898             params->color.sig_peak = mp_trc_nom_peak(params->color.gamma);
899         }
900     }
901 
902     if (!mp_trc_is_hdr(params->color.gamma)) {
903         // Some clips have leftover HDR metadata after conversion to SDR, so to
904         // avoid blowing up the tone mapping code, strip/sanitize it
905         params->color.sig_peak = 1.0;
906     }
907 
908     if (params->chroma_location == MP_CHROMA_AUTO) {
909         if (params->color.levels == MP_CSP_LEVELS_TV)
910             params->chroma_location = MP_CHROMA_LEFT;
911         if (params->color.levels == MP_CSP_LEVELS_PC)
912             params->chroma_location = MP_CHROMA_CENTER;
913     }
914 
915     if (params->color.light == MP_CSP_LIGHT_AUTO) {
916         // HLG is always scene-referred (using its own OOTF), everything else
917         // we assume is display-refered by default.
918         if (params->color.gamma == MP_CSP_TRC_HLG) {
919             params->color.light = MP_CSP_LIGHT_SCENE_HLG;
920         } else {
921             params->color.light = MP_CSP_LIGHT_DISPLAY;
922         }
923     }
924 }
925 
926 // Create a new mp_image reference to av_frame.
mp_image_from_av_frame(struct AVFrame * src)927 struct mp_image *mp_image_from_av_frame(struct AVFrame *src)
928 {
929     struct mp_image *dst = &(struct mp_image){0};
930     AVFrameSideData *sd;
931 
932     for (int p = 0; p < MP_MAX_PLANES; p++)
933         dst->bufs[p] = src->buf[p];
934 
935     dst->hwctx = src->hw_frames_ctx;
936 
937     mp_image_setfmt(dst, pixfmt2imgfmt(src->format));
938     mp_image_set_size(dst, src->width, src->height);
939 
940     dst->params.p_w = src->sample_aspect_ratio.num;
941     dst->params.p_h = src->sample_aspect_ratio.den;
942 
943     for (int i = 0; i < 4; i++) {
944         dst->planes[i] = src->data[i];
945         dst->stride[i] = src->linesize[i];
946     }
947 
948     dst->pict_type = src->pict_type;
949 
950     dst->fields = 0;
951     if (src->interlaced_frame)
952         dst->fields |= MP_IMGFIELD_INTERLACED;
953     if (src->top_field_first)
954         dst->fields |= MP_IMGFIELD_TOP_FIRST;
955     if (src->repeat_pict == 1)
956         dst->fields |= MP_IMGFIELD_REPEAT_FIRST;
957 
958     dst->params.color = (struct mp_colorspace){
959         .space = avcol_spc_to_mp_csp(src->colorspace),
960         .levels = avcol_range_to_mp_csp_levels(src->color_range),
961         .primaries = avcol_pri_to_mp_csp_prim(src->color_primaries),
962         .gamma = avcol_trc_to_mp_csp_trc(src->color_trc),
963     };
964 
965     dst->params.chroma_location = avchroma_location_to_mp(src->chroma_location);
966 
967     if (src->opaque_ref) {
968         struct mp_image_params *p = (void *)src->opaque_ref->data;
969         dst->params.rotate = p->rotate;
970         dst->params.stereo3d = p->stereo3d;
971         // Might be incorrect if colorspace changes.
972         dst->params.color.light = p->color.light;
973         dst->params.alpha = p->alpha;
974     }
975 
976     sd = av_frame_get_side_data(src, AV_FRAME_DATA_ICC_PROFILE);
977     if (sd)
978         dst->icc_profile = sd->buf;
979 
980     // Get the content light metadata if available
981     sd = av_frame_get_side_data(src, AV_FRAME_DATA_CONTENT_LIGHT_LEVEL);
982     if (sd) {
983         AVContentLightMetadata *clm = (AVContentLightMetadata *)sd->data;
984         dst->params.color.sig_peak = clm->MaxCLL / MP_REF_WHITE;
985     }
986 
987     // Otherwise, try getting the mastering metadata if available
988     sd = av_frame_get_side_data(src, AV_FRAME_DATA_MASTERING_DISPLAY_METADATA);
989     if (!dst->params.color.sig_peak && sd) {
990         AVMasteringDisplayMetadata *mdm = (AVMasteringDisplayMetadata *)sd->data;
991         if (mdm->has_luminance)
992             dst->params.color.sig_peak = av_q2d(mdm->max_luminance) / MP_REF_WHITE;
993     }
994 
995     sd = av_frame_get_side_data(src, AV_FRAME_DATA_A53_CC);
996     if (sd)
997         dst->a53_cc = sd->buf;
998 
999     for (int n = 0; n < src->nb_side_data; n++) {
1000         sd = src->side_data[n];
1001         struct mp_ff_side_data mpsd = {
1002             .type = sd->type,
1003             .buf = sd->buf,
1004         };
1005         MP_TARRAY_APPEND(NULL, dst->ff_side_data, dst->num_ff_side_data, mpsd);
1006     }
1007 
1008     if (dst->hwctx) {
1009         AVHWFramesContext *fctx = (void *)dst->hwctx->data;
1010         dst->params.hw_subfmt = pixfmt2imgfmt(fctx->sw_format);
1011     }
1012 
1013     struct mp_image *res = mp_image_new_ref(dst);
1014 
1015     // Allocated, but non-refcounted data.
1016     talloc_free(dst->ff_side_data);
1017 
1018     return res;
1019 }
1020 
1021 
1022 // Convert the mp_image reference to a AVFrame reference.
mp_image_to_av_frame(struct mp_image * src)1023 struct AVFrame *mp_image_to_av_frame(struct mp_image *src)
1024 {
1025     struct mp_image *new_ref = mp_image_new_ref(src);
1026     AVFrame *dst = av_frame_alloc();
1027     if (!dst || !new_ref) {
1028         talloc_free(new_ref);
1029         av_frame_free(&dst);
1030         return NULL;
1031     }
1032 
1033     for (int p = 0; p < MP_MAX_PLANES; p++) {
1034         dst->buf[p] = new_ref->bufs[p];
1035         new_ref->bufs[p] = NULL;
1036     }
1037 
1038     dst->hw_frames_ctx = new_ref->hwctx;
1039     new_ref->hwctx = NULL;
1040 
1041     dst->format = imgfmt2pixfmt(src->imgfmt);
1042     dst->width = src->w;
1043     dst->height = src->h;
1044 
1045     dst->sample_aspect_ratio.num = src->params.p_w;
1046     dst->sample_aspect_ratio.den = src->params.p_h;
1047 
1048     for (int i = 0; i < 4; i++) {
1049         dst->data[i] = src->planes[i];
1050         dst->linesize[i] = src->stride[i];
1051     }
1052     dst->extended_data = dst->data;
1053 
1054     dst->pict_type = src->pict_type;
1055     if (src->fields & MP_IMGFIELD_INTERLACED)
1056         dst->interlaced_frame = 1;
1057     if (src->fields & MP_IMGFIELD_TOP_FIRST)
1058         dst->top_field_first = 1;
1059     if (src->fields & MP_IMGFIELD_REPEAT_FIRST)
1060         dst->repeat_pict = 1;
1061 
1062     dst->colorspace = mp_csp_to_avcol_spc(src->params.color.space);
1063     dst->color_range = mp_csp_levels_to_avcol_range(src->params.color.levels);
1064     dst->color_primaries =
1065         mp_csp_prim_to_avcol_pri(src->params.color.primaries);
1066     dst->color_trc = mp_csp_trc_to_avcol_trc(src->params.color.gamma);
1067 
1068     dst->chroma_location = mp_chroma_location_to_av(src->params.chroma_location);
1069 
1070     dst->opaque_ref = av_buffer_alloc(sizeof(struct mp_image_params));
1071     if (!dst->opaque_ref)
1072         abort();
1073     *(struct mp_image_params *)dst->opaque_ref->data = src->params;
1074 
1075     if (src->icc_profile) {
1076         AVFrameSideData *sd =
1077             av_frame_new_side_data_from_buf(dst, AV_FRAME_DATA_ICC_PROFILE,
1078                                             new_ref->icc_profile);
1079         if (!sd)
1080             abort();
1081         new_ref->icc_profile = NULL;
1082     }
1083 
1084     if (src->params.color.sig_peak) {
1085         AVContentLightMetadata *clm =
1086             av_content_light_metadata_create_side_data(dst);
1087         if (!clm)
1088             abort();
1089         clm->MaxCLL = src->params.color.sig_peak * MP_REF_WHITE;
1090     }
1091 
1092     // Add back side data, but only for types which are not specially handled
1093     // above. Keep in mind that the types above will be out of sync anyway.
1094     for (int n = 0; n < new_ref->num_ff_side_data; n++) {
1095         struct mp_ff_side_data *mpsd = &new_ref->ff_side_data[n];
1096         if (!av_frame_get_side_data(dst, mpsd->type)) {
1097             AVFrameSideData *sd = av_frame_new_side_data_from_buf(dst, mpsd->type,
1098                                                                   mpsd->buf);
1099             if (!sd)
1100                 abort();
1101             mpsd->buf = NULL;
1102         }
1103     }
1104 
1105     talloc_free(new_ref);
1106 
1107     if (dst->format == AV_PIX_FMT_NONE)
1108         av_frame_free(&dst);
1109     return dst;
1110 }
1111 
1112 // Same as mp_image_to_av_frame(), but unref img. (It does so even on failure.)
mp_image_to_av_frame_and_unref(struct mp_image * img)1113 struct AVFrame *mp_image_to_av_frame_and_unref(struct mp_image *img)
1114 {
1115     AVFrame *frame = mp_image_to_av_frame(img);
1116     talloc_free(img);
1117     return frame;
1118 }
1119 
memset_pic(void * dst,int fill,int bytesPerLine,int height,int stride)1120 void memset_pic(void *dst, int fill, int bytesPerLine, int height, int stride)
1121 {
1122     if (bytesPerLine == stride && height) {
1123         memset(dst, fill, stride * (height - 1) + bytesPerLine);
1124     } else {
1125         for (int i = 0; i < height; i++) {
1126             memset(dst, fill, bytesPerLine);
1127             dst = (uint8_t *)dst + stride;
1128         }
1129     }
1130 }
1131 
memset16_pic(void * dst,int fill,int unitsPerLine,int height,int stride)1132 void memset16_pic(void *dst, int fill, int unitsPerLine, int height, int stride)
1133 {
1134     if (fill == 0) {
1135         memset_pic(dst, 0, unitsPerLine * 2, height, stride);
1136     } else {
1137         for (int i = 0; i < height; i++) {
1138             uint16_t *line = dst;
1139             uint16_t *end = line + unitsPerLine;
1140             while (line < end)
1141                 *line++ = fill;
1142             dst = (uint8_t *)dst + stride;
1143         }
1144     }
1145 }
1146 
1147 // Pixel at the given luma position on the given plane. x/y always refer to
1148 // non-subsampled coordinates (even if plane is chroma).
1149 // The coordinates must be aligned to mp_imgfmt_desc.align_x/y (these are byte
1150 // and chroma boundaries).
1151 // You cannot access e.g. individual luma pixels on the luma plane with yuv420p.
mp_image_pixel_ptr(struct mp_image * img,int plane,int x,int y)1152 void *mp_image_pixel_ptr(struct mp_image *img, int plane, int x, int y)
1153 {
1154     assert(MP_IS_ALIGNED(x, img->fmt.align_x));
1155     assert(MP_IS_ALIGNED(y, img->fmt.align_y));
1156     return mp_image_pixel_ptr_ny(img, plane, x, y);
1157 }
1158 
1159 // Like mp_image_pixel_ptr(), but do not require alignment on Y coordinates if
1160 // the plane does not require it. Use with care.
1161 // Useful for addressing luma rows.
mp_image_pixel_ptr_ny(struct mp_image * img,int plane,int x,int y)1162 void *mp_image_pixel_ptr_ny(struct mp_image *img, int plane, int x, int y)
1163 {
1164     assert(MP_IS_ALIGNED(x, img->fmt.align_x));
1165     assert(MP_IS_ALIGNED(y, 1 << img->fmt.ys[plane]));
1166     return img->planes[plane] +
1167            img->stride[plane] * (ptrdiff_t)(y >> img->fmt.ys[plane]) +
1168            (x >> img->fmt.xs[plane]) * (size_t)img->fmt.bpp[plane] / 8;
1169 }
1170 
1171 // Return size of pixels [x0, x0+w-1] in bytes. The coordinates refer to non-
1172 // subsampled pixels (basically plane 0), and the size is rounded to chroma
1173 // and byte alignment boundaries for the entire image, even if plane!=0.
1174 // x0!=0 is useful for rounding (e.g. 8 bpp, x0=7, w=7 => 0..15 => 2 bytes).
mp_image_plane_bytes(struct mp_image * img,int plane,int x0,int w)1175 size_t mp_image_plane_bytes(struct mp_image *img, int plane, int x0, int w)
1176 {
1177     int x1 = MP_ALIGN_UP(x0 + w, img->fmt.align_x);
1178     x0 = MP_ALIGN_DOWN(x0, img->fmt.align_x);
1179     size_t bpp = img->fmt.bpp[plane];
1180     int xs = img->fmt.xs[plane];
1181     return (x1 >> xs) * bpp / 8 - (x0 >> xs) * bpp / 8;
1182 }
1183