vt_get_buffer shouldn't do buffer pool's job.
Unified · Split
| @@ -210,9 +210,36 @@ static int vt_pool_alloc(AVHWFramesContext *ctx) · 209 unmodified lines | ||
| 210 | 210 | return AVERROR_EXTERNAL; |
| 211 | 211 | } |
| 212 | 212 | |
| 213 | −static AVBufferRef *vt_dummy_pool_alloc(void *opaque, size_t size) | |
| 213 | +static void videotoolbox_buffer_release(void *opaque, uint8_t *data) | |
| 214 | +{ | |
| 215 | + CVPixelBufferRelease((CVPixelBufferRef)data); | |
| 216 | +} | |
| 217 | + | |
| 218 | +static AVBufferRef *vt_pool_alloc_buffer(void *opaque, size_t size) | |
| 214 | 219 | { |
| 215 | − return NULL; | |
| 220 | + CVPixelBufferRef pixbuf; | |
| 221 | + AVBufferRef *buf; | |
| 222 | + CVReturn err; | |
| 223 | + AVHWFramesContext *ctx = opaque; | |
| 224 | + VTFramesContext *fctx = ctx->internal->priv; | |
| 225 | + | |
| 226 | + err = CVPixelBufferPoolCreatePixelBuffer( | |
| 227 | + NULL, | |
| 228 | + fctx->pool, | |
| 229 | + &pixbuf | |
| 230 | + ); | |
| 231 | + if (err != kCVReturnSuccess) { | |
| 232 | + av_log(ctx, AV_LOG_ERROR, "Failed to create pixel buffer from pool: %d\n", err); | |
| 233 | + return NULL; | |
| 234 | + } | |
| 235 | + | |
| 236 | + buf = av_buffer_create((uint8_t *)pixbuf, size, | |
| 237 | + videotoolbox_buffer_release, NULL, 0); | |
| 238 | + if (!buf) { | |
| 239 | + CVPixelBufferRelease(pixbuf); | |
| 240 | + return NULL; | |
| 241 | + } | |
| 242 | + return buf; | |
| 216 | 243 | } |
| 217 | 244 | |
| 218 | 245 | static void vt_frames_uninit(AVHWFramesContext *ctx) |
| @@ -238,9 +265,9 @@ static int vt_frames_init(AVHWFramesContext *ctx) · 19 unmodified lines | ||
| 238 | 265 | return AVERROR(ENOSYS); |
| 239 | 266 | } |
| 240 | 267 | |
| 241 | − // create a dummy pool so av_hwframe_get_buffer doesn't EINVAL | |
| 242 | 268 | if (!ctx->pool) { |
| 243 | − ctx->internal->pool_internal = av_buffer_pool_init2(0, ctx, vt_dummy_pool_alloc, NULL); | |
| 269 | + ctx->internal->pool_internal = av_buffer_pool_init2( | |
| 270 | + sizeof(CVPixelBufferRef), ctx, vt_pool_alloc_buffer, NULL); | |
| 244 | 271 | if (!ctx->internal->pool_internal) |
| 245 | 272 | return AVERROR(ENOMEM); |
| 246 | 273 | } |
| @@ -252,41 +279,11 @@ static int vt_frames_init(AVHWFramesContext *ctx) · 5 unmodified lines | ||
| 252 | 279 | return 0; |
| 253 | 280 | } |
| 254 | 281 | |
| 255 | −static void videotoolbox_buffer_release(void *opaque, uint8_t *data) | |
| 256 | −{ | |
| 257 | − CVPixelBufferRelease((CVPixelBufferRef)data); | |
| 258 | −} | |
| 259 | − | |
| 260 | 282 | static int vt_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) |
| 261 | 283 | { |
| 262 | − VTFramesContext *fctx = ctx->internal->priv; | |
| 263 | − | |
| 264 | − if (ctx->pool && ctx->pool->size != 0) { | |
| 265 | − frame->buf[0] = av_buffer_pool_get(ctx->pool); | |
| 266 | − if (!frame->buf[0]) | |
| 267 | − return AVERROR(ENOMEM); | |
| 268 | − } else { | |
| 269 | − CVPixelBufferRef pixbuf; | |
| 270 | − AVBufferRef *buf = NULL; | |
| 271 | − CVReturn err; | |
| 272 | − | |
| 273 | − err = CVPixelBufferPoolCreatePixelBuffer( | |
| 274 | − NULL, | |
| 275 | − fctx->pool, | |
| 276 | − &pixbuf | |
| 277 | − ); | |
| 278 | − if (err != kCVReturnSuccess) { | |
| 279 | − av_log(ctx, AV_LOG_ERROR, "Failed to create pixel buffer from pool: %d\n", err); | |
| 280 | − return AVERROR_EXTERNAL; | |
| 281 | − } | |
| 282 | − | |
| 283 | − buf = av_buffer_create((uint8_t *)pixbuf, 1, videotoolbox_buffer_release, NULL, 0); | |
| 284 | − if (!buf) { | |
| 285 | − CVPixelBufferRelease(pixbuf); | |
| 286 | − return AVERROR(ENOMEM); | |
| 287 | − } | |
| 288 | − frame->buf[0] = buf; | |
| 289 | − } | |
| 284 | + frame->buf[0] = av_buffer_pool_get(ctx->pool); | |
| 285 | + if (!frame->buf[0]) | |
| 286 | + return AVERROR(ENOMEM); | |
| 290 | 287 | |
| 291 | 288 | frame->data[3] = frame->buf[0]->data; |
| 292 | 289 | frame->format = AV_PIX_FMT_VIDEOTOOLBOX; |