blob: bab08bbc722b32a459b4a01e86084e0e3f9ab084 [file] [log] [blame]
James Kuszmaul82f6c042021-01-17 11:30:16 -08001/**
2 * @file rtmp/chunk.c Real Time Messaging Protocol (RTMP) -- Chunking
3 *
4 * Copyright (C) 2010 Creytiv.com
5 */
6#include <string.h>
7#include <re_types.h>
8#include <re_fmt.h>
9#include <re_mem.h>
10#include <re_mbuf.h>
11#include <re_net.h>
12#include <re_sa.h>
13#include <re_tcp.h>
14#include <re_list.h>
15#include <re_rtmp.h>
16#include "rtmp.h"
17
18
19/*
20 * Stateless RTMP chunker
21 */
22int rtmp_chunker(unsigned format, uint32_t chunk_id,
23 uint32_t timestamp, uint32_t timestamp_delta,
24 uint8_t msg_type_id, uint32_t msg_stream_id,
25 const uint8_t *payload, size_t payload_len,
26 size_t max_chunk_sz, struct tcp_conn *tc)
27{
28 const uint8_t *pend = payload + payload_len;
29 struct rtmp_header hdr;
30 struct mbuf *mb;
31 size_t chunk_sz;
32 int err;
33
34 if (!payload || !payload_len || !max_chunk_sz || !tc)
35 return EINVAL;
36
37 mb = mbuf_alloc(payload_len + 256);
38 if (!mb)
39 return ENOMEM;
40
41 memset(&hdr, 0, sizeof(hdr));
42
43 hdr.format = format;
44 hdr.chunk_id = chunk_id;
45
46 hdr.timestamp = timestamp;
47 hdr.timestamp_delta = timestamp_delta;
48 hdr.length = (uint32_t)payload_len;
49 hdr.type_id = msg_type_id;
50 hdr.stream_id = msg_stream_id;
51
52 chunk_sz = min(payload_len, max_chunk_sz);
53
54 err = rtmp_header_encode(mb, &hdr);
55 err |= mbuf_write_mem(mb, payload, chunk_sz);
56 if (err)
57 goto out;
58
59 payload += chunk_sz;
60
61 hdr.format = 3;
62
63 while (payload < pend) {
64
65 const size_t len = pend - payload;
66
67 chunk_sz = min(len, max_chunk_sz);
68
69 err = rtmp_header_encode(mb, &hdr);
70 err |= mbuf_write_mem(mb, payload, chunk_sz);
71 if (err)
72 goto out;
73
74 payload += chunk_sz;
75 }
76
77 mb->pos = 0;
78
79 err = tcp_send(tc, mb);
80 if (err)
81 goto out;
82
83 out:
84 mem_deref(mb);
85
86 return err;
87}