+
+ if (!videotoolbox->session || !vtctx->bitstream || !vtctx->bitstream_size)
+ return AVERROR_INVALIDDATA;
+
+ status = videotoolbox_session_decode_frame(avctx);
+ if (status != noErr) {
+ if (status == kVTVideoDecoderMalfunctionErr || status == kVTInvalidSessionErr)
+ vtctx->reconfig_needed = true;
+ av_log(avctx, AV_LOG_ERROR, "Failed to decode frame (%s, %d)\n", videotoolbox_error_string(status), (int)status);
+ return AVERROR_UNKNOWN;
+ }
+
+ if (!vtctx->frame) {
+ vtctx->reconfig_needed = true;
+ return AVERROR_UNKNOWN;
+ }
+
+ return videotoolbox_buffer_create(avctx, frame);
+}
+
+static int videotoolbox_h264_end_frame(AVCodecContext *avctx)
+{
+ H264Context *h = avctx->priv_data;
+ AVFrame *frame = h->cur_pic_ptr->f;
+ VTContext *vtctx = avctx->internal->hwaccel_priv_data;
+ int ret = videotoolbox_common_end_frame(avctx, frame);
+ vtctx->bitstream_size = 0;
+ return ret;
+}
+
+static int videotoolbox_hevc_decode_params(AVCodecContext *avctx,
+ int type,
+ const uint8_t *buffer,
+ uint32_t size)
+{
+ return ff_videotoolbox_h264_decode_slice(avctx, buffer, size);
+}
+
+static int videotoolbox_hevc_end_frame(AVCodecContext *avctx)
+{
+ HEVCContext *h = avctx->priv_data;
+ AVFrame *frame = h->ref->frame;
+ VTContext *vtctx = avctx->internal->hwaccel_priv_data;
+ int ret;
+
+ ret = videotoolbox_common_end_frame(avctx, frame);
+ vtctx->bitstream_size = 0;
+ return ret;
+}
+
+static int videotoolbox_mpeg_start_frame(AVCodecContext *avctx,
+ const uint8_t *buffer,
+ uint32_t size)
+{
+ VTContext *vtctx = avctx->internal->hwaccel_priv_data;
+
+ return videotoolbox_buffer_copy(vtctx, buffer, size);
+}
+
+static int videotoolbox_mpeg_decode_slice(AVCodecContext *avctx,
+ const uint8_t *buffer,
+ uint32_t size)
+{
+ return 0;
+}
+
+static int videotoolbox_mpeg_end_frame(AVCodecContext *avctx)
+{
+ MpegEncContext *s = avctx->priv_data;
+ AVFrame *frame = s->current_picture_ptr->f;
+
+ return videotoolbox_common_end_frame(avctx, frame);