static int sanity_check_payloads(void) { uint32_t i, j, n_codecs, n_channels; codec_id_t cid; const codec_format_t *cf = NULL; const cc_details_t *ccd = NULL; cc_id_t ccid; u_char pt; n_codecs = codec_get_number_of_codecs(); n_channels = channel_get_coder_count(); for(i = 0; i < n_codecs; i++) { cid = codec_get_codec_number(i); cf = codec_get_format(cid); pt = codec_get_payload(cid); if (pt != CODEC_PAYLOAD_DYNAMIC) { ccid = channel_coder_get_by_payload(pt); for(j = 0; j < n_channels; j++) { ccd = channel_get_coder_details(j); if (ccd == channel_get_null_coder()) { continue; } if (ccd->descriptor == ccid) { debug_msg("clash with %s %s payload (%d)\n", cf->long_name, ccd->name, pt); return FALSE; } } } else { /* codec is not mapped into codec space so ignore */ } } return TRUE; }
static void vanilla_encoder_output(ve_state *ve, struct s_pb *out) { uint32_t i, used; channel_data *cd; /* We have state for first unit and data for all others */ channel_data_create(&cd, ve->nelem + 1); /* Fill in payload */ cd->elem[0]->pt = codec_get_payload(ve->codec_id); used = 0; /* Get state for first unit if there */ if (ve->elem[0]->rep[0]->state) { cd->elem[0]->data = ve->elem[0]->rep[0]->state; cd->elem[0]->data_len = ve->elem[0]->rep[0]->state_len; ve->elem[0]->rep[0]->state = NULL; ve->elem[0]->rep[0]->state_len = 0; used++; } /* Transfer coded data to channel_data */ for(i = 0; i < ve->nelem; i++) { cd->elem[used]->data = ve->elem[i]->rep[0]->data; cd->elem[used]->data_len = ve->elem[i]->rep[0]->data_len; ve->elem[i]->rep[0]->data = NULL; ve->elem[i]->rep[0]->data_len = 0; used++; media_data_destroy(&ve->elem[i], sizeof(media_data)); } ve->nelem = 0; assert(used <= cd->nelem); pb_add(out, (u_char*)cd, sizeof(channel_data), ve->playout); }
/* Adds header to next free slot in channel_data */ static void add_hdr(channel_unit *chu, int hdr_type, codec_id_t cid, uint32_t uo, uint32_t len) { uint32_t so; /* sample time offset */ u_char pt; assert(chu != NULL); assert(chu->data == NULL); pt = codec_get_payload(cid); assert(payload_is_valid(pt)); so = codec_get_samples_per_frame(cid) * uo; assert(so <= RED_MAX_OFFSET); assert(len <= RED_MAX_LEN ); if (hdr_type == RED_EXTRA) { uint32_t *h; h = (uint32_t*)block_alloc(4); RED_HDR32_INIT(*h); RED_HDR32_SET_PT(*h, (uint32_t)pt); RED_HDR32_SET_OFF(*h, so); RED_HDR32_SET_LEN(*h, len); *h = htonl(*h); chu->data = (u_char*)h; chu->data_len = sizeof(*h); } else { u_char *h; assert(hdr_type == RED_PRIMARY); h = (u_char*)block_alloc(1); RED_HDR8_INIT(*h); RED_HDR8_SET_PT(*h, pt); chu->data = h; chu->data_len = sizeof(*h); } }
int audio_device_reconfigure(session_t *sp) { audio_config prev_config, *curr_config, *new_config; audio_port_t iport = 0, oport = 0; int change_req; assert(sp->new_config != NULL); new_config = sp->new_config; change_req = FALSE; if (new_config->device == 0) { /* No request to change audio device */ new_config->device = sp->audio_device; } else if (new_config->device != sp->audio_device) { /* Request to change device */ change_req = TRUE; debug_msg("Change device requested.\n"); } if (sp->audio_device) { iport = audio_get_iport(sp->audio_device); oport = audio_get_oport(sp->audio_device); } if (new_config->primary == 0) { /* No request to change primary encoding */ new_config->primary = codec_get_by_payload(sp->encodings[0]); } else if (codec_audio_formats_compatible(new_config->primary, codec_get_by_payload(sp->encodings[0])) == FALSE) { /* Request to change primary and format incompatible so * device needs rejigging */ change_req = TRUE; debug_msg("Change primary requested.\n"); } else { /* Request to change primary to compatible coding. */ sp->encodings[0] = codec_get_payload(new_config->primary); } if (new_config->render_3d == -1) { /* No request to change 3d rendering */ new_config->render_3d = sp->render_3d; } else if (new_config->render_3d != sp->render_3d) { change_req = TRUE; debug_msg("Change 3d rendering enabled requested.\n"); } if (change_req) { /* Store current config in case it reconfig attempt fails */ prev_config.device = sp->audio_device; prev_config.primary = codec_get_by_payload(sp->encodings[0]); prev_config.render_3d = sp->render_3d; if (sp->audio_device) { audio_device_release(sp, sp->audio_device); } if (audio_device_attempt_config(sp, new_config)) { /* New config acceptable */ curr_config = new_config; } else if (audio_device_attempt_config(sp, &prev_config)) { /* else attempt to fallback to previous config */ curr_config = &prev_config; debug_msg("Fellback to old dev config\n"); } else { /* Fallback to guaranteed config - something * went badly wrong */ ac_destroy(&new_config); audio_device_get_safe_config(&new_config); assert(new_config); if (audio_device_attempt_config(sp, new_config) == FALSE) { /* should never get here */ abort(); } curr_config = new_config; debug_msg("Fell back to safe config\n"); } debug_msg("0x%08x 0x%08x\n", prev_config.device, curr_config->device); if (prev_config.device == curr_config->device) { debug_msg("Restoring ports\n"); audio_set_iport(curr_config->device, iport); audio_set_oport(curr_config->device, oport); } else { const audio_port_details_t *papd; /* Ports will be squiffy */ papd = audio_get_iport_details(curr_config->device, 0); audio_set_iport(curr_config->device, papd->port); papd = audio_get_oport_details(curr_config->device, 0); audio_set_oport(curr_config->device, papd->port); } audio_loopback(curr_config->device, sp->loopback_gain); sp->audio_device = curr_config->device; sp->encodings[0] = codec_get_payload(curr_config->primary); /* If using redundancy check it is still relevent */ if (sp->num_encodings > 1 && !codec_audio_formats_compatible(curr_config->primary, codec_get_by_payload(sp->encodings[1]))) { const cc_details_t *ccd; channel_encoder_destroy(&sp->channel_coder); ccd = channel_get_null_coder(); channel_encoder_create(ccd->descriptor, &sp->channel_coder); sp->num_encodings = 1; } sp->render_3d = curr_config->render_3d; } else { debug_msg("audio device reconfigure - nothing to do.\n"); if (tx_is_sending(sp->tb)) { tx_stop(sp->tb); tx_start(sp->tb); } } tx_igain_update(sp->tb); ac_destroy(&sp->new_config); return change_req; }
static void layered_encoder_output(lay_state *le, struct s_pb *out) { uint32_t i, used; channel_data *cd; uint8_t j; uint16_t cd_len[LAY_MAX_LAYERS], markers[LAY_MAX_LAYERS]; coded_unit *lu; /* We have state for first unit and data for all others */ channel_data_create(&cd, (le->nelem + 2)*(le->n_layers)); /* Fill in payload */ cd->elem[0]->pt = codec_get_payload(le->codec_id); used = 0; /* leave space for headers */ used += le->n_layers; /* Get state for first unit if there */ if (le->elem[0]->rep[0]->state) { for(j=0; j<le->n_layers; j++) { cd->elem[used]->data_len = le->elem[0]->rep[0]->state_len; //SV-XXX cd->elem[used]->data = (char *)block_alloc(le->elem[0]->rep[0]->state_len); cd->elem[used]->data = (unsigned char*)block_alloc(le->elem[0]->rep[0]->state_len); memcpy(cd->elem[used]->data, le->elem[0]->rep[0]->state, le->elem[0]->rep[0]->state_len); used++; } } for(j = 0; j < le->n_layers; j++) { cd_len[j] = 0; } lu = (coded_unit*)block_alloc(sizeof(coded_unit)); /* Transfer coded data to channel_data */ for(i = 0; i < le->nelem; i++) { for(j = 0; j < le->n_layers; j++) { codec_get_layer(le->codec_id, le->elem[i]->rep[0], j, markers, lu); cd->elem[used]->data_len = lu->data_len; //SV-XXX cd->elem[used]->data = (char*)block_alloc(lu->data_len); cd->elem[used]->data = (unsigned char*)block_alloc(lu->data_len); memcpy(cd->elem[used]->data, lu->data, lu->data_len); used++; if(i==0) cd_len[j] = (uint16_t)lu->data_len; if(lu->state_len) { block_free(lu->state, lu->state_len); lu->state = NULL; lu->state_len = 0; } if(lu->data_len) { block_free(lu->data, lu->data_len); lu->data = NULL; lu->data_len = 0; } } block_free(le->elem[i]->rep[0]->data, le->elem[i]->rep[0]->data_len); le->elem[i]->rep[0]->data = NULL; le->elem[i]->rep[0]->data_len = 0; media_data_destroy(&le->elem[i], sizeof(media_data)); } le->nelem = 0; assert(lu->data_len == 0); block_free(lu, sizeof(coded_unit)); for(j=0; j<le->n_layers; j++) { add_hdr(cd->elem[j], cd->elem[0]->pt, markers[j], cd_len[j]); } assert(used <= cd->nelem); pb_add(out, (u_char*)cd, sizeof(channel_data), le->playout); }
void session_init(session_t *sp, int index, int mode) { codec_id_t cid; const codec_format_t *cf = NULL; const converter_details_t *conv = NULL; const cc_details_t *ccd = NULL; uint8_t i; memset(sp, 0, sizeof(session_t)); codec_init(); sanity_check_payloads(); vu_table_init(); cid = codec_get_by_name("DVI-8K-Mono"); assert(cid); cf = codec_get_format(cid); sp->cur_ts = ts_map32(8000,0); sp->encodings[0] = codec_get_payload(cid); /* user chosen encoding for primary */ sp->num_encodings = 1; /* Number of encodings applied */ ccd = channel_get_null_coder(); channel_encoder_create(ccd->descriptor, &sp->channel_coder); conv = converter_get_details(0); sp->converter = conv->id; sp->other_session = NULL; /* Completed in main_engine.c if we're a transoder */ sp->id = index; sp->mode = mode; sp->rtp_session_count = 0; for (i = 0; i < MAX_LAYERS; i++) { sp->rx_rtp_port[i] = sp->tx_rtp_port[i] = sp->rx_rtcp_port[i] = sp->tx_rtcp_port[i] = PORT_UNINIT; sp->rtp_session[i] = NULL; } sp->rx_rtp_port[0] = 5004; /* Default ports per: */ sp->tx_rtp_port[0] = 5004; /* draft-ietf-avt-profile-new-00 */ sp->rx_rtcp_port[0] = 5005; sp->tx_rtcp_port[0] = 5005; sp->ttl = 127; sp->filter_loopback = TRUE; sp->playing_audio = TRUE; sp->lecture = FALSE; sp->auto_lecture = 0; sp->receive_audit_required = FALSE; sp->silence_detection = SILENCE_DETECTION_OFF; sp->sync_on = FALSE; sp->agc_on = FALSE; sp->ui_on = FALSE; sp->meter = TRUE; /* Powermeter operation */ sp->in_file = NULL; sp->out_file = NULL; sp->local_file_player = NULL; sp->mbus_engine_addr = NULL; sp->mbus_engine = NULL; sp->mbus_ui_addr = NULL; sp->mbus_video_addr = xstrdup("(media:video module:engine)"); sp->min_playout = 0; sp->max_playout = 1000; sp->last_depart_ts = 0; sp->loopback_gain = 0; sp->layers = 1; sp->ui_activated = FALSE; sp->encrkey = NULL; sp->logger = NULL; sp->mbus_waiting = FALSE; sp->mbus_waiting_token = NULL; sp->mbus_go = FALSE; sp->mbus_go_token = NULL; sp->magic = 0xcafebabe; /* Magic number for debugging */ source_list_create(&sp->active_sources); sp->title = "Untitled session"; strncpy(sp->asc_address[0], "127.0.0.3", MAXHOSTNAMELEN); /* Yeuch! This value should never be used! */ }