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 | return AVERROR_EXTERNAL; | 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 | static void vt_frames_uninit(AVHWFramesContext *ctx) | 245 | static void vt_frames_uninit(AVHWFramesContext *ctx) |
| @@ -238,9 +265,9 @@ static int vt_frames_init(AVHWFramesContext *ctx) · 19 unmodified lines | |||
| 238 | return AVERROR(ENOSYS); | 265 | return AVERROR(ENOSYS); |
| 239 | } | 266 | } |
| 240 | 267 | ||
| 241 | // create a dummy pool so av_hwframe_get_buffer doesn't EINVAL | ||
| 242 | if (!ctx->pool) { | 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 | if (!ctx->internal->pool_internal) | 271 | if (!ctx->internal->pool_internal) |
| 245 | return AVERROR(ENOMEM); | 272 | return AVERROR(ENOMEM); |
| 246 | } | 273 | } |
| @@ -252,41 +279,11 @@ static int vt_frames_init(AVHWFramesContext *ctx) · 5 unmodified lines | |||
| 252 | return 0; | 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 | static int vt_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) | 282 | static int vt_get_buffer(AVHWFramesContext *ctx, AVFrame *frame) |
| 261 | { | 283 | { |
| 262 | VTFramesContext *fctx = ctx->internal->priv; | 284 | frame->buf[0] = av_buffer_pool_get(ctx->pool); |
| 263 | 285 | if (!frame->buf[0]) | |
| 264 | if (ctx->pool && ctx->pool->size != 0) { | 286 | return AVERROR(ENOMEM); |
| 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 | } | ||
| 290 | 287 | ||
| 291 | frame->data[3] = frame->buf[0]->data; | 288 | frame->data[3] = frame->buf[0]->data; |
| 292 | frame->format = AV_PIX_FMT_VIDEOTOOLBOX; | 289 | frame->format = AV_PIX_FMT_VIDEOTOOLBOX; |