mirror of
https://github.com/arut/nginx-rtmp-module.git
synced 2025-08-06 15:00:18 +08:00
video & audio working
This commit is contained in:
@ -137,10 +137,14 @@ typedef struct {
|
|||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
ngx_uint_t id;
|
||||||
|
|
||||||
ngx_int_t type;
|
ngx_int_t type;
|
||||||
ngx_int_t codec;
|
ngx_int_t codec;
|
||||||
uint32_t csid;
|
uint32_t csid;
|
||||||
u_char fhdr;
|
u_char fhdr;
|
||||||
|
ngx_int_t time_scale;
|
||||||
|
uint64_t duration;
|
||||||
|
|
||||||
u_char *header;
|
u_char *header;
|
||||||
size_t header_size;
|
size_t header_size;
|
||||||
@ -242,6 +246,8 @@ static ngx_int_t ngx_rtmp_mp4_parse(ngx_rtmp_session_t *s, u_char *pos,
|
|||||||
u_char *last);
|
u_char *last);
|
||||||
static ngx_int_t ngx_rtmp_mp4_parse_trak(ngx_rtmp_session_t *s, u_char *pos,
|
static ngx_int_t ngx_rtmp_mp4_parse_trak(ngx_rtmp_session_t *s, u_char *pos,
|
||||||
u_char *last);
|
u_char *last);
|
||||||
|
static ngx_int_t ngx_rtmp_mp4_parse_mdhd(ngx_rtmp_session_t *s, u_char *pos,
|
||||||
|
u_char *last);
|
||||||
static ngx_int_t ngx_rtmp_mp4_parse_hdlr(ngx_rtmp_session_t *s, u_char *pos,
|
static ngx_int_t ngx_rtmp_mp4_parse_hdlr(ngx_rtmp_session_t *s, u_char *pos,
|
||||||
u_char *last);
|
u_char *last);
|
||||||
static ngx_int_t ngx_rtmp_mp4_parse_stsd(ngx_rtmp_session_t *s, u_char *pos,
|
static ngx_int_t ngx_rtmp_mp4_parse_stsd(ngx_rtmp_session_t *s, u_char *pos,
|
||||||
@ -290,6 +296,7 @@ typedef struct {
|
|||||||
static ngx_rtmp_mp4_box_t ngx_rtmp_mp4_boxes[] = {
|
static ngx_rtmp_mp4_box_t ngx_rtmp_mp4_boxes[] = {
|
||||||
{ ngx_rtmp_mp4_make_tag('t','r','a','k'), ngx_rtmp_mp4_parse_trak },
|
{ ngx_rtmp_mp4_make_tag('t','r','a','k'), ngx_rtmp_mp4_parse_trak },
|
||||||
{ ngx_rtmp_mp4_make_tag('m','d','i','a'), ngx_rtmp_mp4_parse },
|
{ ngx_rtmp_mp4_make_tag('m','d','i','a'), ngx_rtmp_mp4_parse },
|
||||||
|
{ ngx_rtmp_mp4_make_tag('m','d','h','d'), ngx_rtmp_mp4_parse_mdhd },
|
||||||
{ ngx_rtmp_mp4_make_tag('h','d','l','r'), ngx_rtmp_mp4_parse_hdlr },
|
{ ngx_rtmp_mp4_make_tag('h','d','l','r'), ngx_rtmp_mp4_parse_hdlr },
|
||||||
{ ngx_rtmp_mp4_make_tag('m','i','n','f'), ngx_rtmp_mp4_parse },
|
{ ngx_rtmp_mp4_make_tag('m','i','n','f'), ngx_rtmp_mp4_parse },
|
||||||
{ ngx_rtmp_mp4_make_tag('s','t','b','l'), ngx_rtmp_mp4_parse },
|
{ ngx_rtmp_mp4_make_tag('s','t','b','l'), ngx_rtmp_mp4_parse },
|
||||||
@ -396,6 +403,8 @@ ngx_rtmp_mp4_parse_trak(ngx_rtmp_session_t *s, u_char *pos, u_char *last)
|
|||||||
|
|
||||||
if (ctx->track) {
|
if (ctx->track) {
|
||||||
ngx_memzero(ctx->track, sizeof(ctx->track));
|
ngx_memzero(ctx->track, sizeof(ctx->track));
|
||||||
|
ctx->track->id = ctx->ntracks;
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: trying track %ui", ctx->ntracks);
|
"mp4: trying track %ui", ctx->ntracks);
|
||||||
}
|
}
|
||||||
@ -423,6 +432,62 @@ ngx_rtmp_mp4_parse_trak(ngx_rtmp_session_t *s, u_char *pos, u_char *last)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_int_t
|
||||||
|
ngx_rtmp_mp4_parse_mdhd(ngx_rtmp_session_t *s, u_char *pos, u_char *last)
|
||||||
|
{
|
||||||
|
ngx_rtmp_mp4_ctx_t *ctx;
|
||||||
|
ngx_rtmp_mp4_track_t *t;
|
||||||
|
uint8_t version;
|
||||||
|
|
||||||
|
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_mp4_module);
|
||||||
|
|
||||||
|
if (ctx->track == NULL) {
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = ctx->track;
|
||||||
|
|
||||||
|
if (pos + 1 > last) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
version = *(uint8_t *) pos;
|
||||||
|
|
||||||
|
switch (version) {
|
||||||
|
case 0:
|
||||||
|
if (pos + 20 > last) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 12;
|
||||||
|
t->time_scale = ngx_rtmp_r32(*(uint32_t *) pos);
|
||||||
|
pos += 4;
|
||||||
|
t->duration = ngx_rtmp_r32(*(uint32_t *) pos);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
if (pos + 28 > last) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
pos += 20;
|
||||||
|
t->time_scale = ngx_rtmp_r32(*(uint32_t *) pos);
|
||||||
|
pos += 4;
|
||||||
|
t->duration = ngx_rtmp_r64(*(uint64_t *) pos);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
|
"mp4: duration time_scale=%ui duration=%uL",
|
||||||
|
t->time_scale, t->duration);
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_rtmp_mp4_parse_hdlr(ngx_rtmp_session_t *s, u_char *pos, u_char *last)
|
ngx_rtmp_mp4_parse_hdlr(ngx_rtmp_session_t *s, u_char *pos, u_char *last)
|
||||||
{
|
{
|
||||||
@ -1091,17 +1156,27 @@ ngx_rtmp_mp4_next_time(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
cr = &t->cursor;
|
cr = &t->cursor;
|
||||||
|
|
||||||
if (cr->time_pos >= ngx_rtmp_r32(t->times->entry_count)) {
|
if (cr->time_pos >= ngx_rtmp_r32(t->times->entry_count)) {
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: next time overflow: time_pos=%ui",
|
"mp4: track#%ui time[%ui/%uD] overflow",
|
||||||
cr->time_pos);
|
t->id, cr->time_pos,
|
||||||
|
ngx_rtmp_r32(t->times->entry_count));
|
||||||
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
te = &t->times->entries[cr->time_pos];
|
te = &t->times->entries[cr->time_pos];
|
||||||
|
|
||||||
cr->duration = ngx_rtmp_r32(te->sample_delta) / 90;
|
cr->duration = ngx_rtmp_r32(te->sample_delta);
|
||||||
cr->timestamp += cr->duration;
|
cr->timestamp += cr->duration;
|
||||||
|
|
||||||
|
ngx_log_debug8(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
|
"mp4: track#%ui time[%ui] [%ui/%uD][%ui/%uD]=%uD t=%uD",
|
||||||
|
t->id, cr->pos, cr->time_pos,
|
||||||
|
ngx_rtmp_r32(t->times->entry_count),
|
||||||
|
cr->time_count, ngx_rtmp_r32(te->sample_count),
|
||||||
|
ngx_rtmp_r32(te->sample_delta),
|
||||||
|
cr->timestamp);
|
||||||
|
|
||||||
cr->time_count++;
|
cr->time_count++;
|
||||||
cr->pos++;
|
cr->pos++;
|
||||||
|
|
||||||
@ -1110,12 +1185,6 @@ ngx_rtmp_mp4_next_time(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
cr->time_count = 0;
|
cr->time_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug5(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
|
||||||
"mp4: next time time_pos=%ui, timestamp=%uD, "
|
|
||||||
"duration=%uD, time_count=%ui, pos=%ui",
|
|
||||||
cr->time_pos, cr->timestamp, cr->duration,
|
|
||||||
cr->time_count, cr->pos);
|
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1158,17 +1227,23 @@ ngx_rtmp_mp4_seek_time(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cr->time_pos >= ngx_rtmp_r32(t->times->entry_count)) {
|
if (cr->time_pos >= ngx_rtmp_r32(t->times->entry_count)) {
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: seek time overflow time_pos=%ui",
|
"mp4: track#%ui seek time[%ui/%uD] overflow",
|
||||||
cr->time_pos);
|
t->id, cr->time_pos,
|
||||||
|
ngx_rtmp_r32(t->times->entry_count));
|
||||||
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug4(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug8(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: seek time src_timestamp=%i, timestamp=%D, "
|
"mp4: track#%ui seek time[%ui] [%ui/%uD][%ui/%uD]=%uD "
|
||||||
"time_pos=%ui, pos=%ui",
|
"t=%uD",
|
||||||
timestamp, cr->timestamp, cr->time_pos, cr->pos);
|
t->id, cr->pos, cr->time_pos,
|
||||||
|
ngx_rtmp_r32(t->times->entry_count),
|
||||||
|
cr->time_count,
|
||||||
|
ngx_rtmp_r32(te->sample_count),
|
||||||
|
ngx_rtmp_r32(te->sample_delta),
|
||||||
|
cr->timestamp);
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
@ -1183,8 +1258,9 @@ ngx_rtmp_mp4_update_offset(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
cr = &t->cursor;
|
cr = &t->cursor;
|
||||||
|
|
||||||
if (cr->chunk < 1) {
|
if (cr->chunk < 1) {
|
||||||
ngx_log_debug0(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: update offset underflow");
|
"mp4: track#%ui offset[%ui] underflow",
|
||||||
|
t->id, cr->chunk);
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1192,9 +1268,10 @@ ngx_rtmp_mp4_update_offset(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
|
|
||||||
if (t->offsets) {
|
if (t->offsets) {
|
||||||
if (chunk >= ngx_rtmp_r32(t->offsets->entry_count)) {
|
if (chunk >= ngx_rtmp_r32(t->offsets->entry_count)) {
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: update offset overflow: chunk=%ui",
|
"mp4: track#[%ui] offset[%ui/%uD] overflow",
|
||||||
cr->chunk);
|
t->id, cr->chunk,
|
||||||
|
ngx_rtmp_r32(t->offsets->entry_count));
|
||||||
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
@ -1202,8 +1279,10 @@ ngx_rtmp_mp4_update_offset(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
cr->offset = ngx_rtmp_r32(t->offsets->entries[chunk]);
|
cr->offset = ngx_rtmp_r32(t->offsets->entries[chunk]);
|
||||||
cr->size = 0;
|
cr->size = 0;
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug4(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: update offset offset=%O",
|
"mp4: track#%ui offset[%ui/%uD]=%O",
|
||||||
|
t->id, cr->chunk,
|
||||||
|
ngx_rtmp_r32(t->offsets->entry_count),
|
||||||
cr->offset);
|
cr->offset);
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
@ -1211,9 +1290,10 @@ ngx_rtmp_mp4_update_offset(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
|
|
||||||
if (t->offsets64) {
|
if (t->offsets64) {
|
||||||
if (chunk >= ngx_rtmp_r32(t->offsets64->entry_count)) {
|
if (chunk >= ngx_rtmp_r32(t->offsets64->entry_count)) {
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: update offset64 overflow: chunk=%ui",
|
"mp4: track#%ui offset64[%ui/%uD] overflow",
|
||||||
cr->chunk);
|
t->id, cr->chunk,
|
||||||
|
ngx_rtmp_r32(t->offsets->entry_count));
|
||||||
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
@ -1221,8 +1301,10 @@ ngx_rtmp_mp4_update_offset(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
cr->offset = ngx_rtmp_r32(t->offsets64->entries[chunk]);
|
cr->offset = ngx_rtmp_r32(t->offsets64->entries[chunk]);
|
||||||
cr->size = 0;
|
cr->size = 0;
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug4(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: update offset64 offset=%O",
|
"mp4: track#%ui offset64[%ui/%uD]=%O",
|
||||||
|
t->id, cr->chunk,
|
||||||
|
ngx_rtmp_r32(t->offsets->entry_count),
|
||||||
cr->offset);
|
cr->offset);
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
@ -1237,6 +1319,7 @@ ngx_rtmp_mp4_next_chunk(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
{
|
{
|
||||||
ngx_rtmp_mp4_cursor_t *cr;
|
ngx_rtmp_mp4_cursor_t *cr;
|
||||||
ngx_rtmp_mp4_chunk_entry_t *ce, *nce;
|
ngx_rtmp_mp4_chunk_entry_t *ce, *nce;
|
||||||
|
ngx_int_t new_chunk;
|
||||||
|
|
||||||
if (t->chunks == NULL) {
|
if (t->chunks == NULL) {
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
@ -1245,9 +1328,10 @@ ngx_rtmp_mp4_next_chunk(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
cr = &t->cursor;
|
cr = &t->cursor;
|
||||||
|
|
||||||
if (cr->chunk_pos >= ngx_rtmp_r32(t->chunks->entry_count)) {
|
if (cr->chunk_pos >= ngx_rtmp_r32(t->chunks->entry_count)) {
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: next chunk overflow chunk_pos=%ui",
|
"mp4: track#%ui chunk[%ui/%uD] overflow",
|
||||||
cr->chunk_pos);
|
t->id, cr->chunk_pos,
|
||||||
|
ngx_rtmp_r32(t->chunks->entry_count));
|
||||||
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
@ -1264,22 +1348,29 @@ ngx_rtmp_mp4_next_chunk(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
nce = ce + 1;
|
nce = ce + 1;
|
||||||
if (cr->chunk >= ngx_rtmp_r32(nce->first_chunk)) {
|
if (cr->chunk >= ngx_rtmp_r32(nce->first_chunk)) {
|
||||||
cr->chunk_pos++;
|
cr->chunk_pos++;
|
||||||
|
ce = nce;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
new_chunk = 1;
|
||||||
"mp4: next chunk chunk=%ui, chunk_pos=%ui "
|
|
||||||
"chunk_count=%ui",
|
|
||||||
cr->chunk, cr->chunk_pos, cr->chunk_count);
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
new_chunk = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_log_debug7(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
|
"mp4: track#%ui chunk[%ui/%uD][%uD..%ui][%ui/%uD]",
|
||||||
|
t->id, cr->chunk_pos,
|
||||||
|
ngx_rtmp_r32(t->chunks->entry_count),
|
||||||
|
ngx_rtmp_r32(ce->first_chunk),
|
||||||
|
cr->chunk, cr->chunk_count,
|
||||||
|
ngx_rtmp_r32(ce->samples_per_chunk));
|
||||||
|
|
||||||
|
|
||||||
|
if (new_chunk) {
|
||||||
return ngx_rtmp_mp4_update_offset(s, t);
|
return ngx_rtmp_mp4_update_offset(s, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
|
||||||
"mp4: next chunk kept chunk=%ui, chunk_pos=%ui "
|
|
||||||
"chunk_count=%ui",
|
|
||||||
cr->chunk, cr->chunk_pos, cr->chunk_count);
|
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1328,10 +1419,13 @@ ngx_rtmp_mp4_seek_chunk(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
cr->chunk_count = (ngx_uint_t) (cr->pos - dchunk *
|
cr->chunk_count = (ngx_uint_t) (cr->pos - dchunk *
|
||||||
ngx_rtmp_r32(ce->samples_per_chunk));
|
ngx_rtmp_r32(ce->samples_per_chunk));
|
||||||
|
|
||||||
ngx_log_debug4(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug7(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: seek chunk pos=%ui, chunk=%ui, chunk_pos=%ui, "
|
"mp4: track#%ui seek chunk[%ui/%uD][%uD..%ui][%ui/%uD]",
|
||||||
"chunk_count=%ui",
|
t->id, cr->chunk_pos,
|
||||||
cr->pos, cr->chunk, cr->chunk_pos, cr->chunk_count);
|
ngx_rtmp_r32(t->chunks->entry_count),
|
||||||
|
ngx_rtmp_r32(ce->first_chunk),
|
||||||
|
cr->chunk, cr->chunk_count,
|
||||||
|
ngx_rtmp_r32(ce->samples_per_chunk));
|
||||||
|
|
||||||
return ngx_rtmp_mp4_update_offset(s, t);
|
return ngx_rtmp_mp4_update_offset(s, t);
|
||||||
}
|
}
|
||||||
@ -1350,9 +1444,9 @@ ngx_rtmp_mp4_next_size(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
if (t->sizes->sample_size) {
|
if (t->sizes->sample_size) {
|
||||||
cr->size = ngx_rtmp_r32(t->sizes->sample_size);
|
cr->size = ngx_rtmp_r32(t->sizes->sample_size);
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: next size const_size=%uz",
|
"mp4: track#%ui size fix=%uz",
|
||||||
cr->size);
|
t->id, cr->size);
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
@ -1360,27 +1454,31 @@ ngx_rtmp_mp4_next_size(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
cr->size_pos++;
|
cr->size_pos++;
|
||||||
|
|
||||||
if (cr->size_pos >= ngx_rtmp_r32(t->sizes->sample_count)) {
|
if (cr->size_pos >= ngx_rtmp_r32(t->sizes->sample_count)) {
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: next size overflow size_pos=%ui",
|
"mp4: track#%ui size[%ui/%uD] overflow",
|
||||||
cr->size_pos);
|
t->id, cr->size_pos,
|
||||||
|
ngx_rtmp_r32(t->sizes->sample_count));
|
||||||
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
cr->size = ngx_rtmp_r32(t->sizes->entries[cr->size_pos]);
|
cr->size = ngx_rtmp_r32(t->sizes->entries[cr->size_pos]);
|
||||||
|
|
||||||
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug4(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: next size size_pos=%ui, size=%uz",
|
"mp4: track#%ui size[%ui/%uD]=%uz",
|
||||||
cr->size_pos, cr->size);
|
t->id, cr->size_pos,
|
||||||
|
ngx_rtmp_r32(t->sizes->sample_count),
|
||||||
|
cr->size);
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t->sizes2) {
|
if (t->sizes2) {
|
||||||
if (cr->size_pos >= ngx_rtmp_r32(t->sizes2->sample_count)) {
|
if (cr->size_pos >= ngx_rtmp_r32(t->sizes2->sample_count)) {
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: next size2 overflow size_pos=%ui",
|
"mp4: track#%ui size[%ui/%uD] overflow",
|
||||||
cr->size_pos);
|
t->id, cr->size_pos,
|
||||||
|
ngx_rtmp_r32(t->sizes2->sample_count));
|
||||||
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
@ -1405,17 +1503,18 @@ ngx_rtmp_mp4_seek_size(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
if (t->sizes->sample_size) {
|
if (t->sizes->sample_size) {
|
||||||
cr->size = ngx_rtmp_r32(t->sizes->sample_size);
|
cr->size = ngx_rtmp_r32(t->sizes->sample_size);
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: seek size const_size=%uz",
|
"mp4: track#%ui seek size fix=%uz",
|
||||||
cr->size);
|
t->id, cr->size);
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cr->pos >= ngx_rtmp_r32(t->sizes->sample_count)) {
|
if (cr->pos >= ngx_rtmp_r32(t->sizes->sample_count)) {
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: seek size overflow pos=%ui",
|
"mp4: track#%ui seek size[%ui/%uD] overflow",
|
||||||
cr->pos);
|
t->id, cr->pos,
|
||||||
|
ngx_rtmp_r32(t->sizes->sample_count));
|
||||||
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
@ -1423,18 +1522,21 @@ ngx_rtmp_mp4_seek_size(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
cr->size_pos = cr->pos;
|
cr->size_pos = cr->pos;
|
||||||
cr->size = ngx_rtmp_r32(t->sizes->entries[cr->size_pos]);
|
cr->size = ngx_rtmp_r32(t->sizes->entries[cr->size_pos]);
|
||||||
|
|
||||||
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug4(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: seek size size_pos=%ui, size=%uz",
|
"mp4: track#%ui seek size[%ui/%uD]=%uz",
|
||||||
cr->size_pos, cr->size);
|
t->id, cr->size_pos,
|
||||||
|
ngx_rtmp_r32(t->sizes->sample_count),
|
||||||
|
cr->size);
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (t->sizes2) {
|
if (t->sizes2) {
|
||||||
if (cr->size_pos >= ngx_rtmp_r32(t->sizes2->sample_count)) {
|
if (cr->size_pos >= ngx_rtmp_r32(t->sizes2->sample_count)) {
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: next size2 overflow size_pos=%ui",
|
"mp4: track#%ui seek size2[%ui/%uD] overflow",
|
||||||
cr->size_pos);
|
t->id, cr->size_pos,
|
||||||
|
ngx_rtmp_r32(t->sizes->sample_count));
|
||||||
|
|
||||||
return NGX_ERROR;
|
return NGX_ERROR;
|
||||||
}
|
}
|
||||||
@ -1453,6 +1555,7 @@ static ngx_int_t
|
|||||||
ngx_rtmp_mp4_next_key(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
ngx_rtmp_mp4_next_key(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
||||||
{
|
{
|
||||||
ngx_rtmp_mp4_cursor_t *cr;
|
ngx_rtmp_mp4_cursor_t *cr;
|
||||||
|
uint32_t *ke;
|
||||||
|
|
||||||
cr = &t->cursor;
|
cr = &t->cursor;
|
||||||
|
|
||||||
@ -1460,23 +1563,30 @@ ngx_rtmp_mp4_next_key(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cr->key_pos >= ngx_rtmp_r32(t->keys->entry_count)) {
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
|
||||||
"mp4: next key overflow key_pos=%ui",
|
|
||||||
cr->key_pos);
|
|
||||||
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
cr->key = (cr->pos + 1 == ngx_rtmp_r32(t->keys->entries[cr->key_pos]));
|
|
||||||
|
|
||||||
if (cr->key) {
|
if (cr->key) {
|
||||||
cr->key_pos++;
|
cr->key_pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cr->key_pos >= ngx_rtmp_r32(t->keys->entry_count)) {
|
||||||
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: next key %s pos=%ui, key_pos=%ui",
|
"mp4: track#%ui key[%ui/%uD] overflow",
|
||||||
cr->key ? "match" : "miss", cr->pos, cr->key_pos);
|
t->id, cr->key_pos,
|
||||||
|
ngx_rtmp_r32(t->keys->entry_count));
|
||||||
|
|
||||||
|
cr->key = 0;
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ke = &t->keys->entries[cr->key_pos];
|
||||||
|
cr->key = (cr->pos + 1 == ngx_rtmp_r32(*ke));
|
||||||
|
|
||||||
|
ngx_log_debug6(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
|
"mp4: track#%ui key[%ui/%uD][%ui/%uD]=%s",
|
||||||
|
t->id, cr->key_pos,
|
||||||
|
ngx_rtmp_r32(t->keys->entry_count),
|
||||||
|
cr->pos, ngx_rtmp_r32(*ke),
|
||||||
|
cr->key ? "match" : "miss");
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
@ -1486,6 +1596,7 @@ static ngx_int_t
|
|||||||
ngx_rtmp_mp4_seek_key(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
ngx_rtmp_mp4_seek_key(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
||||||
{
|
{
|
||||||
ngx_rtmp_mp4_cursor_t *cr;
|
ngx_rtmp_mp4_cursor_t *cr;
|
||||||
|
uint32_t *ke;
|
||||||
|
|
||||||
cr = &t->cursor;
|
cr = &t->cursor;
|
||||||
|
|
||||||
@ -1501,12 +1612,23 @@ ngx_rtmp_mp4_seek_key(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
cr->key_pos++;
|
cr->key_pos++;
|
||||||
}
|
}
|
||||||
|
|
||||||
cr->key = (cr->key_pos < ngx_rtmp_r32(t->keys->entry_count) &&
|
if (cr->key_pos >= ngx_rtmp_r32(t->keys->entry_count)) {
|
||||||
cr->pos + 1 == ngx_rtmp_r32(t->keys->entries[cr->key_pos]));
|
|
||||||
|
|
||||||
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: seek key %s key_pos=%ui, pos=%ui",
|
"mp4: track#%ui seek key[%ui/%uD] overflow",
|
||||||
cr->key ? "match" : "miss", cr->key_pos, cr->pos);
|
t->id, cr->key_pos,
|
||||||
|
ngx_rtmp_r32(t->keys->entry_count));
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ke = &t->keys->entries[cr->key_pos];
|
||||||
|
cr->key = (cr->pos + 1 == ngx_rtmp_r32(*ke));
|
||||||
|
|
||||||
|
ngx_log_debug6(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
|
"mp4: track#%ui seek key[%ui/%uD][%ui/%uD]=%s",
|
||||||
|
t->id, cr->key_pos,
|
||||||
|
ngx_rtmp_r32(t->keys->entry_count),
|
||||||
|
cr->pos, ngx_rtmp_r32(*ke),
|
||||||
|
cr->key ? "match" : "miss");
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
@ -1516,6 +1638,7 @@ static ngx_int_t
|
|||||||
ngx_rtmp_mp4_next_delay(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
ngx_rtmp_mp4_next_delay(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
||||||
{
|
{
|
||||||
ngx_rtmp_mp4_cursor_t *cr;
|
ngx_rtmp_mp4_cursor_t *cr;
|
||||||
|
ngx_rtmp_mp4_delay_entry_t *de;
|
||||||
|
|
||||||
cr = &t->cursor;
|
cr = &t->cursor;
|
||||||
|
|
||||||
@ -1524,30 +1647,40 @@ ngx_rtmp_mp4_next_delay(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cr->delay_pos >= ngx_rtmp_r32(t->delays->entry_count)) {
|
if (cr->delay_pos >= ngx_rtmp_r32(t->delays->entry_count)) {
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: next delay overflow key_pos=%ui",
|
"mp4: track#%ui delay[%ui/%uD] overflow",
|
||||||
cr->delay_pos);
|
t->id, cr->delay_pos,
|
||||||
|
ngx_rtmp_r32(t->delays->entry_count));
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
cr->delay_count++;
|
cr->delay_count++;
|
||||||
|
de = &t->delays->entries[cr->delay_pos];
|
||||||
|
|
||||||
if (cr->delay_count >=
|
if (cr->delay_count >= ngx_rtmp_r32(de->sample_count)) {
|
||||||
ngx_rtmp_r32(t->delays->entries[cr->delay_pos].sample_count))
|
|
||||||
{
|
|
||||||
cr->delay_pos++;
|
cr->delay_pos++;
|
||||||
|
de++;
|
||||||
cr->delay_count = 0;
|
cr->delay_count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cr->delay_pos < ngx_rtmp_r32(t->delays->entry_count)) {
|
if (cr->delay_pos >= ngx_rtmp_r32(t->delays->entry_count)) {
|
||||||
cr->delay = ngx_rtmp_r32(t->delays->entries[cr->delay_pos]
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
.sample_offset);
|
"mp4: track#%ui delay[%ui/%uD] overflow",
|
||||||
|
t->id, cr->delay_pos,
|
||||||
|
ngx_rtmp_r32(t->delays->entry_count));
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
cr->delay = ngx_rtmp_r32(de->sample_offset);
|
||||||
"mp4: next delay delay_pos=%ui, delay_count=%ui, delay=%ui",
|
|
||||||
cr->delay_pos, cr->delay_count, cr->delay);
|
ngx_log_debug6(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
|
"mp4: track#%ui delay[%ui/%uD][%ui/%uD]=%ui",
|
||||||
|
t->id, cr->delay_pos,
|
||||||
|
ngx_rtmp_r32(t->delays->entry_count),
|
||||||
|
cr->delay_count,
|
||||||
|
ngx_rtmp_r32(de->sample_count), cr->delay);
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
@ -1557,6 +1690,7 @@ static ngx_int_t
|
|||||||
ngx_rtmp_mp4_seek_delay(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
ngx_rtmp_mp4_seek_delay(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
||||||
{
|
{
|
||||||
ngx_rtmp_mp4_cursor_t *cr;
|
ngx_rtmp_mp4_cursor_t *cr;
|
||||||
|
ngx_rtmp_mp4_delay_entry_t *de;
|
||||||
uint32_t pos, dpos;
|
uint32_t pos, dpos;
|
||||||
|
|
||||||
cr = &t->cursor;
|
cr = &t->cursor;
|
||||||
@ -1566,24 +1700,37 @@ ngx_rtmp_mp4_seek_delay(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
pos = 0;
|
pos = 0;
|
||||||
|
de = t->delays->entries;
|
||||||
|
|
||||||
while (cr->delay_pos < ngx_rtmp_r32(t->delays->entry_count)) {
|
while (cr->delay_pos < ngx_rtmp_r32(t->delays->entry_count)) {
|
||||||
dpos = ngx_rtmp_r32(t->delays->entries[cr->delay_pos].sample_count);
|
dpos = ngx_rtmp_r32(de->sample_count);
|
||||||
|
|
||||||
if (pos + dpos > cr->pos) {
|
if (pos + dpos > cr->pos) {
|
||||||
cr->delay_count = cr->pos - pos;
|
cr->delay_count = cr->pos - pos;
|
||||||
cr->delay = ngx_rtmp_r32(t->delays->entries[cr->delay_pos]
|
cr->delay = ngx_rtmp_r32(de->sample_offset);
|
||||||
.sample_offset);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
cr->delay_pos++;
|
cr->delay_pos++;
|
||||||
pos += dpos;
|
pos += dpos;
|
||||||
|
de++;
|
||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
if (cr->delay_pos >= ngx_rtmp_r32(t->delays->entry_count)) {
|
||||||
"mp4: seek delay delay_pos=%ui, delay_count=%ui",
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
cr->delay_pos, cr->delay_count);
|
"mp4: track#%ui seek delay[%ui/%uD] overflow",
|
||||||
|
t->id, cr->delay_pos,
|
||||||
|
ngx_rtmp_r32(t->delays->entry_count));
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_log_debug6(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
|
"mp4: track#%ui seek delay[%ui/%uD][%ui/%uD]=%ui",
|
||||||
|
t->id, cr->delay_pos,
|
||||||
|
ngx_rtmp_r32(t->delays->entry_count),
|
||||||
|
cr->delay_count,
|
||||||
|
ngx_rtmp_r32(de->sample_count), cr->delay);
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
@ -1601,6 +1748,13 @@ ngx_rtmp_mp4_next(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static uint32_t
|
||||||
|
ngx_rtmp_mp4_to_rtmp_timestamp(ngx_rtmp_mp4_track_t *t, uint32_t ts)
|
||||||
|
{
|
||||||
|
return (uint64_t) ts * 1000 / t->time_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
ngx_rtmp_mp4_send(ngx_event_t *e)
|
ngx_rtmp_mp4_send(ngx_event_t *e)
|
||||||
{
|
{
|
||||||
@ -1612,7 +1766,8 @@ ngx_rtmp_mp4_send(ngx_event_t *e)
|
|||||||
ngx_chain_t *out, in;
|
ngx_chain_t *out, in;
|
||||||
ngx_rtmp_mp4_track_t *t;
|
ngx_rtmp_mp4_track_t *t;
|
||||||
ngx_rtmp_mp4_cursor_t *cr;
|
ngx_rtmp_mp4_cursor_t *cr;
|
||||||
uint32_t buflen, end_timestamp, sched;
|
uint32_t buflen, end_timestamp, sched,
|
||||||
|
timestamp, duration;
|
||||||
ssize_t ret;
|
ssize_t ret;
|
||||||
u_char fhdr[5];
|
u_char fhdr[5];
|
||||||
size_t fhdr_size;
|
size_t fhdr_size;
|
||||||
@ -1645,14 +1800,17 @@ ngx_rtmp_mp4_send(ngx_event_t *e)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cr->timestamp > end_timestamp) {
|
timestamp = ngx_rtmp_mp4_to_rtmp_timestamp(t, cr->timestamp);
|
||||||
|
|
||||||
|
if (timestamp > end_timestamp) {
|
||||||
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug3(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: track=%ui ahead %uD > %uD",
|
"mp4: track#%ui ahead %uD > %uD",
|
||||||
n, cr->timestamp, end_timestamp);
|
t->id, timestamp, end_timestamp);
|
||||||
goto next;
|
goto next;
|
||||||
}
|
}
|
||||||
|
|
||||||
abs_frame = (cr->duration == 0);
|
duration = ngx_rtmp_mp4_to_rtmp_timestamp(t, cr->duration);
|
||||||
|
abs_frame = (duration == 0);
|
||||||
|
|
||||||
ngx_memzero(&h, sizeof(h));
|
ngx_memzero(&h, sizeof(h));
|
||||||
|
|
||||||
@ -1662,15 +1820,15 @@ ngx_rtmp_mp4_send(ngx_event_t *e)
|
|||||||
|
|
||||||
lh = h;
|
lh = h;
|
||||||
|
|
||||||
h.timestamp = (abs_frame ? cr->timestamp : cr->duration);
|
h.timestamp = (abs_frame ? timestamp : duration);
|
||||||
|
|
||||||
ngx_memzero(&in, sizeof(in));
|
ngx_memzero(&in, sizeof(in));
|
||||||
ngx_memzero(&in_buf, sizeof(in_buf));
|
ngx_memzero(&in_buf, sizeof(in_buf));
|
||||||
|
|
||||||
if (t->header && !t->header_sent) {
|
if (t->header && !t->header_sent) {
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug2(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: sending header size=%uz",
|
"mp4: track#%ui sending header of size=%uz",
|
||||||
t->header_size);
|
t->id, t->header_size);
|
||||||
|
|
||||||
fhdr[0] = t->fhdr | 0x10;
|
fhdr[0] = t->fhdr | 0x10;
|
||||||
fhdr[1] = fhdr[2] = fhdr[3] = fhdr[4] = 0;
|
fhdr[1] = fhdr[2] = fhdr[3] = fhdr[4] = 0;
|
||||||
@ -1697,16 +1855,17 @@ ngx_rtmp_mp4_send(ngx_event_t *e)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug5(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug5(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: read frame of track=%ui, "
|
"mp4: track#%ui read frame "
|
||||||
"offset=%O, size=%uz, timestamp=%uD, duration=%uD",
|
"offset=%O, size=%uz, timestamp=%uD, duration=%uD",
|
||||||
n, cr->offset, cr->size, cr->timestamp, cr->duration);
|
t->id, cr->offset, cr->size, timestamp,
|
||||||
|
cr->duration);
|
||||||
|
|
||||||
fhdr_size = (t->header ? 5 : 1);
|
fhdr_size = (t->header ? 5 : 1);
|
||||||
|
|
||||||
if (cr->size + fhdr_size > sizeof(ngx_rtmp_mp4_buffer)) {
|
if (cr->size + fhdr_size > sizeof(ngx_rtmp_mp4_buffer)) {
|
||||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||||
"mp4: too big frame: %D>%uz",
|
"mp4: track#%ui too big frame: %D>%uz",
|
||||||
cr->size, sizeof(ngx_rtmp_mp4_buffer));
|
t->id, cr->size, sizeof(ngx_rtmp_mp4_buffer));
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1715,7 +1874,7 @@ ngx_rtmp_mp4_send(ngx_event_t *e)
|
|||||||
|
|
||||||
if (ret != (ssize_t) cr->size) {
|
if (ret != (ssize_t) cr->size) {
|
||||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||||
"mp4: could not read frame");
|
"mp4: track#%ui could not read frame", t->id);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1749,10 +1908,10 @@ ngx_rtmp_mp4_send(ngx_event_t *e)
|
|||||||
next:
|
next:
|
||||||
active = 1;
|
active = 1;
|
||||||
|
|
||||||
if (cr->timestamp > end_timestamp &&
|
if (timestamp > end_timestamp &&
|
||||||
(sched == 0 || cr->timestamp < end_timestamp + sched))
|
(sched == 0 || timestamp < end_timestamp + sched))
|
||||||
{
|
{
|
||||||
sched = (uint32_t) (cr->timestamp - end_timestamp);
|
sched = (uint32_t) (timestamp - end_timestamp);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1778,7 +1937,8 @@ ngx_rtmp_mp4_seek_track(ngx_rtmp_session_t *s, ngx_rtmp_mp4_track_t *t,
|
|||||||
cr = &t->cursor;
|
cr = &t->cursor;
|
||||||
ngx_memzero(cr, sizeof(cr));
|
ngx_memzero(cr, sizeof(cr));
|
||||||
|
|
||||||
return ngx_rtmp_mp4_seek_time(s, t, timestamp * 90) != NGX_OK ||
|
return ngx_rtmp_mp4_seek_time(s, t, timestamp *
|
||||||
|
t->time_scale / 1000) != NGX_OK ||
|
||||||
ngx_rtmp_mp4_seek_key(s, t) != NGX_OK ||
|
ngx_rtmp_mp4_seek_key(s, t) != NGX_OK ||
|
||||||
ngx_rtmp_mp4_seek_chunk(s, t) != NGX_OK ||
|
ngx_rtmp_mp4_seek_chunk(s, t) != NGX_OK ||
|
||||||
ngx_rtmp_mp4_seek_size(s, t) != NGX_OK ||
|
ngx_rtmp_mp4_seek_size(s, t) != NGX_OK ||
|
||||||
@ -1800,13 +1960,13 @@ ngx_rtmp_mp4_start(ngx_rtmp_session_t *s, ngx_int_t timestamp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: start timestamp=%i", timestamp);
|
"mp4: start t=%i", timestamp);
|
||||||
|
|
||||||
ngx_rtmp_mp4_stop(s);
|
ngx_rtmp_mp4_stop(s);
|
||||||
|
|
||||||
for (n = 0; n < ctx->ntracks; ++n) {
|
for (n = 0; n < ctx->ntracks; ++n) {
|
||||||
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
"mp4: seek track %ui", n);
|
"mp4: track#%ui seek", n);
|
||||||
|
|
||||||
ngx_rtmp_mp4_seek_track(s, &ctx->tracks[n], timestamp);
|
ngx_rtmp_mp4_seek_track(s, &ctx->tracks[n], timestamp);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user