FFmpeg
rtmpcrypt.c
Go to the documentation of this file.
1 /*
2  * RTMPE network protocol
3  * Copyright (c) 2008-2009 Andrej Stepanchuk
4  * Copyright (c) 2009-2010 Howard Chu
5  * Copyright (c) 2012 Samuel Pitoiset
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 /**
25  * @file
26  * RTMPE protocol
27  */
28 
29 #include "libavutil/blowfish.h"
30 #include "libavutil/intreadwrite.h"
31 #include "libavutil/opt.h"
32 #include "libavutil/rc4.h"
33 #include "libavutil/xtea.h"
34 
35 #include "internal.h"
36 #include "rtmp.h"
37 #include "rtmpdh.h"
38 #include "rtmpcrypt.h"
39 #include "url.h"
40 
41 /* protocol handler context */
42 typedef struct RTMPEContext {
43  const AVClass *class;
44  URLContext *stream; ///< TCP stream
45  FF_DH *dh; ///< Diffie-Hellman context
46  struct AVRC4 key_in; ///< RC4 key used for decrypt data
47  struct AVRC4 key_out; ///< RC4 key used for encrypt data
48  int handshaked; ///< flag indicating when the handshake is performed
49  int tunneling; ///< use a HTTP connection (RTMPTE)
50 } RTMPEContext;
51 
52 static const uint8_t rtmpe8_keys[16][16] = {
53  { 0xb2, 0x34, 0xf0, 0xbf, 0x1f, 0x08, 0xd9, 0x11,
54  0x95, 0xb7, 0xdf, 0xcc, 0x32, 0xe7, 0x8d, 0x74 },
55  { 0xb6, 0x5e, 0x6a, 0x08, 0x0e, 0x09, 0x43, 0x17,
56  0xb8, 0x5a, 0xf0, 0x6e, 0xe2, 0x39, 0x5a, 0xfe },
57  { 0x6f, 0x95, 0x10, 0x7b, 0x21, 0x05, 0xce, 0x76,
58  0x3a, 0xa7, 0x88, 0x23, 0xa1, 0x49, 0x01, 0x44 },
59  { 0x17, 0xf3, 0x43, 0xa9, 0xb2, 0x1b, 0xf1, 0xeb,
60  0xee, 0xa5, 0x91, 0xa6, 0x39, 0x63, 0xf3, 0x17 },
61  { 0x0a, 0xe0, 0x30, 0x7a, 0x2c, 0xe2, 0x29, 0xb5,
62  0xa5, 0xae, 0x87, 0xa0, 0xac, 0x79, 0xcb, 0xc0 },
63  { 0x23, 0x0c, 0xce, 0xbd, 0xff, 0xde, 0xeb, 0x2f,
64  0x16, 0xae, 0xfa, 0x1c, 0x9d, 0x23, 0x23, 0x11 },
65  { 0x7b, 0x3f, 0xdd, 0x55, 0x2e, 0xe6, 0xe7, 0x77,
66  0x99, 0xc4, 0xb8, 0x9b, 0xe4, 0x1e, 0x48, 0xc9 },
67  { 0xb4, 0xb6, 0x7b, 0x40, 0x36, 0x91, 0xe8, 0x71,
68  0x55, 0xbf, 0xae, 0xa7, 0x39, 0xb8, 0x33, 0xca },
69  { 0xc3, 0xbd, 0xf6, 0xfc, 0x97, 0x36, 0x3c, 0xb6,
70  0x25, 0xf8, 0xe4, 0x7c, 0xb2, 0x59, 0xd9, 0x04 },
71  { 0xfd, 0x91, 0xe0, 0x28, 0x4c, 0x4c, 0x95, 0x41,
72  0x00, 0xdb, 0xb7, 0x7f, 0xf8, 0x66, 0xa0, 0xe3 },
73  { 0x76, 0x5b, 0x84, 0x57, 0x03, 0x1b, 0x25, 0x4f,
74  0xcd, 0x5b, 0xd4, 0x46, 0x29, 0x0d, 0xc3, 0xa2 },
75  { 0xf8, 0xee, 0xcc, 0x0a, 0x46, 0xb5, 0x55, 0xda,
76  0x52, 0x34, 0x47, 0x03, 0x3b, 0x71, 0x63, 0x58 },
77  { 0xdc, 0x75, 0x20, 0xb8, 0xee, 0x1f, 0x5f, 0xa7,
78  0xe8, 0x68, 0x42, 0xd8, 0xcc, 0x44, 0x2a, 0xa7 },
79  { 0x9e, 0x6e, 0xcf, 0x07, 0x25, 0x7b, 0x6d, 0xa1,
80  0x6c, 0xae, 0xa7, 0x9f, 0x29, 0x56, 0x2f, 0xd9 },
81  { 0xe4, 0xea, 0xb1, 0xfe, 0xe1, 0x3c, 0x8c, 0x8c,
82  0xa7, 0x64, 0x00, 0x4e, 0x2a, 0x7c, 0x38, 0x6a },
83  { 0x27, 0x94, 0x3a, 0x89, 0xa2, 0x13, 0x30, 0xcc,
84  0x5b, 0x38, 0x06, 0xf1, 0x27, 0xf9, 0x29, 0xa8 }
85 };
86 
87 static const uint8_t rtmpe9_keys[16][24] = {
88  { 0x79, 0x34, 0x77, 0x4c, 0x67, 0xd1, 0x38, 0x3a, 0xdf, 0xb3, 0x56, 0xbe,
89  0x8b, 0x7b, 0xd0, 0x24, 0x38, 0xe0, 0x73, 0x58, 0x41, 0x5d, 0x69, 0x67, },
90  { 0x46, 0xf6, 0xb4, 0xcc, 0x01, 0x93, 0xe3, 0xa1, 0x9e, 0x7d, 0x3c, 0x65,
91  0x55, 0x86, 0xfd, 0x09, 0x8f, 0xf7, 0xb3, 0xc4, 0x6f, 0x41, 0xca, 0x5c, },
92  { 0x1a, 0xe7, 0xe2, 0xf3, 0xf9, 0x14, 0x79, 0x94, 0xc0, 0xd3, 0x97, 0x43,
93  0x08, 0x7b, 0xb3, 0x84, 0x43, 0x2f, 0x9d, 0x84, 0x3f, 0x21, 0x01, 0x9b, },
94  { 0xd3, 0xe3, 0x54, 0xb0, 0xf7, 0x1d, 0xf6, 0x2b, 0x5a, 0x43, 0x4d, 0x04,
95  0x83, 0x64, 0x3e, 0x0d, 0x59, 0x2f, 0x61, 0xcb, 0xb1, 0x6a, 0x59, 0x0d, },
96  { 0xc8, 0xc1, 0xe9, 0xb8, 0x16, 0x56, 0x99, 0x21, 0x7b, 0x5b, 0x36, 0xb7,
97  0xb5, 0x9b, 0xdf, 0x06, 0x49, 0x2c, 0x97, 0xf5, 0x95, 0x48, 0x85, 0x7e, },
98  { 0xeb, 0xe5, 0xe6, 0x2e, 0xa4, 0xba, 0xd4, 0x2c, 0xf2, 0x16, 0xe0, 0x8f,
99  0x66, 0x23, 0xa9, 0x43, 0x41, 0xce, 0x38, 0x14, 0x84, 0x95, 0x00, 0x53, },
100  { 0x66, 0xdb, 0x90, 0xf0, 0x3b, 0x4f, 0xf5, 0x6f, 0xe4, 0x9c, 0x20, 0x89,
101  0x35, 0x5e, 0xd2, 0xb2, 0xc3, 0x9e, 0x9f, 0x7f, 0x63, 0xb2, 0x28, 0x81, },
102  { 0xbb, 0x20, 0xac, 0xed, 0x2a, 0x04, 0x6a, 0x19, 0x94, 0x98, 0x9b, 0xc8,
103  0xff, 0xcd, 0x93, 0xef, 0xc6, 0x0d, 0x56, 0xa7, 0xeb, 0x13, 0xd9, 0x30, },
104  { 0xbc, 0xf2, 0x43, 0x82, 0x09, 0x40, 0x8a, 0x87, 0x25, 0x43, 0x6d, 0xe6,
105  0xbb, 0xa4, 0xb9, 0x44, 0x58, 0x3f, 0x21, 0x7c, 0x99, 0xbb, 0x3f, 0x24, },
106  { 0xec, 0x1a, 0xaa, 0xcd, 0xce, 0xbd, 0x53, 0x11, 0xd2, 0xfb, 0x83, 0xb6,
107  0xc3, 0xba, 0xab, 0x4f, 0x62, 0x79, 0xe8, 0x65, 0xa9, 0x92, 0x28, 0x76, },
108  { 0xc6, 0x0c, 0x30, 0x03, 0x91, 0x18, 0x2d, 0x7b, 0x79, 0xda, 0xe1, 0xd5,
109  0x64, 0x77, 0x9a, 0x12, 0xc5, 0xb1, 0xd7, 0x91, 0x4f, 0x96, 0x4c, 0xa3, },
110  { 0xd7, 0x7c, 0x2a, 0xbf, 0xa6, 0xe7, 0x85, 0x7c, 0x45, 0xad, 0xff, 0x12,
111  0x94, 0xd8, 0xde, 0xa4, 0x5c, 0x3d, 0x79, 0xa4, 0x44, 0x02, 0x5d, 0x22, },
112  { 0x16, 0x19, 0x0d, 0x81, 0x6a, 0x4c, 0xc7, 0xf8, 0xb8, 0xf9, 0x4e, 0xcd,
113  0x2c, 0x9e, 0x90, 0x84, 0xb2, 0x08, 0x25, 0x60, 0xe1, 0x1e, 0xae, 0x18, },
114  { 0xe9, 0x7c, 0x58, 0x26, 0x1b, 0x51, 0x9e, 0x49, 0x82, 0x60, 0x61, 0xfc,
115  0xa0, 0xa0, 0x1b, 0xcd, 0xf5, 0x05, 0xd6, 0xa6, 0x6d, 0x07, 0x88, 0xa3, },
116  { 0x2b, 0x97, 0x11, 0x8b, 0xd9, 0x4e, 0xd9, 0xdf, 0x20, 0xe3, 0x9c, 0x10,
117  0xe6, 0xa1, 0x35, 0x21, 0x11, 0xf9, 0x13, 0x0d, 0x0b, 0x24, 0x65, 0xb2, },
118  { 0x53, 0x6a, 0x4c, 0x54, 0xac, 0x8b, 0x9b, 0xb8, 0x97, 0x29, 0xfc, 0x60,
119  0x2c, 0x5b, 0x3a, 0x85, 0x68, 0xb5, 0xaa, 0x6a, 0x44, 0xcd, 0x3f, 0xa7, },
120 };
121 
123 {
124  RTMPEContext *rt = h->priv_data;
125  int offset, ret;
126 
127  if (!(rt->dh = ff_dh_init(1024)))
128  return AVERROR(ENOMEM);
129 
130  offset = ff_rtmp_calc_digest_pos(buf, 768, 632, 8);
131  if (offset < 0)
132  return offset;
133 
134  /* generate a Diffie-Hellmann public key */
135  if ((ret = ff_dh_generate_public_key(rt->dh)) < 0)
136  return ret;
137 
138  /* write the public key into the handshake buffer */
139  if ((ret = ff_dh_write_public_key(rt->dh, buf + offset, 128)) < 0)
140  return ret;
141 
142  return 0;
143 }
144 
146  const uint8_t *clientdata, int type)
147 {
148  RTMPEContext *rt = h->priv_data;
149  uint8_t secret_key[128], digest[32];
150  int server_pos, client_pos;
151  int ret;
152 
153  if (type) {
154  if ((server_pos = ff_rtmp_calc_digest_pos(serverdata, 1532, 632, 772)) < 0)
155  return server_pos;
156  } else {
157  if ((server_pos = ff_rtmp_calc_digest_pos(serverdata, 768, 632, 8)) < 0)
158  return server_pos;
159  }
160 
161  if ((client_pos = ff_rtmp_calc_digest_pos(clientdata, 768, 632, 8)) < 0)
162  return client_pos;
163 
164  /* compute the shared secret secret in order to compute RC4 keys */
165  if ((ret = ff_dh_compute_shared_secret_key(rt->dh, serverdata + server_pos,
166  128, secret_key, sizeof(secret_key))) < 0)
167  return ret;
168 
169  /* set output key */
170  if ((ret = ff_rtmp_calc_digest(serverdata + server_pos, 128, 0, secret_key,
171  128, digest)) < 0)
172  return ret;
173  av_rc4_init(&rt->key_out, digest, 16 * 8, 1);
174 
175  /* set input key */
176  if ((ret = ff_rtmp_calc_digest(clientdata + client_pos, 128, 0, secret_key,
177  128, digest)) < 0)
178  return ret;
179  av_rc4_init(&rt->key_in, digest, 16 * 8, 1);
180 
181  return 0;
182 }
183 
184 static void rtmpe8_sig(const uint8_t *in, uint8_t *out, int key_id)
185 {
186  struct AVXTEA ctx;
187 
188  av_xtea_le_init(&ctx, rtmpe8_keys[key_id]);
189  av_xtea_le_crypt(&ctx, out, in, 1, NULL, 0);
190 }
191 
192 static void rtmpe9_sig(const uint8_t *in, uint8_t *out, int key_id)
193 {
194  struct AVBlowfish ctx;
195  uint32_t xl, xr;
196 
197  xl = AV_RL32(in);
198  xr = AV_RL32(in + 4);
199 
200  av_blowfish_init(&ctx, rtmpe9_keys[key_id], 24);
201  av_blowfish_crypt_ecb(&ctx, &xl, &xr, 0);
202 
203  AV_WL32(out, xl);
204  AV_WL32(out + 4, xr);
205 }
206 
207 void ff_rtmpe_encrypt_sig(URLContext *h, uint8_t *sig, const uint8_t *digest,
208  int type)
209 {
210  int i;
211 
212  for (i = 0; i < 32; i += 8) {
213  if (type == 8) {
214  /* RTMPE type 8 uses XTEA on the signature */
215  rtmpe8_sig(sig + i, sig + i, digest[i] % 15);
216  } else if (type == 9) {
217  /* RTMPE type 9 uses Blowfish on the signature */
218  rtmpe9_sig(sig + i, sig + i, digest[i] % 15);
219  }
220  }
221 }
222 
224 {
225  RTMPEContext *rt = h->priv_data;
226  char buf[RTMP_HANDSHAKE_PACKET_SIZE];
227 
228  /* skip past 1536 bytes of the RC4 bytestream */
229  av_rc4_crypt(&rt->key_in, buf, NULL, sizeof(buf), NULL, 1);
230  av_rc4_crypt(&rt->key_out, buf, NULL, sizeof(buf), NULL, 1);
231 
232  /* the next requests will be encrypted using RC4 keys */
233  rt->handshaked = 1;
234 
235  return 0;
236 }
237 
239 {
240  RTMPEContext *rt = h->priv_data;
241 
242  ff_dh_free(rt->dh);
243  ffurl_closep(&rt->stream);
244 
245  return 0;
246 }
247 
248 static int rtmpe_open(URLContext *h, const char *uri, int flags)
249 {
250  RTMPEContext *rt = h->priv_data;
251  char host[256], url[1024];
252  int ret, port;
253 
254  av_url_split(NULL, 0, NULL, 0, host, sizeof(host), &port, NULL, 0, uri);
255 
256  if (rt->tunneling) {
257  if (port < 0)
258  port = 80;
259  ff_url_join(url, sizeof(url), "ffrtmphttp", NULL, host, port, NULL);
260  } else {
261  if (port < 0)
262  port = 1935;
263  ff_url_join(url, sizeof(url), "tcp", NULL, host, port, NULL);
264  }
265 
266  /* open the tcp or ffrtmphttp connection */
268  &h->interrupt_callback, NULL,
269  h->protocol_whitelist, h->protocol_blacklist, h)) < 0) {
270  rtmpe_close(h);
271  return ret;
272  }
273 
274  return 0;
275 }
276 
277 static int rtmpe_read(URLContext *h, uint8_t *buf, int size)
278 {
279  RTMPEContext *rt = h->priv_data;
280  int ret;
281 
282  rt->stream->flags |= h->flags & AVIO_FLAG_NONBLOCK;
283  ret = ffurl_read(rt->stream, buf, size);
285 
286  if (ret < 0 && ret != AVERROR_EOF)
287  return ret;
288 
289  if (rt->handshaked && ret > 0) {
290  /* decrypt data received by the server */
291  av_rc4_crypt(&rt->key_in, buf, buf, ret, NULL, 1);
292  }
293 
294  return ret;
295 }
296 
297 static int rtmpe_write(URLContext *h, const uint8_t *buf, int size)
298 {
299  RTMPEContext *rt = h->priv_data;
300  int ret;
301 
302  if (rt->handshaked) {
303  /* encrypt data to send to the server */
304  av_rc4_crypt(&rt->key_out, (uint8_t *)buf, buf, size, NULL, 1);
305  }
306 
307  if ((ret = ffurl_write(rt->stream, buf, size)) < 0)
308  return ret;
309 
310  return size;
311 }
312 
313 #define OFFSET(x) offsetof(RTMPEContext, x)
314 #define DEC AV_OPT_FLAG_DECODING_PARAM
315 
316 static const AVOption ffrtmpcrypt_options[] = {
317  {"ffrtmpcrypt_tunneling", "Use a HTTP tunneling connection (RTMPTE).", OFFSET(tunneling), AV_OPT_TYPE_INT, {.i64 = 0}, 0, 1, DEC},
318  { NULL },
319 };
320 
321 static const AVClass ffrtmpcrypt_class = {
322  .class_name = "ffrtmpcrypt",
323  .item_name = av_default_item_name,
324  .option = ffrtmpcrypt_options,
325  .version = LIBAVUTIL_VERSION_INT,
326 };
327 
329  .name = "ffrtmpcrypt",
330  .url_open = rtmpe_open,
331  .url_read = rtmpe_read,
332  .url_write = rtmpe_write,
333  .url_close = rtmpe_close,
334  .priv_data_size = sizeof(RTMPEContext),
336  .priv_data_class = &ffrtmpcrypt_class,
337 };
RTMPEContext::dh
FF_DH * dh
Diffie-Hellman context.
Definition: rtmpcrypt.c:45
ff_ffrtmpcrypt_protocol
const URLProtocol ff_ffrtmpcrypt_protocol
Definition: rtmpcrypt.c:328
ff_rtmpe_update_keystream
int ff_rtmpe_update_keystream(URLContext *h)
Update the keystream and set RC4 keys for encryption.
Definition: rtmpcrypt.c:223
RTMP_HANDSHAKE_PACKET_SIZE
#define RTMP_HANDSHAKE_PACKET_SIZE
Definition: rtmp.h:30
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
AV_WL32
#define AV_WL32(p, v)
Definition: intreadwrite.h:426
URL_PROTOCOL_FLAG_NETWORK
#define URL_PROTOCOL_FLAG_NETWORK
Definition: url.h:34
out
FILE * out
Definition: movenc.c:54
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:55
AVIO_FLAG_READ_WRITE
#define AVIO_FLAG_READ_WRITE
read-write pseudo flag
Definition: avio.h:676
ff_dh_compute_shared_secret_key
int ff_dh_compute_shared_secret_key(FF_DH *dh, const uint8_t *pub_key, int pub_key_len, uint8_t *secret_key, int secret_key_len)
Compute the shared secret key from the private FF_DH value and the other party's public value.
Definition: rtmpdh.c:390
AVRC4
Definition: rc4.h:32
AVOption
AVOption.
Definition: opt.h:246
RTMPEContext::tunneling
int tunneling
use a HTTP connection (RTMPTE)
Definition: rtmpcrypt.c:49
URLProtocol
Definition: url.h:54
ffrtmpcrypt_class
static const AVClass ffrtmpcrypt_class
Definition: rtmpcrypt.c:321
DEC
#define DEC
Definition: rtmpcrypt.c:314
rtmpe8_sig
static void rtmpe8_sig(const uint8_t *in, uint8_t *out, int key_id)
Definition: rtmpcrypt.c:184
rtmpe9_keys
static const uint8_t rtmpe9_keys[16][24]
Definition: rtmpcrypt.c:87
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
rtmpe_read
static int rtmpe_read(URLContext *h, uint8_t *buf, int size)
Definition: rtmpcrypt.c:277
rtmpe_close
static int rtmpe_close(URLContext *h)
Definition: rtmpcrypt.c:238
RTMPEContext::key_in
struct AVRC4 key_in
RC4 key used for decrypt data.
Definition: rtmpcrypt.c:46
ffurl_open_whitelist
int ffurl_open_whitelist(URLContext **puc, const char *filename, int flags, const AVIOInterruptCB *int_cb, AVDictionary **options, const char *whitelist, const char *blacklist, URLContext *parent)
Create an URLContext for accessing to the resource indicated by url, and open it.
Definition: avio.c:307
intreadwrite.h
URLContext::flags
int flags
Definition: url.h:43
ff_url_join
int ff_url_join(char *str, int size, const char *proto, const char *authorization, const char *hostname, int port, const char *fmt,...)
Definition: url.c:38
ctx
AVFormatContext * ctx
Definition: movenc.c:48
internal.h
ffrtmpcrypt_options
static const AVOption ffrtmpcrypt_options[]
Definition: rtmpcrypt.c:316
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
ff_rtmp_calc_digest
int ff_rtmp_calc_digest(const uint8_t *src, int len, int gap, const uint8_t *key, int keylen, uint8_t *dst)
Calculate HMAC-SHA2 digest for RTMP handshake packets.
Definition: rtmpdigest.c:34
NULL
#define NULL
Definition: coverity.c:32
ff_rtmpe_gen_pub_key
int ff_rtmpe_gen_pub_key(URLContext *h, uint8_t *buf)
Initialize the Diffie-Hellmann context and generate the public key.
Definition: rtmpcrypt.c:122
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
RTMPEContext::stream
URLContext * stream
TCP stream.
Definition: rtmpcrypt.c:44
blowfish.h
OFFSET
#define OFFSET(x)
Definition: rtmpcrypt.c:313
size
int size
Definition: twinvq_data.h:11134
URLProtocol::name
const char * name
Definition: url.h:55
ff_rtmp_calc_digest_pos
int ff_rtmp_calc_digest_pos(const uint8_t *buf, int off, int mod_val, int add_val)
Calculate digest position for RTMP handshake packets.
Definition: rtmpdigest.c:57
rtmpcrypt.h
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
av_xtea_le_init
void av_xtea_le_init(AVXTEA *ctx, const uint8_t key[16])
Initialize an AVXTEA context.
Definition: xtea.c:50
AVBlowfish
Definition: blowfish.h:35
in
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (dithered)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> in
Definition: audio_convert.c:326
URLContext
Definition: url.h:38
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
rtmpe8_keys
static const uint8_t rtmpe8_keys[16][16]
Definition: rtmpcrypt.c:52
av_rc4_crypt
void av_rc4_crypt(AVRC4 *r, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypts / decrypts using the RC4 algorithm.
Definition: rc4.c:54
AVXTEA
Definition: xtea.h:35
RTMPEContext::handshaked
int handshaked
flag indicating when the handshake is performed
Definition: rtmpcrypt.c:48
av_url_split
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
Definition: utils.c:4802
url.h
uint8_t
uint8_t
Definition: audio_convert.c:194
rtmp.h
ffurl_closep
int ffurl_closep(URLContext **hh)
Close the resource accessed by the URLContext h, and free the memory used by it.
Definition: avio.c:446
ret
ret
Definition: filter_design.txt:187
av_rc4_init
int av_rc4_init(AVRC4 *r, const uint8_t *key, int key_bits, int decrypt)
Initializes an AVRC4 context.
Definition: rc4.c:33
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
RTMPEContext::key_out
struct AVRC4 key_out
RC4 key used for encrypt data.
Definition: rtmpcrypt.c:47
AV_RL32
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_RL32
Definition: bytestream.h:88
ff_dh_write_public_key
int ff_dh_write_public_key(FF_DH *dh, uint8_t *pub_key, int pub_key_len)
Write the public key into the given buffer.
Definition: rtmpdh.c:374
FF_DH
Definition: rtmpdh.h:50
rtmpdh.h
ff_rtmpe_encrypt_sig
void ff_rtmpe_encrypt_sig(URLContext *h, uint8_t *sig, const uint8_t *digest, int type)
Encrypt the signature.
Definition: rtmpcrypt.c:207
ff_rtmpe_compute_secret_key
int ff_rtmpe_compute_secret_key(URLContext *h, const uint8_t *serverdata, const uint8_t *clientdata, int type)
Compute the shared secret key and initialize the RC4 encryption.
Definition: rtmpcrypt.c:145
ffurl_read
int ffurl_read(URLContext *h, unsigned char *buf, int size)
Read up to size bytes from the resource accessed by h, and store the read bytes in buf.
Definition: avio.c:409
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:223
ffurl_write
int ffurl_write(URLContext *h, const unsigned char *buf, int size)
Write size bytes from buf to the resource accessed by h.
Definition: avio.c:423
ff_dh_free
void ff_dh_free(FF_DH *dh)
Free a Diffie-Hellmann context.
Definition: rtmpdh.c:269
av_blowfish_crypt_ecb
void av_blowfish_crypt_ecb(AVBlowfish *ctx, uint32_t *xl, uint32_t *xr, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: blowfish.c:344
rtmpe9_sig
static void rtmpe9_sig(const uint8_t *in, uint8_t *out, int key_id)
Definition: rtmpcrypt.c:192
av_xtea_le_crypt
void av_xtea_le_crypt(AVXTEA *ctx, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context, in little endian format.
Definition: xtea.c:249
xtea.h
Public header for libavutil XTEA algorithm.
ff_dh_generate_public_key
int ff_dh_generate_public_key(FF_DH *dh)
Generate a public key.
Definition: rtmpdh.c:348
RTMPEContext
Definition: rtmpcrypt.c:42
AVIO_FLAG_NONBLOCK
#define AVIO_FLAG_NONBLOCK
Use non-blocking mode.
Definition: avio.h:693
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:565
av_blowfish_init
av_cold void av_blowfish_init(AVBlowfish *ctx, const uint8_t *key, int key_len)
Initialize an AVBlowfish context.
Definition: blowfish.c:309
h
h
Definition: vp9dsp_template.c:2038
rc4.h
ff_dh_init
av_cold FF_DH * ff_dh_init(int key_len)
Initialize a Diffie-Hellmann context.
Definition: rtmpdh.c:321
rtmpe_open
static int rtmpe_open(URLContext *h, const char *uri, int flags)
Definition: rtmpcrypt.c:248
rtmpe_write
static int rtmpe_write(URLContext *h, const uint8_t *buf, int size)
Definition: rtmpcrypt.c:297