get_buffer.c (9530B)
1 /* 2 * The default get_buffer2() implementation 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * FFmpeg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with FFmpeg; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21 #include <stdint.h> 22 23 #include "libavutil/avassert.h" 24 #include "libavutil/avutil.h" 25 #include "libavutil/buffer.h" 26 #include "libavutil/frame.h" 27 #include "libavutil/hwcontext.h" 28 #include "libavutil/imgutils.h" 29 #include "libavutil/mem.h" 30 #include "libavutil/samplefmt.h" 31 #include "libavutil/version.h" 32 33 #include "avcodec.h" 34 #include "internal.h" 35 #include "libavutil/refstruct.h" 36 37 typedef struct FramePool { 38 /** 39 * Pools for each data plane. For audio all the planes have the same size, 40 * so only pools[0] is used. 41 */ 42 AVBufferPool *pools[4]; 43 44 /* 45 * Pool parameters 46 */ 47 int format; 48 int width, height; 49 int stride_align[AV_NUM_DATA_POINTERS]; 50 int linesize[4]; 51 int planes; 52 int channels; 53 int samples; 54 } FramePool; 55 56 static void frame_pool_free(AVRefStructOpaque unused, void *obj) 57 { 58 FramePool *pool = obj; 59 int i; 60 61 for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) 62 av_buffer_pool_uninit(&pool->pools[i]); 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, 123 CONFIG_MEMORY_POISONING ? 124 NULL : 125 av_buffer_allocz); 126 if (!pool->pools[i]) { 127 ret = AVERROR(ENOMEM); 128 goto fail; 129 } 130 } 131 } 132 pool->format = frame->format; 133 pool->width = frame->width; 134 pool->height = frame->height; 135 136 break; 137 } 138 case AVMEDIA_TYPE_AUDIO: { 139 ret = av_samples_get_buffer_size(&pool->linesize[0], 140 frame->ch_layout.nb_channels, 141 frame->nb_samples, frame->format, 0); 142 if (ret < 0) 143 goto fail; 144 145 pool->pools[0] = av_buffer_pool_init(pool->linesize[0], 146 CONFIG_MEMORY_POISONING ? 147 NULL : 148 av_buffer_allocz); 149 if (!pool->pools[0]) { 150 ret = AVERROR(ENOMEM); 151 goto fail; 152 } 153 154 pool->format = frame->format; 155 pool->channels = frame->ch_layout.nb_channels; 156 pool->samples = frame->nb_samples; 157 pool->planes = av_sample_fmt_is_planar(pool->format) ? pool->channels : 1; 158 break; 159 } 160 default: av_assert0(0); 161 } 162 163 av_refstruct_unref(&avctx->internal->pool); 164 avctx->internal->pool = pool; 165 166 return 0; 167 fail: 168 av_refstruct_unref(&pool); 169 return ret; 170 } 171 172 static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) 173 { 174 FramePool *pool = avctx->internal->pool; 175 int planes = pool->planes; 176 int i; 177 178 frame->linesize[0] = pool->linesize[0]; 179 180 if (planes > AV_NUM_DATA_POINTERS) { 181 frame->extended_data = av_calloc(planes, sizeof(*frame->extended_data)); 182 frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS; 183 frame->extended_buf = av_calloc(frame->nb_extended_buf, 184 sizeof(*frame->extended_buf)); 185 if (!frame->extended_data || !frame->extended_buf) { 186 av_freep(&frame->extended_data); 187 av_freep(&frame->extended_buf); 188 return AVERROR(ENOMEM); 189 } 190 } else { 191 frame->extended_data = frame->data; 192 av_assert0(frame->nb_extended_buf == 0); 193 } 194 195 for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) { 196 frame->buf[i] = av_buffer_pool_get(pool->pools[0]); 197 if (!frame->buf[i]) 198 goto fail; 199 frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; 200 } 201 for (i = 0; i < frame->nb_extended_buf; i++) { 202 frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]); 203 if (!frame->extended_buf[i]) 204 goto fail; 205 frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data; 206 } 207 208 if (avctx->debug & FF_DEBUG_BUFFERS) 209 av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p", frame); 210 211 return 0; 212 fail: 213 av_frame_unref(frame); 214 return AVERROR(ENOMEM); 215 } 216 217 static int video_get_buffer(AVCodecContext *s, AVFrame *pic) 218 { 219 FramePool *pool = s->internal->pool; 220 int i; 221 222 if (pic->data[0] || pic->data[1] || pic->data[2] || pic->data[3]) { 223 av_log(s, AV_LOG_ERROR, "pic->data[*]!=NULL in avcodec_default_get_buffer\n"); 224 return -1; 225 } 226 227 memset(pic->data, 0, sizeof(pic->data)); 228 pic->extended_data = pic->data; 229 230 for (i = 0; i < 4 && pool->pools[i]; i++) { 231 pic->linesize[i] = pool->linesize[i]; 232 233 pic->buf[i] = av_buffer_pool_get(pool->pools[i]); 234 if (!pic->buf[i]) 235 goto fail; 236 237 pic->data[i] = pic->buf[i]->data; 238 } 239 for (; i < AV_NUM_DATA_POINTERS; i++) { 240 pic->data[i] = NULL; 241 pic->linesize[i] = 0; 242 } 243 244 if (s->debug & FF_DEBUG_BUFFERS) 245 av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p\n", pic); 246 247 return 0; 248 fail: 249 av_frame_unref(pic); 250 return AVERROR(ENOMEM); 251 } 252 253 int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags) 254 { 255 int ret; 256 257 if (avctx->hw_frames_ctx) { 258 ret = av_hwframe_get_buffer(avctx->hw_frames_ctx, frame, 0); 259 if (ret == AVERROR(ENOMEM)) { 260 AVHWFramesContext *frames_ctx = 261 (AVHWFramesContext*)avctx->hw_frames_ctx->data; 262 if (frames_ctx->initial_pool_size > 0 && 263 !avctx->internal->warned_on_failed_allocation_from_fixed_pool) { 264 av_log(avctx, AV_LOG_WARNING, "Failed to allocate a %s/%s " 265 "frame from a fixed pool of hardware frames.\n", 266 av_get_pix_fmt_name(frames_ctx->format), 267 av_get_pix_fmt_name(frames_ctx->sw_format)); 268 av_log(avctx, AV_LOG_WARNING, "Consider setting " 269 "extra_hw_frames to a larger value " 270 "(currently set to %d, giving a pool size of %d).\n", 271 avctx->extra_hw_frames, frames_ctx->initial_pool_size); 272 avctx->internal->warned_on_failed_allocation_from_fixed_pool = 1; 273 } 274 } 275 frame->width = avctx->coded_width; 276 frame->height = avctx->coded_height; 277 return ret; 278 } 279 280 if ((ret = update_frame_pool(avctx, frame)) < 0) 281 return ret; 282 283 switch (avctx->codec_type) { 284 case AVMEDIA_TYPE_VIDEO: 285 return video_get_buffer(avctx, frame); 286 case AVMEDIA_TYPE_AUDIO: 287 return audio_get_buffer(avctx, frame); 288 default: 289 return -1; 290 } 291 }