Skip to content

Commit

Permalink
implemented avc sps parser & improved dash & stats
Browse files Browse the repository at this point in the history
  • Loading branch information
arut committed Dec 20, 2013
1 parent aa4bcf8 commit 18fa7a5
Show file tree
Hide file tree
Showing 9 changed files with 483 additions and 146 deletions.
2 changes: 2 additions & 0 deletions config
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ NGX_ADDON_DEPS="$NGX_ADDON_DEPS \
$ngx_addon_dir/ngx_rtmp_record_module.h \
$ngx_addon_dir/ngx_rtmp_relay_module.h \
$ngx_addon_dir/ngx_rtmp_streams.h \
$ngx_addon_dir/ngx_rtmp_bitop.h \
$ngx_addon_dir/hls/ngx_rtmp_mpegts.h \
$ngx_addon_dir/dash/ngx_rtmp_mp4.h \
"
Expand Down Expand Up @@ -77,6 +78,7 @@ NGX_ADDON_SRCS="$NGX_ADDON_SRCS \
$ngx_addon_dir/ngx_rtmp_notify_module.c \
$ngx_addon_dir/ngx_rtmp_log_module.c \
$ngx_addon_dir/ngx_rtmp_limit_module.c \
$ngx_addon_dir/ngx_rtmp_bitop.c \
$ngx_addon_dir/hls/ngx_rtmp_hls_module.c \
$ngx_addon_dir/dash/ngx_rtmp_dash_module.c \
$ngx_addon_dir/hls/ngx_rtmp_mpegts.c \
Expand Down
20 changes: 12 additions & 8 deletions dash/ngx_rtmp_mp4.c
Original file line number Diff line number Diff line change
Expand Up @@ -511,14 +511,18 @@ ngx_rtmp_mp4_write_avcc(ngx_rtmp_session_t *s, ngx_buf_t *b)

/* assume config fits one chunk (highly probable) */

/* check for start code */
for (p = in->buf->pos; p <= in->buf->last; p++) {
if (*p == 0x01) {
break;
}
}

if (in->buf->last - p > 0) {
/*
* Skip:
* - flv fmt
* - H264 CONF/PICT (0x00)
* - 0
* - 0
* - 0
*/

p = in->buf->pos + 5;

if (p < in->buf->last) {
ngx_rtmp_mp4_data(b, p, (size_t) (in->buf->last - p));
} else {
ngx_log_error(NGX_LOG_ERR, s->connection->log, ngx_errno,
Expand Down
55 changes: 7 additions & 48 deletions hls/ngx_rtmp_hls_module.c
Original file line number Diff line number Diff line change
Expand Up @@ -657,7 +657,7 @@ ngx_rtmp_hls_append_sps_pps(ngx_rtmp_session_t *s, ngx_buf_t *out)
nnals &= 0x1f; /* 5lsb */

ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"h264: SPS number: %uz", nnals);
"hls: SPS number: %uz", nnals);

/* SPS */
for (n = 0; ; ++n) {
Expand All @@ -671,12 +671,12 @@ ngx_rtmp_hls_append_sps_pps(ngx_rtmp_session_t *s, ngx_buf_t *out)
ngx_rtmp_rmemcpy(&len, &rlen, 2);

ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"h264: header NAL length: %uz", (size_t) len);
"hls: header NAL length: %uz", (size_t) len);

/* AnnexB prefix */
if (out->end - out->last < 4) {
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
"h264: too small buffer for header NAL size");
"hls: too small buffer for header NAL size");
return NGX_ERROR;
}

Expand All @@ -688,7 +688,7 @@ ngx_rtmp_hls_append_sps_pps(ngx_rtmp_session_t *s, ngx_buf_t *out)
/* NAL body */
if (out->end - out->last < len) {
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
"h264: too small buffer for header NAL");
"hls: too small buffer for header NAL");
return NGX_ERROR;
}

Expand All @@ -709,7 +709,7 @@ ngx_rtmp_hls_append_sps_pps(ngx_rtmp_session_t *s, ngx_buf_t *out)
}

ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"h264: PPS number: %uz", nnals);
"hls: PPS number: %uz", nnals);
}

return NGX_OK;
Expand Down Expand Up @@ -1612,40 +1612,6 @@ ngx_rtmp_hls_audio(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
}


static ngx_int_t
ngx_rtmp_hls_get_nal_bytes(ngx_rtmp_session_t *s)
{
ngx_rtmp_codec_ctx_t *codec_ctx;
ngx_chain_t *cl;
u_char *p;
uint8_t nal_bytes;

codec_ctx = ngx_rtmp_get_module_ctx(s, ngx_rtmp_codec_module);

cl = codec_ctx->avc_header;

p = cl->buf->pos;

if (ngx_rtmp_hls_copy(s, NULL, &p, 9, &cl) != NGX_OK) {
return NGX_ERROR;
}

/* NAL size length (1,2,4) */
if (ngx_rtmp_hls_copy(s, &nal_bytes, &p, 1, &cl) != NGX_OK) {
return NGX_ERROR;
}

nal_bytes &= 0x03; /* 2 lsb */

++nal_bytes;

ngx_log_debug1(NGX_LOG_DEBUG_RTMP, s->connection->log, 0,
"hls: NAL bytes: %ui", (ngx_uint_t) nal_bytes);

return nal_bytes;
}


static ngx_int_t
ngx_rtmp_hls_video(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
ngx_chain_t *in)
Expand All @@ -1660,7 +1626,7 @@ ngx_rtmp_hls_video(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
uint32_t cts;
ngx_rtmp_mpegts_frame_t frame;
ngx_uint_t nal_bytes;
ngx_int_t aud_sent, sps_pps_sent, rc, boundary;
ngx_int_t aud_sent, sps_pps_sent, boundary;
static u_char buffer[NGX_RTMP_HLS_BUFSIZE];

hacf = ngx_rtmp_get_module_app_conf(s, ngx_rtmp_hls_module);
Expand Down Expand Up @@ -1719,14 +1685,7 @@ ngx_rtmp_hls_video(ngx_rtmp_session_t *s, ngx_rtmp_header_t *h,
out.pos = out.start;
out.last = out.pos;

rc = ngx_rtmp_hls_get_nal_bytes(s);
if (rc < 0) {
ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
"hls: failed to parse NAL bytes");
return NGX_OK;
}

nal_bytes = rc;
nal_bytes = codec_ctx->avc_nal_bytes;
aud_sent = 0;
sps_pps_sent = 0;

Expand Down
63 changes: 63 additions & 0 deletions ngx_rtmp_bitop.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@

/*
* Copyright (C) Roman Arutyunyan
*/


#include <ngx_config.h>
#include <ngx_core.h>
#include "ngx_rtmp_bitop.h"


void
ngx_rtmp_bit_init_reader(ngx_rtmp_bit_reader_t *br, u_char *pos, u_char *last)
{
ngx_memzero(br, sizeof(ngx_rtmp_bit_reader_t));

br->pos = pos;
br->last = last;
}


uint64_t
ngx_rtmp_bit_read(ngx_rtmp_bit_reader_t *br, ngx_uint_t n)
{
uint64_t v;
ngx_uint_t d;

v = 0;

while (n) {

if (br->pos >= br->last) {
br->err = 1;
return 0;
}

d = (br->offs + n > 8 ? (ngx_uint_t) (8 - br->offs) : n);

v <<= d;
v += (*br->pos >> (8 - br->offs - d)) & ((u_char) 0xff >> (8 - d));

br->offs += d;
n -= d;

if (br->offs == 8) {
br->pos++;
br->offs = 0;
}
}

return v;
}


uint64_t
ngx_rtmp_bit_read_golomb(ngx_rtmp_bit_reader_t *br)
{
ngx_uint_t n;

for (n = 0; ngx_rtmp_bit_read(br, 1) == 0 && !br->err; n++);

return ((uint64_t) 1 << n) + ngx_rtmp_bit_read(br, n) - 1;
}
46 changes: 46 additions & 0 deletions ngx_rtmp_bitop.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

/*
* Copyright (C) Roman Arutyunyan
*/


#ifndef _NGX_RTMP_BITOP_H_INCLUDED_
#define _NGX_RTMP_BITOP_H_INCLUDED_


#include <ngx_config.h>
#include <ngx_core.h>


typedef struct {
u_char *pos;
u_char *last;
ngx_uint_t offs;
ngx_uint_t err;
} ngx_rtmp_bit_reader_t;


void ngx_rtmp_bit_init_reader(ngx_rtmp_bit_reader_t *br, u_char *pos,
u_char *last);
uint64_t ngx_rtmp_bit_read(ngx_rtmp_bit_reader_t *br, ngx_uint_t n);
uint64_t ngx_rtmp_bit_read_golomb(ngx_rtmp_bit_reader_t *br);


#define ngx_rtmp_bit_read_err(br) ((br)->err)

#define ngx_rtmp_bit_read_eof(br) ((br)->pos == (br)->last)

#define ngx_rtmp_bit_read_8(br) \
((uint8_t) ngx_rtmp_bit_read(br, 8))

#define ngx_rtmp_bit_read_16(br) \
((uint16_t) ngx_rtmp_bit_read(br, 16))

#define ngx_rtmp_bit_read_32(br) \
((uint32_t) ngx_rtmp_bit_read(br, 32))

#define ngx_rtmp_bit_read_64(br) \
((uint64_t) ngx_rtmp_read(br, 64))


#endif /* _NGX_RTMP_BITOP_H_INCLUDED_ */
Loading

0 comments on commit 18fa7a5

Please sign in to comment.