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_tbuffer_size;
size_tmax_buffer_size;
+ngx_flag_talign_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 *)