Beispiel #1
0
krad_vpx_encoder_t *krad_vpx_encoder_create (int width, int height, int fps_numerator,
											 int fps_denominator, int bitrate) {

	krad_vpx_encoder_t *kradvpx;
	
	kradvpx = calloc(1, sizeof(krad_vpx_encoder_t));
	
	kradvpx->width = width;
	kradvpx->height = height;
	kradvpx->fps_numerator = fps_numerator;
	kradvpx->fps_denominator = fps_denominator;
	kradvpx->bitrate = bitrate;
	
	printk ("Krad Radio using libvpx version: %s", vpx_codec_version_str ());

	if ((kradvpx->image = vpx_img_alloc (NULL, VPX_IMG_FMT_YV12, kradvpx->width, kradvpx->height, 1)) == NULL) {
		failfast ("Failed to allocate vpx image\n");
	}

	kradvpx->res = vpx_codec_enc_config_default (vpx_codec_vp8_cx(), &kradvpx->cfg, 0);

	if (kradvpx->res) {
		failfast ("Failed to get config: %s\n", vpx_codec_err_to_string(kradvpx->res));
    }

	// print default config
	//krad_vpx_encoder_print_config (kradvpx);

	kradvpx->cfg.g_w = kradvpx->width;
	kradvpx->cfg.g_h = kradvpx->height;
	/* Next two lines are really right */
	kradvpx->cfg.g_timebase.num = kradvpx->fps_denominator;
	kradvpx->cfg.g_timebase.den = kradvpx->fps_numerator;
	kradvpx->cfg.rc_target_bitrate = bitrate;	
	kradvpx->cfg.g_threads = 4;
	kradvpx->cfg.kf_mode = VPX_KF_AUTO;
	kradvpx->cfg.rc_end_usage = VPX_VBR;
	
	kradvpx->deadline = 15 * 1000;

	kradvpx->min_quantizer = kradvpx->cfg.rc_min_quantizer;
	kradvpx->max_quantizer = kradvpx->cfg.rc_max_quantizer;

	//krad_vpx_encoder_print_config (kradvpx);

	if (vpx_codec_enc_init(&kradvpx->encoder, vpx_codec_vp8_cx(), &kradvpx->cfg, 0)) {
		 krad_vpx_fail (&kradvpx->encoder, "Failed to initialize encoder");
	}

	//krad_vpx_encoder_print_config (kradvpx);


#ifdef BENCHMARK
	printk ("Benchmarking enabled, reporting every %d frames", BENCHMARK_COUNT);
kradvpx->krad_timer = krad_timer_create();
#endif

	return kradvpx;

}
Beispiel #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);
}