21 case AVCOL_SPC_SMPTE170M:
22 case AVCOL_SPC_SMPTE240M:
38 [AVCOL_TRC_BT709] = { 1.099, 0.018, 0.45, 4.5 },
39 [AVCOL_TRC_GAMMA22] = { 1.0, 0.0, 1.0 / 2.2, 0.0 },
40 [AVCOL_TRC_GAMMA28] = { 1.0, 0.0, 1.0 / 2.8, 0.0 },
41 [AVCOL_TRC_SMPTE170M] = { 1.099, 0.018, 0.45, 4.5 },
42 [AVCOL_TRC_SMPTE240M] = { 1.1115, 0.0228, 0.45, 4.0 },
43 [AVCOL_TRC_IEC61966_2_1] = { 1.055, 0.0031308, 1.0 / 2.4, 12.92 },
44 [AVCOL_TRC_IEC61966_2_4] = { 1.099, 0.018, 0.45, 4.5 },
45 [AVCOL_TRC_BT2020_10] = { 1.099, 0.018, 0.45, 4.5 },
46 [AVCOL_TRC_BT2020_12] = { 1.0993, 0.0181, 0.45, 4.5 },
51 if ((
unsigned)t < AVCOL_TRC_NB) {
65 return encoded_to_linear;
77 [
WP_D65] = { 0.3127f, 0.3290f },
78 [
WP_C] = { 0.3100f, 0.3160f },
79 [
WP_DCI] = { 0.3140f, 0.3510f },
80 [
WP_E] = { 1/3.0f, 1/3.0f },
83#define ExpandWP(index) gWP[index].fX, gWP[index].fY
86 [AVCOL_PRI_BT709] = { 0.640f, 0.330f, 0.300f, 0.600f, 0.150f, 0.060f,
ExpandWP(
WP_D65) },
87 [AVCOL_PRI_BT470M] = { 0.670f, 0.330f, 0.210f, 0.710f, 0.140f, 0.080f,
ExpandWP(
WP_C) },
88 [AVCOL_PRI_BT470BG] = { 0.640f, 0.330f, 0.290f, 0.600f, 0.150f, 0.060f,
ExpandWP(
WP_D65) },
89 [AVCOL_PRI_SMPTE170M] = { 0.630f, 0.340f, 0.310f, 0.595f, 0.155f, 0.070f,
ExpandWP(
WP_D65) },
90 [AVCOL_PRI_SMPTE240M] = { 0.630f, 0.340f, 0.310f, 0.595f, 0.155f, 0.070f,
ExpandWP(
WP_D65) },
91 [AVCOL_PRI_SMPTE428] = { 0.735f, 0.265f, 0.274f, 0.718f, 0.167f, 0.009f,
ExpandWP(
WP_E) },
92 [AVCOL_PRI_SMPTE431] = { 0.680f, 0.320f, 0.265f, 0.690f, 0.150f, 0.060f,
ExpandWP(
WP_DCI) },
93 [AVCOL_PRI_SMPTE432] = { 0.680f, 0.320f, 0.265f, 0.690f, 0.150f, 0.060f,
ExpandWP(
WP_D65) },
94 [AVCOL_PRI_FILM] = { 0.681f, 0.319f, 0.243f, 0.692f, 0.145f, 0.049f,
ExpandWP(
WP_C) },
95 [AVCOL_PRI_BT2020] = { 0.708f, 0.292f, 0.170f, 0.797f, 0.131f, 0.046f,
ExpandWP(
WP_D65) },
96 [AVCOL_PRI_JEDEC_P22] = { 0.630f, 0.340f, 0.295f, 0.605f, 0.155f, 0.077f,
ExpandWP(
WP_D65) },
100 AVColorTransferCharacteristic transfer) {
101 if (primaries == AVCOL_PRI_BT709 && transfer == AVCOL_TRC_BT709) {
106 if ((
unsigned)primaries < (
unsigned)AVCOL_PRI_NB) {
111 p->toXYZD50(&matrix);
116static bool check_err(
int err,
const int silentList[] =
nullptr) {
122 for (; *silentList; ++silentList) {
123 if (*silentList == err) {
130 const char *errbuf_ptr = errbuf;
132 if (av_strerror(err, errbuf,
sizeof(errbuf)) < 0) {
133 errbuf_ptr = strerror(AVUNERROR(err));
141 int result = (
int)stream->read(dstBuffer, dstSize);
154 pos = (int64_t)stream->getPosition() +
pos;
157 pos = (int64_t)stream->getLength() +
pos;
167 uint8_t*
const data[],
184 rContext, yuvaPixmaps, skgpu::Mipmapped::kNo,
false, std::move(cs));
189SkVideoDecoder::ConvertedColorSpace::ConvertedColorSpace()
190 : fPrimaries(AVCOL_PRI_NB), fTransfer(AVCOL_TRC_NB)
193void SkVideoDecoder::ConvertedColorSpace::update(AVColorPrimaries primaries,
194 AVColorTransferCharacteristic transfer) {
195 if (fPrimaries != primaries || fTransfer != transfer) {
196 fPrimaries = primaries;
197 fTransfer = transfer;
202double SkVideoDecoder::computeTimeStamp(
const AVFrame*
frame)
const {
203 AVRational
base = fFormatCtx->streams[fStreamIndex]->time_base;
211 fCSCache.update(
frame->color_primaries,
frame->color_trc);
215 SkASSERT(fDecoderCtx->color_primaries ==
frame->color_primaries);
223 switch (
frame->format) {
224 case AV_PIX_FMT_YUV420P:
226 frame->data,
frame->linesize, yuv_space, fCSCache.fCS)) {
244 auto* ctx = sws_getContext(
frame->width,
frame->height, (AVPixelFormat)
frame->format,
246 SWS_BILINEAR,
nullptr,
nullptr,
nullptr);
251 sws_scale(ctx,
frame->data,
frame->linesize, 0,
frame->height, dst, dst_stride);
253 sws_freeContext(ctx);
261 double defaultTimeStampStorage = 0;
263 timeStamp = &defaultTimeStampStorage;
266 if (fFormatCtx ==
nullptr) {
270 if (fMode == kProcessing_Mode) {
274 while (!av_read_frame(fFormatCtx, &fPacket)) {
275 if (fPacket.stream_index != fStreamIndex) {
280 int ret = avcodec_send_packet(fDecoderCtx, &fPacket);
281 if (ret == AVERROR(EAGAIN)) {
292 if (
check_err(avcodec_receive_frame(fDecoderCtx, fFrame), silentList)) {
295 *timeStamp = this->computeTimeStamp(fFrame);
296 return this->convertFrame(fFrame);
300 fMode = kDraining_Mode;
301 (void)avcodec_send_packet(fDecoderCtx,
nullptr);
303 if (fMode == kDraining_Mode) {
304 if (avcodec_receive_frame(fDecoderCtx, fFrame) >= 0) {
305 *timeStamp = this->computeTimeStamp(fFrame);
306 return this->convertFrame(fFrame);
322 av_frame_free(&fFrame);
326 avcodec_free_context(&fDecoderCtx);
327 fDecoderCtx =
nullptr;
330 avformat_close_input(&fFormatCtx);
331 fFormatCtx =
nullptr;
334 av_freep(&fStreamCtx->buffer);
335 avio_context_free(&fStreamCtx);
336 fStreamCtx =
nullptr;
339 fStream.reset(
nullptr);
350 int bufferSize = 4 * 1024;
351 uint8_t*
buffer = (uint8_t*)av_malloc(bufferSize);
356 fStream = std::move(stream);
357 fStreamCtx = avio_alloc_context(
buffer, bufferSize, 0, fStream.get(),
365 fFormatCtx = avformat_alloc_context();
370 fFormatCtx->pb = fStreamCtx;
372 int err = avformat_open_input(&fFormatCtx,
nullptr,
nullptr,
nullptr);
374 SkDebugf(
"avformat_open_input failed %d\n", err);
378 const AVCodec* codec;
379 fStreamIndex = av_find_best_stream(fFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &codec, 0);
380 if (fStreamIndex < 0) {
381 SkDebugf(
"av_find_best_stream failed %d\n", fStreamIndex);
387 fDecoderCtx = avcodec_alloc_context3(codec);
389 AVStream* strm = fFormatCtx->streams[fStreamIndex];
390 if ((err = avcodec_parameters_to_context(fDecoderCtx, strm->codecpar)) < 0) {
391 SkDebugf(
"avcodec_parameters_to_context failed %d\n", err);
396 if ((err = avcodec_open2(fDecoderCtx, codec,
nullptr)) < 0) {
397 SkDebugf(
"avcodec_open2 failed %d\n", err);
402 fFrame = av_frame_alloc();
405 av_init_packet(&fPacket);
407 fMode = kProcessing_Mode;
417 AVStream* strm = fFormatCtx->streams[fStreamIndex];
418 return {strm->codecpar->width, strm->codecpar->height};
426 AVStream* strm = fFormatCtx->streams[fStreamIndex];
427 AVRational
base = strm->time_base;
428 return 1.0 * strm->duration *
base.num /
base.den;
432 auto stream = std::move(fStream);
static void info(const char *fmt,...) SK_PRINTF_LIKE(1
@ kOpaque_SkAlphaType
pixel is opaque
void SK_SPI SkDebugf(const char format[],...) SK_PRINTF_LIKE(1
@ kRec601_SkYUVColorSpace
@ kRec709_SkYUVColorSpace
@ kIdentity_SkYUVColorSpace
maps Y->R, U->G, V->B
constexpr size_t SkToSizeT(S x)
constexpr int SkToInt(S x)
#define SK_PMCOLOR_BYTE_ORDER(C0, C1, C2, C3)
static skcms_TransferFunction compute_transfer(AVColorTransferCharacteristic t)
const SkColorSpacePrimaries gPrimaries[AVCOL_PRI_NB]
sk_sp< SkColorSpace > make_colorspace(AVColorPrimaries primaries, AVColorTransferCharacteristic transfer)
const av_transfer_characteristics gTransfer[AVCOL_TRC_NB]
static bool check_err(int err, const int silentList[]=nullptr)
static int skstream_read_packet(void *ctx, uint8_t *dstBuffer, int dstSize)
static SkYUVColorSpace get_yuvspace(AVColorSpace space)
static sk_sp< SkImage > make_yuv_420(GrRecordingContext *rContext, int w, int h, uint8_t *const data[], int const strides[], SkYUVColorSpace yuvSpace, sk_sp< SkColorSpace > cs)
static int64_t skstream_seek_packet(void *ctx, int64_t pos, int whence)
Type::kYUV Type::kRGBA() int(0.7 *637)
void allocPixels(const SkImageInfo &info, size_t rowBytes)
const SkPixmap & pixmap() const
static sk_sp< SkColorSpace > MakeSRGB()
static sk_sp< SkColorSpace > MakeRGB(const skcms_TransferFunction &transferFn, const skcms_Matrix3x3 &toXYZ)
void * writable_addr() const
SkISize dimensions() const
SkVideoDecoder(GrRecordingContext *=nullptr)
bool loadStream(std::unique_ptr< SkStream >)
sk_sp< SkImage > nextImage(double *timeStamp=nullptr)
@ kY_U_V
Plane 0: Y, Plane 1: U, Plane 2: V.
@ k420
1 set of UV values for each 2x2 block of Y values.
static SkYUVAPixmaps FromExternalPixmaps(const SkYUVAInfo &, const SkPixmap[kMaxPlanes])
static const uint8_t buffer[]
SK_API sk_sp< SkImage > TextureFromYUVAPixmaps(GrRecordingContext *context, const SkYUVAPixmaps &pixmaps, skgpu::Mipmapped buildMips, bool limitToMaxTextureSize, sk_sp< SkColorSpace > imageColorSpace)
SK_API sk_sp< SkImage > RasterFromBitmap(const SkBitmap &bitmap)
static SkString fmt(SkColor4f c)
bool skcms_TransferFunction_invert(const skcms_TransferFunction *src, skcms_TransferFunction *dst)
static SkImageInfo MakeN32(int width, int height, SkAlphaType at)
static SkImageInfo MakeA8(int width, int height)