FreeSWITCH API Documentation  1.7.0
switch_vpx.c
Go to the documentation of this file.
1 /*
2  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
3  * Copyright (C) 2005-2015, Anthony Minessale II <anthm@freeswitch.org>
4  *
5  * Version: MPL 1.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
18  *
19  * The Initial Developer of the Original Code is
20  * Seven Du <dujinfang@gmail.com>
21  * Portions created by the Initial Developer are Copyright (C)
22  * the Initial Developer. All Rights Reserved.
23  *
24  * Contributor(s):
25  *
26  * Anthony Minessale II <anthm@freeswitch.org>
27  * Seven Du <dujinfang@gmail.com>
28  * Sam Russell <sam.h.russell@gmail.com>
29  *
30  * mod_vpx.c -- VP8/9 Video Codec, with transcoding
31  *
32  */
33 
34 #include <switch.h>
35 #ifdef SWITCH_HAVE_YUV
36 #ifdef SWITCH_HAVE_VPX
37 #include <vpx/vpx_encoder.h>
38 #include <vpx/vpx_decoder.h>
39 #include <vpx/vp8cx.h>
40 #include <vpx/vp8dx.h>
41 #include <vpx/vp8.h>
42 
43 // #define DEBUG_VP9
44 
45 #define SLICE_SIZE SWITCH_DEFAULT_VIDEO_SIZE
46 #define KEY_FRAME_MIN_FREQ 250000
47 
48 /* http://tools.ietf.org/html/draft-ietf-payload-vp8-10
49 
50  The first octets after the RTP header are the VP8 payload descriptor, with the following structure.
51 #endif
52 
53  0 1 2 3 4 5 6 7
54  +-+-+-+-+-+-+-+-+
55  |X|R|N|S|R| PID | (REQUIRED)
56  +-+-+-+-+-+-+-+-+
57  X: |I|L|T|K| RSV | (OPTIONAL)
58  +-+-+-+-+-+-+-+-+
59  I: |M| PictureID | (OPTIONAL)
60  +-+-+-+-+-+-+-+-+
61  L: | TL0PICIDX | (OPTIONAL)
62  +-+-+-+-+-+-+-+-+
63  T/K:|TID|Y| KEYIDX | (OPTIONAL)
64  +-+-+-+-+-+-+-+-+
65 
66 
67  VP8 Payload Header
68 
69  0 1 2 3 4 5 6 7
70  +-+-+-+-+-+-+-+-+
71  |Size0|H| VER |P|
72  +-+-+-+-+-+-+-+-+
73  | Size1 |
74  +-+-+-+-+-+-+-+-+
75  | Size2 |
76  +-+-+-+-+-+-+-+-+
77  | Bytes 4..N of |
78  | VP8 payload |
79  : :
80  +-+-+-+-+-+-+-+-+
81  | OPTIONAL RTP |
82  | padding |
83  : :
84  +-+-+-+-+-+-+-+-+
85 */
86 
87 
88 #ifdef _MSC_VER
89 #pragma pack(push, r1, 1)
90 #endif
91 
92 #if SWITCH_BYTE_ORDER == __BIG_ENDIAN
93 
94 typedef struct {
95  unsigned extended:1;
96  unsigned reserved1:1;
97  unsigned non_referenced:1;
98  unsigned start:1;
99  unsigned reserved2:1;
100  unsigned pid:3;
101 } vp8_payload_descriptor_t;
102 
103 typedef struct {
104  unsigned have_pid:1;
105  unsigned have_p_layer:1;
106  unsigned have_layer_ind:1;
107  unsigned is_flexible:1;
108  unsigned start:1;
109  unsigned end:1;
110  unsigned have_ss:1;
111  unsigned zero:1;
112 } vp9_payload_descriptor_t;
113 
114 typedef struct {
115  unsigned n_s:3;
116  unsigned y:1;
117  unsigned g:1;
118  unsigned zero:3;
119 } vp9_ss_t;
120 
121 typedef struct {
122  unsigned t:3;
123  unsigned u:1;
124  unsigned r:2;
125  unsigned zero:2;
126 } vp9_n_g_t;
127 
128 typedef struct {
129  unsigned temporal_id:3;
130  unsigned temporal_up_switch:1;
131  unsigned spatial_id:3;
132  unsigned inter_layer_predicted:1;
133 } vp9_p_layer_t;
134 
135 #else /* ELSE LITTLE */
136 
137 typedef struct {
138  unsigned pid:3;
139  unsigned reserved2:1;
140  unsigned start:1;
141  unsigned non_referenced:1;
142  unsigned reserved1:1;
143  unsigned extended:1;
144 } vp8_payload_descriptor_t;
145 
146 typedef struct {
147  unsigned zero:1;
148  unsigned have_ss:1;
149  unsigned end:1;
150  unsigned start:1;
151  unsigned is_flexible:1;
152  unsigned have_layer_ind:1;
153  unsigned have_p_layer:1;
154  unsigned have_pid:1;
155 } vp9_payload_descriptor_t;
156 
157 typedef struct {
158  unsigned zero:3;
159  unsigned g:1;
160  unsigned y:1;
161  unsigned n_s:3;
162 } vp9_ss_t;
163 
164 typedef struct {
165  unsigned zero:2;
166  unsigned r:2;
167  unsigned u:1;
168  unsigned t:3;
169 } vp9_n_g_t;
170 
171 typedef struct {
172  unsigned inter_layer_predicted:1;
173  unsigned spatial_id:3;
174  unsigned temporal_up_switch:1;
175  unsigned temporal_id:3;
176 } vp9_p_layer_t;
177 
178 #endif
179 
180 typedef union {
181  vp8_payload_descriptor_t vp8;
182  vp9_payload_descriptor_t vp9;
183 } vpx_payload_descriptor_t;
184 
185 #define kMaxVp9NumberOfSpatialLayers 16
186 
187 typedef struct {
188  switch_bool_t has_received_sli;
189  uint8_t picture_id_sli;
190  switch_bool_t has_received_rpsi;
191  uint64_t picture_id_rpsi;
192  int16_t picture_id; // Negative value to skip pictureId.
193 
194  switch_bool_t inter_pic_predicted; // This layer frame is dependent on previously
195  // coded frame(s).
196  switch_bool_t flexible_mode;
197  switch_bool_t ss_data_available;
198 
199  int tl0_pic_idx; // Negative value to skip tl0PicIdx.
200  uint8_t temporal_idx;
201  uint8_t spatial_idx;
202  switch_bool_t temporal_up_switch;
203  switch_bool_t inter_layer_predicted; // Frame is dependent on directly lower spatial
204  // layer frame.
205  uint8_t gof_idx;
206 
207  // SS data.
208  size_t num_spatial_layers;
209  switch_bool_t spatial_layer_resolution_present;
210  uint16_t width[kMaxVp9NumberOfSpatialLayers];
211  uint16_t height[kMaxVp9NumberOfSpatialLayers];
212  // GofInfoVP9 gof;
213 } vp9_info_t;
214 
215 
216 #ifdef _MSC_VER
217 #pragma pack(pop, r1)
218 #endif
219 
220 
221 #define __IS_VP8_KEY_FRAME(byte) !(((byte) & 0x01))
222 static inline int IS_VP8_KEY_FRAME(uint8_t *data)
223 {
224  uint8_t S;
225  uint8_t DES;
226  uint8_t PID;
227 
228  DES = *data;
229  data++;
230  S = DES & 0x10;
231  PID = DES & 0x07;
232 
233  if (DES & 0x80) { // X
234  uint8_t X = *data;
235  data++;
236  if (X & 0x80) { // I
237  uint8_t M = (*data) & 0x80;
238  data++;
239  if (M) data++;
240  }
241  if (X & 0x40) data++; // L
242  if (X & 0x30) data++; // T/K
243  }
244 
245  if (S && (PID == 0)) {
246  return __IS_VP8_KEY_FRAME(*data);
247  } else {
248  // if (PID > 0) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "PID: %d\n", PID);
249  return 0;
250  }
251 }
252 
253 #define IS_VP9_KEY_FRAME(byte) ((((byte) & 0x40) == 0) && ((byte) & 0x0A))
254 #define IS_VP9_START_PKT(byte) ((byte) & 0x08)
255 
256 SWITCH_MODULE_LOAD_FUNCTION(mod_vpx_load);
257 SWITCH_MODULE_DEFINITION(CORE_VPX_MODULE, mod_vpx_load, NULL, NULL);
258 
259 struct vpx_context {
260  switch_codec_t *codec;
261  int is_vp9;
262  vp9_info_t vp9;
263  int lossless;
264  vpx_codec_iface_t *encoder_interface;
265  vpx_codec_iface_t *decoder_interface;
266  unsigned int flags;
267  switch_codec_settings_t codec_settings;
268  unsigned int bandwidth;
269  vpx_codec_enc_cfg_t config;
270  switch_time_t last_key_frame;
271 
272  vpx_codec_ctx_t encoder;
273  uint8_t encoder_init;
274  vpx_image_t *pic;
275  switch_bool_t force_key_frame;
276  int fps;
277  int format;
278  int intra_period;
279  int num;
280  int partition_index;
281  const vpx_codec_cx_pkt_t *pkt;
282  vpx_codec_iter_t enc_iter;
283  vpx_codec_iter_t dec_iter;
284  uint32_t last_ts;
285  switch_time_t last_ms;
286  vpx_codec_ctx_t decoder;
287  uint8_t decoder_init;
288  switch_buffer_t *vpx_packet_buffer;
289  int got_key_frame;
290  int no_key_frame;
291  int got_start_frame;
292  uint32_t last_received_timestamp;
293  switch_bool_t last_received_complete_picture;
294  int need_key_frame;
295  int need_encoder_reset;
296  int need_decoder_reset;
297  int32_t change_bandwidth;
298  uint64_t framecount;
300  switch_buffer_t *pbuffer;
301  switch_time_t start_time;
302 };
303 typedef struct vpx_context vpx_context_t;
304 
305 
306 static switch_status_t init_decoder(switch_codec_t *codec)
307 {
308  vpx_context_t *context = (vpx_context_t *)codec->private_info;
309  vpx_codec_dec_cfg_t cfg = {0, 0, 0};
310  vpx_codec_flags_t dec_flags = 0;
311 
312  if (context->flags & SWITCH_CODEC_FLAG_DECODE && !context->decoder_init) {
313  vp8_postproc_cfg_t ppcfg;
314 
315  //if (context->decoder_init) {
316  // vpx_codec_destroy(&context->decoder);
317  // context->decoder_init = 0;
318  //}
319 
320  cfg.threads = 1;//(switch_core_cpu_count() > 1) ? 2 : 1;
321 
322  if (!context->is_vp9) { // vp8 only
323  // dec_flags = VPX_CODEC_USE_POSTPROC;
324  }
325 
326  if (vpx_codec_dec_init(&context->decoder, context->decoder_interface, &cfg, dec_flags) != VPX_CODEC_OK) {
327  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec %s init error: [%d:%s]\n", vpx_codec_iface_name(context->decoder_interface), context->encoder.err, context->encoder.err_detail);
328  return SWITCH_STATUS_FALSE;
329  }
330 
331 
332  context->last_ts = 0;
333  context->last_received_timestamp = 0;
334  context->last_received_complete_picture = 0;
335  context->decoder_init = 1;
336  context->got_key_frame = 0;
337  context->no_key_frame = 0;
338  context->got_start_frame = 0;
339  // the types of post processing to be done, should be combination of "vp8_postproc_level"
340  ppcfg.post_proc_flag = VP8_DEBLOCK;//VP8_DEMACROBLOCK | VP8_DEBLOCK;
341  // the strength of deblocking, valid range [0, 16]
342  ppcfg.deblocking_level = 1;
343  // Set deblocking settings
344  vpx_codec_control(&context->decoder, VP8_SET_POSTPROC, &ppcfg);
345 
346  if (context->vpx_packet_buffer) {
347  switch_buffer_zero(context->vpx_packet_buffer);
348  } else {
349  switch_buffer_create_dynamic(&context->vpx_packet_buffer, 512, 512, 0);
350  }
351  }
352 
353  return SWITCH_STATUS_SUCCESS;
354 }
355 
356 
357 static switch_status_t init_encoder(switch_codec_t *codec)
358 {
359  vpx_context_t *context = (vpx_context_t *)codec->private_info;
360  vpx_codec_enc_cfg_t *config = &context->config;
361  int token_parts = 1;
362  int cpus = switch_core_cpu_count();
363  int sane;
364 
365  if (!context->codec_settings.video.width) {
366  context->codec_settings.video.width = 1280;
367  }
368 
369  if (!context->codec_settings.video.height) {
370  context->codec_settings.video.height = 720;
371  }
372 
373  if (context->codec_settings.video.bandwidth == -1) {
374  context->codec_settings.video.bandwidth = 0;
375  }
376 
377  if (context->codec_settings.video.bandwidth) {
378  context->bandwidth = context->codec_settings.video.bandwidth;
379  } else {
380  context->bandwidth = switch_calc_bitrate(context->codec_settings.video.width, context->codec_settings.video.height, 1, 15);
381 
382  }
383 
384  sane = switch_calc_bitrate(1920, 1080, 2, 30);
385 
386  if (context->bandwidth > sane) {
387  switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(codec->session), SWITCH_LOG_WARNING, "BITRATE TRUNCATED FROM %d TO %d\n", context->bandwidth, sane);
388  context->bandwidth = sane;
389  }
390 
391  context->pkt = NULL;
392 
394  "VPX reset encoder picture from %dx%d to %dx%d %u BW\n",
395  config->g_w, config->g_h, context->codec_settings.video.width, context->codec_settings.video.height, context->bandwidth);
396 
397  context->start_time = switch_micro_time_now();
398 
399  config->g_timebase.num = 1;
400  config->g_timebase.den = 1000;
401  config->g_pass = VPX_RC_ONE_PASS;
402  config->g_w = context->codec_settings.video.width;
403  config->g_h = context->codec_settings.video.height;
404  config->rc_target_bitrate = context->bandwidth;
405  config->g_lag_in_frames = 0;
406  config->kf_max_dist = 2000;
407  config->g_threads = 1;//(cpus > 1) ? 2 : 1;
408 
409  if (context->is_vp9) {
410  //config->rc_dropframe_thresh = 2;
411  token_parts = (cpus > 1) ? 3 : 0;
412 
413  if (context->lossless) {
414  config->rc_min_quantizer = 0;
415  config->rc_max_quantizer = 0;
416  } else {
417  config->rc_min_quantizer = 0;
418  config->rc_max_quantizer = 63;
419  }
420 
421  config->temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_NOLAYERING;
422  config->ts_number_layers = 1;
423  config->ts_rate_decimator[0] = 1;
424  config->ts_periodicity = 1;
425  config->ts_layer_id[0] = 0;
426  } else {
427 
428  // settings
429  config->g_profile = 2;
430  config->g_error_resilient = VPX_ERROR_RESILIENT_PARTITIONS;
431  token_parts = (cpus > 1) ? 3 : 0;
432 
433  // rate control settings
434  config->rc_dropframe_thresh = 0;
435  config->rc_end_usage = VPX_CBR;
436  //config->g_pass = VPX_RC_ONE_PASS;
437  config->kf_mode = VPX_KF_AUTO;
438  config->kf_max_dist = 1000;
439 
440  //config->kf_mode = VPX_KF_DISABLED;
441  config->rc_resize_allowed = 1;
442  //config->rc_min_quantizer = 0;
443  //config->rc_max_quantizer = 63;
444  config->rc_min_quantizer = 0;
445  config->rc_max_quantizer = 63;
446  //Rate control adaptation undershoot control.
447  // This value, expressed as a percentage of the target bitrate,
448  // controls the maximum allowed adaptation speed of the codec.
449  // This factor controls the maximum amount of bits that can be
450  // subtracted from the target bitrate in order to compensate for
451  // prior overshoot.
452  // Valid values in the range 0-1000.
453  config->rc_undershoot_pct = 100;
454  //Rate control adaptation overshoot control.
455  // This value, expressed as a percentage of the target bitrate,
456  // controls the maximum allowed adaptation speed of the codec.
457  // This factor controls the maximum amount of bits that can be
458  // added to the target bitrate in order to compensate for prior
459  // undershoot.
460  // Valid values in the range 0-1000.
461  config->rc_overshoot_pct = 15;
462  //Decoder Buffer Size.
463  // This value indicates the amount of data that may be buffered
464  // by the decoding application. Note that this value is expressed
465  // in units of time (milliseconds). For example, a value of 5000
466  // indicates that the client will buffer (at least) 5000ms worth
467  // of encoded data. Use the target bitrate (rc_target_bitrate) to
468  // convert to bits/bytes, if necessary.
469  config->rc_buf_sz = 5000;
470  //Decoder Buffer Initial Size.
471  // This value indicates the amount of data that will be buffered
472  // by the decoding application prior to beginning playback.
473  // This value is expressed in units of time (milliseconds).
474  // Use the target bitrate (rc_target_bitrate) to convert to
475  // bits/bytes, if necessary.
476  config->rc_buf_initial_sz = 1000;
477  //Decoder Buffer Optimal Size.
478  // This value indicates the amount of data that the encoder should
479  // try to maintain in the decoder's buffer. This value is expressed
480  // in units of time (milliseconds).
481  // Use the target bitrate (rc_target_bitrate) to convert to
482  // bits/bytes, if necessary.
483  config->rc_buf_optimal_sz = 1000;
484  }
485 
486  if (context->encoder_init) {
487  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "VPX ENCODER RESET\n");
488  if (vpx_codec_enc_config_set(&context->encoder, config) != VPX_CODEC_OK) {
489  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec init error: [%d:%s]\n", context->encoder.err, context->encoder.err_detail);
490  }
491  } else if (context->flags & SWITCH_CODEC_FLAG_ENCODE) {
492 
493  // #define SHOW(field) fprintf(stderr, " %-28s = %d\n", #field, config->field);
494 
495 #ifdef SHOW
496  fprintf(stderr, "Codec: %s\n", vpx_codec_iface_name(context->encoder_interface));
497 
498  SHOW(g_usage);
499  SHOW(g_threads);
500  SHOW(g_profile);
501  SHOW(g_w);
502  SHOW(g_h);
503  SHOW(g_bit_depth);
504  SHOW(g_input_bit_depth);
505  SHOW(g_timebase.num);
506  SHOW(g_timebase.den);
507  SHOW(g_error_resilient);
508  SHOW(g_pass);
509  SHOW(g_lag_in_frames);
510  SHOW(rc_dropframe_thresh);
511  SHOW(rc_resize_allowed);
512  SHOW(rc_scaled_width);
513  SHOW(rc_scaled_height);
514  SHOW(rc_resize_up_thresh);
515  SHOW(rc_resize_down_thresh);
516  SHOW(rc_end_usage);
517  SHOW(rc_target_bitrate);
518  SHOW(rc_min_quantizer);
519  SHOW(rc_max_quantizer);
520  SHOW(rc_undershoot_pct);
521  SHOW(rc_overshoot_pct);
522  SHOW(rc_buf_sz);
523  SHOW(rc_buf_initial_sz);
524  SHOW(rc_buf_optimal_sz);
525  SHOW(rc_2pass_vbr_bias_pct);
526  SHOW(rc_2pass_vbr_minsection_pct);
527  SHOW(rc_2pass_vbr_maxsection_pct);
528  SHOW(kf_mode);
529  SHOW(kf_min_dist);
530  SHOW(kf_max_dist);
531 #endif
532 
533  if (vpx_codec_enc_init(&context->encoder, context->encoder_interface, config, 0 & VPX_CODEC_USE_OUTPUT_PARTITION) != VPX_CODEC_OK) {
534  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec %s init error: [%d:%s]\n", vpx_codec_iface_name(context->encoder_interface), context->encoder.err, context->encoder.err_detail);
535  return SWITCH_STATUS_FALSE;
536  }
537 
538  context->encoder_init = 1;
539 
540  if (context->is_vp9) {
541  if (context->lossless) {
542  vpx_codec_control(&context->encoder, VP9E_SET_LOSSLESS, 1);
543  vpx_codec_control(&context->encoder, VP8E_SET_CPUUSED, -6);
544  } else {
545  vpx_codec_control(&context->encoder, VP8E_SET_CPUUSED, -8);
546  }
547 
548  vpx_codec_control(&context->encoder, VP8E_SET_STATIC_THRESHOLD, 100);
549  vpx_codec_control(&context->encoder, VP8E_SET_TOKEN_PARTITIONS, token_parts);
550  vpx_codec_control(&context->encoder, VP9E_SET_TUNE_CONTENT, VP9E_CONTENT_SCREEN);
551 
552  } else {
553  // The static threshold imposes a change threshold on blocks below which they will be skipped by the encoder.
554  vpx_codec_control(&context->encoder, VP8E_SET_STATIC_THRESHOLD, 100);
555  //Set cpu usage, a bit lower than normal (-6) but higher than android (-12)
556  vpx_codec_control(&context->encoder, VP8E_SET_CPUUSED, -6);
557  vpx_codec_control(&context->encoder, VP8E_SET_TOKEN_PARTITIONS, token_parts);
558 
559  // Enable noise reduction
560  vpx_codec_control(&context->encoder, VP8E_SET_NOISE_SENSITIVITY, 1);
561  //Set max data rate for Intra frames.
562  // This value controls additional clamping on the maximum size of a keyframe.
563  // It is expressed as a percentage of the average per-frame bitrate, with the
564  // special (and default) value 0 meaning unlimited, or no additional clamping
565  // beyond the codec's built-in algorithm.
566  // For example, to allocate no more than 4.5 frames worth of bitrate to a keyframe, set this to 450.
567  //vpx_codec_control(&context->encoder, VP8E_SET_MAX_INTRA_BITRATE_PCT, 0);
568  }
569  }
570 
571  return SWITCH_STATUS_SUCCESS;
572 }
573 
574 static switch_status_t switch_vpx_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
575 {
576  vpx_context_t *context = NULL;
577  int encoding, decoding;
578 
579  encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
580  decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
581 
582  if (!(encoding || decoding) || ((context = switch_core_alloc(codec->memory_pool, sizeof(*context))) == 0)) {
583  return SWITCH_STATUS_FALSE;
584  }
585 
586  memset(context, 0, sizeof(*context));
587  context->flags = flags;
588  codec->private_info = context;
589  context->pool = codec->memory_pool;
590 
591  if (codec_settings) {
592  context->codec_settings = *codec_settings;
593  }
594 
595  if (!strcmp(codec->implementation->iananame, "VP9")) {
596  context->is_vp9 = 1;
597  context->encoder_interface = vpx_codec_vp9_cx();
598  context->decoder_interface = vpx_codec_vp9_dx();
599  } else {
600  context->encoder_interface = vpx_codec_vp8_cx();
601  context->decoder_interface = vpx_codec_vp8_dx();
602  }
603 
604  if (codec->fmtp_in) {
605  codec->fmtp_out = switch_core_strdup(codec->memory_pool, codec->fmtp_in);
606  }
607 
608  if (vpx_codec_enc_config_default(context->encoder_interface, &context->config, 0) != VPX_CODEC_OK) {
609  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoder config Error\n");
610  return SWITCH_STATUS_FALSE;
611  }
612 
613  context->codec_settings.video.width = 320;
614  context->codec_settings.video.height = 240;
615 
616  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "VPX VER:%s VPX_IMAGE_ABI_VERSION:%d VPX_CODEC_ABI_VERSION:%d\n",
617  vpx_codec_version_str(), VPX_IMAGE_ABI_VERSION, VPX_CODEC_ABI_VERSION);
618 
619  return SWITCH_STATUS_SUCCESS;
620 }
621 
622 static switch_status_t consume_partition(vpx_context_t *context, switch_frame_t *frame)
623 {
624  vpx_payload_descriptor_t *payload_descriptor;
625  uint8_t *body;
626  uint32_t hdrlen = 0, payload_size = 0, packet_size = 0, start = 0, key = 0;
627  switch_size_t remaining_bytes = 0;
628 
629  if (!context->pkt) {
630  if ((context->pkt = vpx_codec_get_cx_data(&context->encoder, &context->enc_iter))) {
631  start = 1;
632  if (!context->pbuffer) {
633  switch_buffer_create_partition(context->pool, &context->pbuffer, context->pkt->data.frame.buf, context->pkt->data.frame.sz);
634  } else {
635  switch_buffer_set_partition_data(context->pbuffer, context->pkt->data.frame.buf, context->pkt->data.frame.sz);
636  }
637  }
638  }
639 
640  if (context->pbuffer) {
641  remaining_bytes = switch_buffer_inuse(context->pbuffer);
642  }
643 
644  if (!context->pkt || context->pkt->kind != VPX_CODEC_CX_FRAME_PKT || !remaining_bytes) {
645  frame->datalen = 0;
646  frame->m = 1;
647  context->pkt = NULL;
649  return SWITCH_STATUS_SUCCESS;
650  }
651 
652  key = (context->pkt->data.frame.flags & VPX_FRAME_IS_KEY);
653 
654 #if 0
655  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "flags: %x pts: %lld duration:%lu partition_id: %d\n",
656  context->pkt->data.frame.flags, context->pkt->data.frame.pts, context->pkt->data.frame.duration, context->pkt->data.frame.partition_id);
657 #endif
658 
659  /* reset header */
660  *(uint8_t *)frame->data = 0;
661  payload_descriptor = (vpx_payload_descriptor_t *) frame->data;
662 
663  // if !extended
664  hdrlen = 1;
665  body = ((uint8_t *)frame->data) + hdrlen;
666  packet_size = SLICE_SIZE;
667  payload_size = packet_size - hdrlen;
668  // else add extended TBD
669 
670  frame->datalen = hdrlen;
671 
672  if (context->is_vp9) {
673  payload_descriptor->vp9.start = start;
674 
675  if (1) {
676  // payload_descriptor->vp9.have_p_layer = key; // key?
677  payload_descriptor->vp9.have_pid = 1;
678 
679  if (payload_descriptor->vp9.have_pid) {
680 
681  if (context->vp9.picture_id < 0) context->vp9.picture_id = 0;
682 
683  if (context->vp9.picture_id > 0x7f) {
684  *body++ = (context->vp9.picture_id >> 8) | 0x80;
685  *body++ = context->vp9.picture_id & 0xff;
686  payload_size--;
687  frame->datalen++;
688  } else {
689  *body++ = context->vp9.picture_id;
690  }
691 
692 
693  payload_size--;
694  frame->datalen++;
695  }
696 
697  if (start) {
698  context->vp9.picture_id++;
699 #ifdef DEBUG_VP9
700  // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sending pid: %d\n", context->vp9.picture_id);
701 #endif
702  }
703 
704  if (key) {
705  vp9_ss_t *ss = (vp9_ss_t *)body;
706 
707  payload_descriptor->vp9.have_ss = 1;
708  payload_descriptor->vp9.have_p_layer = 0;
709  ss->n_s = 0;
710  ss->g = 0;
711  ss->y = 0;
712  ss->zero = 0;
713  body++;
714  payload_size--;
715  frame->datalen++;
716 
717  if (0) { // y ?
718  uint16_t *w;
719  uint16_t *h;
720 
721  ss->y = 1;
722 
723  w = (uint16_t *)body;
724  body+=2;
725  h = (uint16_t *)body;
726  body+=2;
727 
728  *w = (uint16_t)context->codec_settings.video.width;
729  *h = (uint16_t)context->codec_settings.video.height;
730 
731  payload_size-= (ss->n_s + 1) * 4;
732  frame->datalen+= (ss->n_s + 1) * 4;
733  }
734  } else {
735  payload_descriptor->vp9.have_p_layer = 1;
736  }
737  }
738 
739  } else {
740  payload_descriptor->vp8.start = start;
741  }
742 
743  if (remaining_bytes <= payload_size) {
744  switch_buffer_read(context->pbuffer, body, remaining_bytes);
745  context->pkt = NULL;
746  frame->datalen += remaining_bytes;
747  frame->m = 1;
748  return SWITCH_STATUS_SUCCESS;
749  } else {
750  switch_buffer_read(context->pbuffer, body, payload_size);
751  frame->datalen += payload_size;
752  frame->m = 0;
754  }
755 
756  if (frame->m && context->is_vp9) {
757  payload_descriptor->vp9.end = 1;
758  }
759 }
760 
761 static switch_status_t reset_codec_encoder(switch_codec_t *codec)
762 {
763  vpx_context_t *context = (vpx_context_t *)codec->private_info;
764 
765  if (context->encoder_init) {
766  vpx_codec_destroy(&context->encoder);
767  }
768  context->last_ts = 0;
769  context->last_ms = 0;
770  context->framecount = 0;
771  context->encoder_init = 0;
772  context->pkt = NULL;
773  return init_encoder(codec);
774 }
775 
776 static switch_status_t switch_vpx_encode(switch_codec_t *codec, switch_frame_t *frame)
777 {
778  vpx_context_t *context = (vpx_context_t *)codec->private_info;
779  int width = 0;
780  int height = 0;
781  uint32_t dur;
782  int64_t pts;
783  vpx_enc_frame_flags_t vpx_flags = 0;
784  switch_time_t now;
785  int err;
786 
787  if (frame->flags & SFF_SAME_IMAGE) {
788  return consume_partition(context, frame);
789  }
790 
791  if (context->need_encoder_reset != 0) {
792  if (reset_codec_encoder(codec) != SWITCH_STATUS_SUCCESS) {
793  return SWITCH_STATUS_FALSE;
794  }
795  context->need_encoder_reset = 0;
796  }
797 
798  if (frame->img->d_h > 1) {
799  width = frame->img->d_w;
800  height = frame->img->d_h;
801  } else {
802  width = frame->img->w;
803  height = frame->img->h;
804  }
805 
806  if (context->config.g_w != width || context->config.g_h != height) {
807  context->codec_settings.video.width = width;
808  context->codec_settings.video.height = height;
809  reset_codec_encoder(codec);
810  frame->flags |= SFF_PICTURE_RESET;
811  context->need_key_frame = 3;
812  }
813 
814 
815  if (!context->encoder_init) {
816  if (init_encoder(codec) != SWITCH_STATUS_SUCCESS) {
817  return SWITCH_STATUS_FALSE;
818  }
819  }
820 
821  if (context->change_bandwidth) {
822  context->codec_settings.video.bandwidth = context->change_bandwidth;
823  context->change_bandwidth = 0;
824  if (init_encoder(codec) != SWITCH_STATUS_SUCCESS) {
825  return SWITCH_STATUS_FALSE;
826  }
827  }
828 
829  now = switch_time_now();
830 
831  if (context->need_key_frame > 0) {
832  // force generate a key frame
833 
834  if (!context->last_key_frame || (now - context->last_key_frame) > KEY_FRAME_MIN_FREQ) {
835  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "VPX KEYFRAME GENERATED\n");
836  vpx_flags |= VPX_EFLAG_FORCE_KF;
837  context->need_key_frame = 0;
838  context->last_key_frame = now;
839  }
840  }
841 
842  context->framecount++;
843 
844  pts = (now - context->start_time) / 1000;
845 
846  dur = context->last_ms ? (now - context->last_ms) / 1000 : pts;
847 
848  if ((err = vpx_codec_encode(&context->encoder,
849  (vpx_image_t *) frame->img,
850  pts,
851  dur,
852  vpx_flags,
853  VPX_DL_REALTIME)) != VPX_CODEC_OK) {
854  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "VPX encode error %d:%s:%s\n",
855  err, vpx_codec_error(&context->encoder), vpx_codec_error_detail(&context->encoder));
856  frame->datalen = 0;
857  return SWITCH_STATUS_FALSE;
858  }
859 
860  context->enc_iter = NULL;
861  context->last_ts = frame->timestamp;
862  context->last_ms = now;
863 
864  return consume_partition(context, frame);
865 }
866 
867 static switch_status_t buffer_vp8_packets(vpx_context_t *context, switch_frame_t *frame)
868 {
869  uint8_t *data = frame->data;
870  uint8_t S;
871  uint8_t DES;
872  // uint8_t PID;
873  int len;
874 #if 0
875  int key = 0;
876 
878  "VIDEO VPX: seq: %d ts: %u len: %ld %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x mark: %d\n",
879  frame->seq, frame->timestamp, frame->datalen,
880  *((uint8_t *)data), *((uint8_t *)data + 1),
881  *((uint8_t *)data + 2), *((uint8_t *)data + 3),
882  *((uint8_t *)data + 4), *((uint8_t *)data + 5),
883  *((uint8_t *)data + 6), *((uint8_t *)data + 7),
884  *((uint8_t *)data + 8), *((uint8_t *)data + 9),
885  *((uint8_t *)data + 10), frame->m);
886 #endif
887 
888 
889  DES = *data;
890  data++;
891  S = (DES & 0x10);
892  // PID = DES & 0x07;
893 
894  //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "DATA LEN %d S BIT %d PID: %d\n", frame->datalen, S, PID);
895 
896  if (DES & 0x80) { // X
897  uint8_t X = *data;
898  //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "X BIT SET\n");
899  data++;
900  if (X & 0x80) { // I
901  uint8_t M = (*data) & 0x80;
902  //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "I BIT SET\n");
903  data++;
904  if (M) {
905  //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "M BIT SET\n");
906  data++;
907  }
908  }
909  if (X & 0x40) {
910  //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "L BIT SET\n");
911  data++; // L
912  }
913  if (X & 0x30) {
914  //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "T/K BIT SET\n");
915  data++; // T/K
916  }
917  }
918 
919  if (!switch_buffer_inuse(context->vpx_packet_buffer) && !S) {
920  if (context->got_key_frame > 0) {
921  context->got_key_frame = 0;
922  context->got_start_frame = 0;
924  }
926  }
927 
928  if (S) {
929  switch_buffer_zero(context->vpx_packet_buffer);
930  context->last_received_timestamp = frame->timestamp;
931 #if 0
932  if (PID == 0) {
933  key = __IS_VP8_KEY_FRAME(*data);
934  }
935 #endif
936  }
937 
938  len = frame->datalen - (data - (uint8_t *)frame->data);
939  //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POST PARSE: DATA LEN %d KEY %d KEYBYTE = %0x\n", len, key, *data);
940 
941  if (len <= 0) {
942  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid packet %d\n", len);
943  return SWITCH_STATUS_RESTART;
944  }
945 
946  if (context->last_received_timestamp != frame->timestamp) {
947  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG2, "wrong timestamp %u, expect %u, packet loss?\n", frame->timestamp, context->last_received_timestamp);
948  switch_buffer_zero(context->vpx_packet_buffer);
949  return SWITCH_STATUS_RESTART;
950  }
951 
952  switch_buffer_write(context->vpx_packet_buffer, data, len);
953  return SWITCH_STATUS_SUCCESS;
954 }
955 
956 // https://tools.ietf.org/id/draft-ietf-payload-vp9-01.txt
957 
958 static switch_status_t buffer_vp9_packets(vpx_context_t *context, switch_frame_t *frame)
959 {
960  uint8_t *data = (uint8_t *)frame->data;
961  uint8_t *vp9 = (uint8_t *)frame->data;
962  vp9_payload_descriptor_t *desc = (vp9_payload_descriptor_t *)vp9;
963  int len = 0;
964 
965 #ifdef DEBUG_VP9
966  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%02x %02x %02x %02x m=%d len=%4d "
967  "have_pid=%d "
968  "have_p_layer=%d "
969  "have_layer_ind=%d "
970  "is_flexible=%d "
971  "start=%d "
972  "end=%d "
973  "have_ss=%d "
974  "zero=%d\n",
975  *data, *(data+1), *(data+2), *(data+3), frame->m, frame->datalen,
976  desc->have_pid,
977  desc->have_p_layer,
978  desc->have_layer_ind,
979  desc->is_flexible,
980  desc->start,
981  desc->end,
982  desc->have_ss,
983  desc->zero);
984 #endif
985 
986  vp9++;
987 
988  if (desc->have_pid) {
989  uint16_t pid = 0;
990 
991  pid = *vp9 & 0x7f; //0 bit is M , 1-7 bit is pid.
992 
993  if (*vp9 & 0x80) { //if (M==1)
994  vp9++;
995  pid = (pid << 8) + *vp9;
996  }
997 
998  vp9++;
999 
1000 #ifdef DEBUG_VP9
1001  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "have pid: %d start=%d end=%d\n", pid, desc->start, desc->end);
1002 #endif
1003 
1004  }
1005 
1006  if (desc->have_layer_ind) {
1007 #ifdef DEBUG_VP9
1008  vp9_p_layer_t *layer = (vp9_p_layer_t *)vp9;
1009 
1010  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "temporal_id=%d temporal_up_switch=%d spatial_id=%d inter_layer_predicted=%d\n",
1011  layer->temporal_id, layer->temporal_up_switch, layer->spatial_id, layer->inter_layer_predicted);
1012 #endif
1013 
1014  vp9++;
1015  if (!desc->is_flexible) {
1016  vp9++; // TL0PICIDX
1017  }
1018  }
1019 
1020  //When P and F are both set to one, indicating a non-key frame in flexible mode
1021  if (desc->have_p_layer && desc->is_flexible) { // P & F set, P_DIFF
1022  if (*vp9 & 1) { // N
1023  vp9++;
1024  if (*vp9 & 1) { // N
1025  vp9++;
1026  if (*vp9 & 1) {
1027  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid VP9 packet!");
1028  switch_buffer_zero(context->vpx_packet_buffer);
1029  goto end;
1030  }
1031  }
1032  }
1033  vp9++;
1034  }
1035 
1036  if (desc->have_ss) {
1037  vp9_ss_t *ss = (vp9_ss_t *)(vp9++);
1038 
1039 #ifdef DEBUG_VP9
1040  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "have ss: %02x n_s: %d y:%d g:%d\n", *(uint8_t *)ss, ss->n_s, ss->y, ss->g);
1041 #endif
1042  if (ss->y) {
1043  int i;
1044 
1045  for (i=0; i<=ss->n_s; i++) {
1046 #ifdef DEBUG_VP9
1047  int width = ntohs(*(uint16_t *)vp9);
1048  int height = ntohs(*(uint16_t *)(vp9 + 2));
1049  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "SS: %d %dx%d\n", i, width, height);
1050 #endif
1051  vp9 += 4;
1052  }
1053  }
1054 
1055  if (ss->g) {
1056  int i;
1057  uint8_t ng = *vp9++; //N_G indicates the number of frames in a GOF
1058 
1059  for (i = 0; ng > 0 && i < ng; i++) {
1060  vp9_n_g_t *n_g = (vp9_n_g_t *)(vp9++);
1061  vp9 += n_g->r;
1062  }
1063  }
1064  }
1065 
1066  if (vp9 - data >= frame->datalen) {
1067  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Invalid VP9 Packet %" SWITCH_SSIZE_T_FMT " > %d\n", vp9 - data, frame->datalen);
1068  switch_buffer_zero(context->vpx_packet_buffer);
1069  goto end;
1070  }
1071 
1072  if (switch_buffer_inuse(context->vpx_packet_buffer)) { // middle packet
1073  if (desc->start) {
1074  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "got invalid vp9 packet, packet loss? resetting buffer\n");
1075  switch_buffer_zero(context->vpx_packet_buffer);
1076  }
1077  } else { // start packet
1078  if (!desc->start) {
1079  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "got invalid vp9 packet, packet loss? waiting for a start packet\n");
1080  goto end;
1081  }
1082  }
1083 
1084  len = frame->datalen - (vp9 - data);
1085  switch_buffer_write(context->vpx_packet_buffer, vp9, len);
1086 
1087 end:
1088 
1089 #ifdef DEBUG_VP9
1090  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "buffered %d bytes, buffer size: %" SWITCH_SIZE_T_FMT "\n", len, switch_buffer_inuse(context->vpx_packet_buffer));
1091 #endif
1092 
1093  return SWITCH_STATUS_SUCCESS;
1094 }
1095 
1096 static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t *frame)
1097 {
1098  vpx_context_t *context = (vpx_context_t *)codec->private_info;
1099  switch_size_t len;
1100  vpx_codec_ctx_t *decoder = NULL;
1102  int is_start = 0, is_keyframe = 0, get_refresh = 0;
1103 
1104 #if 0
1105  vp9_payload_descriptor_t *desc = (vp9_payload_descriptor_t *)frame->data;
1106  uint8_t *data = frame->data;
1107  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%02x %02x %02x %02x m=%d start=%d end=%d m=%d len=%d\n",
1108  *data, *(data+1), *(data+2), *(data+3), frame->m, desc->start, desc->end, frame->m, frame->datalen);
1109 #endif
1110 
1111  if (context->is_vp9) {
1112  is_keyframe = IS_VP9_KEY_FRAME(*(unsigned char *)frame->data);
1113  is_start = IS_VP9_START_PKT(*(unsigned char *)frame->data);
1114 
1115 #ifdef DEBUG_VP9
1116  if (is_keyframe) {
1117  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "================Got a key frame!!!!========================\n");
1118  }
1119 #endif
1120  } else { // vp8
1121  is_start = (*(unsigned char *)frame->data & 0x10);
1122  is_keyframe = IS_VP8_KEY_FRAME((uint8_t *)frame->data);
1123 
1124 #ifdef DEBUG_VP9
1126 #endif
1127  }
1128 
1129  if (!is_keyframe && context->got_key_frame <= 0) {
1130  context->no_key_frame++;
1131  //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "no keyframe, %d\n", context->no_key_frame);
1132  if (context->no_key_frame > 50) {
1133  if ((is_keyframe = is_start)) {
1134  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "no keyframe, treating start as key. frames=%d\n", context->no_key_frame);
1135  }
1136  }
1137  }
1138 
1139  // if (is_keyframe) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "got key %d\n", context->got_key_frame);
1140 
1141  if (context->need_decoder_reset != 0) {
1142  vpx_codec_destroy(&context->decoder);
1143  context->decoder_init = 0;
1144  init_decoder(codec);
1145  context->need_decoder_reset = 0;
1146  }
1147 
1148  if (!context->decoder_init) {
1149  init_decoder(codec);
1150  }
1151 
1152  if (!context->decoder_init) {
1153  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "VPX decoder is not initialized!\n");
1154  return SWITCH_STATUS_FALSE;
1155  }
1156 
1157  decoder = &context->decoder;
1158 
1159  // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "len: %d ts: %u mark:%d\n", frame->datalen, frame->timestamp, frame->m);
1160 
1161  // context->last_received_timestamp = frame->timestamp;
1162  context->last_received_complete_picture = frame->m ? SWITCH_TRUE : SWITCH_FALSE;
1163 
1164  if (is_start) {
1165  context->got_start_frame = 1;
1166  }
1167 
1168  if (is_keyframe) {
1169  if (context->got_key_frame <= 0) {
1170  context->got_key_frame = 1;
1171  context->no_key_frame = 0;
1172  } else {
1173  context->got_key_frame++;
1174  }
1175  } else if (context->got_key_frame <= 0) {
1176  if ((--context->got_key_frame % 200) == 0) {
1177  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Waiting for key frame %d\n", context->got_key_frame);
1178  }
1179 
1180  get_refresh = 1;
1181 
1182  if (!context->got_start_frame) {
1184  }
1185  }
1186 
1187 
1188  status = context->is_vp9 ? buffer_vp9_packets(context, frame) : buffer_vp8_packets(context, frame);
1189 
1190 
1191  if (context->dec_iter && (frame->img = (switch_image_t *) vpx_codec_get_frame(decoder, &context->dec_iter))) {
1193  }
1194 
1195  // switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "====READ buf:%ld got_key:%d st:%d m:%d\n", switch_buffer_inuse(context->vpx_packet_buffer), context->got_key_frame, status, frame->m);
1196 
1197  len = switch_buffer_inuse(context->vpx_packet_buffer);
1198 
1199  //if (frame->m && (status != SWITCH_STATUS_SUCCESS || !len)) {
1200  //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "WTF????? %d %ld\n", status, len);
1201  //}
1202 
1203  if (status == SWITCH_STATUS_SUCCESS && frame->m && len) {
1204  uint8_t *data;
1205  int corrupted = 0;
1206  int err;
1207 
1208  switch_buffer_peek_zerocopy(context->vpx_packet_buffer, (void *)&data);
1209 
1210  context->dec_iter = NULL;
1211  err = vpx_codec_decode(decoder, data, (unsigned int)len, NULL, 0);
1212 
1213  if (err != VPX_CODEC_OK) {
1214  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Error decoding %" SWITCH_SIZE_T_FMT " bytes, [%d:%s:%s]\n",
1215  len, err, vpx_codec_error(decoder), vpx_codec_error_detail(decoder));
1217  }
1218 
1219  if (vpx_codec_control(decoder, VP8D_GET_FRAME_CORRUPTED, &corrupted) != VPX_CODEC_OK) {
1220  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "VPX control error!\n");
1222  }
1223 
1224  if (corrupted) {
1225  frame->img = NULL;
1226 #ifdef DEBUG_VP9
1228 #endif
1229  } else {
1230  frame->img = (switch_image_t *) vpx_codec_get_frame(decoder, &context->dec_iter);
1231 
1232 #ifdef DEBUG_VP9
1233  switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "decoded: %dx%d\n", frame->img->d_w, frame->img->d_h);
1234 #endif
1235  }
1236 
1237  switch_buffer_zero(context->vpx_packet_buffer);
1238 
1239  if (!frame->img) {
1240  //context->need_decoder_reset = 1;
1241  context->got_key_frame = 0;
1242  context->got_start_frame = 0;
1243  status = SWITCH_STATUS_RESTART;
1244  }
1245  }
1246 
1247 end:
1248 
1249  if (status == SWITCH_STATUS_RESTART) {
1250  switch_buffer_zero(context->vpx_packet_buffer);
1251  //context->need_decoder_reset = 1;
1252  context->got_key_frame = 0;
1253  context->got_start_frame = 0;
1254  //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "RESET VPX\n");
1255  }
1256 
1257  if (!frame->img || status == SWITCH_STATUS_RESTART) {
1258  status = SWITCH_STATUS_MORE_DATA;
1259  }
1260 
1261  if (context->got_key_frame <= 0 || get_refresh) {
1263  }
1264 
1265  return status;
1266 }
1267 
1268 
1269 static switch_status_t switch_vpx_control(switch_codec_t *codec,
1272  void *cmd_data,
1274  void *cmd_arg,
1276  void **ret_data)
1277 {
1278 
1279  vpx_context_t *context = (vpx_context_t *)codec->private_info;
1280 
1281  switch(cmd) {
1282  case SCC_VIDEO_RESET:
1283  {
1284  int mask = *((int *) cmd_data);
1285  if (mask & 1) {
1286  context->need_encoder_reset = 1;
1287  }
1288  if (mask & 2) {
1289  context->need_decoder_reset = 1;
1290  }
1291  }
1292  break;
1294  context->need_key_frame = 1;
1295  break;
1296  case SCC_VIDEO_BANDWIDTH:
1297  {
1298  switch(ctype) {
1299  case SCCT_INT:
1300  context->change_bandwidth = *((int *) cmd_data);
1301  break;
1302  case SCCT_STRING:
1303  {
1304  char *bwv = (char *) cmd_data;
1305  context->change_bandwidth = switch_parse_bandwidth_string(bwv);
1306  }
1307  break;
1308  default:
1309  break;
1310  }
1311  }
1312  break;
1313  default:
1314  break;
1315  }
1316 
1317 
1318  return SWITCH_STATUS_SUCCESS;
1319 }
1320 
1321 
1322 static switch_status_t switch_vpx_destroy(switch_codec_t *codec)
1323 {
1324  vpx_context_t *context = (vpx_context_t *)codec->private_info;
1325 
1326  if (context) {
1327  if ((codec->flags & SWITCH_CODEC_FLAG_ENCODE)) {
1328  vpx_codec_destroy(&context->encoder);
1329  }
1330 
1331  if ((codec->flags & SWITCH_CODEC_FLAG_DECODE)) {
1332  vpx_codec_destroy(&context->decoder);
1333  }
1334 
1335  if (context->pic) {
1336  vpx_img_free(context->pic);
1337  context->pic = NULL;
1338  }
1339  if (context->vpx_packet_buffer) {
1340  switch_buffer_destroy(&context->vpx_packet_buffer);
1341  context->vpx_packet_buffer = NULL;
1342  }
1343  }
1344  return SWITCH_STATUS_SUCCESS;
1345 }
1346 
1347 SWITCH_MODULE_LOAD_FUNCTION(mod_vpx_load)
1348 {
1349  switch_codec_interface_t *codec_interface;
1350 
1351  /* connect my internal structure to the blank pointer passed to me */
1352  *module_interface = switch_loadable_module_create_module_interface(pool, modname);
1353  SWITCH_ADD_CODEC(codec_interface, "VP8 Video");
1354  switch_core_codec_add_video_implementation(pool, codec_interface, 99, "VP8", NULL,
1355  switch_vpx_init, switch_vpx_encode, switch_vpx_decode, switch_vpx_control, switch_vpx_destroy);
1356  SWITCH_ADD_CODEC(codec_interface, "VP9 Video");
1357  switch_core_codec_add_video_implementation(pool, codec_interface, 99, "VP9", NULL,
1358  switch_vpx_init, switch_vpx_encode, switch_vpx_decode, switch_vpx_control, switch_vpx_destroy);
1359 
1360  /* indicate that the module should continue to be loaded */
1361  return SWITCH_STATUS_SUCCESS;
1362 }
1363 
1364 #endif
1365 #endif
1366 /* For Emacs:
1367  * Local Variables:
1368  * mode:c
1369  * indent-tabs-mode:t
1370  * tab-width:4
1371  * c-basic-offset:4
1372  * End:
1373  * For VIM:
1374  * vim:set softtabstop=4 shiftwidth=4 tabstop=4 noet:
1375  */
switch_core_session_t * session
switch_time_t switch_micro_time_now(void)
Get the current epoch time in microseconds.
Definition: switch_time.c:310
switch_bool_t m
Definition: switch_frame.h:72
#define VPX_IMAGE_ABI_VERSION
Current ABI version number.
Definition: switch_image.h:31
void vpx_img_free(vpx_image_t *img)
Close an image descriptor.
#define SWITCH_CHANNEL_SESSION_LOG(x)
Image Descriptor.
Definition: switch_image.h:88
#define switch_set_flag(obj, flag)
Set a flag on an arbitrary object.
Definition: switch_utils.h:631
#define SWITCH_CHANNEL_LOG
switch_size_t switch_buffer_read(_In_ switch_buffer_t *buffer, _In_ void *data, _In_ switch_size_t datalen)
Read data from a switch_buffer_t up to the ammount of datalen if it is available. Remove read data fr...
switch_status_t switch_buffer_create_dynamic(_Out_ switch_buffer_t **buffer, _In_ switch_size_t blocksize, _In_ switch_size_t start_len, _In_ switch_size_t max_len)
Allocate a new dynamic switch_buffer.
switch_bool_t
Definition: switch_types.h:405
uint32_t timestamp
Definition: switch_frame.h:69
#define switch_core_strdup(_pool, _todup)
Copy a string using memory allocation from a given pool.
Definition: switch_core.h:729
switch_memory_pool_t * pool
uint32_t switch_core_cpu_count(void)
Definition: switch_core.c:1042
switch_size_t switch_buffer_write(_In_ switch_buffer_t *buffer, _In_bytecount_(datalen) const void *data, _In_ switch_size_t datalen)
Write data into a switch_buffer_t up to the length of datalen.
static int32_t switch_parse_bandwidth_string(const char *bwv)
uint32_t switch_codec_flag_t
switch_status_t switch_buffer_create_partition(switch_memory_pool_t *pool, switch_buffer_t **buffer, void *data, switch_size_t datalen)
Definition: switch_buffer.c:79
unsigned int d_w
Definition: switch_image.h:99
switch_codec_control_command_t
uint16_t seq
Definition: switch_frame.h:70
switch_codec_control_type_t
int64_t switch_time_t
Definition: switch_apr.h:188
const switch_codec_implementation_t * implementation
if((uint32_t)(unpack->cur-unpack->buf) > unpack->buflen)
uint32_t datalen
Definition: switch_frame.h:57
switch_frame_flag_t flags
Definition: switch_frame.h:74
#define switch_core_alloc(_pool, _mem)
Allocate memory directly from a memory pool.
Definition: switch_core.h:682
switch_memory_pool_t * memory_pool
static int32_t switch_calc_bitrate(int w, int h, int quality, double fps)
Definition: switch_utils.h:998
Top level module interface to implement a series of codec implementations.
void switch_buffer_zero(_In_ switch_buffer_t *buffer)
Remove all data from the buffer.
An abstraction of a data frame.
Definition: switch_frame.h:43
uintptr_t switch_size_t
#define SWITCH_MODULE_LOAD_FUNCTION(name)
#define SWITCH_SSIZE_T_FMT
#define SWITCH_ADD_CODEC(codec_int, int_name)
unsigned int h
Definition: switch_image.h:95
switch_image_t * img
Definition: switch_frame.h:77
switch_status_t
Common return values.
static void switch_core_codec_add_video_implementation(switch_memory_pool_t *pool, switch_codec_interface_t *codec_interface, switch_payload_t ianacode, const char *iananame, char *fmtp, switch_core_codec_init_func_t init, switch_core_codec_video_encode_func_t encode, switch_core_codec_video_decode_func_t decode, switch_core_codec_control_func_t control, switch_core_codec_destroy_func_t destroy)
#define switch_goto_status(_status, _label)
Definition: switch_utils.h:256
switch_loadable_module_interface_t * switch_loadable_module_create_module_interface(switch_memory_pool_t *pool, const char *name)
switch_size_t switch_buffer_peek_zerocopy(_In_ switch_buffer_t *buffer, _Out_ const void **ptr)
Main Library Header.
#define SWITCH_MODULE_DEFINITION(name, load, shutdown, runtime)
struct apr_pool_t switch_memory_pool_t
void switch_log_printf(_In_ switch_text_channel_t channel, _In_z_ const char *file, _In_z_ const char *func, _In_ int line, _In_opt_z_ const char *userdata, _In_ switch_log_level_t level, _In_z_ _Printf_format_string_ const char *fmt,...) PRINTF_FUNCTION(7
Write log data to the logging engine.
unsigned int d_h
Definition: switch_image.h:100
switch_status_t switch_buffer_set_partition_data(switch_buffer_t *buffer, void *data, switch_size_t datalen)
Definition: switch_buffer.c:68
switch_time_t switch_time_now(void)
Definition: switch_apr.c:302
unsigned int w
Definition: switch_image.h:94
switch_size_t switch_buffer_inuse(_In_ switch_buffer_t *buffer)
Get the in use amount of a switch_buffer_t.
void switch_buffer_destroy(switch_buffer_t **buffer)
Destroy the buffer.
memset(buf, 0, buflen)
#define SWITCH_SIZE_T_FMT