| 1 | |
|---|
| 2 | |
|---|
| 3 | |
|---|
| 4 | |
|---|
| 5 | |
|---|
| 6 | |
|---|
| 7 | |
|---|
| 8 | |
|---|
| 9 | |
|---|
| 10 | |
|---|
| 11 | |
|---|
| 12 | |
|---|
| 13 | |
|---|
| 14 | |
|---|
| 15 | #include "config_unix.h" |
|---|
| 16 | #include "config_win32.h" |
|---|
| 17 | #include "audio_types.h" |
|---|
| 18 | #include "codec_types.h" |
|---|
| 19 | #include "ts.h" |
|---|
| 20 | #include "playout.h" |
|---|
| 21 | #include "channel.h" |
|---|
| 22 | #include "channel_types.h" |
|---|
| 23 | #include "codec.h" |
|---|
| 24 | #include "codec_state.h" |
|---|
| 25 | #include "converter.h" |
|---|
| 26 | #include "audio_util.h" |
|---|
| 27 | #include "render_3D.h" |
|---|
| 28 | #include "repair.h" |
|---|
| 29 | #include "timers.h" |
|---|
| 30 | #include "ts.h" |
|---|
| 31 | #include "channel_types.h" |
|---|
| 32 | #include "pdb.h" |
|---|
| 33 | #include "pktbuf.h" |
|---|
| 34 | #include "source.h" |
|---|
| 35 | #include "debug.h" |
|---|
| 36 | #include "util.h" |
|---|
| 37 | #include "net_udp.h" |
|---|
| 38 | #include "mix.h" |
|---|
| 39 | #include "rtp.h" |
|---|
| 40 | #include "playout_calc.h" |
|---|
| 41 | #include "ui.h" |
|---|
| 42 | #include "session.h" |
|---|
| 43 | #include "auddev.h" |
|---|
| 44 | |
|---|
| 45 | #define SKEW_ADAPT_THRESHOLD 5000 |
|---|
| 46 | #define SOURCE_YOUNG_AGE 20 |
|---|
| 47 | #define SOURCE_AUDIO_HISTORY_MS 1000 |
|---|
| 48 | #define NO_TOGED_CONT_FOR_PLAYOUT_RECALC 3 |
|---|
| 49 | |
|---|
| 50 | #define SOURCE_COMPARE_WINDOW_SIZE 8 |
|---|
| 51 | |
|---|
| 52 | |
|---|
| 53 | |
|---|
| 54 | #define MATCH_THRESHOLD 1200 |
|---|
| 55 | |
|---|
| 56 | |
|---|
| 57 | |
|---|
| 58 | |
|---|
| 59 | |
|---|
| 60 | typedef enum { SOURCE_SKEW_SLOW, SOURCE_SKEW_FAST, SOURCE_SKEW_NONE } skew_t; |
|---|
| 61 | |
|---|
| 62 | typedef enum { PLAYOUT_MODE_NORMAL, PLAYOUT_MODE_SPIKE } pmode_t; |
|---|
| 63 | |
|---|
| 64 | typedef struct s_source { |
|---|
| 65 | struct s_source *next; |
|---|
| 66 | struct s_source *prev; |
|---|
| 67 | pdb_entry_t *pdbe; |
|---|
| 68 | uint32_t age; |
|---|
| 69 | ts_t next_played; |
|---|
| 70 | ts_t last_repair; |
|---|
| 71 | ts_t talkstart; |
|---|
| 72 | uint32_t post_talkstart_units; |
|---|
| 73 | uint16_t consec_lost; |
|---|
| 74 | uint32_t mean_energy; |
|---|
| 75 | struct s_pktbuf *pktbuf; |
|---|
| 76 | uint32_t packets_done; |
|---|
| 77 | struct s_channel_state *channel_state; |
|---|
| 78 | struct s_codec_state_store *codec_states; |
|---|
| 79 | struct s_pb *channel; |
|---|
| 80 | struct s_pb *media; |
|---|
| 81 | struct s_pb_iterator *media_pos; |
|---|
| 82 | struct s_converter *converter; |
|---|
| 83 | pmode_t playout_mode; |
|---|
| 84 | ts_t spike_var; |
|---|
| 85 | |
|---|
| 86 | |
|---|
| 87 | skew_t skew; |
|---|
| 88 | ts_t skew_adjust; |
|---|
| 89 | int16_t skew_cnt; |
|---|
| 90 | |
|---|
| 91 | int32_t samples_played; |
|---|
| 92 | int32_t samples_added; |
|---|
| 93 | |
|---|
| 94 | uint32_t byte_count; |
|---|
| 95 | ts_t byte_count_start; |
|---|
| 96 | double bps; |
|---|
| 97 | |
|---|
| 98 | u_char toged_cont; |
|---|
| 99 | uint16_t toged_mask; |
|---|
| 100 | } source; |
|---|
| 101 | |
|---|
| 102 | |
|---|
| 103 | |
|---|
| 104 | |
|---|
| 105 | |
|---|
| 106 | typedef struct s_source_list { |
|---|
| 107 | source sentinel; |
|---|
| 108 | uint16_t nsrcs; |
|---|
| 109 | } source_list; |
|---|
| 110 | |
|---|
| 111 | |
|---|
| 112 | |
|---|
| 113 | |
|---|
| 114 | |
|---|
| 115 | int |
|---|
| 116 | source_list_create(source_list **pplist) |
|---|
| 117 | { |
|---|
| 118 | source_list *plist = (source_list*)xmalloc(sizeof(source_list)); |
|---|
| 119 | if (plist != NULL) { |
|---|
| 120 | *pplist = plist; |
|---|
| 121 | plist->sentinel.next = &plist->sentinel; |
|---|
| 122 | plist->sentinel.prev = &plist->sentinel; |
|---|
| 123 | plist->nsrcs = 0; |
|---|
| 124 | return TRUE; |
|---|
| 125 | } |
|---|
| 126 | return FALSE; |
|---|
| 127 | } |
|---|
| 128 | |
|---|
| 129 | void |
|---|
| 130 | source_list_clear(source_list *plist) |
|---|
| 131 | { |
|---|
| 132 | assert(plist != NULL); |
|---|
| 133 | |
|---|
| 134 | while(plist->sentinel.next != &plist->sentinel) { |
|---|
| 135 | source_remove(plist, plist->sentinel.next); |
|---|
| 136 | } |
|---|
| 137 | } |
|---|
| 138 | |
|---|
| 139 | void |
|---|
| 140 | source_list_destroy(source_list **pplist) |
|---|
| 141 | { |
|---|
| 142 | source_list *plist = *pplist; |
|---|
| 143 | source_list_clear(plist); |
|---|
| 144 | assert(plist->nsrcs == 0); |
|---|
| 145 | xfree(plist); |
|---|
| 146 | *pplist = NULL; |
|---|
| 147 | } |
|---|
| 148 | |
|---|
| 149 | uint32_t |
|---|
| 150 | source_list_source_count(source_list *plist) |
|---|
| 151 | { |
|---|
| 152 | return plist->nsrcs; |
|---|
| 153 | } |
|---|
| 154 | |
|---|
| 155 | source* |
|---|
| 156 | source_list_get_source_no(source_list *plist, uint32_t n) |
|---|
| 157 | { |
|---|
| 158 | source *curr = NULL; |
|---|
| 159 | |
|---|
| 160 | assert(plist != NULL); |
|---|
| 161 | |
|---|
| 162 | if (n < plist->nsrcs) { |
|---|
| 163 | curr = plist->sentinel.next; |
|---|
| 164 | while(n != 0) { |
|---|
| 165 | curr = curr->next; |
|---|
| 166 | n--; |
|---|
| 167 | } |
|---|
| 168 | return curr; |
|---|
| 169 | } |
|---|
| 170 | return NULL; |
|---|
| 171 | } |
|---|
| 172 | |
|---|
| 173 | source* |
|---|
| 174 | source_get_by_ssrc(source_list *plist, uint32_t ssrc) |
|---|
| 175 | { |
|---|
| 176 | source *curr = NULL, *stop = NULL; |
|---|
| 177 | |
|---|
| 178 | curr = plist->sentinel.next; |
|---|
| 179 | stop = &plist->sentinel; |
|---|
| 180 | while(curr != stop) { |
|---|
| 181 | if (curr->pdbe->ssrc == ssrc) { |
|---|
| 182 | return curr; |
|---|
| 183 | } |
|---|
| 184 | curr = curr->next; |
|---|
| 185 | } |
|---|
| 186 | |
|---|
| 187 | return NULL; |
|---|
| 188 | } |
|---|
| 189 | |
|---|
| 190 | |
|---|
| 191 | |
|---|
| 192 | |
|---|
| 193 | |
|---|
| 194 | static ts_t zero_ts; |
|---|
| 195 | static ts_t keep_source_ts; |
|---|
| 196 | static ts_t history_ts; |
|---|
| 197 | static ts_t bw_avg_period; |
|---|
| 198 | static ts_t skew_thresh; |
|---|
| 199 | static ts_t skew_limit; |
|---|
| 200 | static ts_t transit_reset; |
|---|
| 201 | |
|---|
| 202 | static ts_t spike_jump; |
|---|
| 203 | static ts_t spike_end; |
|---|
| 204 | static int time_constants_inited = FALSE; |
|---|
| 205 | |
|---|
| 206 | static void |
|---|
| 207 | time_constants_init() |
|---|
| 208 | { |
|---|
| 209 | |
|---|
| 210 | zero_ts = ts_map32(8000, 0); |
|---|
| 211 | keep_source_ts = ts_map32(8000, 24000); |
|---|
| 212 | history_ts = ts_map32(8000, 1000); |
|---|
| 213 | bw_avg_period = ts_map32(8000, 8000); |
|---|
| 214 | skew_thresh = ts_map32(8000, 320); |
|---|
| 215 | skew_limit = ts_map32(8000, 4000); |
|---|
| 216 | transit_reset = ts_map32(8000, 80000); |
|---|
| 217 | spike_jump = ts_map32(8000, 800); |
|---|
| 218 | spike_end = ts_map32(8000, 64); |
|---|
| 219 | time_constants_inited = TRUE; |
|---|
| 220 | } |
|---|
| 221 | |
|---|
| 222 | |
|---|
| 223 | |
|---|
| 224 | |
|---|
| 225 | |
|---|
| 226 | source* |
|---|
| 227 | source_create(source_list *plist, |
|---|
| 228 | uint32_t ssrc, |
|---|
| 229 | pdb_t *pdb) |
|---|
| 230 | { |
|---|
| 231 | source *psrc; |
|---|
| 232 | int success; |
|---|
| 233 | |
|---|
| 234 | assert(plist != NULL); |
|---|
| 235 | assert(source_get_by_ssrc(plist, ssrc) == NULL); |
|---|
| 236 | |
|---|
| 237 | |
|---|
| 238 | |
|---|
| 239 | |
|---|
| 240 | if (time_constants_inited == FALSE) { |
|---|
| 241 | time_constants_init(); |
|---|
| 242 | } |
|---|
| 243 | |
|---|
| 244 | |
|---|
| 245 | psrc = (source*)block_alloc(sizeof(source)); |
|---|
| 246 | if (psrc == NULL) { |
|---|
| 247 | return NULL; |
|---|
| 248 | } |
|---|
| 249 | memset(psrc, 0, sizeof(source)); |
|---|
| 250 | |
|---|
| 251 | if (pdb_item_get(pdb, ssrc, &psrc->pdbe) == FALSE) { |
|---|
| 252 | debug_msg("Persistent database item not found\n"); |
|---|
| 253 | abort(); |
|---|
| 254 | } |
|---|
| 255 | |
|---|
| 256 | psrc->pdbe->first_mix = 1; |
|---|
| 257 | psrc->toged_cont = 0; |
|---|
| 258 | psrc->toged_mask = 0; |
|---|
| 259 | psrc->channel_state = NULL; |
|---|
| 260 | psrc->skew = SOURCE_SKEW_NONE; |
|---|
| 261 | psrc->samples_played = 0; |
|---|
| 262 | psrc->samples_added = 0; |
|---|
| 263 | psrc->spike_var = zero_ts; |
|---|
| 264 | |
|---|
| 265 | |
|---|
| 266 | success = pb_create(&psrc->channel, |
|---|
| 267 | (playoutfreeproc)channel_data_destroy); |
|---|
| 268 | if (!success) { |
|---|
| 269 | debug_msg("Failed to allocate channel buffer\n"); |
|---|
| 270 | goto fail_create_channel; |
|---|
| 271 | } |
|---|
| 272 | |
|---|
| 273 | success = pb_create(&psrc->media, (playoutfreeproc)media_data_destroy); |
|---|
| 274 | if (!success) { |
|---|
| 275 | debug_msg("Failed to allocate media buffer\n"); |
|---|
| 276 | goto fail_create_media; |
|---|
| 277 | } |
|---|
| 278 | |
|---|
| 279 | success = pb_iterator_create(psrc->media, &psrc->media_pos); |
|---|
| 280 | if (!success) { |
|---|
| 281 | debug_msg("Failed to attach iterator to media buffer\n"); |
|---|
| 282 | goto fail_create_iterator; |
|---|
| 283 | } |
|---|
| 284 | |
|---|
| 285 | success = codec_state_store_create(&psrc->codec_states, DECODER); |
|---|
| 286 | if (!success) { |
|---|
| 287 | debug_msg("Failed to allocate codec state storage\n"); |
|---|
| 288 | goto fail_create_states; |
|---|
| 289 | } |
|---|
| 290 | |
|---|
| 291 | success = pktbuf_create(&psrc->pktbuf, 32); |
|---|
| 292 | if (!success) { |
|---|
| 293 | debug_msg("Failed to allocate packet buffer\n"); |
|---|
| 294 | goto fail_pktbuf; |
|---|
| 295 | } |
|---|
| 296 | |
|---|
| 297 | |
|---|
| 298 | psrc->next = plist->sentinel.next; |
|---|
| 299 | psrc->prev = &plist->sentinel; |
|---|
| 300 | psrc->next->prev = psrc; |
|---|
| 301 | psrc->prev->next = psrc; |
|---|
| 302 | plist->nsrcs++; |
|---|
| 303 | |
|---|
| 304 | debug_msg("Created source decode path\n"); |
|---|
| 305 | |
|---|
| 306 | return psrc; |
|---|
| 307 | |
|---|
| 308 | |
|---|
| 309 | fail_pktbuf: |
|---|
| 310 | codec_state_store_destroy(&psrc->codec_states); |
|---|
| 311 | fail_create_states: |
|---|
| 312 | pb_iterator_destroy(psrc->media, &psrc->media_pos); |
|---|
| 313 | fail_create_iterator: |
|---|
| 314 | pb_destroy(&psrc->media); |
|---|
| 315 | fail_create_media: |
|---|
| 316 | pb_destroy(&psrc->channel); |
|---|
| 317 | fail_create_channel: |
|---|
| 318 | block_free(psrc, sizeof(source)); |
|---|
| 319 | |
|---|
| 320 | return NULL; |
|---|
| 321 | } |
|---|
| 322 | |
|---|
| 323 | |
|---|
| 324 | |
|---|
| 325 | |
|---|
| 326 | |
|---|
| 327 | |
|---|
| 328 | void |
|---|
| 329 | source_reconfigure(source *src, |
|---|
| 330 | converter_id_t conv_id, |
|---|
| 331 | int render_3d, |
|---|
| 332 | uint16_t out_rate, |
|---|
| 333 | uint16_t out_channels) |
|---|
| 334 | { |
|---|
| 335 | uint16_t src_rate, src_channels; |
|---|
| 336 | codec_id_t src_cid; |
|---|
| 337 | const codec_format_t *src_cf; |
|---|
| 338 | |
|---|
| 339 | assert(src->pdbe != NULL); |
|---|
| 340 | |
|---|
| 341 | |
|---|
| 342 | |
|---|
| 343 | |
|---|
| 344 | |
|---|
| 345 | |
|---|
| 346 | src->age = 0; |
|---|
| 347 | pb_flush(src->media); |
|---|
| 348 | |
|---|
| 349 | |
|---|
| 350 | |
|---|
| 351 | |
|---|
| 352 | src_cid = codec_get_by_payload(src->pdbe->enc); |
|---|
| 353 | src_cf = codec_get_format(src_cid); |
|---|
| 354 | src_rate = (uint16_t)src_cf->format.sample_rate; |
|---|
| 355 | src_channels = (uint16_t)src_cf->format.channels; |
|---|
| 356 | |
|---|
| 357 | if (render_3d) { |
|---|
| 358 | assert(out_channels == 2); |
|---|
| 359 | |
|---|
| 360 | if (src->pdbe->render_3D_data) { |
|---|
| 361 | int azi3d, fil3d, len3d; |
|---|
| 362 | render_3D_get_parameters(src->pdbe->render_3D_data, |
|---|
| 363 | &azi3d, |
|---|
| 364 | &fil3d, |
|---|
| 365 | &len3d); |
|---|
| 366 | render_3D_set_parameters(src->pdbe->render_3D_data, |
|---|
| 367 | (int)src_rate, |
|---|
| 368 | azi3d, |
|---|
| 369 | fil3d, |
|---|
| 370 | len3d); |
|---|
| 371 | } else { |
|---|
| 372 | src->pdbe->render_3D_data = render_3D_init((int)src_rate); |
|---|
| 373 | } |
|---|
| 374 | assert(src->pdbe->render_3D_data); |
|---|
| 375 | |
|---|
| 376 | |
|---|
| 377 | src_channels = 2; |
|---|
| 378 | } else { |
|---|
| 379 | |
|---|
| 380 | if (src->pdbe->render_3D_data != NULL) { |
|---|
| 381 | render_3D_free(&src->pdbe->render_3D_data); |
|---|
| 382 | } |
|---|
| 383 | } |
|---|
| 384 | |
|---|
| 385 | |
|---|
| 386 | if (src->converter) { |
|---|
| 387 | converter_destroy(&src->converter); |
|---|
| 388 | } |
|---|
| 389 | |
|---|
| 390 | if (src_rate != out_rate || src_channels != out_channels) { |
|---|
| 391 | converter_fmt_t c; |
|---|
| 392 | c.src_freq = src_rate; |
|---|
| 393 | c.from_channels = src_channels; |
|---|
| 394 | c.dst_freq = out_rate; |
|---|
| 395 | c.to_channels = out_channels; |
|---|
| 396 | converter_create(conv_id, &c, &src->converter); |
|---|
| 397 | } |
|---|
| 398 | src->byte_count = 0; |
|---|
| 399 | src->bps = 0.0; |
|---|
| 400 | } |
|---|
| 401 | |
|---|
| 402 | void |
|---|
| 403 | source_remove(source_list *plist, source *psrc) |
|---|
| 404 | { |
|---|
| 405 | assert(plist); |
|---|
| 406 | assert(psrc); |
|---|
| 407 | assert(source_get_by_ssrc(plist, psrc->pdbe->ssrc) != NULL); |
|---|
| 408 | |
|---|
| 409 | psrc->next->prev = psrc->prev; |
|---|
| 410 | psrc->prev->next = psrc->next; |
|---|
| 411 | |
|---|
| 412 | if (psrc->channel_state) { |
|---|
| 413 | channel_decoder_destroy(&psrc->channel_state); |
|---|
| 414 | } |
|---|
| 415 | |
|---|
| 416 | if (psrc->converter) { |
|---|
| 417 | converter_destroy(&psrc->converter); |
|---|
| 418 | } |
|---|
| 419 | |
|---|
| 420 | pb_iterator_destroy(psrc->media, &psrc->media_pos); |
|---|
| 421 | pb_destroy(&psrc->channel); |
|---|
| 422 | pb_destroy(&psrc->media); |
|---|
| 423 | codec_state_store_destroy(&psrc->codec_states); |
|---|
| 424 | pktbuf_destroy(&psrc->pktbuf); |
|---|
| 425 | plist->nsrcs--; |
|---|
| 426 | |
|---|
| 427 | debug_msg("Destroying source decode path\n"); |
|---|
| 428 | |
|---|
| 429 | block_free(psrc, sizeof(source)); |
|---|
| 430 | |
|---|
| 431 | assert(source_get_by_ssrc(plist, psrc->pdbe->ssrc) == NULL); |
|---|
| 432 | } |
|---|
| 433 | |
|---|
| 434 | |
|---|
| 435 | |
|---|
| 436 | |
|---|
| 437 | static int |
|---|
| 438 | source_process_packet (source *src, |
|---|
| 439 | u_char *pckt, |
|---|
| 440 | uint32_t pckt_len, |
|---|
| 441 | uint8_t payload, |
|---|
| 442 | ts_t playout) |
|---|
| 443 | { |
|---|
| 444 | channel_data *cd; |
|---|
| 445 | channel_unit *cu; |
|---|
| 446 | cc_id_t cid; |
|---|
| 447 | uint8_t clayers; |
|---|
| 448 | |
|---|
| 449 | assert(src != NULL); |
|---|
| 450 | assert(pckt != NULL); |
|---|
| 451 | |
|---|
| 452 | |
|---|
| 453 | |
|---|
| 454 | |
|---|
| 455 | |
|---|
| 456 | |
|---|
| 457 | |
|---|
| 458 | |
|---|
| 459 | |
|---|
| 460 | |
|---|
| 461 | |
|---|
| 462 | |
|---|
| 463 | |
|---|
| 464 | |
|---|
| 465 | |
|---|
| 466 | |
|---|
| 467 | |
|---|
| 468 | cid = channel_coder_get_by_payload(payload); |
|---|
| 469 | clayers = channel_coder_get_layers(cid); |
|---|
| 470 | if (clayers > 1) { |
|---|
| 471 | struct s_pb_iterator *pi; |
|---|
| 472 | uint8_t i; |
|---|
| 473 | uint32_t clen; |
|---|
| 474 | int dup; |
|---|
| 475 | ts_t lplayout; |
|---|
| 476 | pb_iterator_create(src->channel, &pi); |
|---|
| 477 | while(pb_iterator_advance(pi)) { |
|---|
| 478 | pb_iterator_get_at(pi, (u_char**)&cd, &clen, &lplayout); |
|---|
| 479 | |
|---|
| 480 | if(!ts_eq(playout, lplayout)) { |
|---|
| 481 | continue; |
|---|
| 482 | } |
|---|
| 483 | pb_iterator_detach_at(pi, (u_char**)&cd, &clen, &lplayout); |
|---|
| 484 | assert(cd->nelem >= 1); |
|---|
| 485 | |
|---|
| 486 | |
|---|
| 487 | |
|---|
| 488 | if(cd->nelem >= clayers) { |
|---|
| 489 | debug_msg("source_process_packet failed - duplicate layer\n"); |
|---|
| 490 | src->pdbe->duplicates++; |
|---|
| 491 | pb_iterator_destroy(src->channel, &pi); |
|---|
| 492 | goto done; |
|---|
| 493 | } |
|---|
| 494 | |
|---|
| 495 | cu = (channel_unit*)block_alloc(sizeof(channel_unit)); |
|---|
| 496 | cu->data = pckt; |
|---|
| 497 | cu->data_len = pckt_len; |
|---|
| 498 | cu->pt = payload; |
|---|
| 499 | |
|---|
| 500 | dup = 0; |
|---|
| 501 | |
|---|
| 502 | |
|---|
| 503 | for(i=0; i<cd->nelem; i++) { |
|---|
| 504 | if(cu->data_len!=cd->elem[i]->data_len) break; |
|---|
| 505 | |
|---|
| 506 | |
|---|
| 507 | |
|---|
| 508 | if (memcmp(cu->data, cd->elem[i]->data, 20) == 0) { |
|---|
| 509 | dup=1; |
|---|
| 510 | } |
|---|
| 511 | } |
|---|
| 512 | |
|---|
| 513 | |
|---|
| 514 | |
|---|
| 515 | if(dup) { |
|---|
| 516 | debug_msg("source_process_packet failed - duplicate layer\n"); |
|---|
| 517 | src->pdbe->duplicates++; |
|---|
| 518 | |
|---|
| 519 | block_free(cu->data, cu->data_len); |
|---|
| 520 | cu->data_len = 0; |
|---|
| 521 | block_free(cu, sizeof(channel_unit)); |
|---|
| 522 | pb_iterator_destroy(src->channel, &pi); |
|---|
| 523 | goto done; |
|---|
| 524 | } |
|---|
| 525 | |
|---|
| 526 | |
|---|
| 527 | |
|---|
| 528 | |
|---|
| 529 | |
|---|
| 530 | cd->elem[cd->nelem] = cu; |
|---|
| 531 | cd->nelem++; |
|---|
| 532 | pb_iterator_destroy(src->channel, &pi); |
|---|
| 533 | goto done; |
|---|
| 534 | } |
|---|
| 535 | pb_iterator_destroy(src->channel, &pi); |
|---|
| 536 | } |
|---|
| 537 | |
|---|
| 538 | if (channel_data_create(&cd, 1) == 0) { |
|---|
| 539 | return FALSE; |
|---|
| 540 | } |
|---|
| 541 | |
|---|
| 542 | cu = cd->elem[0]; |
|---|
| 543 | cu->data = pckt; |
|---|
| 544 | cu->data_len = pckt_len; |
|---|
| 545 | cu->pt = payload; |
|---|
| 546 | |
|---|
| 547 | src->age++; |
|---|
| 548 | done: |
|---|
| 549 | if (pb_add(src->channel, (u_char*)cd, sizeof(channel_data), playout) == FALSE) { |
|---|
| 550 | src->pdbe->duplicates++; |
|---|
| 551 | channel_data_destroy(&cd, sizeof(channel_data)); |
|---|
| 552 | } |
|---|
| 553 | |
|---|
| 554 | return TRUE; |
|---|
| 555 | } |
|---|
| 556 | |
|---|
| 557 | #ifdef SOURCE_LOG_PLAYOUT |
|---|
| 558 | |
|---|
| 559 | static FILE *psf; |
|---|
| 560 | static uint32_t t0; |
|---|
| 561 | |
|---|
| 562 | static void |
|---|
| 563 | source_close_log(void) |
|---|
| 564 | { |
|---|
| 565 | if (psf) { |
|---|
| 566 | fclose(psf); |
|---|
| 567 | psf = NULL; |
|---|
| 568 | } |
|---|
| 569 | } |
|---|
| 570 | |
|---|
| 571 | static void |
|---|
| 572 | source_playout_log(source *src, uint32_t ts, ts_t now) |
|---|
| 573 | { |
|---|
| 574 | if (psf == NULL) { |
|---|
| 575 | psf = fopen("playout.log", "w"); |
|---|
| 576 | if (psf == NULL) { |
|---|
| 577 | fprintf(stderr, "Could not open playout.log\n"); |
|---|
| 578 | } else { |
|---|
| 579 | atexit(source_close_log); |
|---|
| 580 | fprintf(psf, "# <RTP timestamp> <talkstart> <jitter> <transit> <avg transit> <last transit> <playout del> <spike_var> <arr time>\n"); |
|---|
| 581 | } |
|---|
| 582 | t0 = ts - 1000; |
|---|
| 583 | } |
|---|
| 584 | |
|---|
| 585 | fprintf(psf, "%.6f %5u %5u %5u %5u %5u %5u %5u %5u\n", |
|---|
| 586 | (ts - t0)/8000.0, |
|---|
| 587 | ts_to_ms(src->talkstart), |
|---|
| 588 | ts_to_ms(src->pdbe->jitter), |
|---|
| 589 | ts_to_ms(src->pdbe->transit), |
|---|
| 590 | ts_to_ms(src->pdbe->avg_transit), |
|---|
| 591 | ts_to_ms(src->pdbe->last_transit), |
|---|
| 592 | ts_to_ms(src->pdbe->playout), |
|---|
| 593 | ts_to_ms(src->spike_var), |
|---|
| 594 | ts_to_ms(now) |
|---|
| 595 | ); |
|---|
| 596 | } |
|---|
| 597 | |
|---|
| 598 | #endif |
|---|
| 599 | |
|---|
| 600 | static void |
|---|
| 601 | source_update_toged(source *src, int toged) |
|---|
| 602 | { |
|---|
| 603 | src->toged_mask <<= 1; |
|---|
| 604 | src->toged_mask |= toged; |
|---|
| 605 | src->toged_cont = 0; |
|---|
| 606 | if (toged == 1) { |
|---|
| 607 | int m; |
|---|
| 608 | m = src->toged_mask & 0xff; |
|---|
| 609 | while (m) { |
|---|
| 610 | src->toged_cont += (m & 1); |
|---|
| 611 | m >>= 1; |
|---|
| 612 | } |
|---|
| 613 | } |
|---|
| 614 | } |
|---|
| 615 | |
|---|
| 616 | static void |
|---|
| 617 | source_process_packets(session_t *sp, source *src, ts_t now) |
|---|
| 618 | { |
|---|
| 619 | |
|---|
| 620 | ts_t src_ts, playout, transit; |
|---|
| 621 | pdb_entry_t *e; |
|---|
| 622 | rtp_packet *p; |
|---|
| 623 | cc_id_t ccid = -1; |
|---|
| 624 | uint16_t units_per_packet = -1; |
|---|
| 625 | uint32_t delta_ts, delta_seq; |
|---|
| 626 | uint8_t codec_pt; |
|---|
| 627 | uint8_t adjust_playout; |
|---|
| 628 | |
|---|
| 629 | e = src->pdbe; |
|---|
| 630 | while(pktbuf_dequeue(src->pktbuf, &p)) { |
|---|
| 631 | adjust_playout = FALSE; |
|---|
| 632 | |
|---|
| 633 | ccid = channel_coder_get_by_payload((u_char)p->pt); |
|---|
| 634 | if (channel_verify_and_stat(ccid, (u_char)p->pt, |
|---|
| 635 | p->data, p->data_len, |
|---|
| 636 | &units_per_packet, &codec_pt) == FALSE) { |
|---|
| 637 | debug_msg("Packet discarded: packet failed channel verify.\n"); |
|---|
| 638 | xfree(p); |
|---|
| 639 | continue; |
|---|
| 640 | } |
|---|
| 641 | |
|---|
| 642 | if (e->channel_coder_id != ccid || |
|---|
| 643 | e->enc != codec_pt || |
|---|
| 644 | e->units_per_packet != units_per_packet || |
|---|
| 645 | src->packets_done == 0) { |
|---|
| 646 | |
|---|
| 647 | const codec_format_t *cf; |
|---|
| 648 | const audio_format *dev_fmt; |
|---|
| 649 | codec_id_t cid; |
|---|
| 650 | uint32_t samples_per_frame; |
|---|
| 651 | |
|---|
| 652 | cid = codec_get_by_payload(codec_pt); |
|---|
| 653 | cf = codec_get_format(cid); |
|---|
| 654 | |
|---|
| 655 | change_freq(e->clock, cf->format.sample_rate); |
|---|
| 656 | |
|---|
| 657 | e->enc = codec_pt; |
|---|
| 658 | e->units_per_packet = units_per_packet; |
|---|
| 659 | e->channel_coder_id = ccid; |
|---|
| 660 | if (src->channel_state != NULL) { |
|---|
| 661 | channel_decoder_destroy(&(src->channel_state)); |
|---|
| 662 | pb_flush(src->channel); |
|---|
| 663 | } |
|---|
| 664 | channel_decoder_create(e->channel_coder_id, &(src->channel_state)); |
|---|
| 665 | samples_per_frame = codec_get_samples_per_frame(cid); |
|---|
| 666 | debug_msg("Samples per frame %d rate %d\n", samples_per_frame, cf->format.sample_rate); |
|---|
| 667 | e->inter_pkt_gap = e->units_per_packet * (uint16_t)samples_per_frame; |
|---|
| 668 | e->frame_dur = ts_map32(cf->format.sample_rate, samples_per_frame); |
|---|
| 669 | |
|---|
| 670 | channel_describe_data(ccid, codec_pt, |
|---|
| 671 | p->data, p->data_len, |
|---|
| 672 | e->enc_fmt, e->enc_fmt_len); |
|---|
| 673 | if (sp->mbus_engine) { |
|---|
| 674 | ui_update_stats(sp, e->ssrc); |
|---|
| 675 | } |
|---|
| 676 | debug_msg("Encoding changed to %s\n", e->enc_fmt); |
|---|
| 677 | |
|---|
| 678 | dev_fmt = audio_get_ofmt(sp->audio_device); |
|---|
| 679 | source_reconfigure(src, |
|---|
| 680 | sp->converter, |
|---|
| 681 | sp->render_3d, |
|---|
| 682 | (uint16_t)dev_fmt->sample_rate, |
|---|
| 683 | (uint16_t)dev_fmt->channels); |
|---|
| 684 | adjust_playout = TRUE; |
|---|
| 685 | } |
|---|
| 686 | |
|---|
| 687 | |
|---|
| 688 | |
|---|
| 689 | |
|---|
| 690 | delta_seq = p->seq - e->last_seq; |
|---|
| 691 | delta_ts = p->ts - e->last_ts; |
|---|
| 692 | if (delta_seq * e->inter_pkt_gap != delta_ts) { |
|---|
| 693 | debug_msg("Seq no / timestamp realign (%lu * %lu != %lu)\n", delta_seq, e->inter_pkt_gap, delta_ts); |
|---|
| 694 | adjust_playout = TRUE; |
|---|
| 695 | } |
|---|
| 696 | if (p->m) { |
|---|
| 697 | adjust_playout = TRUE; |
|---|
| 698 | debug_msg("New Talkspurt: %lu\n", p->ts); |
|---|
| 699 | } |
|---|
| 700 | |
|---|
| 701 | src_ts = ts_seq32_in(&e->seq, get_freq(e->clock), p->ts); |
|---|
| 702 | transit = ts_sub(now, src_ts); |
|---|
| 703 | |
|---|
| 704 | |
|---|
| 705 | |
|---|
| 706 | |
|---|
| 707 | if (adjust_playout == FALSE) { |
|---|
| 708 | ts_t spt, delta_transit; |
|---|
| 709 | spt = ts_mul(e->playout, 2); |
|---|
| 710 | spt = ts_add(spt, spike_jump); |
|---|
| 711 | delta_transit = ts_sub(transit, e->last_transit); |
|---|
| 712 | if (ts_gt(delta_transit, spt)) { |
|---|
| 713 | |
|---|
| 714 | debug_msg("Spike\n"); |
|---|
| 715 | src->playout_mode = PLAYOUT_MODE_SPIKE; |
|---|
| 716 | src->spike_var = zero_ts; |
|---|
| 717 | e->spike_events++; |
|---|
| 718 | } else { |
|---|
| 719 | if (src->playout_mode == PLAYOUT_MODE_SPIKE) { |
|---|
| 720 | ts_t delta_var; |
|---|
| 721 | src->spike_var = ts_div(src->spike_var, 2); |
|---|
| 722 | delta_var = ts_add(ts_abs_diff(transit, e->last_transit), |
|---|
| 723 | ts_abs_diff(transit, e->last_last_transit)); |
|---|
| 724 | delta_var = ts_div(delta_var, 8); |
|---|
| 725 | src->spike_var = ts_add(src->spike_var, delta_var); |
|---|
| 726 | if (ts_gt(spike_end, src->spike_var)) { |
|---|
| 727 | debug_msg("Normal mode.\n"); |
|---|
| 728 | src->playout_mode = PLAYOUT_MODE_NORMAL; |
|---|
| 729 | } |
|---|
| 730 | } |
|---|
| 731 | } |
|---|
| 732 | } else { |
|---|
| 733 | src->playout_mode = PLAYOUT_MODE_NORMAL; |
|---|
| 734 | } |
|---|
| 735 | |
|---|
| 736 | |
|---|
| 737 | |
|---|
| 738 | |
|---|
| 739 | if (src->toged_cont >= NO_TOGED_CONT_FOR_PLAYOUT_RECALC) { |
|---|
| 740 | adjust_playout = TRUE; |
|---|
| 741 | src->toged_cont = 0; |
|---|
| 742 | debug_msg("Cont_toged\n"); |
|---|
| 743 | |
|---|
| 744 | |
|---|
| 745 | e->avg_transit = transit; |
|---|
| 746 | } |
|---|
| 747 | |
|---|
| 748 | if (adjust_playout && (ts_gt(ts_sub(now, e->last_arr), transit_reset) || (e->received < 20))) { |
|---|
| 749 | |
|---|
| 750 | |
|---|
| 751 | e->avg_transit = transit; |
|---|
| 752 | } |
|---|
| 753 | |
|---|
| 754 | |
|---|
| 755 | |
|---|
| 756 | |
|---|
| 757 | if (src->playout_mode == PLAYOUT_MODE_NORMAL) { |
|---|
| 758 | playout = playout_calc(sp, e->ssrc, transit, adjust_playout); |
|---|
| 759 | } else { |
|---|
| 760 | playout = e->playout; |
|---|
| 761 | } |
|---|
| 762 | |
|---|
| 763 | if ((p->m || src->packets_done == 0) && ts_gt(playout, e->frame_dur)) { |
|---|
| 764 | |
|---|
| 765 | |
|---|
| 766 | |
|---|
| 767 | playout = ts_sub(playout, e->frame_dur); |
|---|
| 768 | debug_msg("New ts shift XXX\n"); |
|---|
| 769 | } |
|---|
| 770 | |
|---|
| 771 | playout = ts_add(e->transit, playout); |
|---|
| 772 | playout = ts_add(src_ts, playout); |
|---|
| 773 | |
|---|
| 774 | if (adjust_playout) { |
|---|
| 775 | if (ts_valid(src->next_played) && ts_gt(src->next_played, playout)) { |
|---|
| 776 | |
|---|
| 777 | |
|---|
| 778 | |
|---|
| 779 | ts_t overlap = ts_sub(src->next_played, playout); |
|---|
| 780 | debug_msg("Overlap %d us\n", ts_to_us(overlap)); |
|---|
| 781 | e->playout = ts_add(e->playout, overlap); |
|---|
| 782 | playout = ts_add(playout, overlap); |
|---|
| 783 | } |
|---|
| 784 | src->talkstart = playout; |
|---|
| 785 | src->post_talkstart_units = 0; |
|---|
| 786 | } else { |
|---|
| 787 | src->post_talkstart_units++; |
|---|
| 788 | } |
|---|
| 789 | |
|---|
| 790 | if (src->packets_done == 0) { |
|---|
| 791 | |
|---|
| 792 | |
|---|
| 793 | src->next_played = playout; |
|---|
| 794 | } |
|---|
| 795 | |
|---|
| 796 | if (!ts_gt(now, playout)) { |
|---|
| 797 | u_char *u; |
|---|
| 798 | u = (u_char*)block_alloc(p->data_len); |
|---|
| 799 | |
|---|
| 800 | |
|---|
| 801 | memcpy(u, p->data, p->data_len); |
|---|
| 802 | if (source_process_packet(src, u, p->data_len, codec_pt, playout) == FALSE) { |
|---|
| 803 | block_free(u, (int)p->data_len); |
|---|
| 804 | } |
|---|
| 805 | source_update_toged(src, 0); |
|---|
| 806 | } else { |
|---|
| 807 | |
|---|
| 808 | |
|---|
| 809 | |
|---|
| 810 | |
|---|
| 811 | |
|---|
| 812 | |
|---|
| 813 | if (src->playout_mode == PLAYOUT_MODE_NORMAL) { |
|---|
| 814 | debug_msg("Packet late (compared to now)\n"); |
|---|
| 815 | source_update_toged(src, 1); |
|---|
| 816 | src->pdbe->jit_toged++; |
|---|
| 817 | } else { |
|---|
| 818 | |
|---|
| 819 | src->pdbe->spike_toged++; |
|---|
| 820 | } |
|---|
| 821 | } |
|---|
| 822 | |
|---|
| 823 | |
|---|
| 824 | if (e->last_seq > p->seq) { |
|---|
| 825 | e->misordered++; |
|---|
| 826 | } |
|---|
| 827 | e->last_seq = p->seq; |
|---|
| 828 | e->last_ts = p->ts; |
|---|
| 829 | e->last_arr = now; |
|---|
| 830 | e->last_last_transit = e->last_transit; |
|---|
| 831 | e->last_transit = transit; |
|---|
| 832 | |
|---|
| 833 | |
|---|
| 834 | |
|---|
| 835 | |
|---|
| 836 | |
|---|
| 837 | |
|---|
| 838 | |
|---|
| 839 | #ifdef SOURCE_LOG_PLAYOUT |
|---|
| 840 | source_playout_log(src, p->ts, now); |
|---|
| 841 | #endif |
|---|
| 842 | src->packets_done++; |
|---|
| 843 | xfree(p); |
|---|
| 844 | } |
|---|
| 845 | } |
|---|
| 846 | |
|---|
| 847 | int |
|---|
| 848 | source_add_packet (source *src, |
|---|
| 849 | rtp_packet *pckt) |
|---|
| 850 | { |
|---|
| 851 | src->byte_count += pckt->data_len; |
|---|
| 852 | return pktbuf_enqueue(src->pktbuf, pckt); |
|---|
| 853 | } |
|---|
| 854 | |
|---|
| 855 | static void |
|---|
| 856 | source_update_bps(source *src, ts_t now) |
|---|
| 857 | { |
|---|
| 858 | ts_t delta; |
|---|
| 859 | if (!ts_valid(src->byte_count_start)) { |
|---|
| 860 | src->byte_count_start = now; |
|---|
| 861 | src->byte_count = 0; |
|---|
| 862 | src->bps = 0.0; |
|---|
| 863 | return; |
|---|
| 864 | } |
|---|
| 865 | |
|---|
| 866 | delta = ts_sub(now, src->byte_count_start); |
|---|
| 867 | |
|---|
| 868 | if (ts_gt(delta, bw_avg_period)) { |
|---|
| 869 | double this_est; |
|---|
| 870 | this_est = 8.0 * src->byte_count * 1000.0/ ts_to_ms(delta); |
|---|
| 871 | if (src->bps == 0.0) { |
|---|
| 872 | src->bps = this_est; |
|---|
| 873 | } else { |
|---|
| 874 | src->bps += (this_est - src->bps)/2.0; |
|---|
| 875 | } |
|---|
| 876 | src->byte_count = 0; |
|---|
| 877 | src->byte_count_start = now; |
|---|
| 878 | } |
|---|
| 879 | } |
|---|
| 880 | |
|---|
| 881 | double |
|---|
| 882 | source_get_bps(source *src) |
|---|
| 883 | { |
|---|
| 884 | return src->bps; |
|---|
| 885 | } |
|---|
| 886 | |
|---|
| 887 | static uint16_t |
|---|
| 888 | find_local_match(sample *buffer, uint16_t wstart, uint16_t wlen, uint16_t sstart, uint16_t send, uint16_t channels) |
|---|
| 889 | { |
|---|
| 890 | uint16_t i,j, i_min = sstart; |
|---|
| 891 | uint32_t score = 0, score_min = 0xffffffff; |
|---|
| 892 | |
|---|
| 893 | for (i = sstart; i < send; i += channels) { |
|---|
| 894 | score = 0; |
|---|
| 895 | for(j = 0; j < wlen; j += channels) { |
|---|
| 896 | score += abs(buffer[wstart + j] - buffer[i + j]); |
|---|
| 897 | } |
|---|
| 898 | if (score < score_min) { |
|---|
| 899 | score_min = score; |
|---|
| 900 | i_min = i; |
|---|
| 901 | } |
|---|
| 902 | } |
|---|
| 903 | |
|---|
| 904 | if (score_min / wlen < MATCH_THRESHOLD) { |
|---|
| 905 | return i_min; |
|---|
| 906 | } |
|---|
| 907 | return 0; |
|---|
| 908 | } |
|---|
| 909 | |
|---|
| 910 | |
|---|
| 911 | |
|---|
| 912 | |
|---|
| 913 | |
|---|
| 914 | static ts_t |
|---|
| 915 | recommend_skew_adjust_dur(media_data *md, int drop) |
|---|
| 916 | { |
|---|
| 917 | uint16_t matchlen; |
|---|
| 918 | uint16_t rate, channels, samples; |
|---|
| 919 | sample *buffer; |
|---|
| 920 | int16_t i; |
|---|
| 921 | |
|---|
| 922 | i = md->nrep - 1; |
|---|
| 923 | while(i >= 0) { |
|---|
| 924 | if (codec_get_native_info(md->rep[i]->id, &rate, &channels)) { |
|---|
| 925 | break; |
|---|
| 926 | } |
|---|
| 927 | i--; |
|---|
| 928 | } |
|---|
| 929 | assert(i != -1); |
|---|
| 930 | |
|---|
| 931 | buffer = (sample*)md->rep[i]->data; |
|---|
| 932 | samples = md->rep[i]->data_len / (sizeof(sample) * channels); |
|---|
| 933 | if (drop) { |
|---|
| 934 | |
|---|
| 935 | |
|---|
| 936 | matchlen = find_local_match((sample*)md->rep[i]->data, |
|---|
| 937 | 0, |
|---|
| 938 | SOURCE_COMPARE_WINDOW_SIZE * channels, |
|---|
| 939 | SOURCE_COMPARE_WINDOW_SIZE * channels, |
|---|
| 940 | (samples - SOURCE_COMPARE_WINDOW_SIZE) * channels, |
|---|
| 941 | channels); |
|---|
| 942 | } else { |
|---|
| 943 | |
|---|
| 944 | |
|---|
| 945 | matchlen = find_local_match((sample*)md->rep[i]->data, |
|---|
| 946 | (samples - SOURCE_COMPARE_WINDOW_SIZE) * channels, |
|---|
| 947 | SOURCE_COMPARE_WINDOW_SIZE * channels, |
|---|
| 948 | 0, |
|---|
| 949 | (samples - 2 * SOURCE_COMPARE_WINDOW_SIZE) * channels, |
|---|
| 950 | channels); |
|---|
| 951 | |
|---|
| 952 | matchlen = samples - matchlen - SOURCE_COMPARE_WINDOW_SIZE; |
|---|
| 953 | } |
|---|
| 954 | |
|---|
| 955 | return ts_map32(rate, matchlen); |
|---|
| 956 | } |
|---|
| 957 | |
|---|
| 958 | #define SOURCE_MERGE_LEN_SAMPLES 5 |
|---|
| 959 | |
|---|
| 960 | static void |
|---|
| 961 | conceal_dropped_samples(media_data *md, ts_t drop_dur) |
|---|
| 962 | { |
|---|
| 963 | |
|---|
| 964 | |
|---|
| 965 | |
|---|
| 966 | uint32_t drop_samples; |
|---|
| 967 | uint16_t rate, channels; |
|---|
| 968 | int32_t tmp, a, b, i, merge_len; |
|---|
| 969 | sample *new_start, *old_start; |
|---|
| 970 | |
|---|
| 971 | for (i = md->nrep - 1; i >= 0; i--) { |
|---|
| 972 | if (codec_get_native_info(md->rep[i]->id, &rate, &channels)) { |
|---|
| 973 | break; |
|---|
| 974 | } |
|---|
| 975 | } |
|---|
| 976 | |
|---|
| 977 | assert(i != -1); |
|---|
| 978 | |
|---|
| 979 | drop_dur = ts_convert(rate, drop_dur); |
|---|
| 980 | drop_samples = channels * drop_dur.ticks; |
|---|
| 981 | |
|---|
| 982 | |
|---|
| 983 | new_start = (sample*)md->rep[i]->data + drop_samples; |
|---|
| 984 | old_start = (sample*)md->rep[i]->data; |
|---|
| 985 | |
|---|
| 986 | merge_len = SOURCE_MERGE_LEN_SAMPLES * channels; |
|---|
| 987 | for (i = 0; i < merge_len; i++) { |
|---|
| 988 | a = (merge_len - i) * old_start[i]; |
|---|
| 989 | b = i * new_start[i]; |
|---|
| 990 | tmp = (a + b) / merge_len; |
|---|
| 991 | new_start[i] = (sample)tmp; |
|---|
| 992 | } |
|---|
| 993 | } |
|---|
| 994 | |
|---|
| 995 | |
|---|
| 996 | |
|---|
| 997 | |
|---|
| 998 | |
|---|
| 999 | static void |
|---|
| 1000 | conceal_inserted_samples(media_data *omd, media_data *imd, ts_t insert_dur) |
|---|
| 1001 | { |
|---|
| 1002 | uint16_t rate, channels; |
|---|
| 1003 | int32_t tmp, a, b, i, merge_len; |
|---|
| 1004 | sample *dst, *src; |
|---|
| 1005 | |
|---|
| 1006 | assert(omd != NULL); |
|---|
| 1007 | assert(imd != NULL); |
|---|
| 1008 | |
|---|
| 1009 | for (i = omd->nrep - 1; i >= 0; i--) { |
|---|
| 1010 | if (codec_get_native_info(omd->rep[i]->id, &rate, &channels)) { |
|---|
| 1011 | break; |
|---|
| 1012 | } |
|---|
| 1013 | } |
|---|
| 1014 | assert(i >= 0); |
|---|
| 1015 | merge_len = SOURCE_MERGE_LEN_SAMPLES * channels; |
|---|
| 1016 | a = omd->rep[i]->data_len / sizeof(sample) * channels - merge_len; |
|---|
| 1017 | dst = (sample*)omd->rep[i]->data + a; |
|---|
| 1018 | |
|---|
| 1019 | for (i = imd->nrep - 1; i >= 0; i--) { |
|---|
| 1020 | if (codec_get_native_info(imd->rep[i]->id, &rate, &channels)) { |
|---|
| 1021 | break; |
|---|
| 1022 | } |
|---|
| 1023 | } |
|---|
| 1024 | assert(i >= 0); |
|---|
| 1025 | b = insert_dur.ticks * channels; |
|---|
| 1026 | src = (sample*)imd->rep[i]->data + b; |
|---|
| 1027 | |
|---|
| 1028 | for(i = 0; i < merge_len; i++) { |
|---|
| 1029 | a = (merge_len - i) * dst[i]; |
|---|
| 1030 | b = i * src[i]; |
|---|
| 1031 | tmp = (a + b) / merge_len; |
|---|
| 1032 | dst[i] = (sample)tmp; |
|---|
| 1033 | } |
|---|
| 1034 | |
|---|
| 1035 | UNUSED(tmp); |
|---|
| 1036 | } |
|---|
| 1037 | |
|---|
| 1038 | |
|---|
| 1039 | |
|---|
| 1040 | |
|---|
| 1041 | |
|---|
| 1042 | int |
|---|
| 1043 | source_check_buffering(source *src) |
|---|
| 1044 | { |
|---|
| 1045 | ts_t actual, desired, diff; |
|---|
| 1046 | |
|---|
| 1047 | if (src->post_talkstart_units < 20) { |
|---|
| 1048 | |
|---|
| 1049 | |
|---|
| 1050 | return FALSE; |
|---|
| 1051 | } |
|---|
| 1052 | |
|---|
| 1053 | actual = source_get_audio_buffered(src); |
|---|
| 1054 | desired = source_get_playout_delay(src); |
|---|
| 1055 | diff = ts_abs_diff(actual, desired); |
|---|
| 1056 | |
|---|
| 1057 | if (ts_gt(actual, desired) && ts_gt(diff, skew_thresh)) { |
|---|
| 1058 | src->skew_adjust = diff; |
|---|
| 1059 | |
|---|
| 1060 | src->skew = SOURCE_SKEW_FAST; |
|---|
| 1061 | src->skew_cnt++; |
|---|
| 1062 | return TRUE; |
|---|
| 1063 | } else if (ts_gt(desired, actual)) { |
|---|
| 1064 | |
|---|
| 1065 | |
|---|
| 1066 | |
|---|
| 1067 | |
|---|
| 1068 | src->skew_adjust = diff; |
|---|
| 1069 | src->skew = SOURCE_SKEW_SLOW; |
|---|
| 1070 | return TRUE; |
|---|
| 1071 | } |
|---|
| 1072 | src->skew = SOURCE_SKEW_NONE; |
|---|
| 1073 | src->skew_adjust = zero_ts; |
|---|
| 1074 | return FALSE; |
|---|
| 1075 | } |
|---|
| 1076 | |
|---|
| 1077 | |
|---|
| 1078 | |
|---|
| 1079 | |
|---|
| 1080 | |
|---|
| 1081 | |
|---|
| 1082 | |
|---|
| 1083 | |
|---|
| 1084 | |
|---|
| 1085 | static skew_t |
|---|
| 1086 | source_skew_adapt(source *src, media_data *md, ts_t playout) |
|---|
| 1087 | { |
|---|
| 1088 | uint32_t i = 0, e = 0, samples = 0; |
|---|
| 1089 | uint16_t rate, channels; |
|---|
| 1090 | ts_t adjustment, frame_dur; |
|---|
| 1091 | |
|---|
| 1092 | assert(src); |
|---|
| 1093 | assert(md); |
|---|
| 1094 | assert(src->skew != SOURCE_SKEW_NONE); |
|---|
| 1095 | |
|---|
| 1096 | for(i = 0; i < md->nrep; i++) { |
|---|
| 1097 | if (codec_get_native_info(md->rep[i]->id, &rate, &channels)) { |
|---|
| 1098 | samples = md->rep[i]->data_len / (channels * sizeof(sample)); |
|---|
| 1099 | e = avg_audio_energy((sample*)md->rep[i]->data, samples * channels, channels); |
|---|
| 1100 | src->mean_energy = (15 * src->mean_energy + e)/16; |
|---|
| 1101 | frame_dur = ts_map32(rate, samples); |
|---|
| 1102 | break; |
|---|
| 1103 | } |
|---|
| 1104 | } |
|---|
| 1105 | |
|---|
| 1106 | if (i == md->nrep) { |
|---|
| 1107 | |
|---|
| 1108 | |
|---|
| 1109 | return SOURCE_SKEW_NONE; |
|---|
| 1110 | } |
|---|
| 1111 | |
|---|
| 1112 | |
|---|
| 1113 | |
|---|
| 1114 | |
|---|
| 1115 | |
|---|
| 1116 | |
|---|
| 1117 | if (src->skew == SOURCE_SKEW_FAST && src->skew_cnt > 3) { |
|---|
| 1118 | |
|---|
| 1119 | |
|---|
| 1120 | |
|---|
| 1121 | |
|---|
| 1122 | |
|---|
| 1123 | if (ts_gt(skew_limit, src->skew_adjust)) { |
|---|
| 1124 | adjustment = recommend_skew_adjust_dur(md, TRUE); |
|---|
| 1125 | } else { |
|---|
| 1126 | |
|---|
| 1127 | |
|---|
| 1128 | |
|---|
| 1129 | debug_msg("Dropping Frame\n"); |
|---|
| 1130 | adjustment = ts_div(src->pdbe->frame_dur, 2); |
|---|
| 1131 | } |
|---|
| 1132 | |
|---|
| 1133 | if (ts_gt(adjustment, src->skew_adjust) || adjustment.ticks == 0) { |
|---|
| 1134 | |
|---|
| 1135 | |
|---|
| 1136 | |
|---|
| 1137 | return SOURCE_SKEW_NONE; |
|---|
| 1138 | } |
|---|
| 1139 | debug_msg("dropping %d / %d samples\n", adjustment.ticks, src->skew_adjust.ticks); |
|---|
| 1140 | pb_shift_forward(src->media, adjustment); |
|---|
| 1141 | pb_shift_forward(src->channel, adjustment); |
|---|
| 1142 | |
|---|
| 1143 | src->samples_added += adjustment.ticks; |
|---|
| 1144 | src->pdbe->transit = ts_sub(src->pdbe->transit, adjustment); |
|---|
| 1145 | src->skew_cnt = 0; |
|---|
| 1146 | |
|---|
| 1147 | |
|---|
| 1148 | |
|---|
| 1149 | if (ts_valid(src->last_repair)) { |
|---|
| 1150 | src->last_repair = ts_sub(src->last_repair, adjustment); |
|---|
| 1151 | } |
|---|
| 1152 | |
|---|
| 1153 | src->next_played = ts_sub(src->next_played, adjustment); |
|---|
| 1154 | |
|---|
| 1155 | |
|---|
| 1156 | if (ts_gt(src->skew_adjust, adjustment)) { |
|---|
| 1157 | src->skew_adjust = ts_sub(src->skew_adjust, adjustment); |
|---|
| 1158 | } else { |
|---|
| 1159 | src->skew = SOURCE_SKEW_NONE; |
|---|
| 1160 | } |
|---|
| 1161 | |
|---|
| 1162 | conceal_dropped_samples(md, adjustment); |
|---|
| 1163 | |
|---|
| 1164 | return SOURCE_SKEW_FAST; |
|---|
| 1165 | } else if (src->skew == SOURCE_SKEW_SLOW) { |
|---|
| 1166 | media_data *fmd; |
|---|
| 1167 | ts_t insert_playout; |
|---|
| 1168 | |
|---|
| 1169 | adjustment = recommend_skew_adjust_dur(md, FALSE); |
|---|
| 1170 | if (adjustment.ticks == 152) { |
|---|
| 1171 | debug_msg("bad match\n"); |
|---|
| 1172 | return src->skew; |
|---|
| 1173 | } |
|---|
| 1174 | debug_msg("Insert %d samples\n", adjustment.ticks); |
|---|
| 1175 | pb_shift_units_back_after(src->media, playout, adjustment); |
|---|
| 1176 | pb_shift_units_back_after(src->channel, playout, adjustment); |
|---|
| 1177 | src->pdbe->transit = ts_add(src->pdbe->transit, adjustment); |
|---|
| 1178 | |
|---|
| 1179 | |
|---|
| 1180 | media_data_dup(&fmd, md); |
|---|
| 1181 | insert_playout = ts_add(playout, adjustment); |
|---|
| 1182 | |
|---|
| 1183 | if (pb_add(src->media, (u_char*)fmd, sizeof(media_data), insert_playout) == TRUE) { |
|---|
| 1184 | conceal_inserted_samples(md, fmd, adjustment); |
|---|
| 1185 | } else { |
|---|
| 1186 | debug_msg("Buffer push back: insert failed\n"); |
|---|
| 1187 | media_data_destroy(&fmd, sizeof(media_data)); |
|---|
| 1188 | } |
|---|
| 1189 | |
|---|
| 1190 | if (ts_gt(adjustment, src->skew_adjust)) { |
|---|
| 1191 | src->skew_adjust = zero_ts; |
|---|
| 1192 | } else { |
|---|
| 1193 | src->skew_adjust = ts_sub(src->skew_adjust, adjustment); |
|---|
| 1194 | } |
|---|
| 1195 | |
|---|
| 1196 | src->samples_added -= adjustment.ticks; |
|---|
| 1197 | |
|---|
| 1198 | debug_msg("Playout buffer shift back %d samples.\n", adjustment.ticks); |
|---|
| 1199 | src->skew = SOURCE_SKEW_NONE; |
|---|
| 1200 | return SOURCE_SKEW_SLOW; |
|---|
| 1201 | } |
|---|
| 1202 | |
|---|
| 1203 | return SOURCE_SKEW_NONE; |
|---|
| 1204 | } |
|---|
| 1205 | |
|---|
| 1206 | static int |
|---|
| 1207 | source_repair(source *src, |
|---|
| 1208 | repair_id_t r, |
|---|
| 1209 | ts_t fill_ts) |
|---|
| 1210 | { |
|---|
| 1211 | media_data* fill_md, *prev_md; |
|---|
| 1212 | ts_t prev_ts; |
|---|
| 1213 | uint32_t success, prev_len; |
|---|
| 1214 | |
|---|
| 1215 | |
|---|
| 1216 | if (pb_iterator_retreat(src->media_pos) == FALSE) { |
|---|
| 1217 | |
|---|
| 1218 | debug_msg("Repair not possible no previous unit!\n"); |
|---|
| 1219 | return FALSE; |
|---|
| 1220 | } |
|---|
| 1221 | |
|---|
| 1222 | pb_iterator_get_at(src->media_pos, |
|---|
| 1223 | (u_char**)&prev_md, |
|---|
| 1224 | &prev_len, |
|---|
| 1225 | &prev_ts); |
|---|
| 1226 | |
|---|
| 1227 | media_data_create(&fill_md, 1); |
|---|
| 1228 | repair(r, |
|---|
| 1229 | src->consec_lost, |
|---|
| 1230 | src->codec_states, |
|---|
| 1231 | prev_md, |
|---|
| 1232 | fill_md->rep[0]); |
|---|
| 1233 | |
|---|
| 1234 | success = pb_add(src->media, |
|---|
| 1235 | (u_char*)fill_md, |
|---|
| 1236 | sizeof(media_data), |
|---|
| 1237 | fill_ts); |
|---|
| 1238 | |
|---|
| 1239 | if (success) { |
|---|
| 1240 | src->consec_lost++; |
|---|
| 1241 | src->last_repair = fill_ts; |
|---|
| 1242 | |
|---|
| 1243 | pb_iterator_advance(src->media_pos); |
|---|
| 1244 | } else { |
|---|
| 1245 | |
|---|
| 1246 | |
|---|
| 1247 | |
|---|
| 1248 | |
|---|
| 1249 | debug_msg("Repair add data failed (%d).\n", fill_ts.ticks); |
|---|
| 1250 | media_data_destroy(&fill_md, sizeof(media_data)); |
|---|
| 1251 | src->consec_lost = 0; |
|---|
| 1252 | return FALSE; |
|---|
| 1253 | } |
|---|
| 1254 | return TRUE; |
|---|
| 1255 | } |
|---|
| 1256 | |
|---|
| 1257 | int |
|---|
| 1258 | source_process(session_t *sp, |
|---|
| 1259 | source *src, |
|---|
| 1260 | struct s_mix_info *ms, |
|---|
| 1261 | int render_3d, |
|---|
| 1262 | repair_id_t repair_type, |
|---|
| 1263 | ts_t start_ts, |
|---|
| 1264 | ts_t end_ts) |
|---|
| 1265 | { |
|---|
| 1266 | media_data *md; |
|---|
| 1267 | coded_unit *cu; |
|---|
| 1268 | codec_state *cs; |
|---|
| 1269 | uint32_t md_len; |
|---|
| 1270 | ts_t playout, step; |
|---|
| 1271 | int i, success, hold_repair = 0; |
|---|
| 1272 | uint16_t sample_rate, channels; |
|---|
| 1273 | |
|---|
| 1274 | |
|---|
| 1275 | |
|---|
| 1276 | |
|---|
| 1277 | |
|---|
| 1278 | |
|---|
| 1279 | |
|---|
| 1280 | source_process_packets(sp, src, start_ts); |
|---|
| 1281 | |
|---|
| 1282 | |
|---|
| 1283 | if (pb_node_count(src->channel)) { |
|---|
| 1284 | channel_decoder_decode(src->channel_state, |
|---|
| 1285 | src->channel, |
|---|
| 1286 | src->media, |
|---|
| 1287 | end_ts); |
|---|
| 1288 | } |
|---|
| 1289 | |
|---|
| 1290 | while (ts_gt(end_ts, src->next_played) && |
|---|
| 1291 | pb_iterator_advance(src->media_pos)) { |
|---|
| 1292 | pb_iterator_get_at(src->media_pos, |
|---|
| 1293 | (u_char**)&md, |
|---|
| 1294 | &md_len, |
|---|
| 1295 | &playout); |
|---|
| 1296 | assert(md != NULL); |
|---|
| 1297 | assert(md_len == sizeof(media_data)); |
|---|
| 1298 | |
|---|
| 1299 | |
|---|
| 1300 | |
|---|
| 1301 | |
|---|
| 1302 | |
|---|
| 1303 | |
|---|
| 1304 | |
|---|
| 1305 | |
|---|
| 1306 | |
|---|
| 1307 | |
|---|
| 1308 | |
|---|
| 1309 | if (ts_gt(playout, src->next_played) && |
|---|
| 1310 | ((ts_gt(src->next_played, src->talkstart) && ts_gt(playout, src->talkstart)) || src->post_talkstart_units > 100) && |
|---|
| 1311 | hold_repair == 0) { |
|---|
| 1312 | |
|---|
| 1313 | |
|---|
| 1314 | if (source_repair(src, repair_type, src->next_played) == TRUE) { |
|---|
| 1315 | debug_msg("Repair % 2d got % 6d exp % 6d talks % 6d\n", |
|---|
| 1316 | src->consec_lost, |
|---|
| 1317 | playout.ticks, |
|---|
| 1318 | src->next_played.ticks, |
|---|
| 1319 | src->talkstart.ticks); |
|---|
| 1320 | success = pb_iterator_get_at(src->media_pos, |
|---|
| 1321 | (u_char**)&md, |
|---|
| 1322 | &md_len, |
|---|
| 1323 | &playout); |
|---|
| 1324 | assert(success); |
|---|
| 1325 | assert(ts_eq(playout, src->next_played)); |
|---|
| 1326 | } else { |
|---|
| 1327 | |
|---|
| 1328 | |
|---|
| 1329 | debug_msg("Repair failed unexpectedly\n"); |
|---|
| 1330 | hold_repair += 2; |
|---|
| 1331 | } |
|---|
| 1332 | } else { |
|---|
| 1333 | if (hold_repair > 0) { |
|---|
| 1334 | hold_repair --; |
|---|
| 1335 | } |
|---|
| 1336 | src->consec_lost = 0; |
|---|
| 1337 | } |
|---|
| 1338 | |
|---|
| 1339 | if (ts_gt(playout, end_ts)) { |
|---|
| 1340 | |
|---|
| 1341 | pb_iterator_retreat(src->media_pos); |
|---|
| 1342 | break; |
|---|
| 1343 | } |
|---|
| 1344 | |
|---|
| 1345 | for(i = 0; i < md->nrep; i++) { |
|---|
| 1346 | if (codec_is_native_coding(md->rep[i]->id)) { |
|---|
| 1347 | break; |
|---|
| 1348 | } |
|---|
| 1349 | } |
|---|
| 1350 | |
|---|
| 1351 | if (i == md->nrep) { |
|---|
| 1352 | |
|---|
| 1353 | |
|---|
| 1354 | |
|---|
| 1355 | #ifdef DEBUG |
|---|
| 1356 | for(i = 0; i < md->nrep; i++) { |
|---|
| 1357 | |
|---|
| 1358 | |
|---|
| 1359 | |
|---|
| 1360 | assert(md->rep[i] != NULL); |
|---|
| 1361 | assert(codec_id_is_valid(md->rep[i]->id)); |
|---|
| 1362 | assert(codec_is_native_coding(md->rep[i]->id) == FALSE); |
|---|
| 1363 | } |
|---|
| 1364 | #endif |
|---|
| 1365 | cu = (coded_unit*)block_alloc(sizeof(coded_unit)); |
|---|
| 1366 | |
|---|
| 1367 | assert(cu != NULL); |
|---|
| 1368 | memset(cu, 0, sizeof(coded_unit)); |
|---|
| 1369 | cs = codec_state_store_get(src->codec_states, md->rep[0]->id); |
|---|
| 1370 | codec_decode(cs, md->rep[0], cu); |
|---|
| 1371 | assert(md->rep[md->nrep] == NULL); |
|---|
| 1372 | md->rep[md->nrep] = cu; |
|---|
| 1373 | md->nrep++; |
|---|
| 1374 | } |
|---|
| 1375 | |
|---|
| 1376 | if (render_3d && src->pdbe->render_3D_data) { |
|---|
| 1377 | |
|---|
| 1378 | coded_unit *decoded, *render; |
|---|
| 1379 | decoded = md->rep[md->nrep - 1]; |
|---|
| 1380 | assert(codec_is_native_coding(decoded->id)); |
|---|
| 1381 | |
|---|
| 1382 | render = (coded_unit*)block_alloc(sizeof(coded_unit)); |
|---|
| 1383 | memset(render, 0, sizeof(coded_unit)); |
|---|
| 1384 | |
|---|
| 1385 | render_3D(src->pdbe->render_3D_data,decoded,render); |
|---|
| 1386 | assert(md->rep[md->nrep] == NULL); |
|---|
| 1387 | md->rep[md->nrep] = render; |
|---|
| 1388 | md->nrep++; |
|---|
| 1389 | } |
|---|
| 1390 | |
|---|
| 1391 | if (src->converter) { |
|---|
| 1392 | |
|---|
| 1393 | coded_unit *decoded, *render; |
|---|
| 1394 | decoded = md->rep[md->nrep - 1]; |
|---|
| 1395 | assert(codec_is_native_coding(decoded->id)); |
|---|
| 1396 | |
|---|
| 1397 | render = (coded_unit*)block_alloc(sizeof(coded_unit)); |
|---|
| 1398 | memset(render, 0, sizeof(coded_unit)); |
|---|
| 1399 | converter_process(src->converter, |
|---|
| 1400 | decoded, |
|---|
| 1401 | render); |
|---|
| 1402 | assert(md->rep[md->nrep] == NULL); |
|---|
| 1403 | md->rep[md->nrep] = render; |
|---|
| 1404 | md->nrep++; |
|---|
| 1405 | } |
|---|
| 1406 | |
|---|
| 1407 | if (src->skew != SOURCE_SKEW_NONE && |
|---|
| 1408 | source_skew_adapt(src, md, playout) != SOURCE_SKEW_NONE) { |
|---|
| 1409 | |
|---|
| 1410 | |
|---|
| 1411 | |
|---|
| 1412 | pb_iterator_get_at(src->media_pos, |
|---|
| 1413 | (u_char**)&md, |
|---|
| 1414 | &md_len, |
|---|
| 1415 | &playout); |
|---|
| 1416 | assert(md != NULL); |
|---|
| 1417 | assert(md_len == sizeof(media_data)); |
|---|
| 1418 | } |
|---|
| 1419 | |
|---|
| 1420 | if (src->pdbe->gain != 1.0 && codec_is_native_coding(md->rep[md->nrep - 1]->id)) { |
|---|
| 1421 | audio_scale_buffer((sample*)md->rep[md->nrep - 1]->data, |
|---|
| 1422 | md->rep[md->nrep - 1]->data_len / sizeof(sample), |
|---|
| 1423 | src->pdbe->gain); |
|---|
| 1424 | } |
|---|
| 1425 | |
|---|
| 1426 | assert(codec_is_native_coding(md->rep[md->nrep - 1]->id)); |
|---|
| 1427 | codec_get_native_info(md->rep[md->nrep - 1]->id, &sample_rate, &channels); |
|---|
| 1428 | step = ts_map32(sample_rate, md->rep[md->nrep - 1]->data_len / (channels * sizeof(sample))); |
|---|
| 1429 | src->next_played = ts_add(playout, step); |
|---|
| 1430 | src->samples_played += md->rep[md->nrep - 1]->data_len / (channels * sizeof(sample)); |
|---|
| 1431 | |
|---|
| 1432 | if (mix_process(ms, src->pdbe, md->rep[md->nrep - 1], playout) == FALSE) { |
|---|
| 1433 | |
|---|
| 1434 | |
|---|
| 1435 | |
|---|
| 1436 | |
|---|
| 1437 | |
|---|
| 1438 | |
|---|
| 1439 | |
|---|
| 1440 | pb_flush(src->media); |
|---|
| 1441 | pb_flush(src->channel); |
|---|
| 1442 | } |
|---|
| 1443 | } |
|---|
| 1444 | |
|---|
| 1445 | source_update_bps(src, start_ts); |
|---|
| 1446 | |
|---|
| 1447 | UNUSED(i); |
|---|
| 1448 | |
|---|
| 1449 | return TRUE; |
|---|
| 1450 | } |
|---|
| 1451 | |
|---|
| 1452 | int |
|---|
| 1453 | source_audit(source *src) |
|---|
| 1454 | { |
|---|
| 1455 | if (src->age != 0) { |
|---|
| 1456 | |
|---|
| 1457 | pb_iterator_audit(src->media_pos, history_ts); |
|---|
| 1458 | return TRUE; |
|---|
| 1459 | } |
|---|
| 1460 | return FALSE; |
|---|
| 1461 | } |
|---|
| 1462 | |
|---|
| 1463 | ts_t |
|---|
| 1464 | source_get_audio_buffered (source *src) |
|---|
| 1465 | { |
|---|
| 1466 | |
|---|
| 1467 | |
|---|
| 1468 | ts_t delta; |
|---|
| 1469 | delta = ts_sub(src->pdbe->transit, src->pdbe->avg_transit); |
|---|
| 1470 | return ts_add(src->pdbe->playout, delta); |
|---|
| 1471 | } |
|---|
| 1472 | |
|---|
| 1473 | ts_t |
|---|
| 1474 | source_get_playout_delay (source *src) |
|---|
| 1475 | { |
|---|
| 1476 | return src->pdbe->playout; |
|---|
| 1477 | } |
|---|
| 1478 | |
|---|
| 1479 | int |
|---|
| 1480 | source_relevant(source *src, ts_t now) |
|---|
| 1481 | { |
|---|
| 1482 | assert(src); |
|---|
| 1483 | |
|---|
| 1484 | if (pb_relevant(src->media, now) || pb_relevant(src->channel, now) || src->age < 50) { |
|---|
| 1485 | return TRUE; |
|---|
| 1486 | } if (ts_valid(src->next_played)) { |
|---|
| 1487 | |
|---|
| 1488 | ts_t quiet; |
|---|
| 1489 | quiet = ts_sub(now, src->next_played); |
|---|
| 1490 | if (ts_gt(keep_source_ts, quiet)) { |
|---|
| 1491 | return TRUE; |
|---|
| 1492 | } |
|---|
| 1493 | } |
|---|
| 1494 | return FALSE; |
|---|
| 1495 | } |
|---|
| 1496 | |
|---|
| 1497 | struct s_pb* |
|---|
| 1498 | source_get_decoded_buffer(source *src) |
|---|
| 1499 | { |
|---|
| 1500 | return src->media; |
|---|
| 1501 | } |
|---|
| 1502 | |
|---|
| 1503 | uint32_t |
|---|
| 1504 | source_get_ssrc(source *src) |
|---|
| 1505 | { |
|---|
| 1506 | return src->pdbe->ssrc; |
|---|
| 1507 | } |
|---|
| 1508 | |
|---|
| 1509 | double |
|---|
| 1510 | source_get_skew_rate(source *src) |
|---|
| 1511 | { |
|---|
| 1512 | if (src->samples_played) { |
|---|
| 1513 | double r = (double)(src->samples_played + src->samples_added) / (double)src->samples_played; |
|---|
| 1514 | return r; |
|---|
| 1515 | } |
|---|
| 1516 | return 1.0; |
|---|
| 1517 | } |
|---|