* 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 | * @param s the mpeg context | 3307 | * @param s the mpeg context |
| 3308 | */ | 3308 | */ |
| 3309 | void (*decode_mb)(struct MpegEncContext *s); | 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 | } AVHWAccel; | 3333 | } AVHWAccel; |
| 3311 | 3334 | ||
| 3312 | /** | 3335 | /** |
| @@ -122,6 +122,11 @@ typedef struct AVCodecInternal { · 121 unmodified lines | |||
| 122 | * Number of audio samples to skip at the start of the next decoded frame | 122 | * Number of audio samples to skip at the start of the next decoded frame |
| 123 | */ | 123 | */ |
| 124 | int skip_samples; | 124 | int skip_samples; |
| 125 | |||
| 126 | /** | ||
| 127 | * hwaccel-specific private data | ||
| 128 | */ | ||
| 129 | void *hwaccel_priv_data; | ||
| 125 | } AVCodecInternal; | 130 | } AVCodecInternal; |
| 126 | 131 | ||
| 127 | struct AVCodecDefault { | 132 | struct AVCodecDefault { |
| @@ -226,6 +226,7 @@ static int update_context_from_thread(AVCodecContext *dst, AVCodecContext *src, · 225 unmodified lines | |||
| 226 | dst->sample_rate = src->sample_rate; | 226 | dst->sample_rate = src->sample_rate; |
| 227 | dst->sample_fmt = src->sample_fmt; | 227 | dst->sample_fmt = src->sample_fmt; |
| 228 | dst->channel_layout = src->channel_layout; | 228 | dst->channel_layout = src->channel_layout; |
| 229 | dst->internal->hwaccel_priv_data = src->internal->hwaccel_priv_data; | ||
| 229 | } | 230 | } |
| 230 | 231 | ||
| 231 | if (for_user) { | 232 | if (for_user) { |
| @@ -1146,16 +1146,37 @@ int ff_get_format(AVCodecContext *avctx, const enum AVPixelFormat *fmt) · 1145 unmodified lines | |||
| 1146 | if (!desc) | 1146 | if (!desc) |
| 1147 | return AV_PIX_FMT_NONE; | 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 | if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) { | 1154 | if (desc->flags & AV_PIX_FMT_FLAG_HWACCEL) { |
| 1150 | avctx->hwaccel = find_hwaccel(avctx->codec_id, ret); | 1155 | AVHWAccel *hwaccel; |
| 1151 | if (!avctx->hwaccel) { | 1156 | int err; |
| 1157 | |||
| 1158 | hwaccel = find_hwaccel(avctx->codec_id, ret); | ||
| 1159 | if (!hwaccel) { | ||
| 1152 | av_log(avctx, AV_LOG_ERROR, | 1160 | av_log(avctx, AV_LOG_ERROR, |
| 1153 | "Could not find an AVHWAccel for the pixel format: %s", | 1161 | "Could not find an AVHWAccel for the pixel format: %s", |
| 1154 | desc->name); | 1162 | desc->name); |
| 1155 | return AV_PIX_FMT_NONE; | 1163 | return AV_PIX_FMT_NONE; |
| 1156 | } | 1164 | } |
| 1157 | } else { | 1165 | |
| 1158 | avctx->hwaccel = NULL; | 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 | return ret; | 1182 | return ret; |
| @@ -2689,6 +2710,11 @@ av_cold int avcodec_close(AVCodecContext *avctx) · 1527 unmodified lines | |||
| 2689 | for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) | 2710 | for (i = 0; i < FF_ARRAY_ELEMS(pool->pools); i++) |
| 2690 | av_buffer_pool_uninit(&pool->pools[i]); | 2711 | av_buffer_pool_uninit(&pool->pools[i]); |
| 2691 | av_freep(&avctx->internal->pool); | 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 | av_freep(&avctx->internal); | 2718 | av_freep(&avctx->internal); |
| 2693 | } | 2719 | } |
| 2694 | 2720 | ||