kr_v4l2s *kr_v4l2s_create(kr_v4l2s_params *params) { kr_v4l2s *v4l2s; kr_v4l2_setup setup; kr_v4l2_mode mode; v4l2s = calloc(1, sizeof(kr_v4l2s)); v4l2s->params = params; v4l2s->mkv = kr_mkv_create_stream(v4l2s->params->host, v4l2s->params->port, v4l2s->params->mount, v4l2s->params->password); if (v4l2s->mkv == NULL) { fprintf(stderr, "failed to stream :/ \n"); exit(1); } v4l2s->vpx_enc = krad_vpx_encoder_create(v4l2s->params->width, v4l2s->params->height, 1000, 1, v4l2s->params->bitrate); kr_mkv_add_video_track(v4l2s->mkv, VP8, v4l2s->params->fps_num, v4l2s->params->fps_den, v4l2s->params->width, v4l2s->params->height); setup.dev = v4l2s->params->device; setup.priority = 0; mode.width = v4l2s->params->width; mode.height = v4l2s->params->height; mode.num = v4l2s->params->fps_num; mode.den = v4l2s->params->fps_den; mode.format = 0; v4l2s->v4l2 = kr_v4l2_create(&setup); kr_v4l2_mode_set(v4l2s->v4l2, &mode); return v4l2s; }
static void remux (kr_mkv_t *mkv, char *file) { int bytes_read; uint32_t track; uint64_t timecode; uint8_t *buffer; uint32_t out_track; kr_mkv_t *new_mkv; int keyframe; uint8_t flags; int packets; packets = 0; buffer = malloc (10000000); new_mkv = kr_mkv_create_file (file); if (new_mkv == NULL) { fprintf (stderr, "Could not open %s\n", file); exit (1); } printf ("Created file: %s\n", file); out_track = kr_mkv_add_video_track (new_mkv, VP8, 30, 1, mkv->tracks[VIDEO_TRACK].width, mkv->tracks[VIDEO_TRACK].height); printf ("Added new track: %d\n", out_track); printf ("\n"); while ((bytes_read = kr_mkv_read_packet (mkv, &track, &timecode, &flags, buffer)) > 0) { printf ("\rRead packet %d track %d %d bytes\t\t", packets++, track, bytes_read); fflush (stdout); if (flags == 0x80) { keyframe = 1; } else { keyframe = 0; } if (track == 1) { kr_mkv_add_video (new_mkv, out_track, buffer, bytes_read, keyframe); } } printf ("\nDone.\n"); kr_mkv_destroy (&new_mkv); free (buffer); }
int krad_container_add_video_track (krad_container_t *container, krad_codec_t codec, int fps_numerator, int fps_denominator, int width, int height) { if (container->type == OGG) { return krad_ogg_add_video_track (container->ogg, codec, fps_numerator, fps_denominator, width, height); } if (container->type == MKV) { return kr_mkv_add_video_track (container->mkv, codec, fps_numerator, fps_denominator, width, height); } return -1; }
void krad_transmitter_mkv_test2 (int port, char *filename1, char *filename2) { krad_transmitter_t *transmitter; kr_mkv_t *mkv_tx; kr_mkv_t *in[2]; krad_ticker_t *ticker; int i; int ret; uint32_t track; int bytes_read; uint32_t out_track; uint64_t start_tc; uint64_t timecode; uint64_t last_tc; uint64_t sleeptime; uint8_t *buffer; int keyframe; uint8_t flags; int packets; start_tc = 0; last_tc = 0; packets = 0; char *stream_name = "stream.webm"; char *content_type = "video/webm"; buffer = malloc (10000000); for (i = 0; i < 2; i++) { if (i == 0) { in[i] = kr_mkv_open_file (filename1); } else { in[i] = kr_mkv_open_file (filename2); } printf ("File %d: FPS %d/%d RES %dx%d\n", i, in[i]->tracks[VIDEO_TRACK].fps_numerator, in[i]->tracks[VIDEO_TRACK].fps_denominator, in[i]->tracks[VIDEO_TRACK].width, in[i]->tracks[VIDEO_TRACK].height); if ((i == 0) && (in[i] == NULL)) { fprintf (stderr, "Could not open input file1: %s\n", filename1); exit (1); } if ((i == 1) && (in[i] == NULL)) { fprintf (stderr, "Could not open input file2: %s\n", filename2); exit (1); } } if ((in[0]->tracks[VIDEO_TRACK].width != in[0]->tracks[VIDEO_TRACK].width) || (in[1]->tracks[VIDEO_TRACK].height != in[1]->tracks[VIDEO_TRACK].height)) { fprintf (stderr, "Resolutions are not equal\n"); exit (1); } ticker = krad_ticker_throttle_create (); transmitter = krad_transmitter_create (); ret = krad_transmitter_listen_on (transmitter, port); if (ret != 0) { fprintf (stderr, "transmitter could not listen on port %d\n", port); exit (1); } mkv_tx = kr_mkv_create_transmission (transmitter, stream_name, content_type); if (mkv_tx == NULL) { fprintf (stderr, "Could not create mkv transmission\n"); exit (1); } out_track = kr_mkv_add_video_track (mkv_tx, VP8, 30, 1, in[0]->tracks[VIDEO_TRACK].width, in[0]->tracks[VIDEO_TRACK].height); printf ("Added new track: %d\n", out_track); for (i = 0; i < 2; i++) { while ((bytes_read = kr_mkv_read_packet (in[i], &track, &timecode, &flags, buffer)) > 0) { if (start_tc == 0) { start_tc = timecode; krad_ticker_start (ticker); } if (flags == 0x80) { keyframe = 1; } else { keyframe = 0; } printf ("\rFile %d Packet %10d track %d sync %d timecode %14"PRIu64"s", i, packets++, track, keyframe, timecode / 1000); fflush (stdout); if (track == 1) { kr_mkv_add_video (mkv_tx, out_track, buffer, bytes_read, keyframe); } if ((last_tc) && (last_tc < timecode)) { sleeptime = (timecode - start_tc) - (last_tc - start_tc); krad_ticker_throttle (ticker, sleeptime); } if (timecode > last_tc) { last_tc = timecode; } } } krad_ticker_destroy (ticker); kr_mkv_destroy (&in[0]); kr_mkv_destroy (&in[1]); kr_mkv_destroy (&mkv_tx); krad_transmitter_destroy (transmitter); free (buffer); }
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; }
static void kraise_splice (char *file1, char *file2, char *fileout) { kr_mkv_t *in[2]; kr_mkv_t *out; int i; int bytes_read; uint32_t track; uint64_t timecode; uint8_t *buffer[2]; uint32_t out_track; int keyframe; uint8_t flags; int packets; int have_buffer[2]; int have_buffer_bytes[2]; int inframes; have_buffer_bytes[0] = 0; have_buffer_bytes[1] = 0; have_buffer[1] = 0; inframes = 0; have_buffer[0] = 0; have_buffer[1] = 0; packets = 0; buffer[0] = malloc (10000000); buffer[1] = malloc (10000000); for (i = 0; i < 2; i++) { if (i == 0) { in[i] = kr_mkv_open_file (file1); } else { in[i] = kr_mkv_open_file (file2); } printf ("File %d: FPS %d/%d RES %dx%d\n", i, in[i]->tracks[VIDEO_TRACK].fps_numerator, in[i]->tracks[VIDEO_TRACK].fps_denominator, in[i]->tracks[VIDEO_TRACK].width, in[i]->tracks[VIDEO_TRACK].height); if (in[0] == NULL) { fprintf (stderr, "Could not open input file: %s\n", file1); exit (1); } } if ((in[0]->tracks[VIDEO_TRACK].width != in[0]->tracks[VIDEO_TRACK].width) || (in[1]->tracks[VIDEO_TRACK].height != in[1]->tracks[VIDEO_TRACK].height)) { fprintf (stderr, "Resolutions are not equal\n"); exit (1); } out = kr_mkv_create_file (fileout); if (out == NULL) { fprintf (stderr, "Could not open output file: %s\n", fileout); exit (1); } printf ("Created file: %s\n", fileout); out_track = kr_mkv_add_video_track (out, VP8, 30, 1, in[0]->tracks[VIDEO_TRACK].width, in[0]->tracks[VIDEO_TRACK].height); printf ("Added new track: %d\n", out_track); while ((bytes_read = kr_mkv_read_packet (in[0], &track, &timecode, &flags, buffer[0])) > 0) { have_buffer_bytes[0] = bytes_read; printf ("Read file %d packet %d track %d %d bytes\n", 1, packets++, track, bytes_read); fflush (stdout); if (flags == 0x80) { keyframe = 1; } else { keyframe = 0; } if (keyframe == 1) { inframes = 0; while ((have_buffer[1] == 1) || (((bytes_read = kr_mkv_read_packet (in[1], &track, &timecode, &flags, buffer[1])) > 0))) { if (have_buffer[1] == 1) { keyframe = 1; have_buffer[1] = 0; } else { printf ("Read file %d packet %d track %d %d bytes\n", 2, packets++, track, bytes_read); fflush (stdout); if (flags == 0x80) { keyframe = 1; } else { keyframe = 0; } have_buffer_bytes[1] = bytes_read; if ((keyframe == 1) && (inframes > 0)) { have_buffer[1] = 1; break; } } if (track == 1) { kr_mkv_add_video (out, out_track, buffer[1], have_buffer_bytes[1], keyframe); } inframes++; } } if (track == 1) { kr_mkv_add_video (out, out_track, buffer[0], have_buffer_bytes[0], keyframe); } } printf ("\nDone.\n"); free (buffer[0]); free (buffer[1]); kr_mkv_destroy (&in[0]); kr_mkv_destroy (&in[1]); kr_mkv_destroy (&out); }
static void remuxcode (kr_mkv_t *mkv, char *file, char *file2) { int32_t ret; int32_t bytes_read; uint32_t track; uint64_t timecode; uint8_t *buffer; uint8_t *vbuffer; uint8_t *vbuffer2; uint32_t out_track; kr_mkv_t *new_mkv; int32_t keyframe; uint8_t flags; int32_t packets; krad_vpx_decoder_t *vpx_dec; krad_vpx_encoder_t *vpx_enc; kr_codec_hdr_t header; kr_medium_t *medium; kr_codeme_t *codeme; krad_vorbis_t *vorbis_dec; krad_vorbis_t *vorbis_enc; packets = 0; //vpxtest (); buffer = malloc (20000000); vbuffer = malloc (20000000); vbuffer2 = malloc (20000000); new_mkv = kr_mkv_create_file (file); if (new_mkv == NULL) { fprintf (stderr, "Could not open %s\n", file); exit (1); } printf ("Created file: %s\n", file); vpx_dec = krad_vpx_decoder_create (); vpx_enc = krad_vpx_encoder_create (1280, 720, 30000, 1000, 2200); out_track = kr_mkv_add_video_track (new_mkv, VP8, 30000, 1000, mkv->tracks[VIDEO_TRACK].width, mkv->tracks[VIDEO_TRACK].height); header.count = mkv->tracks[AUDIO_TRACK].headers; header.data[0] = mkv->tracks[AUDIO_TRACK].header[0]; header.sz[0] = mkv->tracks[AUDIO_TRACK].header_len[0]; header.data[1] = mkv->tracks[AUDIO_TRACK].header[1]; header.sz[1] = mkv->tracks[AUDIO_TRACK].header_len[1]; header.data[2] = mkv->tracks[AUDIO_TRACK].header[2]; header.sz[2] = mkv->tracks[AUDIO_TRACK].header_len[2]; vorbis_dec = krad_vorbis_decoder_create (&header); vorbis_enc = krad_vorbis_encoder_create (2, 48000, 0.4); kr_mkv_add_audio_track (new_mkv, VORBIS, 48000, 2, vorbis_enc->hdrdata, 3 + vorbis_enc->header.sz[0] + vorbis_enc->header.sz[1] + vorbis_enc->header.sz[2]); printf ("\n"); while ((bytes_read = kr_mkv_read_packet (mkv, &track, &timecode, &flags, buffer)) > 0) { printk ("Read packet %d track %d %d bytes", packets++, track, bytes_read); //fflush (stdout); if (flags == 0x80) { keyframe = 1; } else { keyframe = 0; } if (track == 1) { /* medium = kr_medium_kludge_create (); codeme = kr_codeme_kludge_create (); codeme->sz = bytes_read; memcpy (codeme->data, buffer, codeme->sz); ret = kr_vpx_decode (vpx_dec, medium, codeme); //printf ("Vpx dec ret was %d", ret); kr_codeme_kludge_destroy (&codeme); codeme = kr_codeme_kludge_create (); ret = kr_vpx_encode (vpx_enc, codeme, medium); //printf ("Vpx enc ret was %d", ret); kr_medium_kludge_destroy (&medium); bytes_read = codeme->sz; memcpy (buffer, codeme->data, codeme->sz); kr_codeme_kludge_destroy (&codeme); */ kr_mkv_add_video (new_mkv, out_track, buffer, bytes_read, keyframe); } if (track == 2) { medium = kr_medium_kludge_create (); codeme = kr_codeme_kludge_create (); codeme->sz = bytes_read; memcpy (codeme->data, buffer, codeme->sz); kr_vorbis_decode (vorbis_dec, medium, codeme); kr_codeme_kludge_destroy (&codeme); if (medium->a.count > 0) { do { codeme = kr_codeme_kludge_create (); ret = kr_vorbis_encode (vorbis_enc, codeme, medium); if (ret == 1) { kr_mkv_add_audio (new_mkv, 2, codeme->data, codeme->sz, codeme->count); } kr_medium_kludge_destroy (&medium); kr_codeme_kludge_destroy (&codeme); } while (ret == 1); } //} } } //----------------------------- krad_vorbis_decoder_destroy (&vorbis_dec); //new_mkv->tracks[VIDEO_TRACK].fps_numerator = 30000; kr_mkv_destroy (&mkv); mkv = kr_mkv_open_file (file2); printf ("FPS %d/%d RES: %dx%d\n", mkv->tracks[VIDEO_TRACK].fps_numerator, mkv->tracks[VIDEO_TRACK].fps_denominator, mkv->tracks[VIDEO_TRACK].width, mkv->tracks[VIDEO_TRACK].height); if (mkv == NULL) { fprintf (stderr, "Could not open %s\n", file2); exit (1); } header.count = mkv->tracks[AUDIO_TRACK].headers; header.data[0] = mkv->tracks[AUDIO_TRACK].header[0]; header.sz[0] = mkv->tracks[AUDIO_TRACK].header_len[0]; header.data[1] = mkv->tracks[AUDIO_TRACK].header[1]; header.sz[1] = mkv->tracks[AUDIO_TRACK].header_len[1]; header.data[2] = mkv->tracks[AUDIO_TRACK].header[2]; header.sz[2] = mkv->tracks[AUDIO_TRACK].header_len[2]; vorbis_dec = krad_vorbis_decoder_create (&header); while ((bytes_read = kr_mkv_read_packet (mkv, &track, &timecode, &flags, buffer)) > 0) { printk ("Read packet %d track %d %d bytes", packets++, track, bytes_read); //fflush (stdout); if (flags == 0x80) { keyframe = 1; } else { keyframe = 0; } if (track == 1) { /* medium = kr_medium_kludge_create (); codeme = kr_codeme_kludge_create (); codeme->sz = bytes_read; memcpy (codeme->data, buffer, codeme->sz); ret = kr_vpx_decode (vpx_dec, medium, codeme); //printf ("Vpx dec ret was %d", ret); kr_codeme_kludge_destroy (&codeme); codeme = kr_codeme_kludge_create (); ret = kr_vpx_encode (vpx_enc, codeme, medium); //printf ("Vpx enc ret was %d", ret); kr_medium_kludge_destroy (&medium); bytes_read = codeme->sz; memcpy (buffer, codeme->data, codeme->sz); kr_codeme_kludge_destroy (&codeme); */ kr_mkv_add_video (new_mkv, out_track, buffer, bytes_read, keyframe); } if (track == 2) { medium = kr_medium_kludge_create (); codeme = kr_codeme_kludge_create (); codeme->sz = bytes_read; memcpy (codeme->data, buffer, codeme->sz); kr_vorbis_decode (vorbis_dec, medium, codeme); kr_codeme_kludge_destroy (&codeme); if (medium->a.count > 0) { do { codeme = kr_codeme_kludge_create (); ret = kr_vorbis_encode (vorbis_enc, codeme, medium); if (ret == 1) { kr_mkv_add_audio (new_mkv, 2, codeme->data, codeme->sz, codeme->count); } kr_medium_kludge_destroy (&medium); kr_codeme_kludge_destroy (&codeme); } while (ret == 1); } //} } } medium = kr_medium_kludge_create (); codeme = kr_codeme_kludge_create (); ret = kr_vorbis_encode (vorbis_enc, codeme, medium); if (codeme->sz > 0) { printk ("Got 1 another sized %zu with %d samples", codeme->sz, codeme->count); kr_mkv_add_audio (new_mkv, 2, codeme->data, codeme->sz, codeme->count); } kr_codeme_kludge_destroy (&codeme); kr_medium_kludge_destroy (&medium); do { codeme = kr_codeme_kludge_create (); ret = kr_vorbis_encode (vorbis_enc, codeme, medium); if (ret == 1) { kr_mkv_add_audio (new_mkv, 2, codeme->data, codeme->sz, codeme->count); } kr_codeme_kludge_destroy (&codeme); } while (ret == 1); //---------------------------- printf ("\nDone.\n"); krad_vpx_encoder_destroy (&vpx_enc); krad_vpx_decoder_destroy (&vpx_dec); krad_vorbis_decoder_destroy (&vorbis_dec); krad_vorbis_encoder_destroy (&vorbis_enc); kr_mkv_destroy (&new_mkv); kr_mkv_destroy (&mkv); free (buffer); free (vbuffer); free (vbuffer2); }