diff --git a/libavcodec/videotoolbox.c b/libavcodec/videotoolbox.c index 9eeada30ba..d29607363c 100644 --- a/libavcodec/videotoolbox.c +++ b/libavcodec/videotoolbox.c @@ -90,6 +90,7 @@ int ff_videotoolbox_alloc_frame(AVCodecContext *avctx, AVFrame *frame) CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx) { + VTContext *vtctx = avctx->internal->hwaccel_priv_data; H264Context *h = avctx->priv_data; CFDataRef data = NULL; uint8_t *p; @@ -116,6 +117,10 @@ CFDataRef ff_videotoolbox_avcc_extradata_create(AVCodecContext *avctx) p += 3 + h->ps.pps->data_size; av_assert0(p - vt_extradata == vt_extradata_size); + // save sps header (profile/level) used to create decoder session, + // so we can detect changes and recreate it. + memcpy(vtctx->sps, h->ps.sps->data + 1, 3); + data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size); av_free(vt_extradata); return data; @@ -320,16 +325,13 @@ static int videotoolbox_h264_decode_params(AVCodecContext *avctx, VTContext *vtctx = avctx->internal->hwaccel_priv_data; if (type == H264_NAL_SPS) { - if (!vtctx->sps || vtctx->sps_len != size || memcmp(buffer, vtctx->sps, size) != 0) { - vtctx->sps = av_fast_realloc(vtctx->sps, &vtctx->sps_capa, size); - if (vtctx->sps) - memcpy(vtctx->sps, buffer, size); + if (size > 4 && memcmp(vtctx->sps, buffer + 1, 3) != 0) { vtctx->reconfig_needed = true; - vtctx->sps_len = size; + memcpy(vtctx->sps, buffer + 1, 3); } } - // pass-through new PPS to the decoder + // pass-through SPS/PPS changes to the decoder return ff_videotoolbox_h264_decode_slice(avctx, buffer, size); } @@ -365,7 +367,6 @@ int ff_videotoolbox_uninit(AVCodecContext *avctx) VTContext *vtctx = avctx->internal->hwaccel_priv_data; if (vtctx) { av_freep(&vtctx->bitstream); - av_freep(&vtctx->sps); if (vtctx->frame) CVPixelBufferRelease(vtctx->frame); } diff --git a/libavcodec/vt_internal.h b/libavcodec/vt_internal.h index fc27dad9f9..929fe423fc 100644 --- a/libavcodec/vt_internal.h +++ b/libavcodec/vt_internal.h @@ -40,9 +40,7 @@ typedef struct VTContext { struct AVVideotoolboxContext *vt_ctx; // Current H264 parameters (used to trigger decoder restart on SPS changes). - uint8_t *sps; - uint32_t sps_len; - unsigned int sps_capa; + uint8_t sps[3]; bool reconfig_needed; } VTContext;