2 * The default get_buffer2() implementation
4 * This file is part of FFmpeg.
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.
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.
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
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"
35 #include "libavutil/refstruct.h"
37 typedef struct FramePool
{
39 * Pools for each data plane. For audio all the planes have the same size,
40 * so only pools[0] is used.
42 AVBufferPool
*pools
[4];
49 int stride_align
[AV_NUM_DATA_POINTERS
];
56 static void frame_pool_free(AVRefStructOpaque unused
, void *obj
)
58 FramePool
*pool
= obj
;
61 for (i
= 0; i
< FF_ARRAY_ELEMS(pool
->pools
); i
++)
62 av_buffer_pool_uninit(&pool
->pools
[i
]);
65 static int update_frame_pool(AVCodecContext
*avctx
, AVFrame
*frame
)
67 FramePool
*pool
= avctx
->internal
->pool
;
70 if (pool
&& pool
->format
== frame
->format
) {
71 if (avctx
->codec_type
== AVMEDIA_TYPE_VIDEO
&&
72 pool
->width
== frame
->width
&& pool
->height
== frame
->height
)
74 if (avctx
->codec_type
== AVMEDIA_TYPE_AUDIO
&&
75 pool
->channels
== frame
->ch_layout
.nb_channels
&&
76 frame
->nb_samples
== pool
->samples
)
80 pool
= av_refstruct_alloc_ext(sizeof(*pool
), 0, NULL
, frame_pool_free
);
82 return AVERROR(ENOMEM
);
84 switch (avctx
->codec_type
) {
85 case AVMEDIA_TYPE_VIDEO
: {
88 int h
= frame
->height
;
90 ptrdiff_t linesize1
[4];
93 avcodec_align_dimensions2(avctx
, &w
, &h
, pool
->stride_align
);
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
);
101 // increase alignment of w for next try (rhs gives the lowest bit set in w)
105 for (i
= 0; i
< 4; i
++)
106 unaligned
|= linesize
[i
] % pool
->stride_align
[i
];
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
);
115 for (i
= 0; i
< 4; i
++) {
116 pool
->linesize
[i
] = linesize
[i
];
118 if (size
[i
] > INT_MAX
- (16 + STRIDE_ALIGN
- 1)) {
119 ret
= AVERROR(EINVAL
);
122 pool
->pools
[i
] = av_buffer_pool_init(size
[i
] + 16 + STRIDE_ALIGN
- 1,
123 CONFIG_MEMORY_POISONING
?
126 if (!pool
->pools
[i
]) {
127 ret
= AVERROR(ENOMEM
);
132 pool
->format
= frame
->format
;
133 pool
->width
= frame
->width
;
134 pool
->height
= frame
->height
;
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);
145 pool
->pools
[0] = av_buffer_pool_init(pool
->linesize
[0],
146 CONFIG_MEMORY_POISONING
?
149 if (!pool
->pools
[0]) {
150 ret
= AVERROR(ENOMEM
);
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;
160 default: av_assert0(0);
163 av_refstruct_unref(&avctx
->internal
->pool
);
164 avctx
->internal
->pool
= pool
;
168 av_refstruct_unref(&pool
);
172 static int audio_get_buffer(AVCodecContext
*avctx
, AVFrame
*frame
)
174 FramePool
*pool
= avctx
->internal
->pool
;
175 int planes
= pool
->planes
;
178 frame
->linesize
[0] = pool
->linesize
[0];
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
);
191 frame
->extended_data
= frame
->data
;
192 av_assert0(frame
->nb_extended_buf
== 0);
195 for (i
= 0; i
< FFMIN(planes
, AV_NUM_DATA_POINTERS
); i
++) {
196 frame
->buf
[i
] = av_buffer_pool_get(pool
->pools
[0]);
199 frame
->extended_data
[i
] = frame
->data
[i
] = frame
->buf
[i
]->data
;
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
])
205 frame
->extended_data
[i
+ AV_NUM_DATA_POINTERS
] = frame
->extended_buf
[i
]->data
;
208 if (avctx
->debug
& FF_DEBUG_BUFFERS
)
209 av_log(avctx
, AV_LOG_DEBUG
, "default_get_buffer called on frame %p", frame
);
213 av_frame_unref(frame
);
214 return AVERROR(ENOMEM
);
217 static int video_get_buffer(AVCodecContext
*s
, AVFrame
*pic
)
219 FramePool
*pool
= s
->internal
->pool
;
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");
227 memset(pic
->data
, 0, sizeof(pic
->data
));
228 pic
->extended_data
= pic
->data
;
230 for (i
= 0; i
< 4 && pool
->pools
[i
]; i
++) {
231 pic
->linesize
[i
] = pool
->linesize
[i
];
233 pic
->buf
[i
] = av_buffer_pool_get(pool
->pools
[i
]);
237 pic
->data
[i
] = pic
->buf
[i
]->data
;
239 for (; i
< AV_NUM_DATA_POINTERS
; i
++) {
241 pic
->linesize
[i
] = 0;
244 if (s
->debug
& FF_DEBUG_BUFFERS
)
245 av_log(s
, AV_LOG_DEBUG
, "default_get_buffer called on pic %p\n", pic
);
250 return AVERROR(ENOMEM
);
253 int avcodec_default_get_buffer2(AVCodecContext
*avctx
, AVFrame
*frame
, int flags
)
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;
275 frame
->width
= avctx
->coded_width
;
276 frame
->height
= avctx
->coded_height
;
280 if ((ret
= update_frame_pool(avctx
, frame
)) < 0)
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
);