From e49f4d64d59c36c05c87df50a7d6a9750acf698c Mon Sep 17 00:00:00 2001 From: "Wang, Shaofei" Date: Tue, 26 Feb 2019 23:45:22 -0500 Subject: [PATCH] add source as option -source , calculate nano timestamp, and add -custom_tag "key1:value1,key2:value2..." option Change-Id: I352311ef5fd7e4b7e8a0bf65dc3da0e19dbed0da --- libavformat/iemetadataenc.c | 59 +++++++++++++++++++++++++++++++++++++++------ 1 file changed, 52 insertions(+), 7 deletions(-) diff --git a/libavformat/iemetadataenc.c b/libavformat/iemetadataenc.c index ac321f8..8249277 100644 --- a/libavformat/iemetadataenc.c +++ b/libavformat/iemetadataenc.c @@ -24,7 +24,8 @@ #include "libavutil/dict.h" #include "libavfilter/avfilter.h" #include "libavfilter/inference.h" - +#include "libavutil/opt.h" +#include #define JSON_HEAD "{\n" #define JSON_TAIL "},\n" @@ -32,14 +33,18 @@ #define JSON_ARRAY_TAIL "]\n" #define JSON_FVALUE(str, name, value) sprintf(str, "\"%s\": %.1f,\n", name, value) #define JSON_IVALUE(str, name, value) sprintf(str, "\"%s\": %d,\n", name, value) +#define JSON_LIVALUE(str, name, value) sprintf(str, "\"%s\": %ld,\n", name, value) #define JSON_STRING(str, name, value) sprintf(str, "\"%s\": \"%s\",\n", name, value) #define BUFFER_SIZE (1024 * 1024) typedef struct IeMetaDataMuxer { + const AVClass *class; char *meta_data_strings; size_t meta_data_length; unsigned int current_escape_num; + char *source; + char *tag; } IeMetaDataMuxer; static int fill_content(AVFormatContext *s, const char *str, int flush) @@ -127,12 +132,13 @@ static int pack(AVFormatContext *s, const char *org, ...) ++md->current_escape_num; break; case 'i': //int value + case 'I': //long int value case 'f': //float value case 's': //str value name = va_arg(argp, char*); - if (p[i] == 'i') { + if (p[i] == 'i' || p[i] == 'I') { ipara = va_arg(argp, int); - JSON_IVALUE(tmp_str, name, ipara); + p[i] == 'i' ? JSON_IVALUE(tmp_str, name, ipara) : JSON_LIVALUE(tmp_str, name, ipara); } else if (p[i] == 'f') { fpara = va_arg(argp, double); JSON_FVALUE(tmp_str, name, fpara); @@ -184,6 +190,7 @@ static void deinit(AVFormatContext *s) { IeMetaDataMuxer *md = s->priv_data; av_free(md->meta_data_strings); + } static int write_header(AVFormatContext *s) @@ -202,13 +209,35 @@ static int jhead_write(AVFormatContext *s, AVFrame *frm_data) { char tmp_str[80]; IeMetaDataMuxer *md = s->priv_data; + long nano_ts = s->streams[0] ? + av_q2d(s->streams[0]->time_base) * frm_data->pts * 1000000000 : + -1; sprintf(tmp_str, "\"resolution\":{\"width\":%d,\"height\":%d},\n", frm_data->width, frm_data->height); - pack(s, "{isS", "timestamp", frm_data->best_effort_timestamp, - "source", "string", + pack(s, "{IsS", "timestamp", nano_ts, + "source", md->source, tmp_str); - sprintf(tmp_str, "\"tag\":{\"custom_key\":\"custom_value\"},\n"); + if (!md->tag) + sprintf(tmp_str, "\"tags\":{\"custom_key\":\"custom_value\"},\n"); + else { + char *token, *save_ptr, *tag_str; + int offset; + char key[128] = ""; + char tags[256]; + float value = 0.0; + + memcpy(tags, md->tag, strlen(md->tag)); + offset = sprintf(tmp_str, "\"tags\":{"); + for (tag_str = tags; ; tag_str = NULL) { + token = strtok_r(tag_str, ",", &save_ptr); + if (token == NULL) + break; + sscanf(token, "%127[^:]:%f", key, &value); + offset += sprintf(tmp_str + offset, "\"%s\":%1.3f,", key, value); + } + sprintf(tmp_str + offset - 2, "},\n"); + } pack(s, "S[", tmp_str, "objects"); return 0; @@ -314,16 +343,32 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) return 0; } +#define OFFSET(x) offsetof(IeMetaDataMuxer, x) +#define ENC AV_OPT_FLAG_ENCODING_PARAM +static const AVOption options[] = { + { "source_url", "the source url/path to put into the json metadata", OFFSET(source), AV_OPT_TYPE_STRING, { .str = "auto" }, 0, 0, ENC }, + { "custom_tag", "the customer tag and value, usage: -custom_tag \"key1:value1,key2:value2\"", OFFSET(tag), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, ENC }, + { NULL }, +}; + +static const AVClass iemetadata_muxer_class = { + .class_name = "iemetadata muxer", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + AVOutputFormat ff_iemetadata_muxer = { .name = "iemetadata", .long_name = NULL_IF_CONFIG_SMALL("Inference engine meta data muxer"), .extensions = "json", .priv_data_size = sizeof(IeMetaDataMuxer), + .priv_class = &iemetadata_muxer_class, .init = init, .deinit = deinit, .video_codec = AV_CODEC_ID_WRAPPED_AVFRAME, .write_header = write_header, .write_packet = write_packet, .write_trailer = write_trailer, - .flags = AVFMT_VARIABLE_FPS | AVFMT_NOTIMESTAMPS, + .flags = AVFMT_VARIABLE_FPS, }; -- 2.7.4