Skip to content

Commit

Permalink
Merge pull request #1281 from JoelLinn/feature-stream-udta-name
Browse files Browse the repository at this point in the history
mp4: parse udta stream names
  • Loading branch information
erankor committed Jun 5, 2021
2 parents 08438c3 + 8de18c5 commit 56a5407
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 3 deletions.
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

0 comments on commit 56a5407

Please sign in to comment.