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 36typedef struct FramePool { 37 /** 38 * Pools for each data plane. For audio all the planes have the same size, 39 * so only pools[0] is used. 40 */ 41 AVBufferPool *pools[4]; 42 43 /* 44 * Pool parameters 45 */ 46 int format; 47 int width, height; 48 int stride_align[AV_NUM_DATA_POINTERS]; 49 int linesize[4]; 50 int planes; 51 int channels; 52 int samples; 53} FramePool; 54 55static void frame_pool_free(void *opaque, uint8_t *data) 56{ 57 FramePool *pool = (FramePool*)data; 58 int i; 59 60 for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) 61 av_buffer_pool_uninit(&pool->pools[i]); 62 63 av_freep(&data); 64} 65 66static AVBufferRef *frame_pool_alloc(void) 67{ 68 FramePool *pool = av_mallocz(sizeof(*pool)); 69 AVBufferRef *buf; 70 71 if (!pool) 72 return NULL; 73 74 buf = av_buffer_create((uint8_t*)pool, sizeof(*pool), 75 frame_pool_free, NULL, 0); 76 if (!buf) { 77 av_freep(&pool); 78 return NULL; 79 } 80 81 return buf; 82} 83 84static int update_frame_pool(AVCodecContext *avctx, AVFrame *frame) 85{ 86 FramePool *pool = avctx->internal->pool ? 87 (FramePool*)avctx->internal->pool->data : NULL; 88 AVBufferRef *pool_buf; 89 int i, ret, ch, planes; 90 91 if (avctx->codec_type == AVMEDIA_TYPE_AUDIO) { 92 int planar = av_sample_fmt_is_planar(frame->format); 93 ch = frame->ch_layout.nb_channels; 94#if FF_API_OLD_CHANNEL_LAYOUT 95FF_DISABLE_DEPRECATION_WARNINGS 96 if (!ch) 97 ch = frame->channels; 98FF_ENABLE_DEPRECATION_WARNINGS 99#endif 100 planes = planar ? ch : 1; 101 } 102 103 if (pool && pool->format == frame->format) { 104 if (avctx->codec_type == AVMEDIA_TYPE_VIDEO && 105 pool->width == frame->width && pool->height == frame->height) 106 return 0; 107 if (avctx->codec_type == AVMEDIA_TYPE_AUDIO && pool->planes == planes && 108 pool->channels == ch && frame->nb_samples == pool->samples) 109 return 0; 110 } 111 112 pool_buf = frame_pool_alloc(); 113 if (!pool_buf) 114 return AVERROR(ENOMEM); 115 pool = (FramePool*)pool_buf->data; 116 117 switch (avctx->codec_type) { 118 case AVMEDIA_TYPE_VIDEO: { 119 int linesize[4]; 120 int w = frame->width; 121 int h = frame->height; 122 int unaligned; 123 ptrdiff_t linesize1[4]; 124 size_t size[4]; 125 126 avcodec_align_dimensions2(avctx, &w, &h, pool->stride_align); 127 128 do { 129 // NOTE: do not align linesizes individually, this breaks e.g. assumptions 130 // that linesize[0] == 2*linesize[1] in the MPEG-encoder for 4:2:2 131 ret = av_image_fill_linesizes(linesize, avctx->pix_fmt, w); 132 if (ret < 0) 133 goto fail; 134 // increase alignment of w for next try (rhs gives the lowest bit set in w) 135 w += w & ~(w - 1); 136 137 unaligned = 0; 138 for (i = 0; i < 4; i++) 139 unaligned |= linesize[i] % pool->stride_align[i]; 140 } while (unaligned); 141 142 for (i = 0; i < 4; i++) 143 linesize1[i] = linesize[i]; 144 ret = av_image_fill_plane_sizes(size, avctx->pix_fmt, h, linesize1); 145 if (ret < 0) 146 goto fail; 147 148 for (i = 0; i < 4; i++) { 149 pool->linesize[i] = linesize[i]; 150 if (size[i]) { 151 if (size[i] > INT_MAX - (16 + STRIDE_ALIGN - 1)) { 152 ret = AVERROR(EINVAL); 153 goto fail; 154 } 155 pool->pools[i] = av_buffer_pool_init(size[i] + 16 + STRIDE_ALIGN - 1, 156 CONFIG_MEMORY_POISONING ? 157 NULL : 158 av_buffer_allocz); 159 if (!pool->pools[i]) { 160 ret = AVERROR(ENOMEM); 161 goto fail; 162 } 163 } 164 } 165 pool->format = frame->format; 166 pool->width = frame->width; 167 pool->height = frame->height; 168 169 break; 170 } 171 case AVMEDIA_TYPE_AUDIO: { 172 ret = av_samples_get_buffer_size(&pool->linesize[0], ch, 173 frame->nb_samples, frame->format, 0); 174 if (ret < 0) 175 goto fail; 176 177 pool->pools[0] = av_buffer_pool_init(pool->linesize[0], NULL); 178 if (!pool->pools[0]) { 179 ret = AVERROR(ENOMEM); 180 goto fail; 181 } 182 183 pool->format = frame->format; 184 pool->planes = planes; 185 pool->channels = ch; 186 pool->samples = frame->nb_samples; 187 break; 188 } 189 default: av_assert0(0); 190 } 191 192 av_buffer_unref(&avctx->internal->pool); 193 avctx->internal->pool = pool_buf; 194 195 return 0; 196fail: 197 av_buffer_unref(&pool_buf); 198 return ret; 199} 200 201static int audio_get_buffer(AVCodecContext *avctx, AVFrame *frame) 202{ 203 FramePool *pool = (FramePool*)avctx->internal->pool->data; 204 int planes = pool->planes; 205 int i; 206 207 frame->linesize[0] = pool->linesize[0]; 208 209 if (planes > AV_NUM_DATA_POINTERS) { 210 frame->extended_data = av_calloc(planes, sizeof(*frame->extended_data)); 211 frame->nb_extended_buf = planes - AV_NUM_DATA_POINTERS; 212 frame->extended_buf = av_calloc(frame->nb_extended_buf, 213 sizeof(*frame->extended_buf)); 214 if (!frame->extended_data || !frame->extended_buf) { 215 av_freep(&frame->extended_data); 216 av_freep(&frame->extended_buf); 217 return AVERROR(ENOMEM); 218 } 219 } else { 220 frame->extended_data = frame->data; 221 av_assert0(frame->nb_extended_buf == 0); 222 } 223 224 for (i = 0; i < FFMIN(planes, AV_NUM_DATA_POINTERS); i++) { 225 frame->buf[i] = av_buffer_pool_get(pool->pools[0]); 226 if (!frame->buf[i]) 227 goto fail; 228 frame->extended_data[i] = frame->data[i] = frame->buf[i]->data; 229 } 230 for (i = 0; i < frame->nb_extended_buf; i++) { 231 frame->extended_buf[i] = av_buffer_pool_get(pool->pools[0]); 232 if (!frame->extended_buf[i]) 233 goto fail; 234 frame->extended_data[i + AV_NUM_DATA_POINTERS] = frame->extended_buf[i]->data; 235 } 236 237 if (avctx->debug & FF_DEBUG_BUFFERS) 238 av_log(avctx, AV_LOG_DEBUG, "default_get_buffer called on frame %p", frame); 239 240 return 0; 241fail: 242 av_frame_unref(frame); 243 return AVERROR(ENOMEM); 244} 245 246static int video_get_buffer(AVCodecContext *s, AVFrame *pic) 247{ 248 FramePool *pool = (FramePool*)s->internal->pool->data; 249 const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(pic->format); 250 int i; 251 252 if (pic->data[0] || pic->data[1] || pic->data[2] || pic->data[3]) { 253 av_log(s, AV_LOG_ERROR, "pic->data[*]!=NULL in avcodec_default_get_buffer\n"); 254 return -1; 255 } 256 257 if (!desc) { 258 av_log(s, AV_LOG_ERROR, 259 "Unable to get pixel format descriptor for format %s\n", 260 av_get_pix_fmt_name(pic->format)); 261 return AVERROR(EINVAL); 262 } 263 264 memset(pic->data, 0, sizeof(pic->data)); 265 pic->extended_data = pic->data; 266 267 for (i = 0; i < 4 && pool->pools[i]; i++) { 268 pic->linesize[i] = pool->linesize[i]; 269 270 pic->buf[i] = av_buffer_pool_get(pool->pools[i]); 271 if (!pic->buf[i]) 272 goto fail; 273 274 pic->data[i] = pic->buf[i]->data; 275 } 276 for (; i < AV_NUM_DATA_POINTERS; i++) { 277 pic->data[i] = NULL; 278 pic->linesize[i] = 0; 279 } 280 281 if (s->debug & FF_DEBUG_BUFFERS) 282 av_log(s, AV_LOG_DEBUG, "default_get_buffer called on pic %p\n", pic); 283 284 return 0; 285fail: 286 av_frame_unref(pic); 287 return AVERROR(ENOMEM); 288} 289 290int avcodec_default_get_buffer2(AVCodecContext *avctx, AVFrame *frame, int flags) 291{ 292 int ret; 293 294 if (avctx->hw_frames_ctx) { 295 ret = av_hwframe_get_buffer(avctx->hw_frames_ctx, frame, 0); 296 frame->width = avctx->coded_width; 297 frame->height = avctx->coded_height; 298 return ret; 299 } 300 301 if ((ret = update_frame_pool(avctx, frame)) < 0) 302 return ret; 303 304 switch (avctx->codec_type) { 305 case AVMEDIA_TYPE_VIDEO: 306 return video_get_buffer(avctx, frame); 307 case AVMEDIA_TYPE_AUDIO: 308 return audio_get_buffer(avctx, frame); 309 default: 310 return -1; 311 } 312} 313