| 73 | #define ALIGN (HAVE_SIMD_ALIGN_64 ? 64 : 32) |
| 74 | |
| 75 | static int get_video_buffer(AVFrame *frame, int align) |
| 76 | { |
| 77 | const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(frame->format); |
| 78 | int ret, padded_height; |
| 79 | int plane_padding; |
| 80 | ptrdiff_t linesizes[4]; |
| 81 | size_t total_size, sizes[4]; |
| 82 | |
| 83 | if (!desc) |
| 84 | return AVERROR(EINVAL); |
| 85 | |
| 86 | if ((ret = av_image_check_size(frame->width, frame->height, 0, NULL)) < 0) |
| 87 | return ret; |
| 88 | |
| 89 | if (align <= 0) |
| 90 | align = ALIGN; |
| 91 | plane_padding = FFMAX(ALIGN, align); |
| 92 | |
| 93 | if (!frame->linesize[0]) { |
| 94 | for (int i = 1; i <= align; i += i) { |
| 95 | ret = av_image_fill_linesizes(frame->linesize, frame->format, |
| 96 | FFALIGN(frame->width, i)); |
| 97 | if (ret < 0) |
| 98 | return ret; |
| 99 | if (!(frame->linesize[0] & (align-1))) |
| 100 | break; |
| 101 | } |
| 102 | |
| 103 | for (int i = 0; i < 4 && frame->linesize[i]; i++) |
| 104 | frame->linesize[i] = FFALIGN(frame->linesize[i], align); |
| 105 | } |
| 106 | |
| 107 | for (int i = 0; i < 4; i++) |
| 108 | linesizes[i] = frame->linesize[i]; |
| 109 | |
| 110 | padded_height = FFALIGN(frame->height, 32); |
| 111 | if ((ret = av_image_fill_plane_sizes(sizes, frame->format, |
| 112 | padded_height, linesizes)) < 0) |
| 113 | return ret; |
| 114 | |
| 115 | total_size = 4 * plane_padding + 4 * align; |
| 116 | for (int i = 0; i < 4; i++) { |
| 117 | if (sizes[i] > SIZE_MAX - total_size) |
| 118 | return AVERROR(EINVAL); |
| 119 | total_size += sizes[i]; |
| 120 | } |
| 121 | |
| 122 | frame->buf[0] = av_buffer_alloc(total_size); |
| 123 | if (!frame->buf[0]) { |
| 124 | ret = AVERROR(ENOMEM); |
| 125 | goto fail; |
| 126 | } |
| 127 | |
| 128 | if ((ret = av_image_fill_pointers(frame->data, frame->format, padded_height, |
| 129 | frame->buf[0]->data, frame->linesize)) < 0) |
| 130 | goto fail; |
| 131 | |
| 132 | for (int i = 1; i < 4; i++) { |
no test coverage detected