krad_transmission_t *krad_transmitter_transmission_create (krad_transmitter_t *krad_transmitter, char *name, char *content_type) { int t; t = 0; for (t = 0; t < DEFAULT_MAX_TRANSMISSIONS; t++) { if (krad_transmitter->krad_transmissions[t].active == 0) { krad_transmitter->krad_transmissions[t].active = 2; krad_transmitter->krad_transmissions[t].ready_receivers = NULL; krad_transmitter->krad_transmissions[t].ready_receiver_count = 0; krad_transmitter->krad_transmissions[t].ready = 0; krad_transmitter->krad_transmissions[t].position = 0; krad_transmitter->krad_transmissions[t].sync_point = -1; strcpy (krad_transmitter->krad_transmissions[t].sysname, name); strcpy (krad_transmitter->krad_transmissions[t].content_type, content_type); krad_transmitter->krad_transmissions[t].http_header_len = sprintf (krad_transmitter->krad_transmissions[t].http_header, "HTTP/1.0 200 OK\r\nContent-Type: %s\r\nServer: %s\r\n" "Cache-Control: no-cache\r\n\r\n", krad_transmitter->krad_transmissions[t].content_type, KRAD_TRANSMITTER_SERVER ); printk ("Krad Transmitter: http header for %s is %d bytes: %s", krad_transmitter->krad_transmissions[t].sysname, krad_transmitter->krad_transmissions[t].http_header_len, krad_transmitter->krad_transmissions[t].http_header); krad_transmitter->krad_transmissions[t].connections_efd = epoll_create (0); krad_transmitter->krad_transmissions[t].transmission_events = calloc (KRAD_TRANSMITTER_MAXEVENTS, sizeof (struct epoll_event)); krad_transmitter->krad_transmissions[t].ringbuffer = krad_ringbuffer_create (DEFAULT_RING_SIZE); if (krad_transmitter->krad_transmissions[t].ringbuffer == NULL) { failfast ("Krad Transmitter: Out of memory creating new transmission"); } krad_transmitter->krad_transmissions[t].transmission_ringbuffer = krad_ringbuffer_create (DEFAULT_RING_SIZE); if (krad_transmitter->krad_transmissions[t].transmission_ringbuffer == NULL) { failfast ("Krad Transmitter: Out of memory creating new transmission"); } krad_transmitter->krad_transmissions[t].transmission_buffer = calloc (1, DEFAULT_RING_SIZE); if (krad_transmitter->krad_transmissions[t].transmission_buffer == NULL) { failfast ("Krad Transmitter: Out of memory creating new transmission"); } pthread_create (&krad_transmitter->krad_transmissions[t].transmission_thread, NULL, krad_transmitter_transmission_thread, (void *)&krad_transmitter->krad_transmissions[t]); krad_transmitter->krad_transmissions[t].active = 1; return &krad_transmitter->krad_transmissions[t]; } } return NULL; }
void audio_encoding_unit_create (void *arg) { //krad_system_set_thread_name ("kr_audio_enc"); krad_link_t *krad_link = (krad_link_t *)arg; int c; printk ("Audio unit create"); if (krad_link->codec != VORBIS) { krad_link->au_buffer = malloc (300000); } krad_link->au_interleaved_samples = malloc (8192 * 4 * KR_MXR_MAX_CHANNELS); for (c = 0; c < krad_link->channels; c++) { krad_link->au_samples[c] = malloc (8192 * 4); krad_link->samples[c] = malloc (8192 * 4); krad_link->audio_input_ringbuffer[c] = krad_ringbuffer_create (2000000); } if (socketpair(AF_UNIX, SOCK_STREAM, 0, krad_link->socketpair)) { printk ("Krad Compositor: subunit could not create socketpair errno: %d", errno); return; } // krad_link->mixer_portgroup = kr_mixer_path_create(krad_link->krad_radio->mixer, // krad_link->sysname, KR_AOUT, 0, krad_link->channels, 0.0f, // krad_link->krad_radio->mixer->master, 0, krad_link, 0); switch (krad_link->codec) { case VORBIS: krad_link->krad_vorbis = krad_vorbis_encoder_create (krad_link->channels, krad_link->krad_radio->mixer->sample_rate, krad_link->vorbis_quality); //krad_link->au_framecnt = KRAD_DEFAULT_VORBIS_FRAME_SIZE; break; case FLAC: krad_link->krad_flac = krad_flac_encoder_create (krad_link->channels, krad_link->krad_radio->mixer->sample_rate, krad_link->flac_bit_depth); krad_link->au_framecnt = KRAD_DEFAULT_FLAC_FRAME_SIZE; break; case OPUS: krad_link->krad_opus = krad_opus_encoder_create (krad_link->channels, krad_link->krad_radio->mixer->sample_rate, krad_link->opus_bitrate, OPUS_APPLICATION_AUDIO); krad_link->au_framecnt = KRAD_MIN_OPUS_FRAME_SIZE; break; default: failfast ("Krad Link Audio Encoder: Unknown Audio Codec"); } krad_link->audio_encoder_ready = 1; }
int main (int argc, char *argv[]) { krad_v4l2_vpx_display_test_t *display_test; krad_flac_t *krad_flac; krad_dirac_t *krad_dirac; krad_vpx_encoder_t *krad_vpx_encoder; //krad_vpx_decoder_t *krad_vpx_decoder; kradgui_t *kradgui; kradebml_t *ebml; cairo_surface_t *cst; cairo_t *cr; char *filename = "/home/oneman/kode/testmedia/capture/new_testfile4.webm"; int hud_width, hud_height; int hud_stride; int hud_byte_size; unsigned char *hud_data; struct SwsContext *sws_context; int fps; int videotrack; int audiotrack; char *device; krad_v4l2_t *kradv4l2; krad_sdl_opengl_display_t *krad_opengl_display; int width; int height; int count; //int first_frame; int read_composited; unsigned char *read_screen_buffer; unsigned char *dbuffer; unsigned char *dfbuffer; krad_audio_t *audio; krad_audio_api_t audio_api; krad_vorbis_t *krad_vorbis; hud_width = 320; hud_height = 240; read_composited = 1; //first_frame = 1; width = 640; height = 480; fps = 30; count = 0; int keyframe; int bitrate; void *frame = NULL; void *vpx_packet; int packet_size; int took; int video_codec; int audio_codec; int framenum; int bytes; bitrate = 1000; video_codec = 1; audio_codec = 1; if (argc < 2) { device = DEFAULT_DEVICE; printf("no device provided, using %s , to provide a device, example: krad_v4l2_test /dev/video0\n", device); } else { device = argv[1]; printf("Using %s\n", device); } display_test = calloc(1, sizeof(krad_v4l2_vpx_display_test_t)); pthread_rwlock_init(&display_test->ebml_write_lock, NULL); pthread_rwlock_rdlock(&display_test->ebml_write_lock); //display_test->kradtimer = kradtimer_create(); display_test->input_ringbuffer[0] = krad_ringbuffer_create (RINGBUFFER_SIZE); display_test->input_ringbuffer[1] = krad_ringbuffer_create (RINGBUFFER_SIZE); display_test->samples[0] = malloc(4 * 8192); display_test->samples[1] = malloc(4 * 8192); display_test->first_block = 1; display_test->audio_codec = audio_codec; dbuffer = calloc(1, 2000000); dfbuffer = calloc(1, 2000000); audio_api = JACK; //audio = kradaudio_create("krad v4l2 vpx display test", audio_api); krad_vorbis = krad_vorbis_encoder_create(2, 44100, 0.7); krad_flac = krad_flac_encoder_create(1, 44100, 16); read_screen_buffer = calloc(1, width * height * 4 * 4 * 4 * 4); sws_context = sws_getContext ( width, height, PIX_FMT_RGB32, width, height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL); ebml = kradebml_create(); //kradebml_open_output_stream(ebml, "192.168.1.2", 9080, "/teststream.webm", "secretkode"); kradebml_open_output_file(ebml, filename); if (video_codec == 1) { kradebml_header(ebml, "webm", APPVERSION); } else { kradebml_header(ebml, "matroska", APPVERSION); } if (video_codec == 1) { videotrack = kradebml_add_video_track(ebml, "V_VP8", 30, width, height); } if (video_codec == 2) { videotrack = kradebml_add_video_track(ebml, "V_DIRAC", 10, width, height); } if (audio_codec == 1) { audiotrack = kradebml_add_audio_track(ebml, "A_VORBIS", 44100, 2, krad_vorbis->header, krad_vorbis->headerpos); } if (audio_codec == 2) { bytes = krad_flac_encoder_read_min_header(krad_flac, dfbuffer); audiotrack = kradebml_add_audio_track(ebml, "A_FLAC", 44100, 1, dfbuffer, bytes); display_test->krad_flac = krad_flac; } kradebml_write(ebml); krad_opengl_display = krad_sdl_opengl_display_create(APPVERSION, width, height, width, height); //krad_opengl_display = krad_sdl_opengl_display_create(APPVERSION, 1920, 1080, width, height); krad_vpx_encoder = krad_vpx_encoder_create(width, height, bitrate); krad_dirac = krad_dirac_encoder_create(width, height); kradgui = kradgui_create(width, height); kradgui_add_item(kradgui, REEL_TO_REEL); hud_stride = cairo_format_stride_for_width (CAIRO_FORMAT_ARGB32, hud_width); hud_byte_size = hud_stride * hud_height; hud_data = calloc (1, hud_byte_size); cst = cairo_image_surface_create_for_data (hud_data, CAIRO_FORMAT_ARGB32, hud_width, hud_height, hud_stride); krad_opengl_display->hud_width = hud_width; krad_opengl_display->hud_height = hud_height; krad_opengl_display->hud_data = hud_data; display_test->audiotrack = audiotrack; display_test->ebml = ebml; //display_test->audio = audio; display_test->krad_vorbis = krad_vorbis; display_test->kradgui = kradgui; kradv4l2 = kradv4l2_create(); kradv4l2_open(kradv4l2, device, width, height, fps); kradv4l2_start_capturing (kradv4l2); kradgui_reset_elapsed_time(kradgui); kradgui->render_timecode = 1; audio = kradaudio_create("krad v4l2 vpx display test", KINPUT, audio_api); display_test->audio = audio; pthread_create(&display_test->audio_encoding_thread, NULL, audio_encoding_thread, (void *)display_test); kradaudio_set_process_callback(audio, krad_v4l2_vpx_display_test_audio_callback, display_test); if (audio_api == JACK) { krad_jack_t *jack = (krad_jack_t *)audio->api; kradjack_connect_port(jack->jack_client, "firewire_pcm:001486af2e61ac6b_Unknown0_in", "krad v4l2 vpx display test:InputLeft"); kradjack_connect_port(jack->jack_client, "firewire_pcm:001486af2e61ac6b_Unknown0_in", "krad v4l2 vpx display test:InputRight"); } while (count < TEST_COUNT) { //kradtimer_start(display_test->kradtimer, "cycle"); cr = cairo_create(cst); kradgui->cr = cr; kradgui_render(kradgui); cairo_destroy(cr); frame = kradv4l2_read_frame_wait (kradv4l2); if (display_test->start_audio == 0) { display_test->start_audio = 1; usleep(200000); } if (video_codec == 2) { // memcpy(dfbuffer, frame, width * height + (((width * height) / 2) * 2)); } krad_vpx_convert_uyvy2yv12(krad_vpx_encoder->image, frame, width, height); ///krad_vpx_convert_frame_for_local_gl_display(krad_vpx_encoder); kradv4l2_frame_done (kradv4l2); krad_sdl_opengl_display_render(krad_opengl_display, krad_vpx_encoder->image->planes[0], krad_vpx_encoder->image->stride[0], krad_vpx_encoder->image->planes[1], krad_vpx_encoder->image->stride[1], krad_vpx_encoder->image->planes[2], krad_vpx_encoder->image->stride[2]); krad_sdl_opengl_draw_screen( krad_opengl_display ); if (read_composited) { krad_sdl_opengl_read_screen( krad_opengl_display, read_screen_buffer); rgb_to_yv12(sws_context, read_screen_buffer, width, height, krad_vpx_encoder->image->planes, krad_vpx_encoder->image->stride); vpx_img_flip(krad_vpx_encoder->image); } if (video_codec == 1) { count++; packet_size = krad_vpx_encoder_write(krad_vpx_encoder, (unsigned char **)&vpx_packet, &keyframe); //printf("packet size was %d\n", packet_size); if (read_composited) { vpx_img_flip(krad_vpx_encoder->image); } if (packet_size) { pthread_rwlock_wrlock(&display_test->ebml_write_lock); kradebml_add_video(ebml, videotrack, vpx_packet, packet_size, keyframe); //kradebml_write(ebml); pthread_rwlock_unlock (&display_test->ebml_write_lock); } } if (video_codec == 2) { // packet_size = krad_dirac_encode (krad_dirac, dfbuffer, dbuffer, &framenum, &took); packet_size = krad_dirac_encode (krad_dirac, krad_vpx_encoder->image->img_data, dbuffer, &framenum, &took); if (took == 1) { took = 0; count++; } if (packet_size > 0) { krad_dirac_packet_type(dbuffer[4]); //write(fd, buffer, len); printf("Encoded size is %d for frame %d\n", packet_size, framenum); } //printf("packet size was %d\n", packet_size); if (read_composited) { vpx_img_flip(krad_vpx_encoder->image); } keyframe = 0; if (packet_size) { pthread_rwlock_wrlock(&display_test->ebml_write_lock); kradebml_add_video(ebml, videotrack, dbuffer, packet_size, keyframe); //kradebml_write(ebml); pthread_rwlock_unlock (&display_test->ebml_write_lock); } } //kradtimer_finish_show(display_test->kradtimer); } display_test->start_audio = 0; if (video_codec == 2) { schro_encoder_end_of_stream (krad_dirac->encoder); // packet_size = krad_dirac_encode (krad_dirac, dfbuffer, dbuffer, &framenum, &took); while ((framenum != count - 1) && (framenum != 0)) { packet_size = krad_dirac_encode (krad_dirac, krad_vpx_encoder->image->img_data, dbuffer, &framenum, &took); if (packet_size > 0) { krad_dirac_packet_type(dbuffer[4]); //write(fd, buffer, len); printf("Encoded size is %d for frame %d\n", packet_size, framenum); } else { usleep(50000); } //printf("packet size was %d\n", packet_size); if (read_composited) { //vpx_img_flip(krad_vpx_encoder->image); } keyframe = 0; if (packet_size) { pthread_rwlock_wrlock(&display_test->ebml_write_lock); kradebml_add_video(ebml, videotrack, dbuffer, packet_size, keyframe); //kradebml_write(ebml); pthread_rwlock_unlock (&display_test->ebml_write_lock); } } } //display_test->start_audio = 0; printf("finish audio encoding\n"); usleep(2000000); display_test->stop_audio_encoding = 1; pthread_join(display_test->audio_encoding_thread, NULL); kradebml_destroy(ebml); kradv4l2_stop_capturing (kradv4l2); kradv4l2_close(kradv4l2); kradv4l2_destroy(kradv4l2); krad_dirac_encoder_destroy(krad_dirac); krad_vpx_encoder_destroy(krad_vpx_encoder); // must be before vorbis kradaudio_destroy(audio); krad_vorbis_encoder_destroy(krad_vorbis); krad_flac_encoder_destroy(krad_flac); free(display_test->samples[0]); free(display_test->samples[1]); krad_sdl_opengl_display_destroy(krad_opengl_display); kradgui_destroy(kradgui); free(read_screen_buffer); sws_freeContext (sws_context); krad_ringbuffer_free ( display_test->input_ringbuffer[0] ); krad_ringbuffer_free ( display_test->input_ringbuffer[1] ); pthread_rwlock_destroy(&display_test->ebml_write_lock); //kradtimer_destroy(display_test->kradtimer); free(display_test); free(dbuffer); free(dfbuffer); return 0; }
kr_streamer_t *kr_streamer_create (kr_streamer_params_t *params) { kr_streamer_t *streamer; uint32_t c; streamer = calloc (1, sizeof(kr_streamer_t)); streamer->params = params; streamer->params->channels = 2; streamer->params->sample_rate = 48000; streamer->client = kr_client_create ("krad streamer client"); if (streamer->client == NULL) { fprintf (stderr, "Could not create KR client.\n"); exit (1); } kr_connect (streamer->client, streamer->params->station); if (!kr_connected (streamer->client)) { fprintf (stderr, "Could not connect to %s krad radio daemon.\n", streamer->params->station); kr_client_destroy (&streamer->client); exit (1); } if (kr_compositor_get_info_wait (streamer->client, &streamer->width, &streamer->height, &streamer->fps_numerator, &streamer->fps_denominator) != 1) { fprintf (stderr, "Could not get compositor info!\n"); kr_client_destroy (&streamer->client); exit (1); } streamer->frame_size = streamer->width * streamer->height * 4; //FIXME streamer->videoport = kr_videoport_create (streamer->client, 0); if (streamer->videoport == NULL) { fprintf (stderr, "Could not make videoport.\n"); kr_client_destroy (&streamer->client); exit (1); } else { printf ("Working!\n"); } kr_videoport_set_callback (streamer->videoport, new_frame, streamer); for (c = 0; c < streamer->params->channels; c++) { streamer->audio_ring[c] = krad_ringbuffer_create (2200000); } if (params->file != NULL) { streamer->mkv = kr_mkv_create_file (params->file); } else { streamer->mkv = kr_mkv_create_stream (streamer->params->host, streamer->params->port, streamer->params->mount, streamer->params->password); } if (streamer->mkv == NULL) { fprintf (stderr, "failed to stream :/ \n"); exit (1); } streamer->vpx_enc = krad_vpx_encoder_create (streamer->params->width, streamer->params->height, streamer->fps_numerator, streamer->fps_denominator, streamer->params->video_bitrate); if (params->file != NULL) { krad_vpx_encoder_set_kf_max_dist (streamer->vpx_enc, 600); } kr_mkv_add_video_track (streamer->mkv, VP8, streamer->fps_numerator, streamer->fps_denominator, streamer->params->width, streamer->params->height); if (kr_mixer_get_info_wait (streamer->client, &streamer->params->sample_rate, NULL) != 1) { fprintf (stderr, "Could not get mixer info!\n"); kr_client_destroy (&streamer->client); exit (1); } streamer->vorbis_enc = krad_vorbis_encoder_create (streamer->params->channels, streamer->params->sample_rate, streamer->params->audio_quality); kr_mkv_add_audio_track (streamer->mkv, VORBIS, streamer->params->sample_rate, streamer->params->channels, streamer->vorbis_enc->hdrdata, 3 + streamer->vorbis_enc->header.sz[0] + streamer->vorbis_enc->header.sz[1] + streamer->vorbis_enc->header.sz[2]); //FIXME streamer->audioport = kr_audioport_create (streamer->client, "streamer2", 0); kr_audioport_set_callback (streamer->audioport, audioport_process, streamer); streamer->frame_ring = krad_ringbuffer_create (90 * sizeof(krad_frame_t *)); streamer->framepool = krad_framepool_create (streamer->width, streamer->height, 8); return streamer; }
krad_opus_t *krad_opus_decoder_create (unsigned char *header_data, int header_length, float output_sample_rate) { int c; krad_opus_t *krad_opus = calloc (1, sizeof(krad_opus_t)); krad_opus->output_sample_rate = output_sample_rate; krad_opus->opus_header = calloc (1, sizeof(OpusHeader)); if (opus_header_parse (header_data, header_length, krad_opus->opus_header) != 1) { failfast ("krad_opus_decoder_create problem reading opus header"); } // oops //krad_opus->input_sample_rate = krad_opus->opus_header->input_sample_rate; krad_opus->channels = krad_opus->opus_header->channels; krad_opus->interleaved_samples = malloc(16 * 8192); for (c = 0; c < krad_opus->channels; c++) { krad_opus->ringbuf[c] = krad_ringbuffer_create (RINGBUFFER_SIZE); krad_opus->resampled_ringbuf[c] = krad_ringbuffer_create (RINGBUFFER_SIZE); krad_opus->samples[c] = malloc (16 * 8192); krad_opus->read_samples[c] = malloc (16 * 8192); krad_opus->resampled_samples[c] = malloc (16 * 8192); krad_opus->src_resampler[c] = src_new (KRAD_OPUS_SRC_QUALITY, 1, &krad_opus->src_error[c]); if (krad_opus->src_resampler[c] == NULL) { failfast ("krad_opus_decoder_create src resampler error: %s", src_strerror (krad_opus->src_error[c])); } krad_opus->src_data[c].src_ratio = output_sample_rate / 48000; printk ("krad_opus_decoder_create src resampler ratio is: %f", krad_opus->src_data[c].src_ratio); } krad_opus->streams = krad_opus->opus_header->nb_streams; krad_opus->coupled_streams = krad_opus->opus_header->nb_coupled; memcpy (krad_opus->mapping, krad_opus->opus_header->stream_map, 256); printk ("krad_opus_decoder_create channels %d streams %d coupled %d", krad_opus->channels, krad_opus->streams, krad_opus->coupled_streams ); krad_opus->decoder = opus_multistream_decoder_create (48000, krad_opus->opus_header->channels, krad_opus->streams, krad_opus->coupled_streams, krad_opus->mapping, &krad_opus->opus_decoder_error); if (krad_opus->opus_decoder_error != OPUS_OK) { failfast ("Cannot create decoder: %s", opus_strerror (krad_opus->opus_decoder_error)); } return krad_opus; }
krad_opus_t *krad_opus_encoder_create (int channels, int input_sample_rate, int bitrate, int application) { int c; krad_opus_t *krad_opus = calloc(1, sizeof(krad_opus_t)); krad_opus->opus_header = calloc(1, sizeof(OpusHeader)); krad_opus->input_sample_rate = input_sample_rate; krad_opus->channels = channels; krad_opus->bitrate = bitrate; krad_opus->application = application; krad_opus->complexity = DEFAULT_OPUS_COMPLEXITY; krad_opus->signal = OPUS_AUTO; krad_opus->frame_size = DEFAULT_OPUS_FRAME_SIZE; krad_opus->bandwidth = OPUS_BANDWIDTH_FULLBAND; krad_opus->new_frame_size = krad_opus->frame_size; krad_opus->new_complexity = krad_opus->complexity; krad_opus->new_bitrate = krad_opus->bitrate; krad_opus->new_signal = krad_opus->signal; krad_opus->new_bandwidth = krad_opus->bandwidth; for (c = 0; c < krad_opus->channels; c++) { krad_opus->ringbuf[c] = krad_ringbuffer_create (RINGBUFFER_SIZE); krad_opus->resampled_ringbuf[c] = krad_ringbuffer_create (RINGBUFFER_SIZE); krad_opus->samples[c] = malloc(16 * 8192); krad_opus->resampled_samples[c] = malloc(16 * 8192); krad_opus->src_resampler[c] = src_new (KRAD_OPUS_SRC_QUALITY, 1, &krad_opus->src_error[c]); if (krad_opus->src_resampler[c] == NULL) { failfast ("Krad Opus Encoder: src resampler error: %s", src_strerror (krad_opus->src_error[c])); } krad_opus->src_data[c].src_ratio = 48000.0 / krad_opus->input_sample_rate; } if (krad_opus->channels < 3) { krad_opus->streams = 1; if (krad_opus->channels == 2) { krad_opus->coupled_streams = 1; krad_opus->mapping[0] = 0; krad_opus->mapping[1] = 1; } else { krad_opus->coupled_streams = 0; krad_opus->mapping[0] = 0; } krad_opus->opus_header->channel_mapping = 0; } else { krad_opus->opus_header->channel_mapping = 1; switch (krad_opus->channels) { case 3: krad_opus->streams = 2; krad_opus->coupled_streams = 1; krad_opus->mapping[0] = 0; krad_opus->mapping[1] = 1; krad_opus->mapping[2] = 2; case 4: krad_opus->streams = 2; krad_opus->coupled_streams = 2; krad_opus->mapping[0] = 0; krad_opus->mapping[1] = 1; krad_opus->mapping[2] = 2; krad_opus->mapping[3] = 3; case 5: krad_opus->streams = 3; krad_opus->coupled_streams = 2; krad_opus->mapping[0] = 0; krad_opus->mapping[1] = 4; krad_opus->mapping[2] = 1; krad_opus->mapping[3] = 2; krad_opus->mapping[4] = 3; case 6: krad_opus->streams = 4; krad_opus->coupled_streams = 2; krad_opus->mapping[0] = 0; krad_opus->mapping[1] = 4; krad_opus->mapping[2] = 1; krad_opus->mapping[3] = 2; krad_opus->mapping[4] = 3; krad_opus->mapping[5] = 5; case 7: krad_opus->streams = 5; krad_opus->coupled_streams = 2; krad_opus->mapping[0] = 0; krad_opus->mapping[1] = 4; krad_opus->mapping[2] = 1; krad_opus->mapping[3] = 2; krad_opus->mapping[4] = 3; krad_opus->mapping[5] = 5; krad_opus->mapping[6] = 6; case 8: krad_opus->streams = 5; krad_opus->coupled_streams = 3; krad_opus->mapping[0] = 0; krad_opus->mapping[1] = 6; krad_opus->mapping[2] = 1; krad_opus->mapping[3] = 2; krad_opus->mapping[4] = 3; krad_opus->mapping[5] = 4; krad_opus->mapping[6] = 5; krad_opus->mapping[7] = 7; } } krad_opus->opus_header->channels = krad_opus->channels; krad_opus->opus_header->nb_streams = krad_opus->streams; krad_opus->opus_header->nb_coupled = krad_opus->coupled_streams; memcpy (krad_opus->opus_header->stream_map, krad_opus->mapping, 256); krad_opus->encoder = opus_multistream_encoder_create (48000, krad_opus->channels, krad_opus->streams, krad_opus->coupled_streams, krad_opus->mapping, krad_opus->application, &krad_opus->err); if (krad_opus->err != OPUS_OK) { failfast ("Krad Opus Encoder: Cannot create encoder: %s", opus_strerror (krad_opus->err)); } opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_GET_LOOKAHEAD (&krad_opus->lookahead)); krad_opus->opus_header->preskip = krad_opus->lookahead; krad_opus->opus_header->gain = 0; krad_opus->opus_header->input_sample_rate = 48000; if (opus_multistream_encoder_ctl (krad_opus->encoder, OPUS_SET_BITRATE (krad_opus->bitrate)) != OPUS_OK) { failfast ("Krad Opus Encoder: bitrate request failed"); } krad_opus->header_data_size = opus_header_to_packet (krad_opus->opus_header, krad_opus->header_data, 100); krad_opus->krad_codec_header.codec = OPUS; krad_opus->krad_codec_header.header[0] = krad_opus->header_data; krad_opus->krad_codec_header.header_size[0] = krad_opus->header_data_size; krad_opus->krad_codec_header.header_combined = krad_opus->header_data; krad_opus->krad_codec_header.header_combined_size = krad_opus->header_data_size; krad_opus->krad_codec_header.header_count = 2; krad_opus->krad_codec_header.header_size[1] = 8 + 4 + strlen (opus_get_version_string ()) + 4 + 4 + strlen ("ENCODER=") + strlen (APPVERSION); krad_opus->opustags_header = calloc (1, krad_opus->krad_codec_header.header_size[1]); memcpy (krad_opus->opustags_header, "OpusTags", 8); krad_opus->opustags_header[8] = strlen (opus_get_version_string ()); memcpy (krad_opus->opustags_header + 12, opus_get_version_string (), strlen (opus_get_version_string ())); krad_opus->opustags_header[12 + strlen (opus_get_version_string ())] = 1; krad_opus->opustags_header[12 + strlen (opus_get_version_string ()) + 4] = strlen ("ENCODER=") + strlen (APPVERSION); memcpy (krad_opus->opustags_header + 12 + strlen (opus_get_version_string ()) + 4 + 4, "ENCODER=", strlen ("ENCODER=")); memcpy (krad_opus->opustags_header + 12 + strlen (opus_get_version_string ()) + 4 + 4 + strlen ("ENCODER="), APPVERSION, strlen (APPVERSION)); krad_opus->krad_codec_header.header[1] = krad_opus->opustags_header; return krad_opus; }