added parsing data frame & added stream meta info to stat xml

This commit is contained in:
Roman Arutyunyan 2012-05-12 17:47:39 +04:00
parent 4d4af44bf2
commit a4f48c5baa
7 changed files with 269 additions and 20 deletions

1
config
View file

@ -35,6 +35,7 @@ NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
$ngx_addon_dir/ngx_rtmp_notify_module.c \
$ngx_addon_dir/ngx_rtmp_stat_module.c \
$ngx_addon_dir/ngx_rtmp_bandwidth.c \
$ngx_addon_dir/ngx_rtmp_codecs.c \
"
CFLAGS="$CFLAGS -I$ngx_addon_dir"

51
ngx_rtmp_codecs.c Normal file
View file

@ -0,0 +1,51 @@
/*
* Copyright (c) 2012 Roman Arutyunyan
*/
#include "ngx_rtmp_codecs.h"
const char * audio_codecs[] = {
"Uncompressed",
"ADPCM",
"MP3",
"",
"",
"Nellymoser8",
"Nellymoser",
"",
"",
"",
"HE-ACC",
"Speex"
};
const char * video_codecs[] = {
"",
"",
"Sorenson-H263",
"ScreenVideo",
"On2-VP6",
"On2-VP6-Alpha",
"H264",
};
u_char *
ngx_rtmp_get_audio_codec_name(ngx_uint_t id)
{
return (u_char *)(id < sizeof(audio_codecs) / sizeof(audio_codecs[0])
? audio_codecs[id]
: "");
}
u_char *
ngx_rtmp_get_video_codec_name(ngx_uint_t id)
{
return (u_char *)(id < sizeof(video_codecs) / sizeof(video_codecs[0])
? video_codecs[id]
: "");
}

40
ngx_rtmp_codecs.h Normal file
View file

@ -0,0 +1,40 @@
/*
* Copyright (c) 2012 Roman Arutyunyan
*/
#ifndef _NGX_RTMP_CODECS_H_INCLUDED_
#define _NGX_RTMP_CODECS_H_INCLUDED_
#include <ngx_core.h>
/* Audio codecs */
enum {
NGX_RTMP_AUDIO_UNCOMPRESSED = 0,
NGX_RTMP_AUDIO_ADPCM = 1,
NGX_RTMP_AUDIO_MP3 = 2,
NGX_RTMP_AUDIO_NELLY8 = 5,
NGX_RTMP_AUDIO_NELLY = 6,
NGX_RTMP_AUDIO_HE_ACC = 10,
NGX_RTMP_AUDIO_SPEEX = 11
};
/* Video codecs */
enum {
NGX_RTMP_VIDEO_SORENSON_H263 = 2,
NGX_RTMP_VIDEO_SCREEN = 3,
NGX_RTMP_VIDEO_ON2_VP6 = 4,
NGX_RTMP_VIDEO_ON2_VP6_ALPHA = 5,
NGX_RTMP_VIDEO_H264 = 7
};
u_char * ngx_rtmp_get_audio_codec_name(ngx_uint_t id);
u_char * ngx_rtmp_get_video_codec_name(ngx_uint_t id);
#endif /* _NGX_RTMP_CODECS_H_INCLUDED_ */

View file

@ -5,6 +5,7 @@
#include "ngx_rtmp_live_module.h"
#include "ngx_rtmp_cmd_module.h"
#include "ngx_rtmp_codecs.h"
static ngx_rtmp_publish_pt next_publish;
@ -443,15 +444,138 @@ next:
}
static ngx_int_t
ngx_rtmp_live_data_frame(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
ngx_chain_t *in)
{
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;
double audio_data_rate;
double audio_codec_id;
} v;
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_NUMBER,
ngx_string("videocodecid"),
&v.video_codec_id, 0 },
{ NGX_RTMP_AMF_NUMBER,
ngx_string("audiodatarate"),
&v.audio_data_rate, 0 },
{ NGX_RTMP_AMF_NUMBER,
ngx_string("audiocodecid"),
&v.audio_codec_id, 0 },
};
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));
if (ngx_rtmp_receive_amf(s, in, in_elts,
sizeof(in_elts) / sizeof(in_elts[0])))
{
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;
meta->audio_data_rate = v.audio_data_rate;
meta->audio_codec_id = v.audio_codec_id;
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_postconfiguration(ngx_conf_t *cf)
{
ngx_rtmp_core_main_conf_t *cmcf;
ngx_rtmp_handler_pt *h;
ngx_rtmp_amf_handler_t *ch;
/* register raw event handlers */
cmcf = ngx_rtmp_conf_get_module_main_conf(cf, ngx_rtmp_core_module);
/* register data frame 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;
/* register raw event handlers */
h = ngx_array_push(&cmcf->events[NGX_RTMP_MSG_AUDIO]);
*h = ngx_rtmp_live_av;

View file

@ -15,6 +15,18 @@
#define NGX_RTMP_LIVE_PUBLISHING 0x01
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_stream_s ngx_rtmp_live_stream_t;
@ -40,6 +52,7 @@ struct ngx_rtmp_live_stream_s {
ngx_uint_t flags;
ngx_rtmp_bandwidth_t bw_in;
ngx_rtmp_bandwidth_t bw_out;
ngx_rtmp_live_meta_t meta;
};

View file

@ -7,6 +7,7 @@
#include "ngx_rtmp.h"
#include "ngx_rtmp_live_module.h"
#include "ngx_rtmp_codecs.h"
static ngx_int_t ngx_rtmp_stat_postconfiguration(ngx_conf_t *cf);
@ -202,6 +203,7 @@ ngx_rtmp_stat_live(ngx_http_request_t *r, ngx_chain_t ***lll,
ngx_rtmp_live_app_conf_t *lacf)
{
ngx_rtmp_live_stream_t *stream;
ngx_rtmp_live_meta_t *meta;
ngx_rtmp_live_ctx_t *ctx;
ngx_rtmp_session_t *s;
ngx_int_t n;
@ -209,6 +211,7 @@ ngx_rtmp_stat_live(ngx_http_request_t *r, ngx_chain_t ***lll,
ngx_int_t publishing;
u_char buf[NGX_OFF_T_LEN + 1];
ngx_rtmp_stat_loc_conf_t *slcf;
u_char *codec;
slcf = ngx_http_get_module_loc_conf(r, ngx_rtmp_stat_module);
@ -224,6 +227,28 @@ ngx_rtmp_stat_live(ngx_http_request_t *r, ngx_chain_t ***lll,
NGX_RTMP_STAT_ECS(stream->name);
NGX_RTMP_STAT_L("</name>\r\n");
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);
nclients = 0;

View file

@ -24,6 +24,10 @@
<th>Out bytes</th>
<th>In Kbps</th>
<th>Out Kbps</th>
<th>Size</th>
<th>Frame Rate</th>
<th>Video</th>
<th>Audio</th>
<th>State</th>
</tr>
<tr>
@ -32,7 +36,6 @@
<td><xsl:value-of select="out"/></td>
<td><xsl:value-of select="round(bwin div 1024)"/></td>
<td><xsl:value-of select="round(bwout div 1024)"/></td>
<td><xsl:apply-templates select="publishing"/></td>
</tr>
<xsl:apply-templates select="server"/>
</table>
@ -75,24 +78,16 @@
<xsl:value-of select="name"/>
</a>
</td>
<td align="middle">
<xsl:value-of select="nclients"/>
</td>
<td>
<xsl:value-of select="in"/>
</td>
<td>
<xsl:value-of select="out"/>
</td>
<td>
<xsl:value-of select="round(bwin div 1024)"/>
</td>
<td>
<xsl:value-of select="round(bwout div 1024)"/>
</td>
<td>
<xsl:apply-templates select="publishing"/>
</td>
<td align="middle"> <xsl:value-of select="nclients"/> </td>
<td><xsl:value-of select="in"/></td>
<td><xsl:value-of select="out"/></td>
<td><xsl:value-of select="round(bwin div 1024)"/></td>
<td><xsl:value-of select="round(bwout div 1024)"/></td>
<td><xsl:value-of select="meta/width"/>x<xsl:value-of select="meta/height"/></td>
<td align="middle"><xsl:value-of select="meta/framerate"/></td>
<td><xsl:value-of select="meta/video"/></td>
<td><xsl:value-of select="meta/audio"/></td>
<td> <xsl:apply-templates select="publishing"/> </td>
</tr>
<tr style="display:none">
<xsl:attribute name="id">