Skip to content

Commit 50e203a

Browse files
committed
support arbitrary language selection
currently, language filtering (-l param) works only for pre-defined languages. change the code to use lang_str string comparison instead, in order to support arbitrary languages (incl. for example, language codes with extentions like zh_cn)
1 parent 26f0687 commit 50e203a

9 files changed

+52
-25
lines changed

ngx_http_vod_module.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -1554,7 +1554,7 @@ ngx_http_vod_init_parse_params_metadata(
15541554
vod_track_mask_and_bits(tracks_mask[media_type], cur_source->tracks_mask[media_type], request_tracks_mask[media_type]);
15551555
}
15561556
parse_params->required_tracks_mask = tracks_mask;
1557-
parse_params->langs_mask = ctx->submodule_context.request_params.langs_mask;
1557+
parse_params->langs = ctx->submodule_context.request_params.langs;
15581558
parse_params->source = cur_source;
15591559
}
15601560

@@ -3576,8 +3576,7 @@ ngx_http_vod_run_generators(ngx_http_vod_ctx_t *ctx)
35763576
continue;
35773577
}
35783578

3579-
if (parse_params.langs_mask != NULL &&
3580-
!vod_is_bit_set(parse_params.langs_mask, cur_source->sequence->tags.language))
3579+
if (!media_format_lang_exists(parse_params.langs, &cur_source->sequence->tags.lang_str))
35813580
{
35823581
ngx_memzero(&cur_source->track_array, sizeof(cur_source->track_array));
35833582
continue;

ngx_http_vod_request_parse.c

+16-11
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,8 @@ ngx_http_vod_parse_uri_file_name(
218218
sequence_tracks_mask_t* sequence_tracks_mask;
219219
ngx_str_t* cur_sequence_id;
220220
ngx_str_t* last_sequence_id;
221+
ngx_str_t* cur_lang;
222+
ngx_str_t* last_lang;
221223
track_mask_t default_tracks_mask;
222224
track_mask_t* tracks_mask;
223225
uint32_t segment_index_shift;
@@ -480,35 +482,38 @@ ngx_http_vod_parse_uri_file_name(
480482
// languages
481483
if (*start_pos == 'l')
482484
{
483-
result->langs_mask = ngx_pcalloc(r->pool, LANG_MASK_SIZE * sizeof(result->langs_mask[0]));
484-
if (result->langs_mask == NULL)
485+
result->langs = ngx_pcalloc(r->pool, MAX_LANGUAGE_COUNT * sizeof(result->langs[0]));
486+
if (result->langs == NULL)
485487
{
486488
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
487489
"ngx_http_vod_parse_uri_file_name: ngx_palloc failed");
488490
return ngx_http_vod_status_to_ngx_error(r, VOD_ALLOC_FAILED);
489491
}
490492

493+
cur_lang = result->langs;
494+
last_lang = cur_lang + MAX_LANGUAGE_COUNT;
495+
491496
for (;;)
492497
{
493498
start_pos++; // skip the l
494-
if (start_pos + LANG_ISO639_3_LEN > end_pos)
499+
500+
if (cur_lang >= last_lang)
495501
{
496502
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
497-
"ngx_http_vod_parse_uri_file_name: language specifier length must be 3 characters");
503+
"ngx_http_vod_parse_uri_file_name: the number of language codes exceeds the limit");
498504
return ngx_http_vod_status_to_ngx_error(r, VOD_BAD_REQUEST);
499505
}
500506

501-
lang_id = lang_parse_iso639_3_code(iso639_3_str_to_int(start_pos));
502-
if (lang_id == 0)
507+
cur_lang->data = start_pos;
508+
509+
while (start_pos < end_pos && *start_pos != '-')
503510
{
504-
ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
505-
"ngx_http_vod_parse_uri_file_name: failed to parse language specifier %*s", (size_t)3, start_pos);
506-
return ngx_http_vod_status_to_ngx_error(r, VOD_BAD_REQUEST);
511+
start_pos++;
507512
}
508513

509-
vod_set_bit(result->langs_mask, lang_id);
514+
cur_lang->len = start_pos - cur_lang->data;
510515

511-
start_pos += LANG_ISO639_3_LEN;
516+
cur_lang++;
512517

513518
skip_dash(start_pos, end_pos);
514519

vod/language_code.h

-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66

77
// constants
88
#define LANG_ISO639_3_LEN (3)
9-
#define LANG_MASK_SIZE vod_array_length_for_bits(VOD_LANG_COUNT)
109

1110
// macros
1211
#define iso639_3_str_to_int(x) \

vod/media_format.c

+24
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,30 @@
33
#include "avc_parser.h"
44
#include "hevc_parser.h"
55

6+
bool_t
7+
media_format_lang_exists(vod_str_t* langs, vod_str_t* lang)
8+
{
9+
vod_str_t* cur;
10+
vod_str_t* last;
11+
12+
if (langs == NULL)
13+
{
14+
return TRUE;
15+
}
16+
17+
last = langs + MAX_LANGUAGE_COUNT;
18+
for (cur = langs; cur < last && cur->len != 0; cur++)
19+
{
20+
if (lang->len == cur->len &&
21+
vod_strncasecmp(lang->data, cur->data, cur->len) == 0)
22+
{
23+
return TRUE;
24+
}
25+
}
26+
27+
return FALSE;
28+
}
29+
630
vod_status_t
731
media_format_finalize_track(
832
request_context_t* request_context,

vod/media_format.h

+4-1
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
#define MAX_DURATION_SEC (1000000)
3636
#define MAX_CLIP_DURATION (90000000) // 25h
3737
#define MAX_SEQUENCE_DURATION (864000000) // 10 days
38+
#define MAX_LANGUAGE_COUNT (4)
3839

3940
// read flags
4041
#define MEDIA_READ_FLAG_REALLOC_BUFFER (0x1)
@@ -180,7 +181,7 @@ typedef struct {
180181

181182
typedef struct {
182183
track_mask_t* required_tracks_mask;
183-
uint64_t* langs_mask;
184+
ngx_str_t* langs;
184185
uint32_t clip_from;
185186
uint32_t clip_to;
186187
media_range_t* range;
@@ -400,6 +401,8 @@ typedef struct {
400401
} media_format_t;
401402

402403
// functions
404+
bool_t media_format_lang_exists(vod_str_t* langs, vod_str_t* lang);
405+
403406
vod_status_t media_format_finalize_track(
404407
request_context_t* request_context,
405408
int parse_type,

vod/media_set.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@ typedef struct {
181181
track_mask_t tracks_mask[MEDIA_TYPE_COUNT];
182182
sequence_tracks_mask_t* sequence_tracks_mask;
183183
sequence_tracks_mask_t* sequence_tracks_mask_end;
184-
uint64_t* langs_mask; // [LANG_MASK_SIZE]
184+
vod_str_t* langs;
185185
uint32_t version;
186186
uint32_t width;
187187
uint32_t height;

vod/mkv/mkv_format.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -867,9 +867,8 @@ mkv_metadata_parse(
867867
}
868868

869869
// filter by language
870-
if (parse_params->langs_mask != NULL &&
871-
media_type == MEDIA_TYPE_AUDIO &&
872-
!vod_is_bit_set(parse_params->langs_mask, lang_id))
870+
if (media_type == MEDIA_TYPE_AUDIO &&
871+
!media_format_lang_exists(parse_params->langs, &track.language))
873872
{
874873
continue;
875874
}

vod/mp4/mp4_parser.c

+2-3
Original file line numberDiff line numberDiff line change
@@ -2889,9 +2889,8 @@ mp4_parser_process_moov_atom_callback(void* ctx, atom_info_t* atom_info)
28892889
}
28902890

28912891
// filter by language
2892-
if (context->parse_params.langs_mask != NULL &&
2893-
metadata_parse_context.media_info.media_type == MEDIA_TYPE_AUDIO &&
2894-
!vod_is_bit_set(context->parse_params.langs_mask, metadata_parse_context.media_info.tags.language))
2892+
if (metadata_parse_context.media_info.media_type == MEDIA_TYPE_AUDIO &&
2893+
!media_format_lang_exists(context->parse_params.langs, &metadata_parse_context.media_info.tags.lang_str))
28952894
{
28962895
return VOD_OK;
28972896
}

vod/subtitle/subtitle_format.c

+1-2
Original file line numberDiff line numberDiff line change
@@ -97,8 +97,7 @@ subtitle_parse(
9797
}
9898

9999
// filter by language
100-
if (parse_params->langs_mask != NULL &&
101-
!vod_is_bit_set(parse_params->langs_mask, tags.language))
100+
if (!media_format_lang_exists(parse_params->langs, &tags.lang_str))
102101
{
103102
metadata->base.tracks.nelts = 0;
104103
return VOD_OK;

0 commit comments

Comments
 (0)