mirror of
https://github.com/zotanmew/nginx-rtmp-module.git
synced 2024-05-20 18:01:08 +02:00
moved metadata handlers from live to codec module & fixed setDataFrame handler to handle ffmpeg packets
This commit is contained in:
parent
fca76ef349
commit
95e2c4172a
|
@ -146,11 +146,31 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
ngx_rtmp_header_t ch, lh;
|
ngx_rtmp_header_t ch, lh;
|
||||||
ngx_uint_t *version;
|
ngx_uint_t *version;
|
||||||
|
|
||||||
|
|
||||||
|
if (h->type != NGX_RTMP_MSG_AUDIO && h->type != NGX_RTMP_MSG_VIDEO) {
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
|
||||||
|
if (ctx == NULL) {
|
||||||
|
ctx = ngx_pcalloc(s->connection->pool, sizeof(ngx_rtmp_codec_ctx_t));
|
||||||
|
ngx_rtmp_set_ctx(s, ctx, ngx_rtmp_codec_module);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* save codec */
|
||||||
|
if (in->buf->last - in->buf->pos < 1) {
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt = in->buf->pos[0];
|
||||||
|
if (h->type == NGX_RTMP_MSG_AUDIO) {
|
||||||
|
ctx->audio_codec_id = (fmt & 0xf0) >> 4;
|
||||||
|
} else {
|
||||||
|
ctx->video_codec_id = (fmt & 0x0f);
|
||||||
|
}
|
||||||
|
|
||||||
/* save AVC/AAC header */
|
/* save AVC/AAC header */
|
||||||
if ((h->type != NGX_RTMP_MSG_AUDIO
|
if (in->buf->last - in->buf->pos < 2) {
|
||||||
&& h->type != NGX_RTMP_MSG_VIDEO)
|
|
||||||
|| in->buf->last - in->buf->pos < 2)
|
|
||||||
{
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,16 +180,9 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
}
|
}
|
||||||
|
|
||||||
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
cscf = ngx_rtmp_get_module_srv_conf(s, ngx_rtmp_core_module);
|
||||||
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
|
|
||||||
if (ctx == NULL) {
|
|
||||||
ctx = ngx_pcalloc(s->connection->pool, sizeof(ngx_rtmp_codec_ctx_t));
|
|
||||||
ngx_rtmp_set_ctx(s, ctx, ngx_rtmp_codec_module);
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt = in->buf->pos[0];
|
|
||||||
header = NULL;
|
header = NULL;
|
||||||
if (h->type == NGX_RTMP_MSG_AUDIO) {
|
if (h->type == NGX_RTMP_MSG_AUDIO) {
|
||||||
if (((fmt & 0xf0) >> 4) == NGX_RTMP_AUDIO_AAC) {
|
if (ctx->audio_codec_id == NGX_RTMP_AUDIO_AAC) {
|
||||||
header = &ctx->aac_header;
|
header = &ctx->aac_header;
|
||||||
pheader = &ctx->aac_pheader;
|
pheader = &ctx->aac_pheader;
|
||||||
version = &ctx->aac_version;
|
version = &ctx->aac_version;
|
||||||
|
@ -177,7 +190,7 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
"codec: AAC header arrived");
|
"codec: AAC header arrived");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if ((fmt & 0x0f) == NGX_RTMP_VIDEO_H264) {
|
if (ctx->video_codec_id == NGX_RTMP_VIDEO_H264) {
|
||||||
header = &ctx->avc_header;
|
header = &ctx->avc_header;
|
||||||
pheader = &ctx->avc_pheader;
|
pheader = &ctx->avc_pheader;
|
||||||
version = &ctx->avc_version;
|
version = &ctx->avc_version;
|
||||||
|
@ -219,11 +232,148 @@ ngx_rtmp_codec_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ngx_int_t
|
||||||
|
ngx_rtmp_codec_meta_data(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
|
ngx_chain_t *in)
|
||||||
|
{
|
||||||
|
ngx_rtmp_codec_ctx_t *ctx;
|
||||||
|
ngx_uint_t skip;
|
||||||
|
|
||||||
|
static struct {
|
||||||
|
double width;
|
||||||
|
double height;
|
||||||
|
double duration;
|
||||||
|
double frame_rate;
|
||||||
|
double video_data_rate;
|
||||||
|
double video_codec_id_n;
|
||||||
|
u_char video_codec_id_s[32];
|
||||||
|
double audio_data_rate;
|
||||||
|
double audio_codec_id_n;
|
||||||
|
u_char audio_codec_id_s[32];
|
||||||
|
} v;
|
||||||
|
|
||||||
|
static ngx_rtmp_amf_elt_t in_video_codec_id[] = {
|
||||||
|
|
||||||
|
{ NGX_RTMP_AMF_NUMBER,
|
||||||
|
ngx_null_string,
|
||||||
|
&v.video_codec_id_n, 0 },
|
||||||
|
|
||||||
|
{ NGX_RTMP_AMF_STRING,
|
||||||
|
ngx_null_string,
|
||||||
|
&v.video_codec_id_s, sizeof(v.video_codec_id_s) },
|
||||||
|
};
|
||||||
|
|
||||||
|
static ngx_rtmp_amf_elt_t in_audio_codec_id[] = {
|
||||||
|
|
||||||
|
{ NGX_RTMP_AMF_NUMBER,
|
||||||
|
ngx_null_string,
|
||||||
|
&v.audio_codec_id_n, 0 },
|
||||||
|
|
||||||
|
{ NGX_RTMP_AMF_STRING,
|
||||||
|
ngx_null_string,
|
||||||
|
&v.audio_codec_id_s, sizeof(v.audio_codec_id_s) },
|
||||||
|
};
|
||||||
|
|
||||||
|
static ngx_rtmp_amf_elt_t in_inf[] = {
|
||||||
|
|
||||||
|
{ NGX_RTMP_AMF_NUMBER,
|
||||||
|
ngx_string("width"),
|
||||||
|
&v.width, 0 },
|
||||||
|
|
||||||
|
{ NGX_RTMP_AMF_NUMBER,
|
||||||
|
ngx_string("height"),
|
||||||
|
&v.height, 0 },
|
||||||
|
|
||||||
|
{ NGX_RTMP_AMF_NUMBER,
|
||||||
|
ngx_string("duration"),
|
||||||
|
&v.duration, 0 },
|
||||||
|
|
||||||
|
{ NGX_RTMP_AMF_NUMBER,
|
||||||
|
ngx_string("framerate"),
|
||||||
|
&v.frame_rate, 0 },
|
||||||
|
|
||||||
|
{ NGX_RTMP_AMF_NUMBER,
|
||||||
|
ngx_string("videodatarate"),
|
||||||
|
&v.video_data_rate, 0 },
|
||||||
|
|
||||||
|
{ NGX_RTMP_AMF_VARIANT,
|
||||||
|
ngx_string("videocodecid"),
|
||||||
|
in_video_codec_id, sizeof(in_video_codec_id) },
|
||||||
|
|
||||||
|
{ NGX_RTMP_AMF_NUMBER,
|
||||||
|
ngx_string("audiodatarate"),
|
||||||
|
&v.audio_data_rate, 0 },
|
||||||
|
|
||||||
|
{ NGX_RTMP_AMF_VARIANT,
|
||||||
|
ngx_string("audiocodecid"),
|
||||||
|
in_audio_codec_id, sizeof(in_audio_codec_id) },
|
||||||
|
};
|
||||||
|
|
||||||
|
static ngx_rtmp_amf_elt_t in_elts[] = {
|
||||||
|
|
||||||
|
{ NGX_RTMP_AMF_STRING,
|
||||||
|
ngx_null_string,
|
||||||
|
NULL, 0 },
|
||||||
|
|
||||||
|
{ NGX_RTMP_AMF_OBJECT,
|
||||||
|
ngx_null_string,
|
||||||
|
in_inf, sizeof(in_inf) },
|
||||||
|
};
|
||||||
|
|
||||||
|
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
|
||||||
|
if (ctx == NULL) {
|
||||||
|
ctx = ngx_pcalloc(s->connection->pool, sizeof(ngx_rtmp_codec_ctx_t));
|
||||||
|
ngx_rtmp_set_ctx(s, ctx, ngx_rtmp_codec_module);
|
||||||
|
}
|
||||||
|
|
||||||
|
ngx_memzero(&v, sizeof(v));
|
||||||
|
|
||||||
|
/* use -1 as a sign of unchanged data;
|
||||||
|
* 0 is a valid value for uncompressed audio */
|
||||||
|
v.audio_codec_id_n = -1;
|
||||||
|
|
||||||
|
/* FFmpeg sends a string in front of actal metadata; ignore it */
|
||||||
|
skip = !(in->buf->last > in->buf->pos
|
||||||
|
&& *in->buf->pos == NGX_RTMP_AMF_STRING);
|
||||||
|
if (ngx_rtmp_receive_amf(s, in, in_elts + skip,
|
||||||
|
sizeof(in_elts) / sizeof(in_elts[0]) - skip))
|
||||||
|
{
|
||||||
|
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
||||||
|
"codec: error parsing data frame");
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->width = v.width;
|
||||||
|
ctx->height = v.height;
|
||||||
|
ctx->duration = v.duration;
|
||||||
|
ctx->frame_rate = v.frame_rate;
|
||||||
|
ctx->video_data_rate = v.video_data_rate;
|
||||||
|
ctx->video_codec_id = v.video_codec_id_n;
|
||||||
|
ctx->audio_data_rate = v.audio_data_rate;
|
||||||
|
ctx->audio_codec_id = (v.audio_codec_id_n == -1
|
||||||
|
? 0 : v.audio_codec_id_n == 0
|
||||||
|
? NGX_RTMP_AUDIO_UNCOMPRESSED : v.audio_codec_id_n);
|
||||||
|
|
||||||
|
ngx_log_debug8(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
||||||
|
"codec: data frame: "
|
||||||
|
"width=%ui height=%ui duration=%ui frame_rate=%ui "
|
||||||
|
"video=%s (%ui) audio=%s (%ui)",
|
||||||
|
ctx->width, ctx->height, ctx->duration, ctx->frame_rate,
|
||||||
|
ngx_rtmp_get_video_codec_name(ctx->video_codec_id),
|
||||||
|
ctx->video_codec_id,
|
||||||
|
ngx_rtmp_get_audio_codec_name(ctx->audio_codec_id),
|
||||||
|
ctx->audio_codec_id);
|
||||||
|
|
||||||
|
return NGX_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_rtmp_codec_postconfiguration(ngx_conf_t *cf)
|
ngx_rtmp_codec_postconfiguration(ngx_conf_t *cf)
|
||||||
{
|
{
|
||||||
ngx_rtmp_core_main_conf_t *cmcf;
|
ngx_rtmp_core_main_conf_t *cmcf;
|
||||||
ngx_rtmp_handler_pt *h;
|
ngx_rtmp_handler_pt *h;
|
||||||
|
ngx_rtmp_amf_handler_t *ch;
|
||||||
|
|
||||||
cmcf = ngx_rtmp_conf_get_module_main_conf(cf, ngx_rtmp_core_module);
|
cmcf = ngx_rtmp_conf_get_module_main_conf(cf, ngx_rtmp_core_module);
|
||||||
|
|
||||||
|
@ -236,5 +386,21 @@ ngx_rtmp_codec_postconfiguration(ngx_conf_t *cf)
|
||||||
h = ngx_array_push(&cmcf->events[NGX_RTMP_DISCONNECT]);
|
h = ngx_array_push(&cmcf->events[NGX_RTMP_DISCONNECT]);
|
||||||
*h = ngx_rtmp_codec_disconnect;
|
*h = ngx_rtmp_codec_disconnect;
|
||||||
|
|
||||||
|
/* register metadata handler */
|
||||||
|
ch = ngx_array_push(&cmcf->amf);
|
||||||
|
if (ch == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
ngx_str_set(&ch->name, "@setDataFrame");
|
||||||
|
ch->handler = ngx_rtmp_codec_meta_data;
|
||||||
|
|
||||||
|
ch = ngx_array_push(&cmcf->amf);
|
||||||
|
if (ch == NULL) {
|
||||||
|
return NGX_ERROR;
|
||||||
|
}
|
||||||
|
ngx_str_set(&ch->name, "onMetaData");
|
||||||
|
ch->handler = ngx_rtmp_codec_meta_data;
|
||||||
|
|
||||||
|
|
||||||
return NGX_OK;
|
return NGX_OK;
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,6 +47,15 @@ u_char * ngx_rtmp_get_video_codec_name(ngx_uint_t id);
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
ngx_uint_t width;
|
||||||
|
ngx_uint_t height;
|
||||||
|
ngx_uint_t duration;
|
||||||
|
ngx_uint_t frame_rate;
|
||||||
|
ngx_uint_t video_data_rate;
|
||||||
|
ngx_uint_t video_codec_id;
|
||||||
|
ngx_uint_t audio_data_rate;
|
||||||
|
ngx_uint_t audio_codec_id;
|
||||||
|
|
||||||
ngx_uint_t avc_version;
|
ngx_uint_t avc_version;
|
||||||
ngx_uint_t aac_version;
|
ngx_uint_t aac_version;
|
||||||
|
|
||||||
|
|
|
@ -290,7 +290,6 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
ngx_rtmp_header_t ch, lh;
|
ngx_rtmp_header_t ch, lh;
|
||||||
ngx_uint_t prio, peer_prio;
|
ngx_uint_t prio, peer_prio;
|
||||||
ngx_uint_t peers, dropped_peers;
|
ngx_uint_t peers, dropped_peers;
|
||||||
uint8_t flv_fmt;
|
|
||||||
size_t header_offset;
|
size_t header_offset;
|
||||||
ngx_uint_t header_version;
|
ngx_uint_t header_version;
|
||||||
|
|
||||||
|
@ -351,15 +350,6 @@ ngx_rtmp_live_av(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
||||||
peers = 0;
|
peers = 0;
|
||||||
dropped_peers = 0;
|
dropped_peers = 0;
|
||||||
|
|
||||||
if (in->buf->last - in->buf->pos >= 1) {
|
|
||||||
flv_fmt = *in->buf->pos;
|
|
||||||
if (h->type == NGX_RTMP_MSG_AUDIO) {
|
|
||||||
ctx->stream->meta.audio_codec_id = (flv_fmt & 0xf0) >> 4;
|
|
||||||
} else {
|
|
||||||
ctx->stream->meta.video_codec_id = (flv_fmt & 0x0f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
codec_ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
|
codec_ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
|
||||||
header_out = NULL;
|
header_out = NULL;
|
||||||
pheader_out = NULL;
|
pheader_out = NULL;
|
||||||
|
@ -489,192 +479,14 @@ next:
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
|
||||||
ngx_rtmp_live_ext_meta_data(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|
||||||
ngx_chain_t *in, ngx_uint_t skip)
|
|
||||||
{
|
|
||||||
ngx_rtmp_live_app_conf_t *lacf;
|
|
||||||
ngx_rtmp_live_ctx_t *ctx;
|
|
||||||
ngx_rtmp_live_meta_t *meta;
|
|
||||||
|
|
||||||
static struct {
|
|
||||||
double width;
|
|
||||||
double height;
|
|
||||||
double duration;
|
|
||||||
double frame_rate;
|
|
||||||
double video_data_rate;
|
|
||||||
double video_codec_id_n;
|
|
||||||
u_char video_codec_id_s[32];
|
|
||||||
double audio_data_rate;
|
|
||||||
double audio_codec_id_n;
|
|
||||||
u_char audio_codec_id_s[32];
|
|
||||||
} v;
|
|
||||||
|
|
||||||
static ngx_rtmp_amf_elt_t in_video_codec_id[] = {
|
|
||||||
|
|
||||||
{ NGX_RTMP_AMF_NUMBER,
|
|
||||||
ngx_null_string,
|
|
||||||
&v.video_codec_id_n, 0 },
|
|
||||||
|
|
||||||
{ NGX_RTMP_AMF_STRING,
|
|
||||||
ngx_null_string,
|
|
||||||
&v.video_codec_id_s, sizeof(v.video_codec_id_s) },
|
|
||||||
};
|
|
||||||
|
|
||||||
static ngx_rtmp_amf_elt_t in_audio_codec_id[] = {
|
|
||||||
|
|
||||||
{ NGX_RTMP_AMF_NUMBER,
|
|
||||||
ngx_null_string,
|
|
||||||
&v.audio_codec_id_n, 0 },
|
|
||||||
|
|
||||||
{ NGX_RTMP_AMF_STRING,
|
|
||||||
ngx_null_string,
|
|
||||||
&v.audio_codec_id_s, sizeof(v.audio_codec_id_s) },
|
|
||||||
};
|
|
||||||
|
|
||||||
static ngx_rtmp_amf_elt_t in_inf[] = {
|
|
||||||
|
|
||||||
{ NGX_RTMP_AMF_NUMBER,
|
|
||||||
ngx_string("width"),
|
|
||||||
&v.width, 0 },
|
|
||||||
|
|
||||||
{ NGX_RTMP_AMF_NUMBER,
|
|
||||||
ngx_string("height"),
|
|
||||||
&v.height, 0 },
|
|
||||||
|
|
||||||
{ NGX_RTMP_AMF_NUMBER,
|
|
||||||
ngx_string("duration"),
|
|
||||||
&v.duration, 0 },
|
|
||||||
|
|
||||||
{ NGX_RTMP_AMF_NUMBER,
|
|
||||||
ngx_string("framerate"),
|
|
||||||
&v.frame_rate, 0 },
|
|
||||||
|
|
||||||
{ NGX_RTMP_AMF_NUMBER,
|
|
||||||
ngx_string("videodatarate"),
|
|
||||||
&v.video_data_rate, 0 },
|
|
||||||
|
|
||||||
{ NGX_RTMP_AMF_VARIANT,
|
|
||||||
ngx_string("videocodecid"),
|
|
||||||
in_video_codec_id, sizeof(in_video_codec_id) },
|
|
||||||
|
|
||||||
{ NGX_RTMP_AMF_NUMBER,
|
|
||||||
ngx_string("audiodatarate"),
|
|
||||||
&v.audio_data_rate, 0 },
|
|
||||||
|
|
||||||
{ NGX_RTMP_AMF_VARIANT,
|
|
||||||
ngx_string("audiocodecid"),
|
|
||||||
in_audio_codec_id, sizeof(in_audio_codec_id) },
|
|
||||||
};
|
|
||||||
|
|
||||||
static ngx_rtmp_amf_elt_t in_elts[] = {
|
|
||||||
|
|
||||||
{ NGX_RTMP_AMF_STRING,
|
|
||||||
ngx_null_string,
|
|
||||||
NULL, 0 },
|
|
||||||
|
|
||||||
{ NGX_RTMP_AMF_OBJECT,
|
|
||||||
ngx_null_string,
|
|
||||||
in_inf, sizeof(in_inf) },
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
lacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_live_module);
|
|
||||||
if (lacf == NULL || !lacf->live) {
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ngx_memzero(&v, sizeof(v));
|
|
||||||
|
|
||||||
/* use -1 as a sign of unchanged data;
|
|
||||||
* 0 is a valid value for uncompressed audio */
|
|
||||||
v.audio_codec_id_n = -1;
|
|
||||||
|
|
||||||
if (ngx_rtmp_receive_amf(s, in, in_elts + skip,
|
|
||||||
sizeof(in_elts) / sizeof(in_elts[0]) - skip))
|
|
||||||
{
|
|
||||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
|
||||||
"live: error parsing data frame");
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_live_module);
|
|
||||||
if (ctx == NULL) {
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ctx->flags & NGX_RTMP_LIVE_PUBLISHING) == 0) {
|
|
||||||
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
|
|
||||||
"live: received data stream from non-publisher");
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
meta = &ctx->stream->meta;
|
|
||||||
meta->width = v.width;
|
|
||||||
meta->height = v.height;
|
|
||||||
meta->duration = v.duration;
|
|
||||||
meta->frame_rate = v.frame_rate;
|
|
||||||
meta->video_data_rate = v.video_data_rate;
|
|
||||||
meta->video_codec_id = v.video_codec_id_n;
|
|
||||||
meta->audio_data_rate = v.audio_data_rate;
|
|
||||||
meta->audio_codec_id = (v.audio_codec_id_n == -1
|
|
||||||
? 0 : v.audio_codec_id_n == 0
|
|
||||||
? NGX_RTMP_AUDIO_UNCOMPRESSED : v.audio_codec_id_n);
|
|
||||||
|
|
||||||
ngx_log_debug8(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
|
|
||||||
"live: data frame: "
|
|
||||||
"width=%ui height=%ui duration=%ui frame_rate=%ui "
|
|
||||||
"video=%s (%ui) audio=%s (%ui)",
|
|
||||||
meta->width, meta->height, meta->duration, meta->frame_rate,
|
|
||||||
ngx_rtmp_get_video_codec_name(meta->video_codec_id),
|
|
||||||
meta->video_codec_id,
|
|
||||||
ngx_rtmp_get_audio_codec_name(meta->audio_codec_id),
|
|
||||||
meta->audio_codec_id);
|
|
||||||
|
|
||||||
return NGX_OK;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
|
||||||
ngx_rtmp_live_data_frame(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|
||||||
ngx_chain_t *in)
|
|
||||||
{
|
|
||||||
return ngx_rtmp_live_ext_meta_data(s, h, in, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
|
||||||
ngx_rtmp_live_meta_data(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
|
|
||||||
ngx_chain_t *in)
|
|
||||||
{
|
|
||||||
return ngx_rtmp_live_ext_meta_data(s, h, in, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static ngx_int_t
|
static ngx_int_t
|
||||||
ngx_rtmp_live_postconfiguration(ngx_conf_t *cf)
|
ngx_rtmp_live_postconfiguration(ngx_conf_t *cf)
|
||||||
{
|
{
|
||||||
ngx_rtmp_core_main_conf_t *cmcf;
|
ngx_rtmp_core_main_conf_t *cmcf;
|
||||||
ngx_rtmp_handler_pt *h;
|
ngx_rtmp_handler_pt *h;
|
||||||
ngx_rtmp_amf_handler_t *ch;
|
|
||||||
|
|
||||||
cmcf = ngx_rtmp_conf_get_module_main_conf(cf, ngx_rtmp_core_module);
|
cmcf = ngx_rtmp_conf_get_module_main_conf(cf, ngx_rtmp_core_module);
|
||||||
|
|
||||||
/* register metadata handler */
|
|
||||||
ch = ngx_array_push(&cmcf->amf);
|
|
||||||
if (ch == NULL) {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
ngx_str_set(&ch->name, "@setDataFrame");
|
|
||||||
ch->handler = ngx_rtmp_live_data_frame;
|
|
||||||
|
|
||||||
ch = ngx_array_push(&cmcf->amf);
|
|
||||||
if (ch == NULL) {
|
|
||||||
return NGX_ERROR;
|
|
||||||
}
|
|
||||||
ngx_str_set(&ch->name, "onMetaData");
|
|
||||||
ch->handler = ngx_rtmp_live_meta_data;
|
|
||||||
|
|
||||||
/* register raw event handlers */
|
/* register raw event handlers */
|
||||||
h = ngx_array_push(&cmcf->events[NGX_RTMP_MSG_AUDIO]);
|
h = ngx_array_push(&cmcf->events[NGX_RTMP_MSG_AUDIO]);
|
||||||
*h = ngx_rtmp_live_av;
|
*h = ngx_rtmp_live_av;
|
||||||
|
|
|
@ -22,18 +22,6 @@
|
||||||
#define NGX_RTMP_LIVE_MSID 1
|
#define NGX_RTMP_LIVE_MSID 1
|
||||||
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
ngx_uint_t width;
|
|
||||||
ngx_uint_t height;
|
|
||||||
ngx_uint_t duration;
|
|
||||||
ngx_uint_t frame_rate;
|
|
||||||
ngx_uint_t video_data_rate;
|
|
||||||
ngx_uint_t video_codec_id;
|
|
||||||
ngx_uint_t audio_data_rate;
|
|
||||||
ngx_uint_t audio_codec_id;
|
|
||||||
} ngx_rtmp_live_meta_t;
|
|
||||||
|
|
||||||
|
|
||||||
typedef struct ngx_rtmp_live_ctx_s ngx_rtmp_live_ctx_t;
|
typedef struct ngx_rtmp_live_ctx_s ngx_rtmp_live_ctx_t;
|
||||||
typedef struct ngx_rtmp_live_stream_s ngx_rtmp_live_stream_t;
|
typedef struct ngx_rtmp_live_stream_s ngx_rtmp_live_stream_t;
|
||||||
|
|
||||||
|
@ -61,7 +49,6 @@ struct ngx_rtmp_live_stream_s {
|
||||||
ngx_uint_t flags;
|
ngx_uint_t flags;
|
||||||
ngx_rtmp_bandwidth_t bw_in;
|
ngx_rtmp_bandwidth_t bw_in;
|
||||||
ngx_rtmp_bandwidth_t bw_out;
|
ngx_rtmp_bandwidth_t bw_out;
|
||||||
ngx_rtmp_live_meta_t meta;
|
|
||||||
ngx_msec_t epoch;
|
ngx_msec_t epoch;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -250,7 +250,7 @@ ngx_rtmp_stat_live(ngx_http_request_t *r, ngx_chain_t ***lll,
|
||||||
ngx_rtmp_live_app_conf_t *lacf)
|
ngx_rtmp_live_app_conf_t *lacf)
|
||||||
{
|
{
|
||||||
ngx_rtmp_live_stream_t *stream;
|
ngx_rtmp_live_stream_t *stream;
|
||||||
ngx_rtmp_live_meta_t *meta;
|
ngx_rtmp_codec_ctx_t *codec;
|
||||||
ngx_rtmp_live_ctx_t *ctx;
|
ngx_rtmp_live_ctx_t *ctx;
|
||||||
ngx_rtmp_session_t *s;
|
ngx_rtmp_session_t *s;
|
||||||
ngx_int_t n;
|
ngx_int_t n;
|
||||||
|
@ -258,7 +258,7 @@ ngx_rtmp_stat_live(ngx_http_request_t *r, ngx_chain_t ***lll,
|
||||||
ngx_int_t publishing;
|
ngx_int_t publishing;
|
||||||
u_char buf[NGX_OFF_T_LEN + 1];
|
u_char buf[NGX_OFF_T_LEN + 1];
|
||||||
ngx_rtmp_stat_loc_conf_t *slcf;
|
ngx_rtmp_stat_loc_conf_t *slcf;
|
||||||
u_char *codec;
|
u_char *cname;
|
||||||
|
|
||||||
slcf = ngx_http_get_module_loc_conf(r, ngx_rtmp_stat_module);
|
slcf = ngx_http_get_module_loc_conf(r, ngx_rtmp_stat_module);
|
||||||
|
|
||||||
|
@ -279,36 +279,12 @@ ngx_rtmp_stat_live(ngx_http_request_t *r, ngx_chain_t ***lll,
|
||||||
"%M", ngx_current_msec - stream->epoch) - buf);
|
"%M", ngx_current_msec - stream->epoch) - buf);
|
||||||
NGX_RTMP_STAT_L("</time>");
|
NGX_RTMP_STAT_L("</time>");
|
||||||
|
|
||||||
meta = &stream->meta;
|
|
||||||
NGX_RTMP_STAT_L("<meta><width>");
|
|
||||||
NGX_RTMP_STAT(buf, ngx_snprintf(buf, sizeof(buf),
|
|
||||||
"%ui", meta->width) - buf);
|
|
||||||
NGX_RTMP_STAT_L("</width><height>");
|
|
||||||
NGX_RTMP_STAT(buf, ngx_snprintf(buf, sizeof(buf),
|
|
||||||
"%ui", meta->height) - buf);
|
|
||||||
NGX_RTMP_STAT_L("</height><framerate>");
|
|
||||||
NGX_RTMP_STAT(buf, ngx_snprintf(buf, sizeof(buf),
|
|
||||||
"%ui", meta->frame_rate) - buf);
|
|
||||||
NGX_RTMP_STAT_L("</framerate><video>");
|
|
||||||
codec = ngx_rtmp_get_video_codec_name(meta->video_codec_id);
|
|
||||||
if (*codec) {
|
|
||||||
NGX_RTMP_STAT_ECS(codec);
|
|
||||||
}
|
|
||||||
NGX_RTMP_STAT_L("</video><audio>");
|
|
||||||
codec = ngx_rtmp_get_audio_codec_name(meta->audio_codec_id);
|
|
||||||
if (*codec) {
|
|
||||||
NGX_RTMP_STAT_ECS(codec);
|
|
||||||
}
|
|
||||||
NGX_RTMP_STAT_L("</audio></meta>\r\n");
|
|
||||||
|
|
||||||
ngx_rtmp_stat_bw(r, lll, &stream->bw_in, &stream->bw_out);
|
ngx_rtmp_stat_bw(r, lll, &stream->bw_in, &stream->bw_out);
|
||||||
|
|
||||||
nclients = 0;
|
nclients = 0;
|
||||||
|
codec = NULL;
|
||||||
for (ctx = stream->ctx; ctx; ctx = ctx->next, ++nclients) {
|
for (ctx = stream->ctx; ctx; ctx = ctx->next, ++nclients) {
|
||||||
s = ctx->session;
|
s = ctx->session;
|
||||||
/* TODO: add
|
|
||||||
* 1) session start time
|
|
||||||
* 2) drop stats */
|
|
||||||
if (slcf->stat & NGX_RTMP_STAT_CLIENTS) {
|
if (slcf->stat & NGX_RTMP_STAT_CLIENTS) {
|
||||||
NGX_RTMP_STAT_L("<client>");
|
NGX_RTMP_STAT_L("<client>");
|
||||||
|
|
||||||
|
@ -356,10 +332,34 @@ ngx_rtmp_stat_live(ngx_http_request_t *r, ngx_chain_t ***lll,
|
||||||
}
|
}
|
||||||
if (ctx->flags & NGX_RTMP_LIVE_PUBLISHING) {
|
if (ctx->flags & NGX_RTMP_LIVE_PUBLISHING) {
|
||||||
publishing = 1;
|
publishing = 1;
|
||||||
|
codec = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
total_nclients += nclients;
|
total_nclients += nclients;
|
||||||
|
|
||||||
|
if (codec) {
|
||||||
|
NGX_RTMP_STAT_L("<meta><width>");
|
||||||
|
NGX_RTMP_STAT(buf, ngx_snprintf(buf, sizeof(buf),
|
||||||
|
"%ui", codec->width) - buf);
|
||||||
|
NGX_RTMP_STAT_L("</width><height>");
|
||||||
|
NGX_RTMP_STAT(buf, ngx_snprintf(buf, sizeof(buf),
|
||||||
|
"%ui", codec->height) - buf);
|
||||||
|
NGX_RTMP_STAT_L("</height><framerate>");
|
||||||
|
NGX_RTMP_STAT(buf, ngx_snprintf(buf, sizeof(buf),
|
||||||
|
"%ui", codec->frame_rate) - buf);
|
||||||
|
NGX_RTMP_STAT_L("</framerate><video>");
|
||||||
|
cname = ngx_rtmp_get_video_codec_name(codec->video_codec_id);
|
||||||
|
if (*cname) {
|
||||||
|
NGX_RTMP_STAT_ECS(cname);
|
||||||
|
}
|
||||||
|
NGX_RTMP_STAT_L("</video><audio>");
|
||||||
|
cname = ngx_rtmp_get_audio_codec_name(codec->audio_codec_id);
|
||||||
|
if (*cname) {
|
||||||
|
NGX_RTMP_STAT_ECS(cname);
|
||||||
|
}
|
||||||
|
NGX_RTMP_STAT_L("</audio></meta>\r\n");
|
||||||
|
}
|
||||||
|
|
||||||
NGX_RTMP_STAT_L("<nclients>");
|
NGX_RTMP_STAT_L("<nclients>");
|
||||||
NGX_RTMP_STAT(buf, ngx_snprintf(buf, sizeof(buf),
|
NGX_RTMP_STAT(buf, ngx_snprintf(buf, sizeof(buf),
|
||||||
"%uz", nclients) - buf);
|
"%uz", nclients) - buf);
|
||||||
|
|
Loading…
Reference in a new issue