srtp.c
Go to the documentation of this file.
1 /*
2  * SRTP encryption/decryption
3  * Copyright (c) 2012 Martin Storsjo
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 #include "libavutil/base64.h"
23 #include "libavutil/aes.h"
24 #include "libavutil/hmac.h"
25 #include "libavutil/intreadwrite.h"
26 #include "libavutil/log.h"
27 #include "rtp.h"
28 #include "rtpdec.h"
29 #include "srtp.h"
30 
31 void ff_srtp_free(struct SRTPContext *s)
32 {
33  if (!s)
34  return;
35  av_freep(&s->aes);
36  if (s->hmac)
37  av_hmac_free(s->hmac);
38  s->hmac = NULL;
39 }
40 
41 static void encrypt_counter(struct AVAES *aes, uint8_t *iv, uint8_t *outbuf,
42  int outlen)
43 {
44  int i, j, outpos;
45  for (i = 0, outpos = 0; outpos < outlen; i++) {
46  uint8_t keystream[16];
47  AV_WB16(&iv[14], i);
48  av_aes_crypt(aes, keystream, iv, 1, NULL, 0);
49  for (j = 0; j < 16 && outpos < outlen; j++, outpos++)
50  outbuf[outpos] ^= keystream[j];
51  }
52 }
53 
54 static void derive_key(struct AVAES *aes, const uint8_t *salt, int label,
55  uint8_t *out, int outlen)
56 {
57  uint8_t input[16] = { 0 };
58  memcpy(input, salt, 14);
59  // Key derivation rate assumed to be zero
60  input[14 - 7] ^= label;
61  memset(out, 0, outlen);
62  encrypt_counter(aes, input, out, outlen);
63 }
64 
65 int ff_srtp_set_crypto(struct SRTPContext *s, const char *suite,
66  const char *params)
67 {
68  uint8_t buf[30];
69 
70  ff_srtp_free(s);
71 
72  // RFC 4568
73  if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_80") ||
74  !strcmp(suite, "SRTP_AES128_CM_HMAC_SHA1_80")) {
75  s->rtp_hmac_size = s->rtcp_hmac_size = 10;
76  } else if (!strcmp(suite, "AES_CM_128_HMAC_SHA1_32")) {
77  s->rtp_hmac_size = s->rtcp_hmac_size = 4;
78  } else if (!strcmp(suite, "SRTP_AES128_CM_HMAC_SHA1_32")) {
79  // RFC 5764 section 4.1.2
80  s->rtp_hmac_size = 4;
81  s->rtcp_hmac_size = 10;
82  } else {
83  av_log(NULL, AV_LOG_WARNING, "SRTP Crypto suite %s not supported\n",
84  suite);
85  return AVERROR(EINVAL);
86  }
87  if (av_base64_decode(buf, params, sizeof(buf)) != sizeof(buf)) {
88  av_log(NULL, AV_LOG_WARNING, "Incorrect amount of SRTP params\n");
89  return AVERROR(EINVAL);
90  }
91  // MKI and lifetime not handled yet
92  s->aes = av_aes_alloc();
94  if (!s->aes || !s->hmac)
95  return AVERROR(ENOMEM);
96  memcpy(s->master_key, buf, 16);
97  memcpy(s->master_salt, buf + 16, 14);
98 
99  // RFC 3711
100  av_aes_init(s->aes, s->master_key, 128, 0);
101 
102  derive_key(s->aes, s->master_salt, 0x00, s->rtp_key, sizeof(s->rtp_key));
103  derive_key(s->aes, s->master_salt, 0x02, s->rtp_salt, sizeof(s->rtp_salt));
104  derive_key(s->aes, s->master_salt, 0x01, s->rtp_auth, sizeof(s->rtp_auth));
105 
106  derive_key(s->aes, s->master_salt, 0x03, s->rtcp_key, sizeof(s->rtcp_key));
107  derive_key(s->aes, s->master_salt, 0x05, s->rtcp_salt, sizeof(s->rtcp_salt));
108  derive_key(s->aes, s->master_salt, 0x04, s->rtcp_auth, sizeof(s->rtcp_auth));
109  return 0;
110 }
111 
112 static void create_iv(uint8_t *iv, const uint8_t *salt, uint64_t index,
113  uint32_t ssrc)
114 {
115  uint8_t indexbuf[8];
116  int i;
117  memset(iv, 0, 16);
118  AV_WB32(&iv[4], ssrc);
119  AV_WB64(indexbuf, index);
120  for (i = 0; i < 8; i++) // index << 16
121  iv[6 + i] ^= indexbuf[i];
122  for (i = 0; i < 14; i++)
123  iv[i] ^= salt[i];
124 }
125 
126 int ff_srtp_decrypt(struct SRTPContext *s, uint8_t *buf, int *lenptr)
127 {
128  uint8_t iv[16] = { 0 }, hmac[20];
129  int len = *lenptr;
130  int av_uninit(seq_largest);
131  uint32_t ssrc, av_uninit(roc);
132  uint64_t index;
133  int rtcp, hmac_size;
134 
135  // TODO: Missing replay protection
136 
137  if (len < 2)
138  return AVERROR_INVALIDDATA;
139 
140  rtcp = RTP_PT_IS_RTCP(buf[1]);
141  hmac_size = rtcp ? s->rtcp_hmac_size : s->rtp_hmac_size;
142 
143  if (len < hmac_size)
144  return AVERROR_INVALIDDATA;
145 
146  // Authentication HMAC
147  av_hmac_init(s->hmac, rtcp ? s->rtcp_auth : s->rtp_auth, sizeof(s->rtp_auth));
148  // If MKI is used, this should exclude the MKI as well
149  av_hmac_update(s->hmac, buf, len - hmac_size);
150 
151  if (!rtcp) {
152  int seq = AV_RB16(buf + 2);
153  uint32_t v;
154  uint8_t rocbuf[4];
155 
156  // RFC 3711 section 3.3.1, appendix A
157  seq_largest = s->seq_initialized ? s->seq_largest : seq;
158  v = roc = s->roc;
159  if (seq_largest < 32768) {
160  if (seq - seq_largest > 32768)
161  v = roc - 1;
162  } else {
163  if (seq_largest - 32768 > seq)
164  v = roc + 1;
165  }
166  if (v == roc) {
167  seq_largest = FFMAX(seq_largest, seq);
168  } else if (v == roc + 1) {
169  seq_largest = seq;
170  roc = v;
171  }
172  index = seq + (((uint64_t)v) << 16);
173 
174  AV_WB32(rocbuf, roc);
175  av_hmac_update(s->hmac, rocbuf, 4);
176  }
177 
178  av_hmac_final(s->hmac, hmac, sizeof(hmac));
179  if (memcmp(hmac, buf + len - hmac_size, hmac_size)) {
180  av_log(NULL, AV_LOG_WARNING, "HMAC mismatch\n");
181  return AVERROR_INVALIDDATA;
182  }
183 
184  len -= hmac_size;
185  *lenptr = len;
186 
187  if (len < 12)
188  return AVERROR_INVALIDDATA;
189 
190  if (rtcp) {
191  uint32_t srtcp_index = AV_RB32(buf + len - 4);
192  len -= 4;
193  *lenptr = len;
194 
195  ssrc = AV_RB32(buf + 4);
196  index = srtcp_index & 0x7fffffff;
197 
198  buf += 8;
199  len -= 8;
200  if (!(srtcp_index & 0x80000000))
201  return 0;
202  } else {
203  int ext, csrc;
204  s->seq_initialized = 1;
205  s->seq_largest = seq_largest;
206  s->roc = roc;
207 
208  csrc = buf[0] & 0x0f;
209  ext = buf[0] & 0x10;
210  ssrc = AV_RB32(buf + 8);
211 
212  buf += 12;
213  len -= 12;
214 
215  buf += 4 * csrc;
216  len -= 4 * csrc;
217  if (len < 0)
218  return AVERROR_INVALIDDATA;
219 
220  if (ext) {
221  if (len < 4)
222  return AVERROR_INVALIDDATA;
223  ext = (AV_RB16(buf + 2) + 1) * 4;
224  if (len < ext)
225  return AVERROR_INVALIDDATA;
226  len -= ext;
227  buf += ext;
228  }
229  }
230 
231  create_iv(iv, rtcp ? s->rtcp_salt : s->rtp_salt, index, ssrc);
232  av_aes_init(s->aes, rtcp ? s->rtcp_key : s->rtp_key, 128, 0);
233  encrypt_counter(s->aes, iv, buf, len);
234 
235  return 0;
236 }
237 
238 int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len,
239  uint8_t *out, int outlen)
240 {
241  uint8_t iv[16] = { 0 }, hmac[20];
242  uint64_t index;
243  uint32_t ssrc;
244  int rtcp, hmac_size, padding;
245  uint8_t *buf;
246 
247  if (len < 8)
248  return AVERROR_INVALIDDATA;
249 
250  rtcp = RTP_PT_IS_RTCP(in[1]);
251  hmac_size = rtcp ? s->rtcp_hmac_size : s->rtp_hmac_size;
252  padding = hmac_size;
253  if (rtcp)
254  padding += 4; // For the RTCP index
255 
256  if (len + padding > outlen)
257  return 0;
258 
259  memcpy(out, in, len);
260  buf = out;
261 
262  if (rtcp) {
263  ssrc = AV_RB32(buf + 4);
264  index = s->rtcp_index++;
265 
266  buf += 8;
267  len -= 8;
268  } else {
269  int ext, csrc;
270  int seq = AV_RB16(buf + 2);
271 
272  if (len < 12)
273  return AVERROR_INVALIDDATA;
274 
275  ssrc = AV_RB32(buf + 8);
276 
277  if (seq < s->seq_largest)
278  s->roc++;
279  s->seq_largest = seq;
280  index = seq + (((uint64_t)s->roc) << 16);
281 
282  csrc = buf[0] & 0x0f;
283  ext = buf[0] & 0x10;
284 
285  buf += 12;
286  len -= 12;
287 
288  buf += 4 * csrc;
289  len -= 4 * csrc;
290  if (len < 0)
291  return AVERROR_INVALIDDATA;
292 
293  if (ext) {
294  if (len < 4)
295  return AVERROR_INVALIDDATA;
296  ext = (AV_RB16(buf + 2) + 1) * 4;
297  if (len < ext)
298  return AVERROR_INVALIDDATA;
299  len -= ext;
300  buf += ext;
301  }
302  }
303 
304  create_iv(iv, rtcp ? s->rtcp_salt : s->rtp_salt, index, ssrc);
305  av_aes_init(s->aes, rtcp ? s->rtcp_key : s->rtp_key, 128, 0);
306  encrypt_counter(s->aes, iv, buf, len);
307 
308  if (rtcp) {
309  AV_WB32(buf + len, 0x80000000 | index);
310  len += 4;
311  }
312 
313  av_hmac_init(s->hmac, rtcp ? s->rtcp_auth : s->rtp_auth, sizeof(s->rtp_auth));
314  av_hmac_update(s->hmac, out, buf + len - out);
315  if (!rtcp) {
316  uint8_t rocbuf[4];
317  AV_WB32(rocbuf, s->roc);
318  av_hmac_update(s->hmac, rocbuf, 4);
319  }
320  av_hmac_final(s->hmac, hmac, sizeof(hmac));
321 
322  memcpy(buf + len, hmac, hmac_size);
323  len += hmac_size;
324  return buf + len - out;
325 }
326 
327 #ifdef TEST
328 #include <stdio.h>
329 
330 static const char *aes128_80_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
331 
332 static const uint8_t rtp_aes128_80[] = {
333  // RTP header
334  0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
335  // encrypted payload
336  0x62, 0x69, 0x76, 0xca, 0xc5,
337  // HMAC
338  0xa1, 0xac, 0x1b, 0xb4, 0xa0, 0x1c, 0xd5, 0x49, 0x28, 0x99,
339 };
340 
341 static const uint8_t rtcp_aes128_80[] = {
342  // RTCP header
343  0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
344  // encrypted payload
345  0x8a, 0xac, 0xdc, 0xa5, 0x4c, 0xf6, 0x78, 0xa6, 0x62, 0x8f, 0x24, 0xda,
346  0x6c, 0x09, 0x3f, 0xa9, 0x28, 0x7a, 0xb5, 0x7f, 0x1f, 0x0f, 0xc9, 0x35,
347  // RTCP index
348  0x80, 0x00, 0x00, 0x03,
349  // HMAC
350  0xe9, 0x3b, 0xc0, 0x5c, 0x0c, 0x06, 0x9f, 0xab, 0xc0, 0xde,
351 };
352 
353 static const char *aes128_32_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
354 
355 static const uint8_t rtp_aes128_32[] = {
356  // RTP header
357  0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
358  // encrypted payload
359  0x62, 0x69, 0x76, 0xca, 0xc5,
360  // HMAC
361  0xa1, 0xac, 0x1b, 0xb4,
362 };
363 
364 static const uint8_t rtcp_aes128_32[] = {
365  // RTCP header
366  0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
367  // encrypted payload
368  0x35, 0xe9, 0xb5, 0xff, 0x0d, 0xd1, 0xde, 0x70, 0x74, 0x10, 0xaa, 0x1b,
369  0xb2, 0x8d, 0xf0, 0x20, 0x02, 0x99, 0x6b, 0x1b, 0x0b, 0xd0, 0x47, 0x34,
370  // RTCP index
371  0x80, 0x00, 0x00, 0x04,
372  // HMAC
373  0x5b, 0xd2, 0xa9, 0x9d,
374 };
375 
376 static const char *aes128_80_32_key = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmn";
377 
378 static const uint8_t rtp_aes128_80_32[] = {
379  // RTP header
380  0x80, 0xe0, 0x12, 0x34, 0x12, 0x34, 0x56, 0x78, 0x12, 0x34, 0x56, 0x78,
381  // encrypted payload
382  0x62, 0x69, 0x76, 0xca, 0xc5,
383  // HMAC
384  0xa1, 0xac, 0x1b, 0xb4,
385 };
386 
387 static const uint8_t rtcp_aes128_80_32[] = {
388  // RTCP header
389  0x81, 0xc9, 0x00, 0x07, 0x12, 0x34, 0x56, 0x78,
390  // encrypted payload
391  0xd6, 0xae, 0xc1, 0x58, 0x63, 0x70, 0xc9, 0x88, 0x66, 0x26, 0x1c, 0x53,
392  0xff, 0x5d, 0x5d, 0x2b, 0x0f, 0x8c, 0x72, 0x3e, 0xc9, 0x1d, 0x43, 0xf9,
393  // RTCP index
394  0x80, 0x00, 0x00, 0x05,
395  // HMAC
396  0x09, 0x16, 0xb4, 0x27, 0x9a, 0xe9, 0x92, 0x26, 0x4e, 0x10,
397 };
398 
399 static void print_data(const uint8_t *buf, int len)
400 {
401  int i;
402  for (i = 0; i < len; i++)
403  printf("%02x", buf[i]);
404  printf("\n");
405 }
406 
407 static int test_decrypt(struct SRTPContext *srtp, const uint8_t *in, int len,
408  uint8_t *out)
409 {
410  memcpy(out, in, len);
411  if (!ff_srtp_decrypt(srtp, out, &len)) {
412  print_data(out, len);
413  return len;
414  } else
415  return -1;
416 }
417 
418 static void test_encrypt(const uint8_t *data, int in_len, const char *suite,
419  const char *key)
420 {
421  struct SRTPContext enc = { 0 }, dec = { 0 };
422  int len;
424  ff_srtp_set_crypto(&enc, suite, key);
425  ff_srtp_set_crypto(&dec, suite, key);
426  len = ff_srtp_encrypt(&enc, data, in_len, buf, sizeof(buf));
427  if (!ff_srtp_decrypt(&dec, buf, &len)) {
428  if (len == in_len && !memcmp(buf, data, len))
429  printf("Decrypted content matches input\n");
430  else
431  printf("Decrypted content doesn't match input\n");
432  } else {
433  printf("Decryption failed\n");
434  }
435  ff_srtp_free(&enc);
436  ff_srtp_free(&dec);
437 }
438 
439 int main(void)
440 {
441  static const char *aes128_80_suite = "AES_CM_128_HMAC_SHA1_80";
442  static const char *aes128_32_suite = "AES_CM_128_HMAC_SHA1_32";
443  static const char *aes128_80_32_suite = "SRTP_AES128_CM_HMAC_SHA1_32";
444  static const char *test_key = "abcdefghijklmnopqrstuvwxyz1234567890ABCD";
446  struct SRTPContext srtp = { 0 };
447  int len;
448  ff_srtp_set_crypto(&srtp, aes128_80_suite, aes128_80_key);
449  len = test_decrypt(&srtp, rtp_aes128_80, sizeof(rtp_aes128_80), buf);
450  test_encrypt(buf, len, aes128_80_suite, test_key);
451  test_encrypt(buf, len, aes128_32_suite, test_key);
452  test_encrypt(buf, len, aes128_80_32_suite, test_key);
453  test_decrypt(&srtp, rtcp_aes128_80, sizeof(rtcp_aes128_80), buf);
454  test_encrypt(buf, len, aes128_80_suite, test_key);
455  test_encrypt(buf, len, aes128_32_suite, test_key);
456  test_encrypt(buf, len, aes128_80_32_suite, test_key);
457  ff_srtp_free(&srtp);
458 
459  memset(&srtp, 0, sizeof(srtp)); // Clear the context
460  ff_srtp_set_crypto(&srtp, aes128_32_suite, aes128_32_key);
461  test_decrypt(&srtp, rtp_aes128_32, sizeof(rtp_aes128_32), buf);
462  test_decrypt(&srtp, rtcp_aes128_32, sizeof(rtcp_aes128_32), buf);
463  ff_srtp_free(&srtp);
464 
465  memset(&srtp, 0, sizeof(srtp)); // Clear the context
466  ff_srtp_set_crypto(&srtp, aes128_80_32_suite, aes128_80_32_key);
467  test_decrypt(&srtp, rtp_aes128_80_32, sizeof(rtp_aes128_80_32), buf);
468  test_decrypt(&srtp, rtcp_aes128_80_32, sizeof(rtcp_aes128_80_32), buf);
469  ff_srtp_free(&srtp);
470  return 0;
471 }
472 #endif /* TEST */
int rtp_hmac_size
Definition: srtp.h:33
float v
const char * s
Definition: avisynth_c.h:668
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int ff_srtp_encrypt(struct SRTPContext *s, const uint8_t *in, int len, uint8_t *out, int outlen)
Definition: srtp.c:238
#define RTP_MAX_PACKET_LENGTH
Definition: rtpdec.h:36
AVHMAC * av_hmac_alloc(enum AVHMACType type)
Allocate an AVHMAC context.
Definition: hmac.c:46
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
static void encrypt_counter(struct AVAES *aes, uint8_t *iv, uint8_t *outbuf, int outlen)
Definition: srtp.c:41
void av_aes_crypt(AVAES *a, uint8_t *dst, const uint8_t *src, int count, uint8_t *iv, int decrypt)
Encrypt or decrypt a buffer using a previously initialized context.
Definition: aes.c:142
About Git write you should know how to use GIT properly Luckily Git comes with excellent documentation git help man git shows you the available git< command > help man git< command > shows information about the subcommand< command > The most comprehensive manual is the website Git Reference visit they are quite exhaustive You do not need a special username or password All you need is to provide a ssh public key to the Git server admin What follows now is a basic introduction to Git and some FFmpeg specific guidelines Read it at least if you are granted commit privileges to the FFmpeg project you are expected to be familiar with these rules I if not You can get git from etc no matter how small Every one of them has been saved from looking like a fool by this many times It s very easy for stray debug output or cosmetic modifications to slip in
Definition: git-howto.txt:5
uint8_t rtcp_auth[20]
Definition: srtp.h:38
uint8_t rtp_auth[20]
Definition: srtp.h:38
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
uint8_t rtcp_salt[14]
Definition: srtp.h:37
#define AV_WB32(p, darg)
Definition: intreadwrite.h:265
int seq_initialized
Definition: srtp.h:39
static void derive_key(struct AVAES *aes, const uint8_t *salt, int label, uint8_t *out, int outlen)
Definition: srtp.c:54
void ff_srtp_free(struct SRTPContext *s)
Definition: srtp.c:31
uint8_t
#define AV_RB32
struct AVHMAC * hmac
Definition: srtp.h:32
void av_hmac_update(AVHMAC *c, const uint8_t *data, unsigned int len)
Hash data with the HMAC.
Definition: hmac.c:108
uint8_t master_salt[14]
Definition: srtp.h:35
struct AVAES * aes
Definition: srtp.h:31
#define AV_RB16
uint8_t rtcp_key[16]
Definition: srtp.h:36
int seq_largest
Definition: srtp.h:39
Spectrum Plot time data
FFmpeg currently uses a custom build this text attempts to document some of its obscure features and options Makefile the full command issued by make and its output will be shown on the screen DESTDIR Destination directory for the install useful to prepare packages or install FFmpeg in cross environments Makefile builds all the libraries and the executables fate Run the fate test suite
Definition: build_system.txt:1
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame This method is called when a frame is wanted on an output For an input
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
struct AVAES * av_aes_alloc(void)
Allocate an AVAES context.
Definition: aes.c:44
#define FFMAX(a, b)
Definition: common.h:56
static void create_iv(uint8_t *iv, const uint8_t *salt, uint64_t index, uint32_t ssrc)
Definition: srtp.c:112
int ff_srtp_decrypt(struct SRTPContext *s, uint8_t *buf, int *lenptr)
Definition: srtp.c:126
void av_hmac_init(AVHMAC *c, const uint8_t *key, unsigned int keylen)
Initialize an AVHMAC context with an authentication key.
Definition: hmac.c:87
uint8_t rtp_key[16]
Definition: srtp.h:36
int av_aes_init(AVAES *a, const uint8_t *key, int key_bits, int decrypt)
Initialize an AVAES context.
Definition: aes.c:193
NULL
Definition: eval.c:55
void * buf
Definition: avisynth_c.h:594
int index
Definition: gxfenc.c:89
synthesis window for stochastic i
#define AV_WB16(p, darg)
Definition: intreadwrite.h:237
uint8_t master_key[16]
Definition: srtp.h:34
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
int av_hmac_final(AVHMAC *c, uint8_t *out, unsigned int outlen)
Finish hashing and output the HMAC digest.
Definition: hmac.c:113
#define RTP_PT_IS_RTCP(x)
Definition: rtp.h:109
#define AV_WB64(p, darg)
Definition: intreadwrite.h:303
const char const char * params
Definition: avisynth_c.h:675
uint32_t rtcp_index
Definition: srtp.h:42
void av_hmac_free(AVHMAC *c)
Free an AVHMAC context.
Definition: hmac.c:79
int len
printf("static const uint8_t my_array[100] = {\n")
int ff_srtp_set_crypto(struct SRTPContext *s, const char *suite, const char *params)
Definition: srtp.c:65
int rtcp_hmac_size
Definition: srtp.h:33
int av_base64_decode(uint8_t *out, const char *in_str, int out_size)
Decode a base64-encoded string.
uint8_t rtp_salt[14]
Definition: srtp.h:37
#define av_uninit(x)
Definition: attributes.h:137
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=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);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_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_dlog(ac->avr,"%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-> out
int main(int argc, char **argv)
Definition: main.c:22
uint32_t roc
Definition: srtp.h:40
Definition: aes.c:34