Skip to content

Commit

Permalink
rtmp hevc support - style fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
erankor committed May 4, 2024
1 parent 30dd576 commit f32e0fa
Show file tree
Hide file tree
Showing 6 changed files with 390 additions and 339 deletions.
140 changes: 68 additions & 72 deletions nginx-kmp-rtmp-module/src/ngx_kmp_rtmp_encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@
#define NGX_RTMP_AVC_SEQUENCE_HEADER 0
#define NGX_RTMP_AVC_NALU 1

#define NGX_RTMP_EXT_HEADER_SIZE 8 /* (frame | packet type), pts_delay, fourcc */
#define NGX_RTMP_EXT_HEADER_SIZE 5 /* (frame | packet type), fourcc */
#define NGX_RTMP_EXT_HEADER_SIZE_NALU 8 /* + pts_delay */
#define NGX_RTMP_EXT_SEQUENCE_HEADER 0
#define NGX_RTMP_EXT_NALU 1
static const uint32_t NGX_RTMP_EXT_FOURCC_HVC1 = 0x31637668;

/* audio */
#define NGX_RTMP_AAC_HEADER_SIZE 2 /* sound_info + packet_type */
Expand All @@ -57,7 +57,7 @@ static const uint32_t NGX_RTMP_EXT_FOURCC_HVC1 = 0x31637668;


#define NGX_RTMP_FRAME_HEADER_MAX_SIZE (NGX_RTMP_HEADER_0_SIZE \
+ NGX_RTMP_EXT_TIMESTAMP_SIZE + NGX_RTMP_EXT_HEADER_SIZE)
+ NGX_RTMP_EXT_TIMESTAMP_SIZE + NGX_RTMP_EXT_HEADER_SIZE_NALU)


#define ngx_kmp_rtmp_chunk_count(mlen, chunk_size) \
Expand Down Expand Up @@ -489,10 +489,6 @@ static ngx_kmp_rtmp_amf_field_t ngx_kmp_rtmp_amf_onfi[] = {
};


static u_char *
ngx_kmp_rtmp_encoder_ext_header_write(uint32_t codec_id, u_char *p, u_char packet_type,
u_char key_frame, uint32_t pts_delay);

static ngx_inline u_char *
ngx_kmp_rtmp_encoder_write_header(u_char *p, ngx_kmp_rtmp_header_t *h)
{
Expand Down Expand Up @@ -901,6 +897,66 @@ ngx_kmp_rtmp_encoder_avc_sequence_write(u_char *p,
}


static u_char *
ngx_kmp_rtmp_encoder_ext_header_write(u_char *p, u_char packet_type,
u_char key_frame, uint32_t fourcc, uint32_t pts_delay)
{
u_char frame_type;

frame_type = key_frame ? NGX_RTMP_FRAME_TYPE_KEY
: NGX_RTMP_FRAME_TYPE_INTER;

*p++ = 0x80 | (frame_type << 4) | packet_type;

p = ngx_copy(p, &fourcc, sizeof(fourcc));

if (packet_type == NGX_RTMP_EXT_NALU) {
ngx_kmp_rtmp_amf_write_be24(p, pts_delay);
}

return p;
}


size_t
ngx_kmp_rtmp_encoder_ext_sequence_get_size(ngx_kmp_rtmp_stream_ctx_t *sc,
ngx_str_t *extra_data)
{
size_t mlen;

mlen = NGX_RTMP_EXT_HEADER_SIZE + extra_data->len;

return NGX_RTMP_HEADER_0_SIZE + mlen
+ (ngx_kmp_rtmp_chunk_count(mlen, sc->chunk_size) - 1)
* NGX_RTMP_HEADER_3_SIZE;
}


u_char *
ngx_kmp_rtmp_encoder_ext_sequence_write(u_char *p,
ngx_kmp_rtmp_stream_ctx_t *sc, uint32_t fourcc, ngx_str_t *extra_data)
{
u_char *body;
ngx_kmp_rtmp_header_t h;

ngx_memzero(&h, sizeof(h));
h.csid = sc->csid;
h.mlen = NGX_RTMP_EXT_HEADER_SIZE + extra_data->len;
h.type = NGX_RTMP_MSG_VIDEO;
h.msid = sc->msid;

p = ngx_kmp_rtmp_encoder_write_header(p, &h);

body = p;
p = ngx_kmp_rtmp_encoder_ext_header_write(p, NGX_RTMP_EXT_SEQUENCE_HEADER,
1, fourcc, 0);
ngx_memcpy(p, extra_data->data, extra_data->len);

return ngx_kmp_rtmp_encoder_add_chunk_headers(body, h.mlen, sc->chunk_size,
h.csid);
}


static u_char *
ngx_kmp_rtmp_encoder_aac_header_write(u_char *p, u_char sound_info,
u_char packet_type)
Expand Down Expand Up @@ -1014,6 +1070,7 @@ ngx_kmp_rtmp_encoder_frame_write(ngx_kmp_rtmp_stream_ctx_t *sc,
h.timestamp = NGX_RTMP_EXT_TIMESTAMP;
}

/* TODO: add support for "vp09" and "av01" */
switch (codec_id) {

case KMP_CODEC_VIDEO_H264:
Expand All @@ -1025,11 +1082,12 @@ ngx_kmp_rtmp_encoder_frame_write(ngx_kmp_rtmp_stream_ctx_t *sc,
break;

case KMP_CODEC_VIDEO_H265:
header_size = NGX_RTMP_EXT_HEADER_SIZE - 4;
header_size = NGX_RTMP_EXT_HEADER_SIZE_NALU;
h.type = NGX_RTMP_MSG_VIDEO;

p = ngx_kmp_rtmp_encoder_ext_header_write(codec_id, p, NGX_RTMP_AVC_NALU,
frame->flags & KMP_FRAME_FLAG_KEY, frame->pts_delay);
p = ngx_kmp_rtmp_encoder_ext_header_write(p, NGX_RTMP_EXT_NALU,
frame->flags & KMP_FRAME_FLAG_KEY, NGX_RTMP_EXT_FOURCC_HVC1,
frame->pts_delay);
break;

case KMP_CODEC_AUDIO_MP3:
Expand Down Expand Up @@ -1115,65 +1173,3 @@ ngx_kmp_rtmp_encoder_frame_write(ngx_kmp_rtmp_stream_ctx_t *sc,

return NGX_OK;
}


size_t
ngx_kmp_rtmp_encoder_ext_sequence_get_size(ngx_kmp_rtmp_stream_ctx_t *sc,
ngx_str_t *extra_data)
{
size_t mlen;

mlen = NGX_RTMP_EXT_HEADER_SIZE - 3 + extra_data->len;

return NGX_RTMP_HEADER_0_SIZE + mlen
+ (ngx_kmp_rtmp_chunk_count(mlen, sc->chunk_size) - 1)
* NGX_RTMP_HEADER_3_SIZE;
}


u_char *
ngx_kmp_rtmp_encoder_ext_sequence_write(uint32_t codec_id, u_char *p,
ngx_kmp_rtmp_stream_ctx_t *sc, ngx_str_t *extra_data)
{
u_char *body;
ngx_kmp_rtmp_header_t h;


ngx_memzero(&h, sizeof(h));
h.csid = sc->csid;
h.mlen = NGX_RTMP_EXT_HEADER_SIZE - 3 + extra_data->len;
h.type = NGX_RTMP_MSG_VIDEO;
h.msid = sc->msid;

p = ngx_kmp_rtmp_encoder_write_header(p, &h);

body = p;
p = ngx_kmp_rtmp_encoder_ext_header_write(codec_id, p, NGX_RTMP_EXT_SEQUENCE_HEADER,
1, 0);
ngx_memcpy(p, extra_data->data, extra_data->len);

return ngx_kmp_rtmp_encoder_add_chunk_headers(body, h.mlen, sc->chunk_size,
h.csid);
}


static u_char *
ngx_kmp_rtmp_encoder_ext_header_write(uint32_t codec_id, u_char *p, u_char packet_type,
u_char key_frame, uint32_t pts_delay)
{
u_char frame_type;

frame_type = key_frame ? NGX_RTMP_FRAME_TYPE_KEY
: NGX_RTMP_FRAME_TYPE_INTER;

*p++ = (frame_type << 4) | 0x80 | packet_type;

// TODO: support for “vp09” and “av01”
p = ngx_copy(p, &NGX_RTMP_EXT_FOURCC_HVC1, 4);

if(packet_type == NGX_RTMP_EXT_NALU) {
ngx_kmp_rtmp_amf_write_be24(p, pts_delay);
}

return p;
}
14 changes: 7 additions & 7 deletions nginx-kmp-rtmp-module/src/ngx_kmp_rtmp_encoder.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

#define NGX_KMP_RTMP_TIMESCALE (1000)

#define NGX_RTMP_EXT_FOURCC_HVC1 0x31637668


typedef ngx_int_t (*ngx_kmp_rtmp_write_pt)(void *data, void *buf, size_t size);

Expand Down Expand Up @@ -95,6 +97,11 @@ size_t ngx_kmp_rtmp_encoder_avc_sequence_get_size(
u_char *ngx_kmp_rtmp_encoder_avc_sequence_write(u_char *p,
ngx_kmp_rtmp_stream_ctx_t *sc, ngx_str_t *extra_data);

size_t ngx_kmp_rtmp_encoder_ext_sequence_get_size(
ngx_kmp_rtmp_stream_ctx_t *sc, ngx_str_t *extra_data);
u_char *ngx_kmp_rtmp_encoder_ext_sequence_write(u_char *p,
ngx_kmp_rtmp_stream_ctx_t *sc, uint32_t fourcc, ngx_str_t *extra_data);

size_t ngx_kmp_rtmp_encoder_aac_sequence_get_size(
ngx_kmp_rtmp_stream_ctx_t *sc, ngx_str_t *extra_data);
u_char *ngx_kmp_rtmp_encoder_aac_sequence_write(u_char *p,
Expand All @@ -110,11 +117,4 @@ ngx_int_t ngx_kmp_rtmp_encoder_frame_write(ngx_kmp_rtmp_stream_ctx_t *sc,
ngx_kmp_rtmp_frame_t *frame, uint32_t codec_id,
ngx_kmp_rtmp_write_pt write, void *data);


size_t ngx_kmp_rtmp_encoder_ext_sequence_get_size(
ngx_kmp_rtmp_stream_ctx_t *sc, ngx_str_t *extra_data);
u_char *ngx_kmp_rtmp_encoder_ext_sequence_write(uint32_t codec_id, u_char *p,
ngx_kmp_rtmp_stream_ctx_t *sc, ngx_str_t *extra_data);


#endif /* _NGX_KMP_RTMP_ENCODER_H_INCLUDED_ */
25 changes: 16 additions & 9 deletions nginx-kmp-rtmp-module/src/ngx_kmp_rtmp_stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -185,13 +185,17 @@ ngx_kmp_rtmp_stream_write_meta(ngx_kmp_rtmp_stream_t *stream)

size = ngx_kmp_rtmp_encoder_metadata_get_size(&stream->ctx, &meta);

if (meta.mi[KMP_MEDIA_VIDEO].codec_id == KMP_CODEC_VIDEO_H264) {
switch (meta.mi[KMP_MEDIA_VIDEO].codec_id) {

case KMP_CODEC_VIDEO_H264:
size += ngx_kmp_rtmp_encoder_avc_sequence_get_size(
&stream->ctx, &extra_data[KMP_MEDIA_VIDEO]);
}
break;

if (meta.mi[KMP_MEDIA_VIDEO].codec_id == KMP_CODEC_VIDEO_H265) {
size += ngx_kmp_rtmp_encoder_ext_sequence_get_size(&stream->ctx, &extra_data[KMP_MEDIA_VIDEO]);
case KMP_CODEC_VIDEO_H265:
size += ngx_kmp_rtmp_encoder_ext_sequence_get_size(
&stream->ctx, &extra_data[KMP_MEDIA_VIDEO]);
break;
}

if (meta.mi[KMP_MEDIA_AUDIO].codec_id == KMP_CODEC_AUDIO_AAC) {
Expand All @@ -208,14 +212,17 @@ ngx_kmp_rtmp_stream_write_meta(ngx_kmp_rtmp_stream_t *stream)

p = ngx_kmp_rtmp_encoder_metadata_write(start, &stream->ctx, &meta);

if (meta.mi[KMP_MEDIA_VIDEO].codec_id == KMP_CODEC_VIDEO_H264) {
switch (meta.mi[KMP_MEDIA_VIDEO].codec_id) {

case KMP_CODEC_VIDEO_H264:
p = ngx_kmp_rtmp_encoder_avc_sequence_write(p, &stream->ctx,
&extra_data[KMP_MEDIA_VIDEO]);
}
break;

if (meta.mi[KMP_MEDIA_VIDEO].codec_id == KMP_CODEC_VIDEO_H265) {
p = ngx_kmp_rtmp_encoder_ext_sequence_write(meta.mi[KMP_MEDIA_VIDEO].codec_id,
p, &stream->ctx, &extra_data[KMP_MEDIA_VIDEO]);
case KMP_CODEC_VIDEO_H265:
p = ngx_kmp_rtmp_encoder_ext_sequence_write(p, &stream->ctx,
NGX_RTMP_EXT_FOURCC_HVC1, &extra_data[KMP_MEDIA_VIDEO]);
break;
}

if (meta.mi[KMP_MEDIA_AUDIO].codec_id == KMP_CODEC_AUDIO_AAC) {
Expand Down
Loading

0 comments on commit f32e0fa

Please sign in to comment.