From 5e73e56611c8275bd8d5d80fd1ead22ecde9270e Mon Sep 17 00:00:00 2001 From: David Winder Date: Mon, 2 Oct 2023 16:00:04 +0300 Subject: [PATCH 1/3] Adding id3TagLabel field for source clip --- README.md | 1 + vod/hls/hls_muxer.c | 15 ++++++++++++++- vod/media_clip.h | 1 + vod/media_set_parser.c | 1 + 4 files changed, 17 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index aa982906..fe9adf70 100644 --- a/README.md +++ b/README.md @@ -584,6 +584,7 @@ Optional fields: to decrypt the file. * `encryptionScheme` - the encryption scheme that was used to encrypt the file. Currently, only two schemes are supported - `cenc` for MP4 files, `aes-cbc` for caption files. +* `id3TagLabel` - a string contain label to insert in the data stream. This will be done only when `vod_hls_mpegts_output_id3_timestamps` is ON and the root sequnce has ID #### Rate filter clip diff --git a/vod/hls/hls_muxer.c b/vod/hls/hls_muxer.c index 26630ddc..91bd6ed9 100644 --- a/vod/hls/hls_muxer.c +++ b/vod/hls/hls_muxer.c @@ -11,8 +11,11 @@ #define ID3_TEXT_JSON_FORMAT "{\"timestamp\":%uL}%Z" #define ID3_TEXT_JSON_SEQUENCE_ID_PREFIX_FORMAT "{\"timestamp\":%uL,\"sequenceId\":\"" +#define ID3_TEXT_JSON_CLIP_LABEL_FORMAT "\",\"clipLabel\":\"" #define ID3_TEXT_JSON_SEQUENCE_ID_SUFFIX "\"}" +#define CLIP_LABEL_MAX_SIZE 32 + // from ffmpeg mpegtsenc #define DEFAULT_PES_HEADER_FREQ 16 #define DEFAULT_PES_PAYLOAD_SIZE ((DEFAULT_PES_HEADER_FREQ - 1) * 184 + 170) @@ -171,6 +174,7 @@ hls_muxer_init_id3_stream( size_t data_size; int64_t timestamp; void* frames_source_context; + vod_str_t clip_label; cur_stream = state->last_stream; @@ -196,8 +200,9 @@ hls_muxer_init_id3_stream( if (sequence_id->len != 0) { sequence_id_escape = vod_escape_json(NULL, sequence_id->data, sequence_id->len); - data_size = sizeof(ID3_TEXT_JSON_SEQUENCE_ID_PREFIX_FORMAT) + VOD_INT64_LEN + + data_size = sizeof(ID3_TEXT_JSON_SEQUENCE_ID_PREFIX_FORMAT) + VOD_INT64_LEN + sequence_id->len + sequence_id_escape + + sizeof(ID3_TEXT_JSON_CLIP_LABEL_FORMAT) + CLIP_LABEL_MAX_SIZE + sizeof(ID3_TEXT_JSON_SEQUENCE_ID_SUFFIX); } else @@ -268,6 +273,14 @@ hls_muxer_init_id3_stream( { p = vod_copy(p, sequence_id->data, sequence_id->len); } + + clip_label = ref_track->file_info.source->id3_tag_label; + if (clip_label.len != 0) + { + p = vod_copy(p, ID3_TEXT_JSON_CLIP_LABEL_FORMAT, sizeof(ID3_TEXT_JSON_CLIP_LABEL_FORMAT) - 1); + p = vod_copy(p, clip_label.data, vod_min(CLIP_LABEL_MAX_SIZE, clip_label.len)); + } + p = vod_copy(p, ID3_TEXT_JSON_SEQUENCE_ID_SUFFIX, sizeof(ID3_TEXT_JSON_SEQUENCE_ID_SUFFIX)); } diff --git a/vod/media_clip.h b/vod/media_clip.h index 6fe34886..19c88090 100644 --- a/vod/media_clip.h +++ b/vod/media_clip.h @@ -94,6 +94,7 @@ struct media_clip_source_s { media_clip_source_t* next; uint64_t last_offset; + vod_str_t id3_tag_label; }; typedef struct { diff --git a/vod/media_set_parser.c b/vod/media_set_parser.c index a1a0e7ff..27c3e728 100644 --- a/vod/media_set_parser.c +++ b/vod/media_set_parser.c @@ -126,6 +126,7 @@ static json_object_value_def_t media_clip_source_params[] = { { vod_string("encryptionKey"), VOD_JSON_STRING, offsetof(media_clip_source_t, encryption.key), media_set_parse_base64_string }, { vod_string("encryptionIv"), VOD_JSON_STRING, offsetof(media_clip_source_t, encryption.iv), media_set_parse_base64_string }, { vod_string("sourceType"), VOD_JSON_STRING, offsetof(media_clip_source_t, source_type), media_set_parse_source_type }, + { vod_string("id3TagLabel"), VOD_JSON_STRING, offsetof(media_clip_source_t, id3_tag_label), media_set_parse_null_term_string }, { vod_null_string, 0, 0, NULL } }; From 9953ff31ab1e86ba9421f7ace410dbda5ffa0fd2 Mon Sep 17 00:00:00 2001 From: David Winder Date: Tue, 3 Oct 2023 11:20:01 +0300 Subject: [PATCH 2/3] Change the field name to id --- README.md | 2 +- vod/hls/hls_muxer.c | 16 ++++++++-------- vod/media_clip.h | 2 +- vod/media_set_parser.c | 2 +- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index fe9adf70..6d5bc9b7 100644 --- a/README.md +++ b/README.md @@ -571,6 +571,7 @@ Mandatory fields: an empty captions file (useful in case only some videos in a playlist have captions) Optional fields: +* `id` - a string that identifies the source clip * `sourceType` - sets the interface that should be used to read the MP4 file, allowed values are: `file` and `http`. By default, the module uses `http` if `vod_remote_upstream_location` is set, and `file` otherwise. @@ -584,7 +585,6 @@ Optional fields: to decrypt the file. * `encryptionScheme` - the encryption scheme that was used to encrypt the file. Currently, only two schemes are supported - `cenc` for MP4 files, `aes-cbc` for caption files. -* `id3TagLabel` - a string contain label to insert in the data stream. This will be done only when `vod_hls_mpegts_output_id3_timestamps` is ON and the root sequnce has ID #### Rate filter clip diff --git a/vod/hls/hls_muxer.c b/vod/hls/hls_muxer.c index 91bd6ed9..a7230ad8 100644 --- a/vod/hls/hls_muxer.c +++ b/vod/hls/hls_muxer.c @@ -11,10 +11,10 @@ #define ID3_TEXT_JSON_FORMAT "{\"timestamp\":%uL}%Z" #define ID3_TEXT_JSON_SEQUENCE_ID_PREFIX_FORMAT "{\"timestamp\":%uL,\"sequenceId\":\"" -#define ID3_TEXT_JSON_CLIP_LABEL_FORMAT "\",\"clipLabel\":\"" +#define ID3_TEXT_JSON_CLIP_ID_FORMAT "\",\"clipId\":\"" #define ID3_TEXT_JSON_SEQUENCE_ID_SUFFIX "\"}" -#define CLIP_LABEL_MAX_SIZE 32 +#define CLIP_ID_MAX_SIZE 32 // from ffmpeg mpegtsenc #define DEFAULT_PES_HEADER_FREQ 16 @@ -174,7 +174,7 @@ hls_muxer_init_id3_stream( size_t data_size; int64_t timestamp; void* frames_source_context; - vod_str_t clip_label; + vod_str_t clip_id; cur_stream = state->last_stream; @@ -202,7 +202,7 @@ hls_muxer_init_id3_stream( sequence_id_escape = vod_escape_json(NULL, sequence_id->data, sequence_id->len); data_size = sizeof(ID3_TEXT_JSON_SEQUENCE_ID_PREFIX_FORMAT) + VOD_INT64_LEN + sequence_id->len + sequence_id_escape + - sizeof(ID3_TEXT_JSON_CLIP_LABEL_FORMAT) + CLIP_LABEL_MAX_SIZE + + sizeof(ID3_TEXT_JSON_CLIP_ID_FORMAT) + CLIP_ID_MAX_SIZE + sizeof(ID3_TEXT_JSON_SEQUENCE_ID_SUFFIX); } else @@ -274,11 +274,11 @@ hls_muxer_init_id3_stream( p = vod_copy(p, sequence_id->data, sequence_id->len); } - clip_label = ref_track->file_info.source->id3_tag_label; - if (clip_label.len != 0) + clip_id = ref_track->file_info.source->id; + if (clip_id.len != 0) { - p = vod_copy(p, ID3_TEXT_JSON_CLIP_LABEL_FORMAT, sizeof(ID3_TEXT_JSON_CLIP_LABEL_FORMAT) - 1); - p = vod_copy(p, clip_label.data, vod_min(CLIP_LABEL_MAX_SIZE, clip_label.len)); + p = vod_copy(p, ID3_TEXT_JSON_CLIP_ID_FORMAT, sizeof(ID3_TEXT_JSON_CLIP_ID_FORMAT) - 1); + p = vod_copy(p, clip_id.data, vod_min(CLIP_ID_MAX_SIZE, clip_id.len)); } p = vod_copy(p, ID3_TEXT_JSON_SEQUENCE_ID_SUFFIX, sizeof(ID3_TEXT_JSON_SEQUENCE_ID_SUFFIX)); diff --git a/vod/media_clip.h b/vod/media_clip.h index 19c88090..c8ab87e2 100644 --- a/vod/media_clip.h +++ b/vod/media_clip.h @@ -65,6 +65,7 @@ typedef struct ngx_http_vod_reader_s ngx_http_vod_reader_t; struct media_clip_source_s { // base media_clip_t base; + vod_str_t id; int64_t clip_time; media_range_t* range; media_track_array_t track_array; @@ -94,7 +95,6 @@ struct media_clip_source_s { media_clip_source_t* next; uint64_t last_offset; - vod_str_t id3_tag_label; }; typedef struct { diff --git a/vod/media_set_parser.c b/vod/media_set_parser.c index 27c3e728..d01f3892 100644 --- a/vod/media_set_parser.c +++ b/vod/media_set_parser.c @@ -119,6 +119,7 @@ static json_parser_union_type_def_t media_clip_union_params[] = { }; static json_object_value_def_t media_clip_source_params[] = { + { vod_string("id"), VOD_JSON_STRING, offsetof(media_clip_source_t, id), media_set_parse_null_term_string }, { vod_string("path"), VOD_JSON_STRING, offsetof(media_clip_source_t, mapped_uri), media_set_parse_null_term_string }, { vod_string("tracks"), VOD_JSON_STRING, offsetof(media_clip_source_t, tracks_mask), media_set_parse_tracks_spec }, { vod_string("clipFrom"), VOD_JSON_INT, offsetof(media_clip_source_t, clip_from), media_set_parse_int64 }, @@ -126,7 +127,6 @@ static json_object_value_def_t media_clip_source_params[] = { { vod_string("encryptionKey"), VOD_JSON_STRING, offsetof(media_clip_source_t, encryption.key), media_set_parse_base64_string }, { vod_string("encryptionIv"), VOD_JSON_STRING, offsetof(media_clip_source_t, encryption.iv), media_set_parse_base64_string }, { vod_string("sourceType"), VOD_JSON_STRING, offsetof(media_clip_source_t, source_type), media_set_parse_source_type }, - { vod_string("id3TagLabel"), VOD_JSON_STRING, offsetof(media_clip_source_t, id3_tag_label), media_set_parse_null_term_string }, { vod_null_string, 0, 0, NULL } }; From 51bdfad224f1ee54a01096cbaf10aa73f4cf29a6 Mon Sep 17 00:00:00 2001 From: David Winder Date: Thu, 5 Oct 2023 13:51:27 +0300 Subject: [PATCH 3/3] Add max of 32 size to clip id --- README.md | 2 +- vod/hls/hls_muxer.c | 3 +-- vod/media_set.h | 1 + vod/media_set_parser.c | 26 +++++++++++++++++++++++++- 4 files changed, 28 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 6d5bc9b7..ddf2fda7 100644 --- a/README.md +++ b/README.md @@ -571,7 +571,7 @@ Mandatory fields: an empty captions file (useful in case only some videos in a playlist have captions) Optional fields: -* `id` - a string that identifies the source clip +* `id` - a string that identifies the source clip (maximum 32 bytes) * `sourceType` - sets the interface that should be used to read the MP4 file, allowed values are: `file` and `http`. By default, the module uses `http` if `vod_remote_upstream_location` is set, and `file` otherwise. diff --git a/vod/hls/hls_muxer.c b/vod/hls/hls_muxer.c index a7230ad8..4cb271f0 100644 --- a/vod/hls/hls_muxer.c +++ b/vod/hls/hls_muxer.c @@ -14,7 +14,6 @@ #define ID3_TEXT_JSON_CLIP_ID_FORMAT "\",\"clipId\":\"" #define ID3_TEXT_JSON_SEQUENCE_ID_SUFFIX "\"}" -#define CLIP_ID_MAX_SIZE 32 // from ffmpeg mpegtsenc #define DEFAULT_PES_HEADER_FREQ 16 @@ -278,7 +277,7 @@ hls_muxer_init_id3_stream( if (clip_id.len != 0) { p = vod_copy(p, ID3_TEXT_JSON_CLIP_ID_FORMAT, sizeof(ID3_TEXT_JSON_CLIP_ID_FORMAT) - 1); - p = vod_copy(p, clip_id.data, vod_min(CLIP_ID_MAX_SIZE, clip_id.len)); + p = vod_copy(p, clip_id.data, clip_id.len); } p = vod_copy(p, ID3_TEXT_JSON_SEQUENCE_ID_SUFFIX, sizeof(ID3_TEXT_JSON_SEQUENCE_ID_SUFFIX)); diff --git a/vod/media_set.h b/vod/media_set.h index dff42ee7..a791c832 100644 --- a/vod/media_set.h +++ b/vod/media_set.h @@ -18,6 +18,7 @@ #define MAX_CLOSED_CAPTIONS (67) #define MAX_CLIPS (128) #define MAX_CLIPS_PER_REQUEST (16) +#define CLIP_ID_MAX_SIZE (32) #define MAX_SEQUENCES (32) #define MAX_SEQUENCE_IDS (4) #define MAX_SEQUENCE_TRACKS_MASKS (2) diff --git a/vod/media_set_parser.c b/vod/media_set_parser.c index d01f3892..ba25ae23 100644 --- a/vod/media_set_parser.c +++ b/vod/media_set_parser.c @@ -105,6 +105,7 @@ static vod_status_t media_set_parse_source(void* ctx, vod_json_object_t* element static vod_status_t media_set_parse_clips_array(void* ctx, vod_json_value_t* value, void* dest); static vod_status_t media_set_parse_bitrate(void* ctx, vod_json_value_t* value, void* dest); static vod_status_t media_set_parse_source_type(void* ctx, vod_json_value_t* value, void* dest); +static vod_status_t media_set_parse_source_clip_id(void* ctx, vod_json_value_t* value, void* dest); // constants static json_parser_union_type_def_t media_clip_union_params[] = { @@ -119,7 +120,7 @@ static json_parser_union_type_def_t media_clip_union_params[] = { }; static json_object_value_def_t media_clip_source_params[] = { - { vod_string("id"), VOD_JSON_STRING, offsetof(media_clip_source_t, id), media_set_parse_null_term_string }, + { vod_string("id"), VOD_JSON_STRING, offsetof(media_clip_source_t, id), media_set_parse_source_clip_id }, { vod_string("path"), VOD_JSON_STRING, offsetof(media_clip_source_t, mapped_uri), media_set_parse_null_term_string }, { vod_string("tracks"), VOD_JSON_STRING, offsetof(media_clip_source_t, tracks_mask), media_set_parse_tracks_spec }, { vod_string("clipFrom"), VOD_JSON_INT, offsetof(media_clip_source_t, clip_from), media_set_parse_int64 }, @@ -321,6 +322,29 @@ media_set_parse_int64( return VOD_OK; } +static vod_status_t +media_set_parse_source_clip_id( + void* ctx, + vod_json_value_t* value, + void* dest) +{ + media_filter_parse_context_t* context = ctx; + vod_status_t rc; + if (value->v.str.len > CLIP_ID_MAX_SIZE) + { + vod_log_error(VOD_LOG_ERR, context->request_context->log, 0, + "media_set_parse_source_clip_id: invalid size of id: %uz", value->v.str.len); + return VOD_BAD_MAPPING; + } + + rc = media_set_parse_null_term_string(context, value, dest); + if (rc != VOD_OK) + { + return rc; + } + return VOD_OK; +} + static vod_status_t media_set_parse_source_type( void* ctx,