2 * Videotoolbox hardware acceleration for VP9
4 * copyright (c) 2021 rcombs
6 * This file is part of FFmpeg.
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * FFmpeg is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "videotoolbox.h"
25 #include "libavutil/hwcontext_videotoolbox.h"
26 #include "libavutil/mem.h"
27 #include "vt_internal.h"
28 #include "libavutil/avassert.h"
29 #include "libavutil/avutil.h"
30 #include "libavutil/frame.h"
31 #include "libavutil/hwcontext.h"
32 #include "libavutil/intreadwrite.h"
33 #include "libavutil/pixdesc.h"
35 #include "hwaccel_internal.h"
37 #include "vp9shared.h"
39 enum VPX_CHROMA_SUBSAMPLING
41 VPX_SUBSAMPLING_420_VERTICAL
= 0,
42 VPX_SUBSAMPLING_420_COLLOCATED_WITH_LUMA
= 1,
43 VPX_SUBSAMPLING_422
= 2,
44 VPX_SUBSAMPLING_444
= 3,
47 static int get_vpx_chroma_subsampling(enum AVPixelFormat pixel_format
,
48 enum AVChromaLocation chroma_location
)
50 int chroma_w
, chroma_h
;
51 if (av_pix_fmt_get_chroma_sub_sample(pixel_format
, &chroma_w
, &chroma_h
) == 0) {
52 if (chroma_w
== 1 && chroma_h
== 1) {
53 return (chroma_location
== AVCHROMA_LOC_LEFT
)
54 ? VPX_SUBSAMPLING_420_VERTICAL
55 : VPX_SUBSAMPLING_420_COLLOCATED_WITH_LUMA
;
56 } else if (chroma_w
== 1 && chroma_h
== 0) {
57 return VPX_SUBSAMPLING_422
;
58 } else if (chroma_w
== 0 && chroma_h
== 0) {
59 return VPX_SUBSAMPLING_444
;
65 CFDataRef
ff_videotoolbox_vpcc_extradata_create(AVCodecContext
*avctx
)
67 const VP9SharedContext
*h
= avctx
->priv_data
;
68 CFDataRef data
= NULL
;
70 int vt_extradata_size
;
71 uint8_t *vt_extradata
;
72 int subsampling
= get_vpx_chroma_subsampling(avctx
->sw_pix_fmt
, avctx
->chroma_sample_location
);
74 vt_extradata_size
= 1 + 3 + 6 + 2;
75 vt_extradata
= av_malloc(vt_extradata_size
);
85 *p
++ = 1; /* version */
86 AV_WB24(p
+ 1, 0); /* flags */
91 *p
++ = (h
->h
.bpp
<< 4) | (subsampling
<< 1) | (avctx
->color_range
== AVCOL_RANGE_JPEG
);
92 *p
++ = avctx
->color_primaries
;
93 *p
++ = avctx
->color_trc
;
94 *p
++ = avctx
->colorspace
;
99 av_assert0(p
- vt_extradata
== vt_extradata_size
);
101 data
= CFDataCreate(kCFAllocatorDefault
, vt_extradata
, vt_extradata_size
);
102 av_free(vt_extradata
);
106 static int videotoolbox_vp9_start_frame(AVCodecContext
*avctx
,
107 const uint8_t *buffer
,
113 static int videotoolbox_vp9_decode_slice(AVCodecContext
*avctx
,
114 const uint8_t *buffer
,
117 VTContext
*vtctx
= avctx
->internal
->hwaccel_priv_data
;
119 return ff_videotoolbox_buffer_copy(vtctx
, buffer
, size
);
122 static int videotoolbox_vp9_end_frame(AVCodecContext
*avctx
)
124 const VP9SharedContext
*h
= avctx
->priv_data
;
125 AVFrame
*frame
= h
->frames
[CUR_FRAME
].tf
.f
;
127 return ff_videotoolbox_common_end_frame(avctx
, frame
);
130 const FFHWAccel ff_vp9_videotoolbox_hwaccel
= {
131 .p
.name
= "vp9_videotoolbox",
132 .p
.type
= AVMEDIA_TYPE_VIDEO
,
133 .p
.id
= AV_CODEC_ID_VP9
,
134 .p
.pix_fmt
= AV_PIX_FMT_VIDEOTOOLBOX
,
135 .alloc_frame
= ff_videotoolbox_alloc_frame
,
136 .start_frame
= videotoolbox_vp9_start_frame
,
137 .decode_slice
= videotoolbox_vp9_decode_slice
,
138 .end_frame
= videotoolbox_vp9_end_frame
,
139 .frame_params
= ff_videotoolbox_frame_params
,
140 .init
= ff_videotoolbox_common_init
,
141 .uninit
= ff_videotoolbox_uninit
,
142 .priv_data_size
= sizeof(VTContext
),