Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
[patch]nginx mp4 module about "keyframe aligning"
Index: bundle/nginx-1.4.3/src/http/modules/ngx_http_mp4_module.c
===================================================================
--- bundle/nginx-1.4.3/src/http/modules/ngx_http_mp4_module.c (revision 126116)
+++ bundle/nginx-1.4.3/src/http/modules/ngx_http_mp4_module.c (working copy)
@@ -129,6 +129,7 @@
off_t end;
off_t content_length;
ngx_uint_t start;
+ ngx_uint_t old_start;
ngx_uint_t length;
uint32_t timescale;
ngx_http_request_t *request;
@@ -2100,6 +2101,51 @@
static ngx_int_t
+ngx_http_mp4_sync_sample_seek(ngx_http_mp4_file_t *mp4,ngx_http_mp4_trak_t *trak, ngx_uint_t *sample, ngx_uint_t old_sample, uint32_t duration, uint32_t timescale, ngx_uint_t flag)
+{
+ uint32_t stss_sample, *stss_entry, *stss_end;
+ ngx_buf_t *stss_data;
+ ngx_uint_t stss_entries;
+
+ stss_data = trak->out[NGX_HTTP_MP4_STSS_DATA].buf;
+ if (stss_data == NULL) return -1;
+
+ if ((mp4->start == 0) && (flag == 1)) {
+ return -1;
+ }
+
+ stss_entries = trak->sync_samples_entries;
+ stss_entry = (uint32_t *) stss_data->pos;
+ stss_end = (uint32_t *) stss_data->last;
+
+ while (stss_entry < stss_end) {
+ stss_sample = ngx_mp4_get_32value(stss_entry);
+
+ if (*sample < stss_sample) {
+ *sample = ngx_mp4_get_32value(stss_entry-1) - 1;
+ break;
+ }
+ if (*sample == stss_sample) {
+ *sample = ngx_mp4_get_32value(stss_entry) - 1;
+ break;
+ }
+
+ stss_entries--;
+ stss_entry++;
+ }
+ if (flag == 1) {
+ mp4->start = (*sample * duration) * 1000 / timescale;
+ }
+
+ if (flag == 0) {
+ mp4->length = (*sample - 1) * duration * 1000 / timescale - mp4->start;
+ }
+
+ return 0;
+}
+
+
+static ngx_int_t
ngx_http_mp4_crop_stts_data(ngx_http_mp4_file_t *mp4,
ngx_http_mp4_trak_t *trak, ngx_uint_t start)
{
@@ -2106,19 +2152,19 @@
uint32_t count, duration, rest;
uint64_t start_time;
ngx_buf_t *data;
- ngx_uint_t start_sample, entries, start_sec;
+ ngx_uint_t start_sample, entries, start_sec, old_start_sample;
ngx_mp4_stts_entry_t *entry, *end;
if (start) {
start_sec = mp4->start;
+ mp4->old_start = mp4->start;
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
"mp4 stts crop start_time:%ui", start_sec);
} else if (mp4->length) {
- start_sec = mp4->length;
-
- ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
+ start_sec = mp4->length + mp4->old_start;
+ ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
"mp4 stts crop end_time:%ui", start_sec);
} else {
@@ -2134,6 +2180,7 @@
entry = (ngx_mp4_stts_entry_t *) data->pos;
end = (ngx_mp4_stts_entry_t *) data->last;
+
while (entry < end) {
count = ngx_mp4_get_32value(entry->count);
duration = ngx_mp4_get_32value(entry->duration);
@@ -2144,6 +2191,10 @@
if (start_time < (uint64_t) count * duration) {
start_sample += (ngx_uint_t) (start_time / duration);
+ old_start_sample = start_sample;
+ ngx_http_mp4_sync_sample_seek(mp4, trak, &start_sample, old_start_sample, duration, trak->timescale, start);
+ start_time = (uint64_t)start_sample * duration;
+
rest = (uint32_t) (start_time / duration);
goto found;
}
@@ -2183,11 +2234,13 @@
trak->start_sample, count - rest);
} else {
- ngx_mp4_set_32value(entry->count, rest);
data->last = (u_char *) (entry + 1);
trak->time_to_sample_entries -= entries - 1;
- trak->end_sample = trak->start_sample + start_sample;
+ trak->end_sample = start_sample - 1;
+
+ ngx_mp4_set_32value(entry->count, trak->end_sample - trak->start_sample);
+
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
"end_sample:%ui, new count:%uD",
trak->end_sample, rest);
@@ -2297,7 +2350,6 @@
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
"sync sample entries:%uD", trak->sync_samples_entries);
-
if (trak->sync_samples_entries) {
entry = (uint32_t *) data->pos;
end = (uint32_t *) data->last;
@@ -2305,8 +2357,10 @@
start_sample = trak->start_sample;
while (entry < end) {
+
sample = ngx_mp4_get_32value(entry);
sample -= start_sample;
+
ngx_mp4_set_32value(entry, sample);
entry++;
}
@@ -2366,7 +2420,13 @@
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, mp4->file.log, 0,
"sync:%uD", sample);
- if (sample >= start_sample) {
+ if (start) {
+ if (sample >= start_sample - 1) {
+ goto found;
+ }
+ }
+
+ if (sample >= start_sample - 1) {
goto found;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.