mirror of https://github.com/FFmpeg/FFmpeg.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
4.5 KiB
143 lines
4.5 KiB
/* |
|
* Videotoolbox hardware acceleration for VP9 |
|
* |
|
* copyright (c) 2021 rcombs |
|
* |
|
* This file is part of FFmpeg. |
|
* |
|
* FFmpeg is free software; you can redistribute it and/or |
|
* modify it under the terms of the GNU Lesser General Public |
|
* License as published by the Free Software Foundation; either |
|
* version 2.1 of the License, or (at your option) any later version. |
|
* |
|
* FFmpeg is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
* Lesser General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU Lesser General Public |
|
* License along with FFmpeg; if not, write to the Free Software |
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
|
*/ |
|
|
|
#include "config.h" |
|
#include "videotoolbox.h" |
|
#include "libavutil/hwcontext_videotoolbox.h" |
|
#include "libavutil/mem.h" |
|
#include "vt_internal.h" |
|
#include "libavutil/avassert.h" |
|
#include "libavutil/avutil.h" |
|
#include "libavutil/frame.h" |
|
#include "libavutil/hwcontext.h" |
|
#include "libavutil/intreadwrite.h" |
|
#include "libavutil/pixdesc.h" |
|
#include "decode.h" |
|
#include "hwaccel_internal.h" |
|
#include "internal.h" |
|
#include "vp9shared.h" |
|
|
|
enum VPX_CHROMA_SUBSAMPLING |
|
{ |
|
VPX_SUBSAMPLING_420_VERTICAL = 0, |
|
VPX_SUBSAMPLING_420_COLLOCATED_WITH_LUMA = 1, |
|
VPX_SUBSAMPLING_422 = 2, |
|
VPX_SUBSAMPLING_444 = 3, |
|
}; |
|
|
|
static int get_vpx_chroma_subsampling(enum AVPixelFormat pixel_format, |
|
enum AVChromaLocation chroma_location) |
|
{ |
|
int chroma_w, chroma_h; |
|
if (av_pix_fmt_get_chroma_sub_sample(pixel_format, &chroma_w, &chroma_h) == 0) { |
|
if (chroma_w == 1 && chroma_h == 1) { |
|
return (chroma_location == AVCHROMA_LOC_LEFT) |
|
? VPX_SUBSAMPLING_420_VERTICAL |
|
: VPX_SUBSAMPLING_420_COLLOCATED_WITH_LUMA; |
|
} else if (chroma_w == 1 && chroma_h == 0) { |
|
return VPX_SUBSAMPLING_422; |
|
} else if (chroma_w == 0 && chroma_h == 0) { |
|
return VPX_SUBSAMPLING_444; |
|
} |
|
} |
|
return -1; |
|
} |
|
|
|
CFDataRef ff_videotoolbox_vpcc_extradata_create(AVCodecContext *avctx) |
|
{ |
|
const VP9SharedContext *h = avctx->priv_data; |
|
CFDataRef data = NULL; |
|
uint8_t *p; |
|
int vt_extradata_size; |
|
uint8_t *vt_extradata; |
|
int subsampling = get_vpx_chroma_subsampling(avctx->sw_pix_fmt, avctx->chroma_sample_location); |
|
|
|
vt_extradata_size = 1 + 3 + 6 + 2; |
|
vt_extradata = av_malloc(vt_extradata_size); |
|
|
|
if (subsampling < 0) |
|
return NULL; |
|
|
|
if (!vt_extradata) |
|
return NULL; |
|
|
|
p = vt_extradata; |
|
|
|
*p++ = 1; /* version */ |
|
AV_WB24(p + 1, 0); /* flags */ |
|
p += 3; |
|
|
|
*p++ = h->h.profile; |
|
*p++ = avctx->level; |
|
*p++ = (h->h.bpp << 4) | (subsampling << 1) | (avctx->color_range == AVCOL_RANGE_JPEG); |
|
*p++ = avctx->color_primaries; |
|
*p++ = avctx->color_trc; |
|
*p++ = avctx->colorspace; |
|
|
|
AV_WB16(p + 0, 0); |
|
p += 2; |
|
|
|
av_assert0(p - vt_extradata == vt_extradata_size); |
|
|
|
data = CFDataCreate(kCFAllocatorDefault, vt_extradata, vt_extradata_size); |
|
av_free(vt_extradata); |
|
return data; |
|
} |
|
|
|
static int videotoolbox_vp9_start_frame(AVCodecContext *avctx, |
|
const uint8_t *buffer, |
|
uint32_t size) |
|
{ |
|
return 0; |
|
} |
|
|
|
static int videotoolbox_vp9_decode_slice(AVCodecContext *avctx, |
|
const uint8_t *buffer, |
|
uint32_t size) |
|
{ |
|
VTContext *vtctx = avctx->internal->hwaccel_priv_data; |
|
|
|
return ff_videotoolbox_buffer_copy(vtctx, buffer, size); |
|
} |
|
|
|
static int videotoolbox_vp9_end_frame(AVCodecContext *avctx) |
|
{ |
|
const VP9SharedContext *h = avctx->priv_data; |
|
AVFrame *frame = h->frames[CUR_FRAME].tf.f; |
|
|
|
return ff_videotoolbox_common_end_frame(avctx, frame); |
|
} |
|
|
|
const FFHWAccel ff_vp9_videotoolbox_hwaccel = { |
|
.p.name = "vp9_videotoolbox", |
|
.p.type = AVMEDIA_TYPE_VIDEO, |
|
.p.id = AV_CODEC_ID_VP9, |
|
.p.pix_fmt = AV_PIX_FMT_VIDEOTOOLBOX, |
|
.alloc_frame = ff_videotoolbox_alloc_frame, |
|
.start_frame = videotoolbox_vp9_start_frame, |
|
.decode_slice = videotoolbox_vp9_decode_slice, |
|
.end_frame = videotoolbox_vp9_end_frame, |
|
.frame_params = ff_videotoolbox_frame_params, |
|
.init = ff_videotoolbox_common_init, |
|
.uninit = ff_videotoolbox_uninit, |
|
.priv_data_size = sizeof(VTContext), |
|
};
|
|
|