From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from ffbox0-bg.mplayerhq.hu (ffbox0-bg.ffmpeg.org [79.124.17.100]) by master.gitmailbox.com (Postfix) with ESMTP id 7CB4846141 for ; Mon, 4 Dec 2023 21:32:29 +0000 (UTC) Received: from [127.0.1.1] (localhost [127.0.0.1]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTP id 7FB0B68CD40; Mon, 4 Dec 2023 23:32:26 +0200 (EET) Received: from mail-pl1-f174.google.com (mail-pl1-f174.google.com [209.85.214.174]) by ffbox0-bg.mplayerhq.hu (Postfix) with ESMTPS id 7B2A86899D7 for ; Mon, 4 Dec 2023 23:32:20 +0200 (EET) Received: by mail-pl1-f174.google.com with SMTP id d9443c01a7336-1d05199f34dso20794615ad.3 for ; Mon, 04 Dec 2023 13:32:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1701725538; x=1702330338; darn=ffmpeg.org; h=content-transfer-encoding:in-reply-to:autocrypt:from:references:to :content-language:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=KxV2PZjgBrrBFO9LdMRVSJZ9uLFa8kAT5HiCE1vyP/w=; b=fH4CgJcVbs+eOLVwqmpcj1LvpTp5AYEBIYmGx9uFyR/sl7cIjfMYFwPTQ3OV3ILb7R sivT/VN3ommvAhfY+R4qN5nr1FEQaPxe1zPyPv+FsvuSLYR6sDFtTc3k1r8YG8E3GsCm Jn16F24RBJv6JO/jQ2ezsuZX/HIovqkpBmug6Hxn1cihA2mTo6y0ID9Ql5zzeW5VKLBk pOhG4MgN8bAGuXtkINUcFgnbLm8T2tIIt26J98VjsRz2H4pP47NGJbIjajAp/eFI0fw1 sgRAw0wPK12iRKm1ShOOFKWWLRB95n7TplbcLBHqx32Z+Y74y4bsCspy0iyUPQnlU6an Dczw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1701725538; x=1702330338; h=content-transfer-encoding:in-reply-to:autocrypt:from:references:to :content-language:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=KxV2PZjgBrrBFO9LdMRVSJZ9uLFa8kAT5HiCE1vyP/w=; b=nyuYHpyMfW7NmffJYlyaxpZzi+146vnUca27TgllGDLjJv3vw/XLMqLKryjfn8kKVW Wei/O/tFcy1lBayPkLeWzBX60/utl4hWPO1gl1i/loA9XQHqhAXBwg6lPyXruZFAhMiV YpvjnVjhTRPdl5pt53s3UB5UCjw1Q0Pcx+gccp4a57p5G1biYjCu1sUNghqoUN3mCfl9 nGvdlWjVhASwJrv9HjeXZdyE8VWbSsllIu3li+fPDoPu2b8/khCqSEguKFTS5ogD0fF4 15ojjAoH/p0064wjWGItDYozMO9vh77sLun5cS+74kM0R9+mfqjQq7OtY4FzPaEE5mLI ZqyQ== X-Gm-Message-State: AOJu0YyXUi1uFpD5yp7U9+40wZCWBD2vGiCq5GCoI60LJPCMNLjj8i5U 3HfscXJbEV9KU7cNQcoqC3oGbrG4Gy0= X-Google-Smtp-Source: AGHT+IFVakc7So5SH0gI9GqPswytXrhRYiX3964xmjbX/iKXsGnm+zoAO31mSbx44DCANhRjmA7YGw== X-Received: by 2002:a17:902:e809:b0:1d0:6ffd:6e6e with SMTP id u9-20020a170902e80900b001d06ffd6e6emr3211813plg.102.1701725537741; Mon, 04 Dec 2023 13:32:17 -0800 (PST) Received: from [192.168.0.16] (host197.190-225-105.telecom.net.ar. [190.225.105.197]) by smtp.gmail.com with ESMTPSA id o18-20020a170902d4d200b001cf96a0e4e6sm6976819plg.242.2023.12.04.13.32.16 for (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 04 Dec 2023 13:32:17 -0800 (PST) Message-ID: <29ed7620-f60f-4f31-bc22-3f0903456c07@gmail.com> Date: Mon, 4 Dec 2023 18:32:51 -0300 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Content-Language: en-US To: ffmpeg-devel@ffmpeg.org References: From: James Almer Autocrypt: addr=jamrial@gmail.com; keydata= xsBNBFjZtqABCADLW+vdEoZaJZDsIO6geYFTOcn1unsEHefj9zn+3oTHlDFFzO47mzHsSfbK 9JE2xpOJEVnC8FAF5Sayi/pVwV+mtQUV3n5dgVeVBYF9GUQwOGFCpK8X54RRqhkgknbunOEE 0CtgAJgmpFmmmHgq02GvEspx1h/rh4apqwQR6QX4Favb+x9+i9ytVpwVcBX94vo2toyP7h/K BWfadQmb8ltgE1kshfg+SQs/H5bTV5Z1DuEASf02ZL/1qYB/sdTgWPLv9XMUHHsRFmMY8TMx wJSkP+Af3AiYQPJYz1B1D4tt98T/NoiVdin10zATakPjV8hXaobuRmxgakkUASXudydDABEB AAHNH0phbWVzIEFsbWVyIDxqYW1yaWFsQGdtYWlsLmNvbT7CwJIEEwEIADwCGwMGCwkIBwMC BhUIAgkKCwQWAgMBAh4BAheAFiEEd1EujP2UoWlX5pp6FGMBrXN2WeAFAmJoLUUCGQEACgkQ FGMBrXN2WeAFVQf9GtGhniRs1PzNUOgJktCnv6j4BbLieaIPYPEFXKDHOgjqQE2zVMYXnoXl Jam928ii902a8OY06r9ywn/R8ApD1/3NY/v64O71CY9scz5XyH2au8wIZ6HwFy3/f7sqjdGD uctY8Qs7rjT7NkoC5lmgMu2v2k03dGtM9AAf5AK5gU+H0EUw7vmKKiXzUqt5kvBuf4CEwXvH AQT1SMJ52rIlDWB7FQFyZeUbOAK2IgY/KNedfK6nsgd/eQVnlofPd2XoddE7kP6iys7jJefw DD3g3rZyDTq7in5dyk5glaNpWZpbHGBs+9SCYLnfQ8XvWqPFOD+gj0plamKANgOvavKTxM7A TQRY2bagAQgA69YtILj8kYxmqPr/M8+MXT7wVoOWVW9lvSmPquCELaDy/NIS7D06VC5EuE/6 JlJXZMTn37NLlyWhzwOgXuXw5w2tyoQQBuvqGiXJijuXwXH7HKdzrc6rpYtAqt5w05hzNrFS KrS0izG64VpWrfproy3BsL+8TBm9brLhhNPynVRqVukbbGzlATTzNQGZ14TTi2/dL6DkMQnM qn4jX9UEe4GdGQBP50bUJSSmeiIkyNLWA+znuN2PZEz930ZwNrF9GtDVw7mzcmpCZ7spldE2 tutbpy9D1bIqxyqBrYDSezyzL2adR1qgHyOTMCHg2AYNkrIQHrSyJxKTpZ1/hqOp8wARAQAB wsBfBBgBAgAJBQJY2bagAhsMAAoJEBRjAa1zdlnghekH/0Yb0iYJ74oID2f/Fj+AJKS2ekQF P2xOr8lpGzgp/+yWUvPtqbX0A33anBJdYwxaAC0NataX3tfZ+oJkzXqfmqhIHMPYHdZesJA2 Bk9hU/33mDl5s5U66/z0uelWzwKVHoQ2O6or4+qF3HJFSJLCe9uvWJ3zXf9F342Ftj73sfx+ 3xkw/IXsN1RqbYqDlzpoEQ99SIEfY/8Jjwnd3sIPfqkuyeaYfe6GJDqKawdCEP1oRRlbXEAp TJgYz8r3nPhGv9cdHNDCk44ISbsqVuxIEnLqi4fTPZaGupiQhT+srl268TTAp2TQW7+6Ce/b NPQorMquzS/LZoyALpmsYi/miMc= In-Reply-To: Subject: Re: [FFmpeg-devel] [PATCH 2/2] avformat/flvdec: support enhanced flv PacketTypeMetadata X-BeenThere: ffmpeg-devel@ffmpeg.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: FFmpeg development discussions and patches List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: FFmpeg development discussions and patches Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="us-ascii"; Format="flowed" Errors-To: ffmpeg-devel-bounces@ffmpeg.org Sender: "ffmpeg-devel" Archived-At: List-Archive: List-Post: On 11/15/2023 11:40 AM, zhupengfei via ffmpeg-devel wrote: > From: Zhu Pengfei <411294962@qq.com> > > Signed-off-by: Zhu Pengfei <411294962@qq.com> > --- > libavformat/flvdec.c | 171 ++++++++++++++++++++++++++++++++++++++++++- > 1 file changed, 170 insertions(+), 1 deletion(-) > > diff --git a/libavformat/flvdec.c b/libavformat/flvdec.c > index e25b5bd163..46bb0825ca 100644 > --- a/libavformat/flvdec.c > +++ b/libavformat/flvdec.c > @@ -34,6 +34,7 @@ > #include "libavutil/intfloat.h" > #include "libavutil/intreadwrite.h" > #include "libavutil/mathematics.h" > +#include "libavutil/mastering_display_metadata.h" > #include "avformat.h" > #include "demux.h" > #include "internal.h" > @@ -45,6 +46,28 @@ > > #define MAX_DEPTH 16 ///< arbitrary limit to prevent unbounded recursion > > +typedef struct FLVMasteringMeta { > + double r_x; > + double r_y; > + double g_x; > + double g_y; > + double b_x; > + double b_y; > + double white_x; > + double white_y; > + double max_luminance; > + double min_luminance; > +} FLVMasteringMeta; > + > +typedef struct FLVMetaVideoColor { > + uint64_t matrix_coefficients; > + uint64_t transfer_characteristics; > + uint64_t primaries; > + uint64_t max_cll; > + uint64_t max_fall; > + FLVMasteringMeta mastering_meta; > +} FLVMetaVideoColor; > + > typedef struct FLVContext { > const AVClass *class; ///< Class for private options. > int trust_metadata; ///< configure streams according onMetaData > @@ -80,6 +103,8 @@ typedef struct FLVContext { > int64_t time_offset; > int64_t time_pos; > > + FLVMetaVideoColor *metaVideoColor; > + int meta_color_info_flag; > } FLVContext; > > /* AMF date type */ > @@ -524,6 +549,7 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, > FLVContext *flv = s->priv_data; > AVIOContext *ioc; > AMFDataType amf_type; > + FLVMetaVideoColor *meta_video_color = flv->metaVideoColor; > char str_val[1024]; > double num_val; > amf_date date; > @@ -655,6 +681,36 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream, > } else if (!strcmp(key, "height") && vpar) { > vpar->height = num_val; > } > + } else if (!strcmp(key, "colorPrimaries") && meta_video_color) { You should put this inside an "else if (meta_video_color)" block, instead of checking for meta_video_color with every single string. See how it's done for flv->trust_metadata above. > + meta_video_color->primaries = num_val; > + } else if (!strcmp(key, "transferCharacteristics") && meta_video_color) { > + meta_video_color->transfer_characteristics = num_val; > + } else if (!strcmp(key, "matrixCoefficients") && meta_video_color) { > + meta_video_color->matrix_coefficients = num_val; > + } else if (!strcmp(key, "maxFall") && meta_video_color) { > + meta_video_color->max_fall = num_val; > + } else if (!strcmp(key, "maxCLL") && meta_video_color) { > + meta_video_color->max_cll = num_val; > + } else if (!strcmp(key, "redX") && meta_video_color) { > + meta_video_color->mastering_meta.r_x = num_val; > + } else if (!strcmp(key, "redY") && meta_video_color) { > + meta_video_color->mastering_meta.r_y = num_val; > + } else if (!strcmp(key, "greenX") && meta_video_color) { > + meta_video_color->mastering_meta.g_x = num_val; > + } else if (!strcmp(key, "greenY") && meta_video_color) { > + meta_video_color->mastering_meta.g_y = num_val; > + } else if (!strcmp(key, "blueX") && meta_video_color) { > + meta_video_color->mastering_meta.b_x = num_val; > + } else if (!strcmp(key, "blueY") && meta_video_color) { > + meta_video_color->mastering_meta.b_y = num_val; > + } else if (!strcmp(key, "whitePointX") && meta_video_color) { > + meta_video_color->mastering_meta.white_x = num_val; > + } else if (!strcmp(key, "whitePointY") && meta_video_color) { > + meta_video_color->mastering_meta.white_y = num_val; > + } else if (!strcmp(key, "maxLuminance") && meta_video_color) { > + meta_video_color->mastering_meta.max_luminance = num_val; > + } else if (!strcmp(key, "minLuminance") && meta_video_color) { > + meta_video_color->mastering_meta.min_luminance = num_val; > } > } > if (amf_type == AMF_DATA_TYPE_STRING) { > @@ -824,6 +880,7 @@ static int flv_read_close(AVFormatContext *s) > av_freep(&flv->new_extradata[i]); > av_freep(&flv->keyframe_times); > av_freep(&flv->keyframe_filepositions); > + av_freep(&flv->metaVideoColor); > return 0; > } > > @@ -1028,6 +1085,104 @@ static int resync(AVFormatContext *s) > return AVERROR_EOF; > } > > +static int flv_parse_video_color_info(AVFormatContext *s, AVStream *st, int64_t next_pos) > +{ > + FLVContext *flv = s->priv_data; > + AMFDataType type; > + AVIOContext *ioc; > + char buffer[32]; > + ioc = s->pb; > + > + // first object needs to be "colorInfo" string > + type = avio_r8(ioc); > + if (type != AMF_DATA_TYPE_STRING || > + amf_get_string(ioc, buffer, sizeof(buffer)) < 0) > + return TYPE_UNKNOWN; > + > + if (strcmp(buffer, "colorInfo")) { > + av_log(s, AV_LOG_DEBUG, "Unknown type %s\n", buffer); > + return TYPE_UNKNOWN; > + } > + > + flv->metaVideoColor = av_mallocz(sizeof(FLVMetaVideoColor)); > + if (!flv->metaVideoColor) { > + return AVERROR(ENOMEM); > + } > + flv->meta_color_info_flag = 1; > + amf_parse_object(s, NULL, NULL, buffer, next_pos, 0); // parse metadata > + return 0; > +} > + > +static int flv_update_video_color_info(AVFormatContext *s, AVStream *st) > +{ > + FLVContext *flv = s->priv_data; > + const FLVMetaVideoColor* meta_video_color = flv->metaVideoColor; > + const FLVMasteringMeta *mastering_meta = &meta_video_color->mastering_meta; > + > + int has_mastering_primaries, has_mastering_luminance; > + // Mastering primaries are CIE 1931 coords, and must be > 0. > + has_mastering_primaries = > + mastering_meta->r_x > 0 && mastering_meta->r_y > 0 && > + mastering_meta->g_x > 0 && mastering_meta->g_y > 0 && > + mastering_meta->b_x > 0 && mastering_meta->b_y > 0 && > + mastering_meta->white_x > 0 && mastering_meta->white_y > 0; > + has_mastering_luminance = mastering_meta->max_luminance >= 0 && mastering_meta->min_luminance >= 0; > + > + if (meta_video_color->matrix_coefficients != AVCOL_SPC_RESERVED) > + st->codecpar->color_space = meta_video_color->matrix_coefficients; > + if (meta_video_color->primaries != AVCOL_PRI_RESERVED && > + meta_video_color->primaries != AVCOL_PRI_RESERVED0) > + st->codecpar->color_primaries = meta_video_color->primaries; > + if (meta_video_color->transfer_characteristics != AVCOL_TRC_RESERVED && > + meta_video_color->transfer_characteristics != AVCOL_TRC_RESERVED0) > + st->codecpar->color_trc = meta_video_color->transfer_characteristics; > + > + if (meta_video_color->max_cll && meta_video_color->max_fall) { > + size_t size = 0; > + AVContentLightMetadata *metadata = av_content_light_metadata_alloc(&size); > + if (!metadata) > + return AVERROR(ENOMEM); > + if (!av_packet_side_data_add(&st->codecpar->coded_side_data, &st->codecpar->nb_coded_side_data, > + AV_PKT_DATA_CONTENT_LIGHT_LEVEL, metadata, size, 0)) { > + av_freep(&metadata); > + return AVERROR(ENOMEM); > + } > + metadata->MaxCLL = meta_video_color->max_cll; > + metadata->MaxFALL = meta_video_color->max_fall; > + } > + > + if (has_mastering_primaries || has_mastering_luminance) { > + AVMasteringDisplayMetadata *metadata; > + AVPacketSideData *sd = av_packet_side_data_new(&st->codecpar->coded_side_data, > + &st->codecpar->nb_coded_side_data, > + AV_PKT_DATA_MASTERING_DISPLAY_METADATA, > + sizeof(AVMasteringDisplayMetadata), 0); > + if (!sd) > + return AVERROR(ENOMEM); > + metadata = (AVMasteringDisplayMetadata*)sd->data; > + memset(metadata, 0, sizeof(AVMasteringDisplayMetadata)); > + // hdrCll > + if (has_mastering_luminance) { > + metadata->max_luminance = av_d2q(mastering_meta->max_luminance, INT_MAX); > + metadata->min_luminance = av_d2q(mastering_meta->min_luminance, INT_MAX); > + metadata->has_luminance = 1; > + } > + // hdrMdcv > + if (has_mastering_primaries) { > + metadata->display_primaries[0][0] = av_d2q(mastering_meta->r_x, INT_MAX); > + metadata->display_primaries[0][1] = av_d2q(mastering_meta->r_y, INT_MAX); > + metadata->display_primaries[1][0] = av_d2q(mastering_meta->g_x, INT_MAX); > + metadata->display_primaries[1][1] = av_d2q(mastering_meta->g_y, INT_MAX); > + metadata->display_primaries[2][0] = av_d2q(mastering_meta->b_x, INT_MAX); > + metadata->display_primaries[2][1] = av_d2q(mastering_meta->b_y, INT_MAX); > + metadata->white_point[0] = av_d2q(mastering_meta->white_x, INT_MAX); > + metadata->white_point[1] = av_d2q(mastering_meta->white_y, INT_MAX); > + metadata->has_primaries = 1; > + } > + } > + return 0; > +} > + > static int flv_read_packet(AVFormatContext *s, AVPacket *pkt) > { > FLVContext *flv = s->priv_data; > @@ -1100,8 +1255,17 @@ retry: > video_codec_id = avio_rb32(s->pb); > size -= 4; > } > - if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD) > + > + if (enhanced_flv && stream_type == FLV_STREAM_TYPE_VIDEO && (flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD) { > + type = flags & 0x0F; > + if (type == PacketTypeMetadata) { > + int ret = flv_parse_video_color_info(s, st, next); > + av_log(s, AV_LOG_INFO, "enhanced flv parse metadata ret %d and skip\n", ret); > + } > + goto skip; > + } else if ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_VIDEO_INFO_CMD) { > goto skip; > + } > } else if (type == FLV_TAG_TYPE_META) { > stream_type=FLV_STREAM_TYPE_SUBTITLE; > if (size > 13 + 1 + 4) { // Header-type metadata stuff > @@ -1287,6 +1451,11 @@ retry_duration: > goto leave; > } > > + if (enhanced_flv && stream_type == FLV_STREAM_TYPE_VIDEO && flv->meta_color_info_flag) { > + flv_update_video_color_info(s, st); // update av packet side data > + flv->meta_color_info_flag = 0; > + } > + > if (st->codecpar->codec_id == AV_CODEC_ID_H264 || st->codecpar->codec_id == AV_CODEC_ID_MPEG4 || > (st->codecpar->codec_id == AV_CODEC_ID_HEVC && type == PacketTypeCodedFrames)) { > // sign extension A test for this would be nice. Can be one that creates a file and then demuxes it. See the fate-lavf-fate-* tests to remux an existing sample. _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-request@ffmpeg.org with subject "unsubscribe".