Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

mp4: parse udta stream names #1281

Merged
merged 1 commit into from Jun 5, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions README.md
Expand Up @@ -1766,6 +1766,13 @@ When enabled, the module ignores any edit lists (elst) in the MP4 file.

When enabled, the module parses the name field of the hdlr MP4 atom, and uses it as the stream label.

#### vod_parse_udta_name
* **syntax**: `vod_parse_udta_name on/off`
* **default**: `off`
* **context**: `http`, `server`, `location`

When enabled, the module parses the name atom child of the udta MP4 atom, and uses it as the stream label.

### Nginx variables

The module adds the following nginx variables:
Expand Down
13 changes: 13 additions & 0 deletions ngx_http_vod_conf.c
Expand Up @@ -89,6 +89,7 @@ ngx_http_vod_create_loc_conf(ngx_conf_t *cf)
conf->max_upstream_headers_size = NGX_CONF_UNSET_SIZE;
conf->ignore_edit_list = NGX_CONF_UNSET;
conf->parse_hdlr_name = NGX_CONF_UNSET;
conf->parse_udta_name = NGX_CONF_UNSET;
conf->max_mapping_response_size = NGX_CONF_UNSET_SIZE;

conf->metadata_cache = NGX_CONF_UNSET_PTR;
Expand Down Expand Up @@ -213,6 +214,7 @@ ngx_http_vod_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)

ngx_conf_merge_value(conf->ignore_edit_list, prev->ignore_edit_list, 0);
ngx_conf_merge_value(conf->parse_hdlr_name, prev->parse_hdlr_name, 0);
ngx_conf_merge_value(conf->parse_udta_name, prev->parse_udta_name, 0);

conf->parse_flags = 0;
if (!conf->ignore_edit_list)
Expand All @@ -223,6 +225,10 @@ ngx_http_vod_merge_loc_conf(ngx_conf_t *cf, void *parent, void *child)
{
conf->parse_flags |= PARSE_FLAG_HDLR_NAME;
}
if (conf->parse_udta_name)
{
conf->parse_flags |= PARSE_FLAG_UDTA_NAME;
}

if (conf->upstream_extra_args == NULL)
{
Expand Down Expand Up @@ -1044,6 +1050,13 @@ ngx_command_t ngx_http_vod_commands[] = {
offsetof(ngx_http_vod_loc_conf_t, parse_hdlr_name),
NULL },

{ ngx_string("vod_parse_udta_name"),
NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
ngx_conf_set_flag_slot,
NGX_HTTP_LOC_CONF_OFFSET,
offsetof(ngx_http_vod_loc_conf_t, parse_udta_name),
NULL },

// upstream parameters - only for mapped/remote modes
{ ngx_string("vod_max_upstream_headers_size"),
NGX_HTTP_MAIN_CONF | NGX_HTTP_SRV_CONF | NGX_HTTP_LOC_CONF | NGX_CONF_TAKE1,
Expand Down
1 change: 1 addition & 0 deletions ngx_http_vod_conf.h
Expand Up @@ -56,6 +56,7 @@ struct ngx_http_vod_loc_conf_s {
size_t max_upstream_headers_size;
ngx_flag_t ignore_edit_list;
ngx_flag_t parse_hdlr_name;
ngx_flag_t parse_udta_name;
int parse_flags;
ngx_http_complex_value_t *upstream_extra_args;
ngx_buffer_cache_t* mapping_cache[CACHE_TYPE_COUNT];
Expand Down
3 changes: 2 additions & 1 deletion vod/media_format.h
Expand Up @@ -33,7 +33,8 @@
#define PARSE_FLAG_SAVE_RAW_ATOMS (0x00000010) // mp4 only
#define PARSE_FLAG_EDIT_LIST (0x00000020)
#define PARSE_FLAG_HDLR_NAME (0x00000040)
#define PARSE_FLAG_CODEC_TRANSFER_CHAR (0x00000080)
#define PARSE_FLAG_UDTA_NAME (0x00000080)
#define PARSE_FLAG_CODEC_TRANSFER_CHAR (0x00000100)

// frames
#define PARSE_FLAG_FRAMES_DURATION (0x00010000)
Expand Down
2 changes: 2 additions & 0 deletions vod/mp4/mp4_defs.h
Expand Up @@ -49,6 +49,8 @@
#define ATOM_NAME_DCOM (0x6d6f6364) // data compression
#define ATOM_NAME_CMVD (0x64766d63) // compressed movie data
#define ATOM_NAME_DOPS (0x73704f64)
#define ATOM_NAME_UDTA (0x61746475)
#define ATOM_NAME_NAME (0x656d616e)

#define ATOM_NAME_NULL (0x00000000)

Expand Down
51 changes: 49 additions & 2 deletions vod/mp4/mp4_parser.c
Expand Up @@ -76,6 +76,7 @@ typedef struct {
atom_info_t dinf;
atom_info_t elst;
atom_info_t tkhd;
atom_info_t udta_name;
} trak_atom_infos_t;

typedef struct {
Expand Down Expand Up @@ -191,11 +192,17 @@ static const relevant_atom_t relevant_atoms_edts[] = {
{ ATOM_NAME_NULL, 0, NULL }
};

static const relevant_atom_t relevant_atoms_udta[] = {
{ ATOM_NAME_NAME, offsetof(trak_atom_infos_t, udta_name), NULL },
{ ATOM_NAME_NULL, 0, NULL }
};

static const relevant_atom_t relevant_atoms_trak[] = {
{ ATOM_NAME_MDIA, 0, relevant_atoms_mdia },
{ ATOM_NAME_EDTS, 0, relevant_atoms_edts },
{ ATOM_NAME_TKHD, offsetof(trak_atom_infos_t, tkhd), NULL },
{ ATOM_NAME_SENC, offsetof(trak_atom_infos_t, senc), NULL },
{ ATOM_NAME_UDTA, 0, relevant_atoms_udta },
{ ATOM_NAME_NULL, 0, NULL }
};

Expand Down Expand Up @@ -272,8 +279,8 @@ mp4_parser_parse_hdlr_atom(atom_info_t* atom_info, metadata_parse_context_t* con
break;
}

// parse the name
if ((context->parse_params.parse_type & PARSE_FLAG_HDLR_NAME) == 0)
// parse the name / already set
if ((context->parse_params.parse_type & PARSE_FLAG_HDLR_NAME) == 0 || context->media_info.label.data != NULL)
{
return VOD_OK;
}
Expand Down Expand Up @@ -533,6 +540,36 @@ mp4_parser_parse_mdhd_atom(atom_info_t* atom_info, metadata_parse_context_t* con
return VOD_OK;
}

static vod_status_t
mp4_parser_parse_udta_name_atom(atom_info_t* atom_info, metadata_parse_context_t* context)
{
vod_str_t name;
name.data = (u_char*)atom_info->ptr;
name.len = atom_info->size;

// atom empty/non-existent or name already set
if (name.len == 0 || context->media_info.label.data != NULL)
{
return VOD_OK;
}

context->media_info.label.data = vod_alloc(
context->request_context->pool,
name.len + 1);
if (context->media_info.label.data == NULL)
{
vod_log_debug0(VOD_LOG_DEBUG_LEVEL, context->request_context->log, 0,
"mp4_parser_parse_udta_name_atom: vod_alloc failed");
return VOD_ALLOC_FAILED;
}

vod_memcpy(context->media_info.label.data, name.data, name.len);
context->media_info.label.data[name.len] = '\0';
context->media_info.label.len = name.len;

return VOD_OK;
}

static vod_status_t
mp4_parser_parse_stts_atom_total_duration_only(atom_info_t* atom_info, metadata_parse_context_t* context)
{
Expand Down Expand Up @@ -2678,6 +2715,16 @@ mp4_parser_process_moov_atom_callback(void* ctx, atom_info_t* atom_info)
return rc;
}

// udta stream name
if ((context->parse_params.parse_type & PARSE_FLAG_UDTA_NAME) != 0)
{
rc = mp4_parser_parse_udta_name_atom(&trak_atom_infos.udta_name, &metadata_parse_context);
if (rc != VOD_OK)
{
return rc;
}
}

// get the codec type and extra data
rc = mp4_parser_parse_stsd_atom(&trak_atom_infos.stsd, &metadata_parse_context);
if (rc != VOD_OK)
Expand Down