| 63 | } |
| 64 | |
| 65 | static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) |
| 66 | { |
| 67 | FramePool *pool = avctx->internal->pool; |
| 68 | int i, ret; |
| 69 | |
| 70 | if (pool && pool->format == frame->format) { |
| 71 | if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && |
| 72 | pool->width == frame->width && pool->height == frame->height) |
| 73 | return 0; |
| 74 | if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && |
| 75 | pool->channels == frame->ch_layout.nb_channels && |
| 76 | frame->nb_samples == pool->samples) |
| 77 | return 0; |
| 78 | } |
| 79 | |
| 80 | pool = av_refstruct_alloc_ext(sizeof(*pool), 0, NULL, frame_pool_free); |
| 81 | if (!pool) |
| 82 | return AVERROR(ENOMEM); |
| 83 | |
| 84 | switch (avctx->codec_type) { |
| 85 | case AVMEDIA_TYPE_VIDEO: { |
| 86 | int linesize[4]; |
| 87 | int w = frame->width; |
| 88 | int h = frame->height; |
| 89 | int unaligned; |
| 90 | ptrdiff_t linesize1[4]; |
| 91 | size_t size[4]; |
| 92 | |
| 93 | avcodec_align_dimensions2(avctx, &w, &h, pool->stride_align); |
| 94 | |
| 95 | do { |
| 96 | // NOTE: do not align linesizes individually, this breaks e.g. assumptions |
| 97 | // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2 |
| 98 | ret = av_image_fill_linesizes(linesize, avctx->pix_fmt, w); |
| 99 | if (ret < 0) |
| 100 | goto fail; |
| 101 | // increase alignment of w for next try (rhs gives the lowest bit set in w) |
| 102 | w += w & ~(w - 1); |
| 103 | |
| 104 | unaligned = 0; |
| 105 | for (i = 0; i < 4; i++) |
| 106 | unaligned |= linesize[i] % pool->stride_align[i]; |
| 107 | } while (unaligned); |
| 108 | |
| 109 | for (i = 0; i < 4; i++) |
| 110 | linesize1[i] = linesize[i]; |
| 111 | ret = av_image_fill_plane_sizes(size, avctx->pix_fmt, h, linesize1); |
| 112 | if (ret < 0) |
| 113 | goto fail; |
| 114 | |
| 115 | for (i = 0; i < 4; i++) { |
| 116 | pool->linesize[i] = linesize[i]; |
| 117 | if (size[i]) { |
| 118 | if (size[i] > INT_MAX - (16 + STRIDE_ALIGN - 1)) { |
| 119 | ret = AVERROR(EINVAL); |
| 120 | goto fail; |
| 121 | } |
| 122 | pool->pools[i] = av_buffer_pool_init(size[i] + 16 + STRIDE_ALIGN - 1, |
no test coverage detected