示例#1
0
void kr_v4l2s_run(kr_v4l2s *v4l2s) {
  kr_image cam_image;
  kr_image scaled_image;
  uint8_t *pixels;
  kr_convert conv;
  kr_codeme_t *vcodeme;
  int32_t ret;
  kr_image_convert_init(&conv);
  vcodeme = kr_codeme_kludge_create();
  pixels = malloc(v4l2s->params->width * v4l2s->params->height * 2);
  scaled_image.w = v4l2s->params->width;
  scaled_image.h = v4l2s->params->height;
  scaled_image.px = pixels;
  scaled_image.ppx[0] = pixels;
  scaled_image.ppx[1] = pixels
   + (v4l2s->params->width * v4l2s->params->height);
  scaled_image.ppx[2] = pixels
   + (v4l2s->params->width * v4l2s->params->height)
   + ((v4l2s->params->width / 2) * (v4l2s->params->height / 2));
  scaled_image.ppx[3] = 0;
  scaled_image.pps[0] = v4l2s->params->width;
  scaled_image.pps[1] = v4l2s->params->width / 2;
  scaled_image.pps[2] = v4l2s->params->width / 2;
  scaled_image.pps[3] = 0;
  scaled_image.fmt = PIX_FMT_YUV420P;
  kr_v4l2_capture(v4l2s->v4l2, 1);
  v4l2s->timer = kr_timer_create();
  krad_vpx_encoder_deadline_set(v4l2s->vpx_enc, 1);
  kr_timer_start(v4l2s->timer);
  while (!destruct) {
    ret = kr_v4l2_poll(v4l2s->v4l2, 15);
    if (ret < 1) {
      continue;
    }
    scaled_image.tc = kr_timer_current_ms(v4l2s->timer);
    ret = kr_v4l2_read(v4l2s->v4l2, &cam_image);
    kr_image_convert(&conv, &scaled_image, &cam_image);
    kr_image_unref(&cam_image);
    ret = kr_vpx_encode(v4l2s->vpx_enc, vcodeme, &scaled_image);
    if (ret == 1) {
      kr_mkv_add_video_tc(v4l2s->mkv, 1, vcodeme->data, vcodeme->sz,
       vcodeme->key, vcodeme->tc);
    }
    printf("\rKrad V4L2 Stream Frame# %12"PRIu64" ", v4l2s->frames++);
    fflush(stdout);
  }
  kr_codeme_kludge_destroy(&vcodeme);
  kr_image_convert_clear(&conv);
  free(pixels);
  kr_timer_destroy(v4l2s->timer);
}
示例#2
0
void kr_streamer_run (kr_streamer_t *streamer) {

  krad_frame_t *frame;
  int32_t frames;
  kr_medium_t *amedium;
  kr_codeme_t *acodeme;
  kr_medium_t *vmedium;
  kr_codeme_t *vcodeme;
  struct SwsContext *converter;
  int sws_algo;
  int32_t ret;
  int32_t muxdelay;
  uint32_t c;

  muxdelay = 1;

  signal (SIGINT, signal_recv);
  signal (SIGTERM, signal_recv);

  converter = NULL;
  sws_algo = SWS_BILINEAR;

  amedium = kr_medium_kludge_create ();
  acodeme = kr_codeme_kludge_create ();
  vmedium = kr_medium_kludge_create ();
  vcodeme = kr_codeme_kludge_create ();

  streamer->timer = krad_timer_create ();

  kr_audioport_connect(streamer->audioport);
  kr_videoport_activate (streamer->videoport);

  while (!destroy) {

    while (krad_ringbuffer_read_space (streamer->audio_ring[1]) >= 1024 * 4) {

      for (c = 0; c < streamer->params->channels; c++) {
        krad_ringbuffer_read (streamer->audio_ring[c],
                              (char *)amedium->a.samples[c],
                              1024 * 4);
      }

      amedium->a.count = 1024;
      amedium->a.channels = streamer->params->channels;

      ret = kr_vorbis_encode (streamer->vorbis_enc, acodeme, amedium);
      if (ret == 1) {
        kr_mkv_add_audio (streamer->mkv, 2,
                          acodeme->data,
                          acodeme->sz,
                          acodeme->count);
        muxdelay = 0;
        while (1) {
        ret = kr_vorbis_encode (streamer->vorbis_enc, acodeme, NULL);
        if (ret == 1) {
          kr_mkv_add_audio (streamer->mkv, 2,
                            acodeme->data,
                            acodeme->sz,
                            acodeme->count);
          } else {
            break;
          }
        }
      }
    }

    if (muxdelay > 0) {
      continue;
    }

    frame = NULL;
    frames = krad_ringbuffer_read_space (streamer->frame_ring) / sizeof(void *);

    if (frames > 1) {
      krad_vpx_encoder_deadline_set (streamer->vpx_enc, 1);
      sws_algo = SWS_POINT;
    }

    if (frames == 0) {
      krad_vpx_encoder_deadline_set (streamer->vpx_enc, 10000);
      sws_algo = SWS_BILINEAR;
      usleep (2000);
      continue;
    }

    if (frames > 0) {
      krad_ringbuffer_read (streamer->frame_ring,
                            (char *)&frame,
                            sizeof(krad_frame_t *));

      vmedium->v.tc = krad_timer_current_ms (streamer->timer);
      if (!krad_timer_started (streamer->timer)) {
        krad_timer_start (streamer->timer);
      }

      frame->yuv_pixels[0] = (uint8_t *)frame->pixels;
      frame->format = PIX_FMT_RGB32;
      frame->yuv_pixels[1] = NULL;
      frame->yuv_pixels[2] = NULL;
      frame->yuv_strides[0] = streamer->width * 4;
      frame->yuv_strides[1] = 0;
      frame->yuv_strides[2] = 0;
      frame->yuv_strides[3] = 0;

      converter = sws_getCachedContext ( converter,
                                         streamer->width,
                                         streamer->height,
                                         frame->format,
                                         streamer->params->width,
                                         streamer->params->height,
                                         PIX_FMT_YUV420P,
                                         sws_algo,
                                         NULL, NULL, NULL);

      if (converter == NULL) {
        failfast ("Krad streamer: could not sws_getCachedContext");
      }

      vmedium->v.pps[0] = streamer->params->width;
      vmedium->v.pps[1] = streamer->params->width/2;
      vmedium->v.pps[2] = streamer->params->width/2;
      vmedium->v.ppx[0] = vmedium->data;
      vmedium->v.ppx[1] = vmedium->data +
                          streamer->params->width * (streamer->params->height);
      vmedium->v.ppx[2] = vmedium->data + streamer->params->width *
                          (streamer->params->height) +
                          ((streamer->params->width * (streamer->params->height)) /4);

      sws_scale (converter,
                (const uint8_t * const*)frame->yuv_pixels,
                frame->yuv_strides,
                0,
                streamer->height,
                vmedium->v.ppx,
                vmedium->v.pps);

      krad_framepool_unref_frame (frame);

      ret = kr_vpx_encode (streamer->vpx_enc, vcodeme, vmedium);
      if (ret == 1) {
        kr_mkv_add_video_tc (streamer->mkv, 1,
                             vcodeme->data, vcodeme->sz,
                             vcodeme->key, vcodeme->tc);
      }

      printf ("\rKrad Streamer Frame# %12"PRIu64"",
              streamer->eframes++);
      fflush (stdout);

      //krad_ticker_wait (streamer->ticker);
    }
  }

  kr_medium_kludge_destroy (&vmedium);
  kr_codeme_kludge_destroy (&vcodeme);

  kr_medium_kludge_destroy (&amedium);
  kr_codeme_kludge_destroy (&acodeme);

  if (converter != NULL) {
    sws_freeContext (converter);
    converter = NULL;
  }

  krad_timer_destroy (streamer->timer);
}
int krad_transponder_handler ( krad_transponder_t *krad_transponder, krad_ipc_server_t *krad_ipc ) {

	krad_link_t *krad_link;

	uint32_t ebml_id;

	uint32_t command;
	uint64_t ebml_data_size;
  kr_address_t address;
	uint64_t element;
	uint64_t response;
	uint64_t payload_loc;
	char string[256];	
	
	uint64_t bigint;
	//int regint;
	uint8_t tinyint;
	int k;
	int devices;
	//float floatval;
	
	string[0] = '\0';
	bigint = 0;
	k = 0;
	
	krad_ipc_server_read_command ( krad_ipc, &command, &ebml_data_size);

	switch ( command ) {

		case EBML_ID_KRAD_TRANSPONDER_CMD_LIST_LINKS:
			//printk ("krad transponder handler! LIST_LINKS");
			
			krad_Xtransponder_list ( krad_transponder->krad_Xtransponder );
			
			krad_ipc_server_response_start ( krad_ipc, EBML_ID_KRAD_TRANSPONDER_MSG, &response);

			
			for (k = 0; k < KRAD_TRANSPONDER_MAX_LINKS; k++) {
				if (krad_transponder->krad_link[k] != NULL) {
					printk ("Link %d Active: %s", k, krad_transponder->krad_link[k]->mount);
					krad_transponder_link_to_ebml ( krad_ipc->current_client, krad_transponder->krad_link[k]);
				}
			}
			

			krad_ipc_server_response_finish ( krad_ipc, response );	
						
			break;
			
		case EBML_ID_KRAD_TRANSPONDER_CMD_CREATE_LINK:
			for (k = 0; k < KRAD_TRANSPONDER_MAX_LINKS; k++) {
				if (krad_transponder->krad_link[k] == NULL) {

					krad_transponder->krad_link[k] = krad_link_prepare (k);
					krad_link = krad_transponder->krad_link[k];
					krad_link->link_num = k;
					krad_link->krad_radio = krad_transponder->krad_radio;
					krad_link->krad_transponder = krad_transponder;
					krad_transponder_ebml_to_link ( krad_ipc, krad_link );
					krad_link_start (krad_link);
				
				  /*
					if ((krad_link->operation_mode == TRANSMIT) || (krad_link->operation_mode == RECORD)) {
						if (krad_link_wait_codec_init (krad_link) == 0) {
							krad_transponder_broadcast_link_created ( krad_ipc, krad_link );
						}
					} else {
						krad_transponder_broadcast_link_created ( krad_ipc, krad_link );
					}
          */
					break;
				}
			}
			break;
		case EBML_ID_KRAD_TRANSPONDER_CMD_DESTROY_LINK:
			tinyint = krad_ipc_server_read_number (krad_ipc, ebml_data_size);
			k = tinyint;
			//printk ("krad transponder handler! DESTROY_LINK: %d %u", k, tinyint);
			
			if (krad_transponder->krad_link[k] != NULL) {
				krad_link_destroy (krad_transponder->krad_link[k]);
				krad_transponder->krad_link[k] = NULL;
			}
			/*
			krad_ipc_server_simple_number_broadcast ( krad_ipc,
													  EBML_ID_KRAD_TRANSPONDER_MSG,
													  EBML_ID_KRAD_TRANSPONDER_LINK_DESTROYED,
													  EBML_ID_KRAD_TRANSPONDER_LINK_NUMBER,
											 		  k);			
			*/
			break;
		case EBML_ID_KRAD_TRANSPONDER_CMD_UPDATE_LINK:
			//printk ("krad transponder handler! UPDATE_LINK");

			krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);	
			
			if (ebml_id == EBML_ID_KRAD_TRANSPONDER_LINK_NUMBER) {
			
				tinyint = krad_ipc_server_read_number (krad_ipc, ebml_data_size);
				k = tinyint;
				//printk ("krad transponder handler! UPDATE_LINK: %d %u", k, tinyint);
			
				if (krad_transponder->krad_link[k] != NULL) {

					krad_ebml_read_element (krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

					if (krad_transponder->krad_link[k]->audio_codec == OPUS) {

						/*
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_APPLICATION) {
							krad_ebml_read_string (krad_ipc->current_client->krad_ebml, string, ebml_data_size);
							if (strncmp(string, "OPUS_APPLICATION_VOIP", 21) == 0) {
								krad_opus_set_application (krad_transponder->krad_link[k]->krad_opus, OPUS_APPLICATION_VOIP);
							}
							if (strncmp(string, "OPUS_APPLICATION_AUDIO", 22) == 0) {
								krad_opus_set_application (krad_transponder->krad_link[k]->krad_opus, OPUS_APPLICATION_AUDIO);
							}
							if (strncmp(string, "OPUS_APPLICATION_RESTRICTED_LOWDELAY", 36) == 0) {
								krad_opus_set_application (krad_transponder->krad_link[k]->krad_opus, OPUS_APPLICATION_RESTRICTED_LOWDELAY);
							}
						}
						*/
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_SIGNAL) {
							krad_ebml_read_string (krad_ipc->current_client->krad_ebml, string, ebml_data_size);

							krad_opus_set_signal (krad_transponder->krad_link[k]->krad_opus, 
													krad_opus_string_to_signal(string));
						}
						
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_BANDWIDTH) {
							
							krad_ebml_read_string (krad_ipc->current_client->krad_ebml, string, ebml_data_size);
							
							krad_opus_set_bandwidth (krad_transponder->krad_link[k]->krad_opus, 
													krad_opus_string_to_bandwidth(string));
						}						

						if (ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_BITRATE) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
					
							if ((bigint >= 500) && (bigint <= 512000)) {
								krad_opus_set_bitrate (krad_transponder->krad_link[k]->krad_opus, bigint);
							}
						}
						
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_COMPLEXITY) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
					
							if ((bigint >= 0) && (bigint <= 10)) {
								krad_opus_set_complexity (krad_transponder->krad_link[k]->krad_opus, bigint);
							}
						}						
				
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_FRAME_SIZE) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
							if ((bigint == 120) || (bigint == 240) || (bigint == 480) || (bigint == 960) || (bigint == 1920) || (bigint == 2880)) {
								krad_opus_set_frame_size (krad_transponder->krad_link[k]->krad_opus, bigint);
							}
						}
						
						//FIXME verify ogg container
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_OGG_MAX_PACKETS_PER_PAGE) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
							if ((bigint > 0) && (bigint < 200)) {					
								krad_ogg_set_max_packets_per_page (krad_transponder->krad_link[k]->krad_container->krad_ogg, bigint);
							}
						}
					}
					
					if (krad_transponder->krad_link[k]->video_codec == THEORA) {
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_THEORA_QUALITY) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
							krad_theora_encoder_quality_set (krad_transponder->krad_link[k]->krad_theora_encoder, bigint);
						}
					}				
					
					if (krad_transponder->krad_link[k]->video_codec == VP8) {
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_VP8_BITRATE) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
					
							if (bigint > 0) {
								krad_vpx_encoder_bitrate_set (krad_transponder->krad_link[k]->krad_vpx_encoder, bigint);
							}
						}
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_VP8_MIN_QUANTIZER) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
					
							if (bigint > 0) {
								krad_vpx_encoder_min_quantizer_set (krad_transponder->krad_link[k]->krad_vpx_encoder, bigint);
							}
						}
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_VP8_MAX_QUANTIZER) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
					
							if (bigint > 0) {
								krad_vpx_encoder_max_quantizer_set (krad_transponder->krad_link[k]->krad_vpx_encoder, bigint);
							}
						}
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_VP8_DEADLINE) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
					
							if (bigint > 0) {
								krad_vpx_encoder_deadline_set (krad_transponder->krad_link[k]->krad_vpx_encoder, bigint);
							}
						}												
						if (ebml_id == EBML_ID_KRAD_LINK_LINK_VP8_FORCE_KEYFRAME) {
							bigint = krad_ebml_read_number (krad_ipc->current_client->krad_ebml, ebml_data_size);
					
							if (bigint > 0) {
								krad_vpx_encoder_want_keyframe (krad_transponder->krad_link[k]->krad_vpx_encoder);
							}
						}
					}
          /*
					if ((ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_BANDWIDTH) || (ebml_id == EBML_ID_KRAD_LINK_LINK_OPUS_SIGNAL)) {

						krad_ipc_server_advanced_string_broadcast ( krad_ipc,
																  EBML_ID_KRAD_TRANSPONDER_MSG,
																  EBML_ID_KRAD_TRANSPONDER_LINK_UPDATED,
																  EBML_ID_KRAD_TRANSPONDER_LINK_NUMBER,
														 		  k,
														 		  ebml_id,
														 		  string);

					} else {
						krad_ipc_server_advanced_number_broadcast ( krad_ipc,
																  EBML_ID_KRAD_TRANSPONDER_MSG,
																  EBML_ID_KRAD_TRANSPONDER_LINK_UPDATED,
																  EBML_ID_KRAD_TRANSPONDER_LINK_NUMBER,
														 		  k,
														 		  ebml_id,
														 		  bigint);
					}
					*/
				}
			}
			
			break;
			
    case EBML_ID_KRAD_TRANSPONDER_CMD_LIST_ADAPTERS:

			address.path.unit = KR_TRANSPONDER;
			address.path.subunit.transponder_subunit = KR_ADAPTER;
#ifdef KR_LINUX
			devices = krad_v4l2_detect_devices ();			

			for (k = 0; k < devices; k++) {
				if (krad_v4l2_get_device_filename (k, string) > 0) {
          address.id.number = k;
          krad_ipc_server_response_start_with_address_and_type ( krad_ipc,
                                                                 &address,
                                                                 EBML_ID_KRAD_SUBUNIT_INFO,
                                                                 &response);
          krad_ipc_server_payload_start ( krad_ipc, &payload_loc);

					krad_ebml_write_string (krad_ipc->current_client->krad_ebml2, EBML_ID_KRAD_TRANSPONDER_V4L2_DEVICE_FILENAME, string);

	        //krad_ebml_start_element (kr_ipc->current_client->krad_ebml2, EBML_ID_KRAD_RADIO_REMOTE_STATUS, &element);
			    //krad_ipc_server_respond_string ( kr_ipc, EBML_ID_KRAD_RADIO_REMOTE_INTERFACE, kr_ipc->tcp_interface[i]);
			    //krad_ipc_server_respond_number ( kr_ipc, EBML_ID_KRAD_RADIO_REMOTE_PORT, kr_ipc->tcp_port[i]);
	        //krad_ebml_finish_element (kr_ipc->current_client->krad_ebml2, element);

          krad_ipc_server_payload_finish ( krad_ipc, payload_loc );
          krad_ipc_server_response_finish ( krad_ipc, response );
        }
      }
#endif
			devices = krad_decklink_detect_devices();

			for (k = 0; k < devices; k++) {
        krad_decklink_get_device_name (k, string);
        address.id.number = k;
        krad_ipc_server_response_start_with_address_and_type ( krad_ipc,
                                                               &address,
                                                               EBML_ID_KRAD_SUBUNIT_INFO,
                                                               &response);
        krad_ipc_server_payload_start ( krad_ipc, &payload_loc);

				krad_ebml_write_string (krad_ipc->current_client->krad_ebml2, EBML_ID_KRAD_TRANSPONDER_DECKLINK_DEVICE_NAME, string);

	        //krad_ebml_start_element (kr_ipc->current_client->krad_ebml2, EBML_ID_KRAD_RADIO_REMOTE_STATUS, &element);
			    //krad_ipc_server_respond_string ( kr_ipc, EBML_ID_KRAD_RADIO_REMOTE_INTERFACE, kr_ipc->tcp_interface[i]);
			    //krad_ipc_server_respond_number ( kr_ipc, EBML_ID_KRAD_RADIO_REMOTE_PORT, kr_ipc->tcp_port[i]);
	        //krad_ebml_finish_element (kr_ipc->current_client->krad_ebml2, element);

        krad_ipc_server_payload_finish ( krad_ipc, payload_loc );
        krad_ipc_server_response_finish ( krad_ipc, response );
      }

      return 1;
	
		case EBML_ID_KRAD_TRANSPONDER_CMD_LISTEN_ENABLE:
		
			krad_ebml_read_element ( krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

			if (ebml_id != EBML_ID_KRAD_RADIO_TCP_PORT) {
				printke ("hrm wtf6");
			}
		
			bigint = krad_ebml_read_number ( krad_ipc->current_client->krad_ebml, ebml_data_size);
		
			krad_receiver_listen_on (krad_transponder->krad_receiver, bigint);
		
			break;

		case EBML_ID_KRAD_TRANSPONDER_CMD_LISTEN_DISABLE:
		
			krad_receiver_stop_listening (krad_transponder->krad_receiver);
		
			break;
			
			
		case EBML_ID_KRAD_TRANSPONDER_CMD_TRANSMITTER_ENABLE:
		
			krad_ebml_read_element ( krad_ipc->current_client->krad_ebml, &ebml_id, &ebml_data_size);	

			if (ebml_id != EBML_ID_KRAD_RADIO_TCP_PORT) {
				printke ("hrm wtf6");
			}
		
			bigint = krad_ebml_read_number ( krad_ipc->current_client->krad_ebml, ebml_data_size);
		
			krad_transmitter_listen_on (krad_transponder->krad_transmitter, bigint);
		
			break;

		case EBML_ID_KRAD_TRANSPONDER_CMD_TRANSMITTER_DISABLE:
		
			krad_transmitter_stop_listening (krad_transponder->krad_transmitter);
		
			break;			

	}

	return 0;
}