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 <a...@nginx.com> 写道:
> > On 19 May 2014, at 04:56, 刘斌 <yurner...@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 <a...@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@nginx.org > http://mailman.nginx.org/mailman/listinfo/nginx-devel _______________________________________________ nginx-devel mailing list nginx-devel@nginx.org http://mailman.nginx.org/mailman/listinfo/nginx-devel