mp4_module doubt

liubin yurnerola at gmail.com
Tue May 20 07:45:31 UTC 2014


Hi:
	It’s really so nice of u guys to help solve this problem.
	Actually ,i tried the patch. Find two little bug:
	1.start_time is badly used ,may anther var should be declared.
	2. 
> 
> start_time += (sample - start_sample) * duration;
	This entry ,maybe we forget the first part. start_sample is in this entry already.
	
	Thanks again!
在 2014年5月19日,下午8:02,Roman Arutyunyan <arut at nginx.com> 写道:

> 
> On 19 May 2014, at 04:56, 刘斌 <yurnerola at gmail.com> wrote:
> 
>> Hello,
>>     I'm just reading this module and wandering if we can reduce flow
>> from nginx by align start time to key frames.Our company is a video
>> website from China.And i want to know does it make sense to do this.
> 
> Here’s the patch solving your problem.  Currently there are no plans to
> add this to upstream but that can change.  It would be nice to hear your
> feedback.  Here’s an example of “mp4_align_start” directive added by
> the patch.
> 
>  location /mp4 {
>      mp4;
>      mp4_align_start on;
>      root /tmp/;
>  }
> 
> # HG changeset patch
> # User Roman Arutyunyan <arut at nginx.com>
> # Date 1400496445 -14400
> #      Mon May 19 14:47:25 2014 +0400
> # Node ID fccafb910a3361e3e2d6ca8afd6edfb576444997
> # Parent  3a48775f1535fe37cd9c034d92c5a5e9ae208c1e
> Mp4: align start to video key frame.
> 
> The new directive mp4_align_start adjusts start time to make
> the result mp4 start with a key frame.  This makes sense for
> some players displaying garbage until the first key frame.
> 
> diff -r 3a48775f1535 -r fccafb910a33 src/http/modules/ngx_http_mp4_module.c
> --- a/src/http/modules/ngx_http_mp4_module.c	Tue Apr 29 12:28:41 2014 +0400
> +++ b/src/http/modules/ngx_http_mp4_module.c	Mon May 19 14:47:25 2014 +0400
> @@ -43,6 +43,7 @@
> typedef struct {
>     size_t                buffer_size;
>     size_t                max_buffer_size;
> +    ngx_flag_t            align_start;
> } ngx_http_mp4_conf_t;
> 
> 
> @@ -303,6 +304,8 @@ static ngx_int_t ngx_http_mp4_update_co6
>     ngx_http_mp4_trak_t *trak);
> static void ngx_http_mp4_adjust_co64_atom(ngx_http_mp4_file_t *mp4,
>     ngx_http_mp4_trak_t *trak, off_t adjustment);
> +static ngx_int_t ngx_http_mp4_align_start(ngx_http_mp4_file_t *mp4,
> +    ngx_http_mp4_trak_t *trak);
> 
> static char *ngx_http_mp4(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
> static void *ngx_http_mp4_create_conf(ngx_conf_t *cf);
> @@ -332,6 +335,13 @@ static ngx_command_t  ngx_http_mp4_comma
>       offsetof(ngx_http_mp4_conf_t, max_buffer_size),
>       NULL },
> 
> +    { ngx_string("mp4_align_start"),
> +      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_mp4_conf_t, align_start),
> +      NULL },
> +
>       ngx_null_command
> };
> 
> @@ -742,6 +752,14 @@ ngx_http_mp4_process(ngx_http_mp4_file_t
>     end_offset = 0;
>     trak = mp4->trak.elts;
> 
> +    if (conf->align_start) {
> +        for (i = 0; i < mp4->trak.nelts; i++) {
> +            if (ngx_http_mp4_align_start(mp4, &trak[i]) == NGX_OK) {
> +                break;
> +            }
> +        }
> +    }
> +
>     for (i = 0; i < mp4->trak.nelts; i++) {
> 
>         if (ngx_http_mp4_update_stts_atom(mp4, &trak[i]) != NGX_OK) {
> @@ -3457,6 +3475,110 @@ ngx_http_mp4_adjust_co64_atom(ngx_http_m
> }
> 
> 
> +static ngx_int_t
> +ngx_http_mp4_align_start(ngx_http_mp4_file_t *mp4, ngx_http_mp4_trak_t *trak)
> +{
> +    uint32_t               count, duration, sample, start_sample,
> +                          *stss_entry, *stss_end;
> +    uint64_t               start_time;
> +    ngx_buf_t             *stts_data, *stss_data;
> +    ngx_mp4_stts_entry_t  *stts_entry, *stts_end;
> +
> +    stss_data = trak->out[NGX_HTTP_MP4_STSS_DATA].buf;
> +    if (stss_data == NULL) {
> +        return NGX_AGAIN;
> +    }
> +
> +    stts_data = trak->out[NGX_HTTP_MP4_STTS_DATA].buf;
> +    if (stts_data == NULL) {
> +        return NGX_AGAIN;
> +    }
> +
> +    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "align start");
> +
> +    start_time = (uint64_t) mp4->start * trak->timescale / 1000;
> +    start_sample = 0;
> +
> +    stts_entry = (ngx_mp4_stts_entry_t *) stts_data->pos;
> +    stts_end = (ngx_mp4_stts_entry_t *) stts_data->last;
> +
> +    while (stts_entry < stts_end) {
> +        count = ngx_mp4_get_32value(stts_entry->count);
> +        duration = ngx_mp4_get_32value(stts_entry->duration);
> +
> +        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
> +                       "time:%uL, count:%uD, duration:%uD",
> +                       start_time, count, duration);
> +
> +        if (start_time < (uint64_t) count * duration) {
> +            start_sample += (ngx_uint_t) (start_time / duration);
> +            goto found_stts;
> +        }
> +
> +        start_sample += count;
> +        start_time -= count * duration;
> +        stts_entry++;
> +    }
> +
> +    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "out of stts samples");
> +
> +    return NGX_AGAIN;
> +
> +found_stts:
> +
> +    stss_entry = (uint32_t *) stss_data->pos;
> +    stss_end = (uint32_t *) stss_data->last;
> +
> +    while (stss_entry < stss_end) {
> +        sample = ngx_mp4_get_32value(stss_entry);
> +
> +        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
> +                       "sync:%uD", sample);
> +
> +        if (sample >= start_sample + 1) {
> +            sample--;
> +            goto found_stss;
> +        }
> +
> +        stss_entry++;
> +    }
> +
> +    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "out of stss samples");
> +
> +    return NGX_AGAIN;
> +
> +found_stss:
> +
> +    while (stts_entry < stts_end) {
> +        count = ngx_mp4_get_32value(stts_entry->count);
> +        duration = ngx_mp4_get_32value(stts_entry->duration);
> +
> +        ngx_log_debug3(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
> +                       "time:%uL, count:%uD, duration:%uD",
> +                       start_time, count, duration);
> +
> +        if (start_sample + count >= sample) {
> +            start_time += (sample - start_sample) * duration;
> +            mp4->start = (uint64_t) start_time * 1000 / trak->timescale;
> +
> +            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
> +                           "aligned start:%ui, samples:%uD",
> +                           mp4->start, sample - start_sample);
> +
> +            return NGX_OK;
> +        }
> +
> +        start_sample += count;
> +        start_time -= count * duration;
> +        stts_entry++;
> +    }
> +
> +    ngx_log_debug0(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0, "out of stts samples");
> +
> +    return NGX_AGAIN;
> +}
> +
> +
> static char *
> ngx_http_mp4(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
> {
> @@ -3481,6 +3603,7 @@ ngx_http_mp4_create_conf(ngx_conf_t *cf)
> 
>     conf->buffer_size = NGX_CONF_UNSET_SIZE;
>     conf->max_buffer_size = NGX_CONF_UNSET_SIZE;
> +    conf->align_start = NGX_CONF_UNSET;
> 
>     return conf;
> }
> @@ -3495,6 +3618,7 @@ ngx_http_mp4_merge_conf(ngx_conf_t *cf, 
>     ngx_conf_merge_size_value(conf->buffer_size, prev->buffer_size, 512 * 1024);
>     ngx_conf_merge_size_value(conf->max_buffer_size, prev->max_buffer_size,
>                               10 * 1024 * 1024);
> +    ngx_conf_merge_value(conf->align_start, prev->align_start, 0);
> 
>     return NGX_CONF_OK;
> }
> 
> _______________________________________________
> nginx-devel mailing list
> nginx-devel at nginx.org
> http://mailman.nginx.org/mailman/listinfo/nginx-devel



More information about the nginx-devel mailing list