* commit 'dd2d3b766b20196d0b65a82e3d897ccecbf7adb8': lavc: Add hwaccel private data and init/uninit callbacks Conflicts: libavcodec/avcodec.h libavcodec/internal.h libavcodec/pthread_frame.c
Unified · Split
| @@ -3307,6 +3307,29 @@ typedef struct AVHWAccel { · 3306 unmodified lines | ||
| 3307 | 3307 | * @param s the mpeg context |
| 3308 | 3308 | */ |
| 3309 | 3309 | void (*decode_mb)(struct MpegEncContext *s); |
| 3310 | + | |
| 3311 | + /** | |
| 3312 | + * Initialize the hwaccel private data. | |
| 3313 | + * | |
| 3314 | + * This will be called from ff_get_format(), after hwaccel and | |
| 3315 | + * hwaccel_context are set and the hwaccel private data in AVCodecInternal | |
| 3316 | + * is allocated. | |
| 3317 | + */ | |
| 3318 | + int (*init)(AVCodecContext *avctx); | |
| 3319 | + | |
| 3320 | + /** | |
| 3321 | + * Uninitialize the hwaccel private data. | |
| 3322 | + * | |
| 3323 | + * This will be called from get_format() or avcodec_close(), after hwaccel | |
| 3324 | + * and hwaccel_context are already uninitialized. | |
| 3325 | + */ | |
| 3326 | + int (*uninit)(AVCodecContext *avctx); | |
| 3327 | + | |
| 3328 | + /** | |
| 3329 | + * Size of the private data to allocate in | |
| 3330 | + * AVCodecInternal.hwaccel_priv_data. | |
| 3331 | + */ | |
| 3332 | + int priv_data_size; | |
| 3310 | 3333 | } AVHWAccel; |
| 3311 | 3334 | |
| 3312 | 3335 | /** |
| @@ -122,6 +122,11 @@ typedef struct AVCodecInternal { · 121 unmodified lines | ||
| 122 | 122 | * Number of audio samples to skip at the start of the next decoded frame |
| 123 | 123 | */ |
| 124 | 124 | int skip_samples; |
| 125 | + | |
| 126 | + /** | |
| 127 | + * hwaccel-specific private data | |
| 128 | + */ | |
| 129 | + void *hwaccel_priv_data; | |
| 125 | 130 | } AVCodecInternal; |
| 126 | 131 | |
| 127 | 132 | struct AVCodecDefault { |
| @@ -226,6 +226,7 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, · 225 unmodified lines | ||
| 226 | 226 | dst->sample_rate = src->sample_rate; |
| 227 | 227 | dst->sample_fmt = src->sample_fmt; |
| 228 | 228 | dst->channel_layout = src->channel_layout; |
| 229 | + dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data; | |
| 229 | 230 | } |
| 230 | 231 | |
| 231 | 232 | if (for_user) { |
| @@ -1146,16 +1146,37 @@ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) · 1145 unmodified lines | ||
| 1146 | 1146 | if (!desc) |
| 1147 | 1147 | return AV_PIX_FMT_NONE; |
| 1148 | 1148 | |
| 1149 | + if (avctx->hwaccel && avctx->hwaccel->uninit) | |
| 1150 | + avctx->hwaccel->uninit(avctx); | |
| 1151 | + av_freep(&avctx->internal->hwaccel_priv_data); | |
| 1152 | + avctx->hwaccel = NULL; | |
| 1153 | + | |
| 1149 | 1154 | if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) { |
| 1150 | − avctx->hwaccel = find_hwaccel(avctx->codec_id, ret); | |
| 1151 | − if (!avctx->hwaccel) { | |
| 1155 | + AVHWAccel *hwaccel; | |
| 1156 | + int err; | |
| 1157 | + | |
| 1158 | + hwaccel = find_hwaccel(avctx->codec_id, ret); | |
| 1159 | + if (!hwaccel) { | |
| 1152 | 1160 | av_log(avctx, AV_LOG_ERROR, |
| 1153 | 1161 | "Could not find an AVHWAccel for the pixel format: %s", |
| 1154 | 1162 | desc->name); |
| 1155 | 1163 | return AV_PIX_FMT_NONE; |
| 1156 | 1164 | } |
| 1157 | − } else { | |
| 1158 | − avctx->hwaccel = NULL; | |
| 1165 | + | |
| 1166 | + if (hwaccel->priv_data_size) { | |
| 1167 | + avctx->internal->hwaccel_priv_data = av_mallocz(hwaccel->priv_data_size); | |
| 1168 | + if (!avctx->internal->hwaccel_priv_data) | |
| 1169 | + return AV_PIX_FMT_NONE; | |
| 1170 | + } | |
| 1171 | + | |
| 1172 | + if (hwaccel->init) { | |
| 1173 | + err = hwaccel->init(avctx); | |
| 1174 | + if (err < 0) { | |
| 1175 | + av_freep(&avctx->internal->hwaccel_priv_data); | |
| 1176 | + return AV_PIX_FMT_NONE; | |
| 1177 | + } | |
| 1178 | + } | |
| 1179 | + avctx->hwaccel = hwaccel; | |
| 1159 | 1180 | } |
| 1160 | 1181 | |
| 1161 | 1182 | return ret; |
| @@ -2689,6 +2710,11 @@ av_cold int avcodec_close(AVCodecContext *avctx) · 1527 unmodified lines | ||
| 2689 | 2710 | for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) |
| 2690 | 2711 | av_buffer_pool_uninit(&pool->pools[i]); |
| 2691 | 2712 | av_freep(&avctx->internal->pool); |
| 2713 | + | |
| 2714 | + if (avctx->hwaccel && avctx->hwaccel->uninit) | |
| 2715 | + avctx->hwaccel->uninit(avctx); | |
| 2716 | + av_freep(&avctx->internal->hwaccel_priv_data); | |
| 2717 | + | |
| 2692 | 2718 | av_freep(&avctx->internal); |
| 2693 | 2719 | } |
| 2694 | 2720 | |