1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * This file is part of FFmpeg. 3cabdff1aSopenharmony_ci * 4cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 5cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 6cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 7cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 8cabdff1aSopenharmony_ci * 9cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 10cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 11cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12cabdff1aSopenharmony_ci * Lesser General Public License for more details. 13cabdff1aSopenharmony_ci * 14cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 15cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 16cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 17cabdff1aSopenharmony_ci */ 18cabdff1aSopenharmony_ci 19cabdff1aSopenharmony_ci#include "libavutil/log.h" 20cabdff1aSopenharmony_ci#include "libavutil/opt.h" 21cabdff1aSopenharmony_ci 22cabdff1aSopenharmony_ci#include "bsf.h" 23cabdff1aSopenharmony_ci#include "bsf_internal.h" 24cabdff1aSopenharmony_ci#include "cbs.h" 25cabdff1aSopenharmony_ci#include "cbs_bsf.h" 26cabdff1aSopenharmony_ci#include "cbs_vp9.h" 27cabdff1aSopenharmony_ci 28cabdff1aSopenharmony_citypedef struct VP9MetadataContext { 29cabdff1aSopenharmony_ci CBSBSFContext common; 30cabdff1aSopenharmony_ci 31cabdff1aSopenharmony_ci int color_space; 32cabdff1aSopenharmony_ci int color_range; 33cabdff1aSopenharmony_ci 34cabdff1aSopenharmony_ci int color_warnings; 35cabdff1aSopenharmony_ci} VP9MetadataContext; 36cabdff1aSopenharmony_ci 37cabdff1aSopenharmony_ci 38cabdff1aSopenharmony_cistatic int vp9_metadata_update_fragment(AVBSFContext *bsf, AVPacket *pkt, 39cabdff1aSopenharmony_ci CodedBitstreamFragment *frag) 40cabdff1aSopenharmony_ci{ 41cabdff1aSopenharmony_ci VP9MetadataContext *ctx = bsf->priv_data; 42cabdff1aSopenharmony_ci int i; 43cabdff1aSopenharmony_ci 44cabdff1aSopenharmony_ci for (i = 0; i < frag->nb_units; i++) { 45cabdff1aSopenharmony_ci VP9RawFrame *frame = frag->units[i].content; 46cabdff1aSopenharmony_ci VP9RawFrameHeader *header = &frame->header; 47cabdff1aSopenharmony_ci int profile = (header->profile_high_bit << 1) + header->profile_low_bit; 48cabdff1aSopenharmony_ci 49cabdff1aSopenharmony_ci if (header->frame_type == VP9_KEY_FRAME || 50cabdff1aSopenharmony_ci header->intra_only && profile > 0) { 51cabdff1aSopenharmony_ci if (ctx->color_space >= 0) { 52cabdff1aSopenharmony_ci if (!(profile & 1) && ctx->color_space == VP9_CS_RGB) { 53cabdff1aSopenharmony_ci if (!(ctx->color_warnings & 2)) { 54cabdff1aSopenharmony_ci av_log(bsf, AV_LOG_WARNING, "Warning: RGB " 55cabdff1aSopenharmony_ci "incompatible with profiles 0 and 2.\n"); 56cabdff1aSopenharmony_ci ctx->color_warnings |= 2; 57cabdff1aSopenharmony_ci } 58cabdff1aSopenharmony_ci } else 59cabdff1aSopenharmony_ci header->color_space = ctx->color_space; 60cabdff1aSopenharmony_ci } 61cabdff1aSopenharmony_ci 62cabdff1aSopenharmony_ci if (ctx->color_range >= 0) 63cabdff1aSopenharmony_ci header->color_range = ctx->color_range; 64cabdff1aSopenharmony_ci if (header->color_space == VP9_CS_RGB) { 65cabdff1aSopenharmony_ci if (!(ctx->color_warnings & 1) && !header->color_range) { 66cabdff1aSopenharmony_ci av_log(bsf, AV_LOG_WARNING, "Warning: Color space RGB " 67cabdff1aSopenharmony_ci "implicitly sets color range to PC range.\n"); 68cabdff1aSopenharmony_ci ctx->color_warnings |= 1; 69cabdff1aSopenharmony_ci } 70cabdff1aSopenharmony_ci header->color_range = 1; 71cabdff1aSopenharmony_ci } 72cabdff1aSopenharmony_ci } else if (!(ctx->color_warnings & 4) && header->intra_only && !profile && 73cabdff1aSopenharmony_ci ctx->color_space >= 0 && ctx->color_space != VP9_CS_BT_601) { 74cabdff1aSopenharmony_ci av_log(bsf, AV_LOG_WARNING, "Warning: Intra-only frames in " 75cabdff1aSopenharmony_ci "profile 0 are automatically BT.601.\n"); 76cabdff1aSopenharmony_ci ctx->color_warnings |= 4; 77cabdff1aSopenharmony_ci } 78cabdff1aSopenharmony_ci } 79cabdff1aSopenharmony_ci 80cabdff1aSopenharmony_ci return 0; 81cabdff1aSopenharmony_ci} 82cabdff1aSopenharmony_ci 83cabdff1aSopenharmony_cistatic const CBSBSFType vp9_metadata_type = { 84cabdff1aSopenharmony_ci .codec_id = AV_CODEC_ID_VP9, 85cabdff1aSopenharmony_ci .fragment_name = "superframe", 86cabdff1aSopenharmony_ci .unit_name = "frame", 87cabdff1aSopenharmony_ci .update_fragment = &vp9_metadata_update_fragment, 88cabdff1aSopenharmony_ci}; 89cabdff1aSopenharmony_ci 90cabdff1aSopenharmony_cistatic int vp9_metadata_init(AVBSFContext *bsf) 91cabdff1aSopenharmony_ci{ 92cabdff1aSopenharmony_ci return ff_cbs_bsf_generic_init(bsf, &vp9_metadata_type); 93cabdff1aSopenharmony_ci} 94cabdff1aSopenharmony_ci 95cabdff1aSopenharmony_ci#define OFFSET(x) offsetof(VP9MetadataContext, x) 96cabdff1aSopenharmony_ci#define FLAGS (AV_OPT_FLAG_VIDEO_PARAM|AV_OPT_FLAG_BSF_PARAM) 97cabdff1aSopenharmony_cistatic const AVOption vp9_metadata_options[] = { 98cabdff1aSopenharmony_ci { "color_space", "Set colour space (section 7.2.2)", 99cabdff1aSopenharmony_ci OFFSET(color_space), AV_OPT_TYPE_INT, 100cabdff1aSopenharmony_ci { .i64 = -1 }, -1, VP9_CS_RGB, FLAGS, "cs" }, 101cabdff1aSopenharmony_ci { "unknown", "Unknown/unspecified", 0, AV_OPT_TYPE_CONST, 102cabdff1aSopenharmony_ci { .i64 = VP9_CS_UNKNOWN }, .flags = FLAGS, .unit = "cs" }, 103cabdff1aSopenharmony_ci { "bt601", "ITU-R BT.601-7", 0, AV_OPT_TYPE_CONST, 104cabdff1aSopenharmony_ci { .i64 = VP9_CS_BT_601 }, .flags = FLAGS, .unit = "cs" }, 105cabdff1aSopenharmony_ci { "bt709", "ITU-R BT.709-6", 0, AV_OPT_TYPE_CONST, 106cabdff1aSopenharmony_ci { .i64 = VP9_CS_BT_709 }, .flags = FLAGS, .unit = "cs" }, 107cabdff1aSopenharmony_ci { "smpte170", "SMPTE-170", 0, AV_OPT_TYPE_CONST, 108cabdff1aSopenharmony_ci { .i64 = VP9_CS_SMPTE_170 }, .flags = FLAGS, .unit = "cs" }, 109cabdff1aSopenharmony_ci { "smpte240", "SMPTE-240", 0, AV_OPT_TYPE_CONST, 110cabdff1aSopenharmony_ci { .i64 = VP9_CS_SMPTE_240 }, .flags = FLAGS, .unit = "cs" }, 111cabdff1aSopenharmony_ci { "bt2020", "ITU-R BT.2020-2", 0, AV_OPT_TYPE_CONST, 112cabdff1aSopenharmony_ci { .i64 = VP9_CS_BT_2020 }, .flags = FLAGS, .unit = "cs" }, 113cabdff1aSopenharmony_ci { "rgb", "sRGB / IEC 61966-2-1", 0, AV_OPT_TYPE_CONST, 114cabdff1aSopenharmony_ci { .i64 = VP9_CS_RGB }, .flags = FLAGS, .unit = "cs" }, 115cabdff1aSopenharmony_ci 116cabdff1aSopenharmony_ci { "color_range", "Set colour range (section 7.2.2)", 117cabdff1aSopenharmony_ci OFFSET(color_range), AV_OPT_TYPE_INT, 118cabdff1aSopenharmony_ci { .i64 = -1 }, -1, 1, FLAGS, "cr" }, 119cabdff1aSopenharmony_ci { "tv", "TV (limited) range", 0, AV_OPT_TYPE_CONST, 120cabdff1aSopenharmony_ci { .i64 = 0 }, .flags = FLAGS, .unit = "cr" }, 121cabdff1aSopenharmony_ci { "pc", "PC (full) range", 0, AV_OPT_TYPE_CONST, 122cabdff1aSopenharmony_ci { .i64 = 1 }, .flags = FLAGS, .unit = "cr" }, 123cabdff1aSopenharmony_ci 124cabdff1aSopenharmony_ci { NULL } 125cabdff1aSopenharmony_ci}; 126cabdff1aSopenharmony_ci 127cabdff1aSopenharmony_cistatic const AVClass vp9_metadata_class = { 128cabdff1aSopenharmony_ci .class_name = "vp9_metadata_bsf", 129cabdff1aSopenharmony_ci .item_name = av_default_item_name, 130cabdff1aSopenharmony_ci .option = vp9_metadata_options, 131cabdff1aSopenharmony_ci .version = LIBAVUTIL_VERSION_INT, 132cabdff1aSopenharmony_ci}; 133cabdff1aSopenharmony_ci 134cabdff1aSopenharmony_cistatic const enum AVCodecID vp9_metadata_codec_ids[] = { 135cabdff1aSopenharmony_ci AV_CODEC_ID_VP9, AV_CODEC_ID_NONE, 136cabdff1aSopenharmony_ci}; 137cabdff1aSopenharmony_ci 138cabdff1aSopenharmony_ciconst FFBitStreamFilter ff_vp9_metadata_bsf = { 139cabdff1aSopenharmony_ci .p.name = "vp9_metadata", 140cabdff1aSopenharmony_ci .p.codec_ids = vp9_metadata_codec_ids, 141cabdff1aSopenharmony_ci .p.priv_class = &vp9_metadata_class, 142cabdff1aSopenharmony_ci .priv_data_size = sizeof(VP9MetadataContext), 143cabdff1aSopenharmony_ci .init = &vp9_metadata_init, 144cabdff1aSopenharmony_ci .close = &ff_cbs_bsf_generic_close, 145cabdff1aSopenharmony_ci .filter = &ff_cbs_bsf_generic_filter, 146cabdff1aSopenharmony_ci}; 147