static switch_status_t switch_vpx_init(switch_codec_t *codec, switch_codec_flag_t flags, const switch_codec_settings_t *codec_settings)
{
	vpx_context_t *context = NULL;
	int encoding, decoding;

	encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
	decoding = (flags & SWITCH_CODEC_FLAG_DECODE);

	if (!(encoding || decoding) || ((context = switch_core_alloc(codec->memory_pool, sizeof(*context))) == 0)) {
		return SWITCH_STATUS_FALSE;
	}

	memset(context, 0, sizeof(*context));
	context->flags = flags;
	codec->private_info = context;
	context->pool = codec->memory_pool;

	if (codec_settings) {
		context->codec_settings = *codec_settings;
	}

	if (!strcmp(codec->implementation->iananame, "VP9")) {
		context->is_vp9 = 1;
		context->encoder_interface = vpx_codec_vp9_cx();
		context->decoder_interface = vpx_codec_vp9_dx();
	} else {
		context->encoder_interface = vpx_codec_vp8_cx();
		context->decoder_interface = vpx_codec_vp8_dx();
	}

	if (codec->fmtp_in) {
		codec->fmtp_out = switch_core_strdup(codec->memory_pool, codec->fmtp_in);
	}

	if (vpx_codec_enc_config_default(context->encoder_interface, &context->config, 0) != VPX_CODEC_OK) {
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoder config Error\n");
		return SWITCH_STATUS_FALSE;
	}

	context->codec_settings.video.width = 320;
	context->codec_settings.video.height = 240;

	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "VPX VER:%s VPX_IMAGE_ABI_VERSION:%d VPX_CODEC_ABI_VERSION:%d\n",
		vpx_codec_version_str(), VPX_IMAGE_ABI_VERSION, VPX_CODEC_ABI_VERSION);

	return SWITCH_STATUS_SUCCESS;
}
Esempio n. 2
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;

}
Esempio n. 3
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 *vpx;
  
  vpx = calloc (1, sizeof(krad_vpx_encoder_t));
  
  vpx->width = width;
  vpx->height = height;
  vpx->fps_numerator = fps_numerator;
  vpx->fps_denominator = fps_denominator;
  vpx->bitrate = bitrate;
  
  printk ("Krad Radio using libvpx version: %s",
          vpx_codec_version_str ());

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

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

  printk ("For reference the default config is:");
  krad_vpx_encoder_print_config (vpx);

  vpx->cfg.g_w = vpx->width;
  vpx->cfg.g_h = vpx->height;

  /* Next two lines are really right */
  vpx->cfg.g_timebase.num = vpx->fps_denominator;
  vpx->cfg.g_timebase.den = vpx->fps_numerator;

  vpx->cfg.rc_target_bitrate = bitrate;  
  vpx->cfg.g_threads = 4;
  vpx->cfg.kf_mode = VPX_KF_AUTO;
  vpx->cfg.rc_end_usage = VPX_VBR;
  
  vpx->cfg.kf_max_dist = 120;
  
  vpx->deadline = 15 * 1000;

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

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

  krad_vpx_encoder_print_config (vpx);

  return vpx;
}
/*
 * Method:    codec_enc_config_default
 */
JNIEXPORT jint JNICALL
Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1enc_1config_1default
    (JNIEnv *env,
     jclass clazz,
     jint iface,
     jlong cfg,
     jint usage)
{
    return vpx_codec_enc_config_default(
                     GET_INTERFACE(iface),
                     (vpx_codec_enc_cfg_t *) (intptr_t) cfg,
                     (int) usage);
}
Esempio n. 5
0
int vp8Encoder::initilize(int frameWidth, int frameHeight)
{
    //display_width = frameWidth;
    //display_height = frameHeight;

    pthread_mutex_lock (&mCodecLock);
    frame_cnt = 0;

    vpx_codec_enc_cfg_t    cfg;
    int cpu_used = 8;
    int static_threshold = 1200;

    vpx_codec_enc_config_default(interface, &cfg, 0);
    LOGD("Using %s\n",vpx_codec_iface_name(interface));

    cfg.rc_target_bitrate = 10*frameWidth * frameHeight * cfg.rc_target_bitrate
        / cfg.g_w / cfg.g_h;
    LOGD("Encoder cfg.rc_target_bitrate=%d", cfg.rc_target_bitrate);
    cfg.g_w = display_width;
    cfg.g_h = display_height;
    /*cfg.g_timebase.num = 1;
    cfg.g_timebase.den = (int) 10000000;
    cfg.rc_end_usage = VPX_CBR;
    cfg.g_pass = VPX_RC_ONE_PASS;
    cfg.g_lag_in_frames = 0;
    cfg.rc_min_quantizer = 20;
    cfg.rc_max_quantizer = 50;
    cfg.rc_dropframe_thresh = 1;
    cfg.rc_buf_optimal_sz = 1000;
    cfg.rc_buf_initial_sz = 1000;
    cfg.rc_buf_sz = 1000;
    cfg.g_error_resilient = 1;
    cfg.kf_mode = VPX_KF_DISABLED;
    cfg.kf_max_dist = 999999;
    cfg.g_threads = 1;*/

    vpx_codec_enc_init(&encoder, interface, &cfg, 0);
    /*vpx_codec_control_(&encoder, VP8E_SET_CPUUSED, cpu_used);
    vpx_codec_control_(&encoder, VP8E_SET_STATIC_THRESHOLD, static_threshold);
    vpx_codec_control_(&encoder, VP8E_SET_ENABLEAUTOALTREF, 0);
    */
    vpx_img_alloc(&raw, VPX_IMG_FMT_I420, display_width, display_height, 1);

    //create_packetizer(&x, XOR, fec_numerator, fec_denominator);

    //sDecoder->initilize();
    pthread_mutex_unlock (&mCodecLock);
    return 0;
}
Esempio n. 6
0
int
x_vpx_encoder_init(vpx_codec_ctx_t *_p_encoder, int numcores, int width,
    int height)
{
  int res;
  vpx_codec_enc_cfg_t cfg;

  res = vpx_codec_enc_config_default((vpx_codec_vp8_cx()), &cfg, 0);
  if (res)
    {
      printf("Failed to get config: %s\n", vpx_codec_err_to_string(res));
      return -EBADF;
    }

  /* Update the default configuration with our settings */
  printf("Initializing: %dx%d, BR=%d, cfg.g_timebase.den=%d\n", width, height,
      cfg.rc_target_bitrate, cfg.g_timebase.den);

  cfg.rc_target_bitrate = width * height * cfg.rc_target_bitrate / cfg.g_w
      / cfg.g_h * 2;
  cfg.g_w = width;
  cfg.g_h = height;
  cfg.g_profile = 0;
  //cfg.kf_mode = VPX_KF_AUTO;
  cfg.kf_max_dist = 30;
  //cfg.kf_min_dist = 0;
  cfg.g_threads = 4;
  cfg.g_pass = VPX_RC_ONE_PASS;
  cfg.rc_end_usage = VPX_CBR;
  if (cfg.rc_end_usage == VPX_CBR)
    {
      cfg.rc_buf_initial_sz = 2000;
      cfg.rc_buf_optimal_sz = 2000;
      cfg.rc_buf_sz = 3000;
    }

  //  cfg.g_timebase.num = 1001;
  //  cfg.g_timebase.den = 30000;

  if (vpx_codec_enc_init(_p_encoder, (vpx_codec_vp8_cx()), &cfg, 0))
    {
      printf("Failed to init config: %s\n", vpx_codec_error(_p_encoder));
      die_codec(_p_encoder, "vpx_codec_enc_init()");
      return -ENOMEM;
    }

  return 0;
}
Esempio n. 7
0
void WebMEncoder::initializeVideoEncoder() {
    /* Populate encoder configuration */
    vpx_codec_err_t res = vpx_codec_enc_config_default(&vpx_enc_vp8_algo, &cfg, 0);
    
    if (res) {
        fprintf(stderr, "Failed to get config: %s\n",
                vpx_codec_err_to_string(res));
	    exit(1);
    }

    if(boost::thread::hardware_concurrency()) {
        cfg.g_threads = boost::thread::hardware_concurrency() - 1;
    }

    /* Change the default timebase to a high enough value so that the encoder
     * will always create strictly increasing timestamps.
     */
    cfg.g_timebase.num = 1;
    cfg.g_timebase.den = 30;

    // lag_in_frames allows for extra optimization at the expense of not writing frames in realtime
    cfg.g_lag_in_frames = 5;

    // Variable bit rate
    cfg.rc_end_usage = VPX_VBR;

    // Target data rate in Kbps (lowercase b)
    cfg.rc_target_bitrate = 1024; //1 Mbit/sec
    
    /* Never use the library's default resolution, require it be parsed
     * from the file or set on the command line.
     */
    cfg.g_w = width;
    cfg.g_h = height;
    
    vpx_img_alloc(&raw, VPX_IMG_FMT_YV12,
                  cfg.g_w, cfg.g_h, 1);
    
    cfg.g_pass = VPX_RC_ONE_PASS;
    
    /* Construct Encoder Context */
    vpx_codec_enc_init(&encoder, &vpx_enc_vp8_algo, &cfg, 0);
    if(encoder.err) {
        printf("Failed to initialize encoder\n");
    }
}
    information()
    {
        m_raw.planes[0] = NULL;
        m_codec.iface = NULL;

        vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &m_cfg, 0);

        m_cfg.rc_target_bitrate = 2000;
        m_cfg.g_w = 640;
        m_cfg.g_h = 480;

        m_frameCnt = 0;

        vpx_codec_enc_init(&m_codec, vpx_codec_vp8_cx(), &m_cfg, 0);

        vpx_img_alloc(&m_raw, VPX_IMG_FMT_I420, 640, 480, 1);
    }
static void
gst_vp9_enc_init (GstVP9Enc * gst_vp9_enc)
{
  vpx_codec_err_t status;
  GstVPXEnc *gst_vpx_enc = GST_VPX_ENC (gst_vp9_enc);
  GST_DEBUG_OBJECT (gst_vp9_enc, "gst_vp9_enc_init");
  status =
      vpx_codec_enc_config_default (gst_vp9_enc_get_algo (gst_vpx_enc),
      &gst_vpx_enc->cfg, 0);
  if (status != VPX_CODEC_OK) {
    GST_ERROR_OBJECT (gst_vpx_enc,
        "Failed to get default encoder configuration: %s",
        gst_vpx_error_name (status));
    gst_vpx_enc->have_default_config = FALSE;
  } else {
    gst_vpx_enc->have_default_config = TRUE;
  }
}
Esempio n. 10
0
JNIEXPORT jint Java_ryulib_VideoZip_VPX_OpenEncoder(JNIEnv* env,
		jclass clazz, jint width, jint height, jint bitRate, int fps, int gop)
{
	RyuVPX *pHandle = (RyuVPX *) malloc(sizeof(RyuVPX));
	
	pHandle->errorCode = 0;

	if (!vpx_img_alloc(&pHandle->img, VPX_IMG_FMT_I420 , width, height, 1)) {
		pHandle->errorCode = _Error_Allocate_Image;
		goto EXIT;
	}

	if (vpx_codec_enc_config_default(interfaceEnc, &pHandle->cfgEnc, 0)) {
		pHandle->errorCode = _Error_Getting_Config;
		goto EXIT;
	}

	pHandle->cfgEnc.g_w = width;
	pHandle->cfgEnc.g_h = height;
	pHandle->cfgEnc.rc_target_bitrate = bitRate;

	if (0 != bitRate) {
		pHandle->cfgEnc.rc_target_bitrate = bitRate;
	} else {
		pHandle->cfgEnc.rc_target_bitrate = width * height * pHandle->cfgEnc.rc_target_bitrate  / pHandle->cfgEnc.g_w / pHandle->cfgEnc.g_h;    
	}

	if (0 != gop) {
		pHandle->cfgEnc.kf_max_dist = gop;
	} 

	if (-1 == gop) {
		pHandle->cfgEnc.kf_mode = VPX_KF_DISABLED;
	}

	if (vpx_codec_enc_init(&pHandle->codec, interfaceEnc, &pHandle->cfgEnc, 0)) {
		pHandle->errorCode = _Error_Init_VideoCodec;
		goto EXIT;
	}

EXIT:

	return pHandle;
}
Esempio n. 11
0
HRESULT InitVPXEncoder(vpx_codec_enc_cfg_t * vpxConfig, vpx_codec_ctx_t * vpxCodec, unsigned int width, unsigned int height)
{
	//vpx_codec_ctx_t      codec;

	vpx_codec_err_t res;

	printf("Using %s\n", vpx_codec_iface_name(vpx_codec_vp8_cx()));

	/* Populate encoder configuration */
	res = vpx_codec_enc_config_default((vpx_codec_vp8_cx()), vpxConfig, 0);

	if (res) {
		printf("Failed to get VPX codec config: %s\n", vpx_codec_err_to_string(res));
		return -1;
	}
	else {
		vpx_img_alloc(&_rawImage, VIDEO_INPUT_FORMAT, WIDTH, HEIGHT, 0);

		vpxConfig->g_w = width;
		vpxConfig->g_h = height;
		vpxConfig->rc_target_bitrate = 5000; // in kbps.
		vpxConfig->rc_min_quantizer = 20; // 50;
		vpxConfig->rc_max_quantizer = 30; // 60;
		vpxConfig->g_pass = VPX_RC_ONE_PASS;
		vpxConfig->rc_end_usage = VPX_CBR;
		//vpxConfig->kf_min_dist = 50;
		//vpxConfig->kf_max_dist = 50;
		//vpxConfig->kf_mode = VPX_KF_DISABLED;
		vpxConfig->g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT;
		vpxConfig->g_lag_in_frames = 0;
		vpxConfig->rc_resize_allowed = 0;

		/* Initialize codec */
		if (vpx_codec_enc_init(vpxCodec, (vpx_codec_vp8_cx()), vpxConfig, 0)) {
			printf("Failed to initialize libvpx encoder.\n");
			return -1;
		}
		else {
			return S_OK;
		}
	}
}
Esempio n. 12
0
static void enc_init(MSFilter *f) {
	vpx_codec_err_t res;
	MSVideoSize vsize;
	EncState *s=(EncState *)ms_new0(EncState,1);

	ms_message("Using %s\n",vpx_codec_iface_name(interface));

	/* Populate encoder configuration */
	res = vpx_codec_enc_config_default(interface, &s->cfg, 0);
	if(res) {
		ms_error("Failed to get config: %s\n", vpx_codec_err_to_string(res));
	}

	if (ms_get_cpu_count() > 1) s->vconf_list = &multicore_vp8_conf_list[0];
	else s->vconf_list = &vp8_conf_list[0];
	MS_VIDEO_SIZE_ASSIGN(vsize, CIF);
	s->vconf = ms_video_find_best_configuration_for_size(s->vconf_list, vsize);
	s->frame_count = 0;
	s->cfg.g_w = s->vconf.vsize.width;
	s->cfg.g_h = s->vconf.vsize.height;
	/* encoder automatically places keyframes */
	s->cfg.kf_mode = VPX_KF_AUTO;
	s->cfg.kf_max_dist = 300;
	s->cfg.rc_target_bitrate = ((float)s->vconf.required_bitrate)*0.92/1024.0; //0.9=take into account IP/UDP/RTP overhead, in average.
	s->cfg.g_pass = VPX_RC_ONE_PASS; /* -p 1 */
	s->cfg.g_timebase.num = 1;
	s->cfg.g_timebase.den = s->vconf.fps;
	s->cfg.rc_end_usage = VPX_CBR; /* --end-usage=cbr */
#if TARGET_IPHONE_SIMULATOR
	s->cfg.g_threads = 1; /*workaround to remove crash on ipad simulator*/ 
#else
	s->cfg.g_threads = ms_get_cpu_count();
#endif
	ms_message("VP8 g_threads=%d", s->cfg.g_threads);
	s->cfg.rc_undershoot_pct = 95; /* --undershoot-pct=95 */
	s->cfg.g_error_resilient = 1;
	s->cfg.g_lag_in_frames = 0;
	s->mtu=ms_get_payload_max_size()-1;/*-1 for the vp8 payload header*/

	f->data = s;
}
Esempio n. 13
0
	int VPXEncoder::InitEncoder(unsigned int width, unsigned int height)
	{
		_vpxCodec = new vpx_codec_ctx_t();
		_rawImage = new vpx_image_t();
		_width = width;
		_height = height;

		vpx_codec_enc_cfg_t vpxConfig;
		vpx_codec_err_t res;

		printf("Using %s\n", vpx_codec_iface_name(vpx_codec_vp8_cx()));

		/* Populate encoder configuration */
		res = vpx_codec_enc_config_default((vpx_codec_vp8_cx()), &vpxConfig, 0);

		if (res) {
			printf("Failed to get VPX codec config: %s\n", vpx_codec_err_to_string(res));
			return -1;
		}
		else {
			vpx_img_alloc(_rawImage, VPX_IMG_FMT_I420, width, height, 0);

			vpxConfig.g_w = width;
			vpxConfig.g_h = height;
			vpxConfig.rc_target_bitrate = 300; // 5000; // in kbps.
			vpxConfig.rc_min_quantizer = 20; // 50;
			vpxConfig.rc_max_quantizer = 30; // 60;
			vpxConfig.g_pass = VPX_RC_ONE_PASS;
			vpxConfig.rc_end_usage = VPX_CBR;
			vpxConfig.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT;
			vpxConfig.g_lag_in_frames = 0;
			vpxConfig.rc_resize_allowed = 0;
			vpxConfig.kf_max_dist = 20;

			/* Initialize codec */
			if (vpx_codec_enc_init(_vpxCodec, (vpx_codec_vp8_cx()), &vpxConfig, 0)) {
				printf("Failed to initialize libvpx encoder.\n");
				return -1;
			}
		}
	}
Esempio n. 14
0
static int init_video_encoder(CSSession *cs, uint16_t max_width, uint16_t max_height, uint32_t video_bitrate)
{
    vpx_codec_enc_cfg_t  cfg;
    int rc = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0);

    if (rc != VPX_CODEC_OK) {
        LOGGER_ERROR("Failed to get config: %s", vpx_codec_err_to_string(rc));
        return -1;
    }

    cfg.rc_target_bitrate = video_bitrate;
    cfg.g_w = max_width;
    cfg.g_h = max_height;
    cfg.g_pass = VPX_RC_ONE_PASS;
    cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT | VPX_ERROR_RESILIENT_PARTITIONS;
    cfg.g_lag_in_frames = 0;
    cfg.kf_min_dist = 0;
    cfg.kf_max_dist = 48;
    cfg.kf_mode = VPX_KF_AUTO;

    rc = vpx_codec_enc_init_ver(&cs->v_encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0, VPX_ENCODER_ABI_VERSION);

    if ( rc != VPX_CODEC_OK) {
        LOGGER_ERROR("Failed to initialize encoder: %s", vpx_codec_err_to_string(rc));
        return -1;
    }

    rc = vpx_codec_control(&cs->v_encoder, VP8E_SET_CPUUSED, 8);

    if ( rc != VPX_CODEC_OK) {
        LOGGER_ERROR("Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc));
        return -1;
    }

    cs->max_width = max_width;
    cs->max_height = max_height;
    cs->video_bitrate = video_bitrate;

    return 0;
}
Esempio n. 15
0
int init_video_encoder(CodecState *cs, uint16_t width, uint16_t height, uint32_t video_bitrate)
{
    vpx_codec_enc_cfg_t  cfg;
    int res = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0);

    if (res) {
        fprintf(stderr, "Failed to get config: %s\n", vpx_codec_err_to_string(res));
        return -1;
    }

    cfg.rc_target_bitrate = video_bitrate;
    cfg.g_w = width;
    cfg.g_h = height;

    if (vpx_codec_enc_init_ver(&cs->v_encoder, VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0,
                               VPX_ENCODER_ABI_VERSION) != VPX_CODEC_OK) {
        fprintf(stderr, "Failed to initialize encoder\n");
        return -1;
    }

    return 0;
}
Esempio n. 16
0
int start_encode(encoding_context *context, char *path, int width, int height, float fps, int *durations, int deadline) {
	if (0!=vpx_codec_enc_config_default(WG_CODEC_INTERFACE, &context->cfg, 0)) return 1000;
	context->cfg.g_w = width;
	context->cfg.g_h = height;
	context->deadline = deadline; // microseconds to spend encoding each frame
	context->timebase_units_per_second = 30.0f; // always 30?
	context->frames_per_second = fps;
	context->frame_durations = durations;
	
	FILE *outfile = fopen(path, "wb");
	if (!outfile) return 1001;
	context->ebml.stream = outfile;
	
	if (!vpx_img_alloc(&context->vpx_image, VPX_IMG_FMT_I420, width, height, 1)) return 1002;
	
	if (0!=vpx_codec_enc_init(&context->codec, WG_CODEC_INTERFACE, &context->cfg, 0)) return 1003;
	
	struct vpx_rational framerate = {fps, 1};
	const struct VpxRational pixel_aspect_ratio = {1, 1};
	write_webm_file_header(&context->ebml, &context->cfg, &framerate, STEREO_FORMAT_MONO, WG_FOURCC, &pixel_aspect_ratio);
	
	return 0;
}
Esempio n. 17
0
struct vpx_context *init_encoder(int width, int height, const char *colorspace)
{
	vpx_codec_enc_cfg_t cfg;
	vpx_img_fmt_t vpx_colorspace;
	struct vpx_context *ctx;
	vpx_codec_iface_t *codec_iface;

	vpx_colorspace = get_vpx_colorspace(colorspace);
	if (vpx_colorspace<0)
		return NULL;

	codec_iface = vpx_codec_vp8_cx();
	if (vpx_codec_enc_config_default(codec_iface, &cfg, 0))
		return NULL;

	cfg.rc_target_bitrate = width * height * cfg.rc_target_bitrate / cfg.g_w / cfg.g_h;
	cfg.g_w = width;
	cfg.g_h = height;
	cfg.g_error_resilient = 0;
	cfg.g_lag_in_frames = 0;
	cfg.rc_dropframe_thresh = 0;
	//cfg.rc_resize_allowed = 1;
	ctx = malloc(sizeof(struct vpx_context));
	if (ctx == NULL)
		return NULL;
	memset(ctx, 0, sizeof(struct vpx_context));
	if (vpx_codec_enc_init(&ctx->codec, codec_iface, &cfg, 0)) {
		codec_error(&ctx->codec, "vpx_codec_enc_init");
		free(ctx);
		return NULL;
	}
	ctx->width = width;
	ctx->height = height;
	ctx->pixfmt = vpx_colorspace;
	return ctx;
}
Esempio n. 18
0
static void enc_init(MSFilter *f) {
	vpx_codec_err_t res;
	EncState *s=(EncState *)ms_new0(EncState,1);

	ms_message("Using %s\n",vpx_codec_iface_name(interface));

	/* Populate encoder configuration */
	res = vpx_codec_enc_config_default(interface, &s->cfg, 0);
	if(res) {
		ms_error("Failed to get config: %s\n", vpx_codec_err_to_string(res));
	}

	s->width = MS_VIDEO_SIZE_CIF_W;
	s->height = MS_VIDEO_SIZE_CIF_H;
	s->bitrate=256000;
	s->frame_count = 0;
	s->cfg.g_w = s->width;
	s->cfg.g_h = s->height;
	/* encoder automatically places keyframes */
	s->cfg.kf_mode = VPX_KF_AUTO;
	s->cfg.kf_max_dist = 300;
	s->cfg.rc_target_bitrate = ((float)s->bitrate)*0.92/1024.0; //0.9=take into account IP/UDP/RTP overhead, in average.
	s->cfg.g_pass = VPX_RC_ONE_PASS; /* -p 1 */
	s->fps=15;
	s->cfg.g_timebase.num = 1;
	s->cfg.g_timebase.den = s->fps;
	s->cfg.rc_end_usage = VPX_CBR; /* --end-usage=cbr */
	s->cfg.g_threads = ms_get_cpu_count();
	ms_message("VP8 g_threads=%d", s->cfg.g_threads);
	s->cfg.rc_undershoot_pct = 95; /* --undershoot-pct=95 */
	s->cfg.g_error_resilient = 1;
	s->cfg.g_lag_in_frames = 0;
	s->mtu=ms_get_payload_max_size()-1;/*-1 for the vp8 payload header*/

	f->data = s;
}
int main(int argc, char **argv) {
    FILE                *infile, *outfile;
    vpx_codec_ctx_t      codec;
    vpx_codec_enc_cfg_t  cfg;
    int                  frame_cnt = 0;
    vpx_image_t          raw;
    vpx_codec_err_t      res;
    long                 width;
    long                 height;
    int                  frame_avail;
    int                  got_data;
    int                  flags = 0;

    /* Open files */
    if(argc!=5)
        die("Usage: %s <width> <height> <infile> <outfile>\n", argv[0]);
    width = strtol(argv[1], NULL, 0);
    height = strtol(argv[2], NULL, 0);
    if(width < 16 || width%2 || height <16 || height%2)
        die("Invalid resolution: %ldx%ld", width, height);
    if(!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 1))
        die("Faile to allocate image", width, height);
    if(!(outfile = fopen(argv[4], "wb")))
        die("Failed to open %s for writing", argv[4]);

    printf("Using %s\n",vpx_codec_iface_name(interface));

    /* Populate encoder configuration */                                      //
    res = vpx_codec_enc_config_default(interface, &cfg, 0);                   //
    if(res) {                                                                 //
        printf("Failed to get config: %s\n", vpx_codec_err_to_string(res));   //
        return EXIT_FAILURE;                                                  //
    }                                                                         //

    /* Update the default configuration with our settings */                  //
    cfg.rc_target_bitrate = width * height * cfg.rc_target_bitrate            //
                            / cfg.g_w / cfg.g_h;                              //
    cfg.g_w = width;                                                          //
    cfg.g_h = height;                                                         //

    write_ivf_file_header(outfile, &cfg, 0);


        /* Open input file for this encoding pass */
        if(!(infile = fopen(argv[3], "rb")))
            die("Failed to open %s for reading", argv[3]);

        /* Initialize codec */                                                //
        if(vpx_codec_enc_init(&codec, interface, &cfg, 0))                    //
            die_codec(&codec, "Failed to initialize encoder");                //

        frame_avail = 1;
        got_data = 0;
        while(frame_avail || got_data) {
            vpx_codec_iter_t iter = NULL;
            const vpx_codec_cx_pkt_t *pkt;

            frame_avail = read_frame(infile, &raw);                           //
            if(vpx_codec_encode(&codec, frame_avail? &raw : NULL, frame_cnt,  //
                                1, flags, VPX_DL_REALTIME))                   //
                die_codec(&codec, "Failed to encode frame");                  //
            got_data = 0;
            while( (pkt = vpx_codec_get_cx_data(&codec, &iter)) ) {
                got_data = 1;
                switch(pkt->kind) {
                case VPX_CODEC_CX_FRAME_PKT:                                  //
                    write_ivf_frame_header(outfile, pkt);                     //
                    if(fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz,     //
                              outfile));                                      //
                    break;                                                    //
                default:
                    break;
                }
                printf(pkt->kind == VPX_CODEC_CX_FRAME_PKT
                       && (pkt->data.frame.flags & VPX_FRAME_IS_KEY)? "K":".");
                fflush(stdout);
            }
            frame_cnt++;
        }
        printf("\n");
        fclose(infile);

    printf("Processed %d frames.\n",frame_cnt-1);
    if(vpx_codec_destroy(&codec))                                             //
        die_codec(&codec, "Failed to destroy codec");                         //

    /* Try to rewrite the file header with the actual frame count */
    if(!fseek(outfile, 0, SEEK_SET))
        write_ivf_file_header(outfile, &cfg, frame_cnt-1);
    fclose(outfile);
    return EXIT_SUCCESS;
}
Esempio n. 20
0
int main(int argc, char* argv[])
{
	if (argc != 7)
	{
		fprintf(stderr, "  Usage: WebMEnc <input filename> <flip> <threads> <bit-rates> <frame-per-second> <output filename>\nExample: WebMEnc frame.%%.5d.tiff 1 8 512 30 frame.webm\n");
		return EXIT_FAILURE;
	}

	ilInit();
	iluInit();

	// Initialize VPX codec.
	//
	vpx_codec_ctx_t vpxContext;
	vpx_codec_enc_cfg_t vpxConfig;

    if (vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &vpxConfig, 0) != VPX_CODEC_OK)
	{
        return EXIT_FAILURE;
    }

	// Try to load the first frame to initialize width and height.
	//
	int flip = (bool)atoi(argv[2]);

	vpx_image_t *rgbImage = NULL, *yv12Image = NULL;
	if (readImage(argv[1], 0, &rgbImage, &yv12Image, flip) == false)
	{
		return EXIT_FAILURE;
	}
	vpxConfig.g_h = yv12Image->h;
	vpxConfig.g_w = yv12Image->w;

	vpxConfig.g_threads = atoi(argv[3]);

	vpxConfig.rc_target_bitrate = atoi(argv[4]);

	vpxConfig.g_timebase.den = atoi(argv[5]);
	vpxConfig.g_timebase.num = 1;

	// Prepare the output .webm file.
	//
	EbmlGlobal ebml;
	memset(&ebml, 0, sizeof(EbmlGlobal));
	ebml.last_pts_ms = -1;
	ebml.stream = fopen(argv[6], "wb");
	if (ebml.stream == NULL)
	{
		return EXIT_FAILURE;
	}
	vpx_rational ebmlFPS = vpxConfig.g_timebase;
	struct vpx_rational arg_framerate = {atoi(argv[5]), 1};
	Ebml_WriteWebMFileHeader(&ebml, &vpxConfig, &arg_framerate);

	unsigned long duration = (float)arg_framerate.den / (float)arg_framerate.num * 1000;

	if (vpx_codec_enc_init(&vpxContext, vpx_codec_vp8_cx(), &vpxConfig, 0) != VPX_CODEC_OK)
	{
        return EXIT_FAILURE;
    }

	//
	fprintf(stdout, "input=%s\nflip=%s\nthreads=%s\nbps=%s\nfps=%s\noutput=%s\n", argv[1], argv[2], argv[3], argv[4], argv[5], argv[6]);

	
	// Reading image file sequence, encoding to .WebM file.
	//
	int frameNumber = 0;
	while(readImage(argv[1], frameNumber, &rgbImage, &yv12Image, flip))
	{
		vpx_codec_err_t vpxError = vpx_codec_encode(&vpxContext, yv12Image, frameNumber, duration, 0, 0);
		if (vpxError != VPX_CODEC_OK)
		{
			return EXIT_FAILURE;
		}
		
		vpx_codec_iter_t iter = NULL;
		const vpx_codec_cx_pkt_t *packet;
		while( (packet = vpx_codec_get_cx_data(&vpxContext, &iter)) )
		{
			Ebml_WriteWebMBlock(&ebml, &vpxConfig, packet);
		}

		frameNumber ++;
		printf("Processed %d frames.\r", frameNumber);

		vpx_img_free(yv12Image);
		yv12Image = NULL;
	}

	Ebml_WriteWebMFileFooter(&ebml, 0);
	fclose(ebml.stream);

	vpx_codec_destroy(&vpxContext);

	return EXIT_SUCCESS;
}
int main(int argc, char **argv) {
    FILE                *infile, *outfile[MAX_LAYERS];
    vpx_codec_ctx_t      codec;
    vpx_codec_enc_cfg_t  cfg;
    int                  frame_cnt = 0;
    vpx_image_t          raw;
    vpx_codec_err_t      res;
    unsigned int         width;
    unsigned int         height;
    int                  frame_avail;
    int                  got_data;
    int                  flags = 0;
    int                  i;
    int                  pts = 0;              // PTS starts at 0
    int                  frame_duration = 1;   // 1 timebase tick per frame

    int                  layering_mode = 0;
    int                  frames_in_layer[MAX_LAYERS] = {0};
    int                  layer_flags[MAX_PERIODICITY] = {0};

    // Check usage and arguments
    if (argc < 9)
        die("Usage: %s <infile> <outfile> <width> <height> <rate_num> "
            " <rate_den> <mode> <Rate_0> ... <Rate_nlayers-1>\n", argv[0]);

    width  = strtol (argv[3], NULL, 0);
    height = strtol (argv[4], NULL, 0);
    if (width < 16 || width%2 || height <16 || height%2)
        die ("Invalid resolution: %d x %d", width, height);

    if (!sscanf(argv[7], "%d", &layering_mode))
        die ("Invalid mode %s", argv[7]);
    if (layering_mode<0 || layering_mode>6)
        die ("Invalid mode (0..6) %s", argv[7]);

    if (argc != 8+mode_to_num_layers[layering_mode])
        die ("Invalid number of arguments");

    if (!vpx_img_alloc (&raw, VPX_IMG_FMT_I420, width, height, 1))
        die ("Failed to allocate image", width, height);

    printf("Using %s\n",vpx_codec_iface_name(interface));

    // Populate encoder configuration
    res = vpx_codec_enc_config_default(interface, &cfg, 0);
    if(res) {
        printf("Failed to get config: %s\n", vpx_codec_err_to_string(res));
        return EXIT_FAILURE;
    }

    // Update the default configuration with our settings
    cfg.g_w = width;
    cfg.g_h = height;

    // Timebase format e.g. 30fps: numerator=1, demoninator=30
    if (!sscanf (argv[5], "%d", &cfg.g_timebase.num ))
        die ("Invalid timebase numerator %s", argv[5]);
    if (!sscanf (argv[6], "%d", &cfg.g_timebase.den ))
        die ("Invalid timebase denominator %s", argv[6]);

    for (i=8; i<8+mode_to_num_layers[layering_mode]; i++)
        if (!sscanf(argv[i], "%d", &cfg.ts_target_bitrate[i-8]))
            die ("Invalid data rate %s", argv[i]);

    // Real time parameters
    cfg.rc_dropframe_thresh = 0;
    cfg.rc_end_usage        = VPX_CBR;
    cfg.rc_resize_allowed   = 0;
    cfg.rc_min_quantizer    = 4;
    cfg.rc_max_quantizer    = 63;
    cfg.rc_undershoot_pct   = 98;
    cfg.rc_overshoot_pct    = 100;
    cfg.rc_buf_initial_sz   = 500;
    cfg.rc_buf_optimal_sz   = 600;
    cfg.rc_buf_sz           = 1000;

    // Enable error resilient mode
    cfg.g_error_resilient = 1;
    cfg.g_lag_in_frames   = 0;
    cfg.kf_mode           = VPX_KF_DISABLED;

    // Disable automatic keyframe placement
    cfg.kf_min_dist = cfg.kf_max_dist = 1000;

    // Temporal scaling parameters:
    // NOTE: The 3 prediction frames cannot be used interchangeably due to
    // differences in the way they are handled throughout the code. The
    // frames should be allocated to layers in the order LAST, GF, ARF.
    // Other combinations work, but may produce slightly inferior results.
    switch (layering_mode)
    {

    case 0:
    {
        // 2-layers, 2-frame period
        int ids[2] = {0,1};
        cfg.ts_number_layers     = 2;
        cfg.ts_periodicity       = 2;
        cfg.ts_rate_decimator[0] = 2;
        cfg.ts_rate_decimator[1] = 1;
        memcpy(cfg.ts_layer_id, ids, sizeof(ids));

#if 1
        // 0=L, 1=GF, Intra-layer prediction enabled
        layer_flags[0] = VPX_EFLAG_FORCE_KF  |
                         VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
                         VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
        layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
                         VP8_EFLAG_NO_REF_ARF;
#else
        // 0=L, 1=GF, Intra-layer prediction disabled
        layer_flags[0] = VPX_EFLAG_FORCE_KF  |
                         VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF |
                         VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF;
        layer_flags[1] = VP8_EFLAG_NO_UPD_ARF | VP8_EFLAG_NO_UPD_LAST |
                         VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_REF_LAST;
#endif
        break;
    }

    case 1:
    {
        // 2-layers, 3-frame period
        int ids[3] = {0,1,1};
        cfg.ts_number_layers     = 2;
        cfg.ts_periodicity       = 3;
        cfg.ts_rate_decimator[0] = 3;
        cfg.ts_rate_decimator[1] = 1;
        memcpy(cfg.ts_layer_id, ids, sizeof(ids));

        // 0=L, 1=GF, Intra-layer prediction enabled
        layer_flags[0] = VPX_EFLAG_FORCE_KF  |
                         VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
                         VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
        layer_flags[1] =
        layer_flags[2] = VP8_EFLAG_NO_REF_GF  |
                         VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF |
                                                VP8_EFLAG_NO_UPD_LAST;
        break;
    }

    case 2:
    {
        // 3-layers, 6-frame period
        int ids[6] = {0,2,2,1,2,2};
        cfg.ts_number_layers     = 3;
        cfg.ts_periodicity       = 6;
        cfg.ts_rate_decimator[0] = 6;
        cfg.ts_rate_decimator[1] = 3;
        cfg.ts_rate_decimator[2] = 1;
        memcpy(cfg.ts_layer_id, ids, sizeof(ids));

        // 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled
        layer_flags[0] = VPX_EFLAG_FORCE_KF  |
                         VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
                         VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
        layer_flags[3] = VP8_EFLAG_NO_REF_ARF | VP8_EFLAG_NO_UPD_ARF |
                                                VP8_EFLAG_NO_UPD_LAST;
        layer_flags[1] =
        layer_flags[2] =
        layer_flags[4] =
        layer_flags[5] = VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_LAST;
        break;
    }

    case 3:
    {
        // 3-layers, 4-frame period
        int ids[4] = {0,2,1,2};
        cfg.ts_number_layers     = 3;
        cfg.ts_periodicity       = 4;
        cfg.ts_rate_decimator[0] = 4;
        cfg.ts_rate_decimator[1] = 2;
        cfg.ts_rate_decimator[2] = 1;
        memcpy(cfg.ts_layer_id, ids, sizeof(ids));

        // 0=L, 1=GF, 2=ARF, Intra-layer prediction disabled
        layer_flags[0] = VPX_EFLAG_FORCE_KF  |
                         VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
                         VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
        layer_flags[2] = VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
                         VP8_EFLAG_NO_UPD_ARF |
                         VP8_EFLAG_NO_UPD_LAST;
        layer_flags[1] =
        layer_flags[3] = VP8_EFLAG_NO_REF_ARF |
                         VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
                         VP8_EFLAG_NO_UPD_ARF;
        break;
    }

    case 4:
    {
        // 3-layers, 4-frame period
        int ids[4] = {0,2,1,2};
        cfg.ts_number_layers     = 3;
        cfg.ts_periodicity       = 4;
        cfg.ts_rate_decimator[0] = 4;
        cfg.ts_rate_decimator[1] = 2;
        cfg.ts_rate_decimator[2] = 1;
        memcpy(cfg.ts_layer_id, ids, sizeof(ids));

        // 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled in layer 1,
        // disabled in layer 2
        layer_flags[0] = VPX_EFLAG_FORCE_KF  |
                         VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
                         VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
        layer_flags[2] = VP8_EFLAG_NO_REF_ARF |
                         VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
        layer_flags[1] =
        layer_flags[3] = VP8_EFLAG_NO_REF_ARF |
                         VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF |
                         VP8_EFLAG_NO_UPD_ARF;
        break;
    }

    case 5:
    {
        // 3-layers, 4-frame period
        int ids[4] = {0,2,1,2};
        cfg.ts_number_layers     = 3;
        cfg.ts_periodicity       = 4;
        cfg.ts_rate_decimator[0] = 4;
        cfg.ts_rate_decimator[1] = 2;
        cfg.ts_rate_decimator[2] = 1;
        memcpy(cfg.ts_layer_id, ids, sizeof(ids));

        // 0=L, 1=GF, 2=ARF, Intra-layer prediction enabled
        layer_flags[0] = VPX_EFLAG_FORCE_KF  |
                         VP8_EFLAG_NO_REF_GF | VP8_EFLAG_NO_REF_ARF |
                         VP8_EFLAG_NO_UPD_GF | VP8_EFLAG_NO_UPD_ARF;
        layer_flags[2] = VP8_EFLAG_NO_REF_ARF |
                         VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_ARF;
        layer_flags[1] =
        layer_flags[3] = VP8_EFLAG_NO_UPD_LAST | VP8_EFLAG_NO_UPD_GF;
        break;
    }

    case 6:
    {
        // NOTE: Probably of academic interest only

        // 5-layers, 16-frame period
        int ids[16] = {0,4,3,4,2,4,3,4,1,4,3,4,2,4,3,4};
        cfg.ts_number_layers     = 5;
        cfg.ts_periodicity       = 16;
        cfg.ts_rate_decimator[0] = 16;
        cfg.ts_rate_decimator[1] = 8;
        cfg.ts_rate_decimator[2] = 4;
        cfg.ts_rate_decimator[3] = 2;
        cfg.ts_rate_decimator[4] = 1;
        memcpy(cfg.ts_layer_id, ids, sizeof(ids));

        layer_flags[0]  = VPX_EFLAG_FORCE_KF;
        layer_flags[1]  =
        layer_flags[3]  =
        layer_flags[5]  =
        layer_flags[7]  =
        layer_flags[9]  =
        layer_flags[11] =
        layer_flags[13] =
        layer_flags[15] = VP8_EFLAG_NO_UPD_LAST |
                          VP8_EFLAG_NO_UPD_GF   |
                          VP8_EFLAG_NO_UPD_ARF  |
                          VP8_EFLAG_NO_UPD_ENTROPY;
        layer_flags[2]  =
        layer_flags[6]  =
        layer_flags[10] =
        layer_flags[14] = 0;
        layer_flags[4]  =
        layer_flags[12] = VP8_EFLAG_NO_REF_LAST;
        layer_flags[8]  = VP8_EFLAG_NO_REF_LAST | VP8_EFLAG_NO_REF_GF |
                          VP8_EFLAG_NO_UPD_ENTROPY;
        break;
    }

    default:
        break;
    }

    // Open input file
    if(!(infile = fopen(argv[1], "rb")))
        die("Failed to open %s for reading", argv[1]);

    // Open an output file for each stream
    for (i=0; i<cfg.ts_number_layers; i++)
    {
        char file_name[512];
        sprintf (file_name, "%s_%d.ivf", argv[2], i);
        if (!(outfile[i] = fopen(file_name, "wb")))
            die("Failed to open %s for writing", file_name);
        write_ivf_file_header(outfile[i], &cfg, 0);
    }

    // Initialize codec
    if (vpx_codec_enc_init (&codec, interface, &cfg, 0))
        die_codec (&codec, "Failed to initialize encoder");

    // Cap CPU & first I-frame size
    vpx_codec_control (&codec, VP8E_SET_CPUUSED, -6);
    vpx_codec_control (&codec, VP8E_SET_MAX_INTRA_BITRATE_PCT, 600);

    frame_avail = 1;
    while (frame_avail || got_data) {
        vpx_codec_iter_t iter = NULL;
        const vpx_codec_cx_pkt_t *pkt;

        flags = layer_flags[frame_cnt % cfg.ts_periodicity];

        frame_avail = read_frame(infile, &raw);
        if (vpx_codec_encode(&codec, frame_avail? &raw : NULL, pts,
                            1, flags, VPX_DL_REALTIME))
            die_codec(&codec, "Failed to encode frame");

        // Reset KF flag
        layer_flags[0] &= ~VPX_EFLAG_FORCE_KF;

        got_data = 0;
        while ( (pkt = vpx_codec_get_cx_data(&codec, &iter)) ) {
            got_data = 1;
            switch (pkt->kind) {
            case VPX_CODEC_CX_FRAME_PKT:
                for (i=cfg.ts_layer_id[frame_cnt % cfg.ts_periodicity];
                                              i<cfg.ts_number_layers; i++)
                {
                    write_ivf_frame_header(outfile[i], pkt);
                    if (fwrite(pkt->data.frame.buf, 1, pkt->data.frame.sz,
                              outfile[i]));
                    frames_in_layer[i]++;
                }
                break;
            default:
                break;
            }
            printf (pkt->kind == VPX_CODEC_CX_FRAME_PKT
                    && (pkt->data.frame.flags & VPX_FRAME_IS_KEY)? "K":".");
            fflush (stdout);
        }
        frame_cnt++;
        pts += frame_duration;
    }
    printf ("\n");
    fclose (infile);

    printf ("Processed %d frames.\n",frame_cnt-1);
    if (vpx_codec_destroy(&codec))
            die_codec (&codec, "Failed to destroy codec");

    // Try to rewrite the output file headers with the actual frame count
    for (i=0; i<cfg.ts_number_layers; i++)
    {
        if (!fseek(outfile[i], 0, SEEK_SET))
            write_ivf_file_header (outfile[i], &cfg, frames_in_layer[i]);
        fclose (outfile[i]);
    }

    return EXIT_SUCCESS;
}
// Prepare to compress frames.
// Compressor should record session and sessionOptions for use in later calls.
// Compressor may modify imageDescription at this point.
// Compressor may create and return pixel buffer options.
ComponentResult
VP8_Encoder_PrepareToCompressFrames(
                                    VP8EncoderGlobals glob,
                                    ICMCompressorSessionRef session,
                                    ICMCompressionSessionOptionsRef sessionOptions,
                                    ImageDescriptionHandle imageDescription,
                                    void *reserved,
                                    CFDictionaryRef *compressorPixelBufferAttributesOut)
{
  dbg_printf("[vp8e] Prepare to Compress Frames\n", (UInt32)glob);
  ComponentResult err = noErr;
  CFMutableDictionaryRef compressorPixelBufferAttributes = NULL;
  //This format later needs to be converted
  OSType pixelFormatList[] = { k422YpCbCr8PixelFormat }; // also known as '2vuy'

  Fixed gammaLevel;
  int frameIndex;
  SInt32 widthRoundedUp, heightRoundedUp;

  // Record the compressor session for later calls to the ICM.
  // Note: this is NOT a CF type and should NOT be CFRetained or CFReleased.
  glob->session = session;

  // Retain the session options for later use.
  ICMCompressionSessionOptionsRelease(glob->sessionOptions);
  glob->sessionOptions = sessionOptions;
  ICMCompressionSessionOptionsRetain(glob->sessionOptions);

  // Modify imageDescription here if needed.
  // We'll set the image description gamma level to say "2.2".
  gammaLevel = kQTCCIR601VideoGammaLevel;
  err = ICMImageDescriptionSetProperty(imageDescription,
                                       kQTPropertyClass_ImageDescription,
                                       kICMImageDescriptionPropertyID_GammaLevel,
                                       sizeof(gammaLevel),
                                       &gammaLevel);

  if (err)
    goto bail;

  // Record the dimensions from the image description.
  glob->width = (*imageDescription)->width;
  glob->height = (*imageDescription)->height;
  dbg_printf("[vp8e - %08lx] Prepare to compress frame width %d height %d\n", (UInt32)glob, glob->width, glob->height);

  if (glob->width < 16 || glob->width % 2 || glob->height < 16 || glob->height % 2)
    dbg_printf("[vp8e - %08lx] Warning :: Invalid resolution: %ldx%ld", (UInt32)glob, glob->width, glob->height);

  if (glob->raw == NULL)
    glob->raw = calloc(1, sizeof(vpx_image_t));

  //Right now I'm only using YV12, this is great for webm, as I control the spit component
  if (!vpx_img_alloc(glob->raw, IMG_FMT_YV12, glob->width, glob->height, 1))
  {
    dbg_printf("[vp8e - %08lx] Error: Failed to allocate image %dx%d", (UInt32)glob, glob->width, glob->height);
    err = paramErr;
    goto bail;
  }

  glob->maxEncodedDataSize = glob->width * glob->height * 2;
  dbg_printf("[vp8e - %08lx] currently allocating %d bytes as my max encoded size\n", (UInt32)glob, glob->maxEncodedDataSize);

  // Create a pixel buffer attributes dictionary.
  err = createPixelBufferAttributesDictionary(glob->width, glob->height,
                                              pixelFormatList, sizeof(pixelFormatList) / sizeof(OSType),
                                              &compressorPixelBufferAttributes);

  if (err)
    goto bail;

  *compressorPixelBufferAttributesOut = compressorPixelBufferAttributes;
  compressorPixelBufferAttributes = NULL;

  /* Populate encoder configuration */
  glob->res = vpx_codec_enc_config_default((&vpx_codec_vp8_cx_algo), &glob->cfg, 0);

  if (glob->res)
  {
    dbg_printf("[vp8e - %08lx] Failed to get config: %s\n", (UInt32)glob, vpx_codec_err_to_string(glob->res));
    err = paramErr; //this may be something different ....
    goto bail;
  }

  glob->cfg.g_w = glob->width;
  glob->cfg.g_h = glob->height;
  dbg_printf("[vp8e - %08lx] resolution %dx%d\n", (UInt32)glob,
             glob->cfg.g_w, glob->cfg.g_h);

bail:

  if (err)
    dbg_printf("[vp8e - %08lx] Error %d\n", (UInt32)glob, err);

  if (compressorPixelBufferAttributes) CFRelease(compressorPixelBufferAttributes);

  return err;
}
Esempio n. 23
0
static gboolean
gst_vp8_enc_handle_frame (GstBaseVideoEncoder * base_video_encoder,
    GstVideoFrame * frame)
{
  GstVP8Enc *encoder;
  const GstVideoState *state;
  vpx_codec_err_t status;
  int flags = 0;
  vpx_codec_iter_t iter = NULL;
  const vpx_codec_cx_pkt_t *pkt;
  vpx_image_t *image;
  GstVP8EncCoderHook *hook;

  GST_DEBUG_OBJECT (base_video_encoder, "handle_frame");

  encoder = GST_VP8_ENC (base_video_encoder);

  state = gst_base_video_encoder_get_state (base_video_encoder);
  encoder->n_frames++;

  GST_DEBUG_OBJECT (base_video_encoder, "size %d %d", state->width,
      state->height);

  if (!encoder->inited) {
    vpx_codec_enc_cfg_t cfg;

    status = vpx_codec_enc_config_default (&vpx_codec_vp8_cx_algo, &cfg, 0);
    if (status != VPX_CODEC_OK) {
      GST_ELEMENT_ERROR (encoder, LIBRARY, INIT,
          ("Failed to get default encoder configuration"), ("%s",
              gst_vpx_error_name (status)));
      return FALSE;
    }

    cfg.g_w = state->width;
    cfg.g_h = state->height;
    cfg.g_timebase.num = state->fps_d;
    cfg.g_timebase.den = state->fps_n;

    cfg.g_error_resilient = encoder->error_resilient;
    cfg.g_lag_in_frames = encoder->max_latency;
    cfg.g_threads = encoder->threads;
    cfg.rc_end_usage = encoder->mode;
    if (encoder->bitrate) {
      cfg.rc_target_bitrate = encoder->bitrate / 1000;
    } else {
      cfg.rc_min_quantizer = 63 - encoder->quality * 5.0;
      cfg.rc_max_quantizer = 63 - encoder->quality * 5.0;
      cfg.rc_target_bitrate = encoder->bitrate;
    }

    cfg.kf_mode = VPX_KF_AUTO;
    cfg.kf_min_dist = 0;
    cfg.kf_max_dist = encoder->max_keyframe_distance;

    cfg.g_pass = encoder->multipass_mode;
    if (encoder->multipass_mode == VPX_RC_FIRST_PASS) {
      encoder->first_pass_cache_content = g_byte_array_sized_new (4096);
    } else if (encoder->multipass_mode == VPX_RC_LAST_PASS) {
      GError *err = NULL;


      if (!encoder->multipass_cache_file) {
        GST_ELEMENT_ERROR (encoder, RESOURCE, OPEN_READ,
            ("No multipass cache file provided"), (NULL));
        return GST_FLOW_ERROR;
      }

      if (!g_file_get_contents (encoder->multipass_cache_file,
              (gchar **) & encoder->last_pass_cache_content.buf,
              &encoder->last_pass_cache_content.sz, &err)) {
        GST_ELEMENT_ERROR (encoder, RESOURCE, OPEN_READ,
            ("Failed to read multipass cache file provided"), ("%s",
                err->message));
        g_error_free (err);
        return GST_FLOW_ERROR;
      }
      cfg.rc_twopass_stats_in = encoder->last_pass_cache_content;
    }

    status = vpx_codec_enc_init (&encoder->encoder, &vpx_codec_vp8_cx_algo,
        &cfg, 0);
    if (status != VPX_CODEC_OK) {
      GST_ELEMENT_ERROR (encoder, LIBRARY, INIT,
          ("Failed to initialize encoder"), ("%s",
              gst_vpx_error_name (status)));
      return GST_FLOW_ERROR;
    }

    status = vpx_codec_control (&encoder->encoder, VP8E_SET_CPUUSED, 0);
    if (status != VPX_CODEC_OK) {
      GST_WARNING_OBJECT (encoder, "Failed to set VP8E_SET_CPUUSED to 0: %s",
          gst_vpx_error_name (status));
    }

    status =
        vpx_codec_control (&encoder->encoder, VP8E_SET_ENABLEAUTOALTREF,
        (encoder->auto_alt_ref_frames ? 1 : 0));
    if (status != VPX_CODEC_OK) {
      GST_WARNING_OBJECT (encoder,
          "Failed to set VP8E_ENABLEAUTOALTREF to %d: %s",
          (encoder->auto_alt_ref_frames ? 1 : 0), gst_vpx_error_name (status));
    }

    gst_base_video_encoder_set_latency (base_video_encoder, 0,
        gst_util_uint64_scale (encoder->max_latency,
            state->fps_d * GST_SECOND, state->fps_n));
    encoder->inited = TRUE;
  }

  image = gst_vp8_enc_buffer_to_image (encoder, frame->sink_buffer);

  hook = g_slice_new0 (GstVP8EncCoderHook);
  hook->image = image;
  frame->coder_hook = hook;

  if (encoder->force_keyframe) {
    flags |= VPX_EFLAG_FORCE_KF;
  }

  status = vpx_codec_encode (&encoder->encoder, image,
      encoder->n_frames, 1, flags, speed_table[encoder->speed]);
  if (status != 0) {
    GST_ELEMENT_ERROR (encoder, LIBRARY, ENCODE,
        ("Failed to encode frame"), ("%s", gst_vpx_error_name (status)));
    g_slice_free (GstVP8EncCoderHook, hook);
    frame->coder_hook = NULL;
    g_slice_free (vpx_image_t, image);
    return FALSE;
  }

  pkt = vpx_codec_get_cx_data (&encoder->encoder, &iter);
  while (pkt != NULL) {
    GstBuffer *buffer;
    gboolean invisible;

    GST_DEBUG_OBJECT (encoder, "packet %u type %d", (guint) pkt->data.frame.sz,
        pkt->kind);

    if (pkt->kind == VPX_CODEC_STATS_PKT
        && encoder->multipass_mode == VPX_RC_FIRST_PASS) {
      GST_LOG_OBJECT (encoder, "handling STATS packet");

      g_byte_array_append (encoder->first_pass_cache_content,
          pkt->data.twopass_stats.buf, pkt->data.twopass_stats.sz);

      frame = gst_base_video_encoder_get_oldest_frame (base_video_encoder);
      if (frame != NULL) {
        buffer = gst_buffer_new ();
        GST_BUFFER_FLAG_SET (buffer, GST_BUFFER_FLAG_PREROLL);
        frame->src_buffer = buffer;
        gst_base_video_encoder_finish_frame (base_video_encoder, frame);
      }

      pkt = vpx_codec_get_cx_data (&encoder->encoder, &iter);
      continue;
    } else if (pkt->kind != VPX_CODEC_CX_FRAME_PKT) {
      GST_LOG_OBJECT (encoder, "non frame pkt: %d", pkt->kind);
      pkt = vpx_codec_get_cx_data (&encoder->encoder, &iter);
      continue;
    }

    invisible = (pkt->data.frame.flags & VPX_FRAME_IS_INVISIBLE) != 0;
    frame = gst_base_video_encoder_get_oldest_frame (base_video_encoder);
    g_assert (frame != NULL);
    frame->is_sync_point = (pkt->data.frame.flags & VPX_FRAME_IS_KEY) != 0;
    hook = frame->coder_hook;

    buffer = gst_buffer_new_and_alloc (pkt->data.frame.sz);

    memcpy (GST_BUFFER_DATA (buffer), pkt->data.frame.buf, pkt->data.frame.sz);

    if (hook->image)
      g_slice_free (vpx_image_t, hook->image);
    hook->image = NULL;

    if (invisible) {
      hook->invisible = g_list_append (hook->invisible, buffer);
    } else {
      frame->src_buffer = buffer;
      gst_base_video_encoder_finish_frame (base_video_encoder, frame);
    }

    pkt = vpx_codec_get_cx_data (&encoder->encoder, &iter);
  }

  return TRUE;
}
Esempio n. 24
0
static pj_status_t pj_vpx_encoder_open(vpx_private *vpx) {
    vpx_codec_flags_t flags = 0;
    const struct vpx_codec_iface *iface = &vpx_codec_vp8_cx_algo;
    struct vpx_codec_enc_cfg enccfg;
    int cpu_speed, rc_max_intra_target;
    int res;

    PJ_LOG(4, (THIS_FILE, "vpx pj_vpx_encoder_open"));

    res = vpx_codec_enc_config_default(iface, &enccfg, 0);
    if (res != VPX_CODEC_OK) {
        PJ_LOG(1,
                (THIS_FILE, "Failed to get vpx default config : %s", vpx_codec_err_to_string(res)));
        return PJMEDIA_CODEC_EFAILED;
    }

    enccfg.g_w = vpx->param.enc_fmt.det.vid.size.w;
    enccfg.g_h = vpx->param.enc_fmt.det.vid.size.h;
    enccfg.g_timebase.num = vpx->param.enc_fmt.det.vid.fps.num;
    enccfg.g_timebase.den = vpx->param.enc_fmt.det.vid.fps.denum;
    //provide dummy value to initialize wrapper, values will be updated each _encode()
    vpx_img_wrap(&vpx->rawimg, VPX_IMG_FMT_I420,
            vpx->param.enc_fmt.det.vid.size.w, vpx->param.enc_fmt.det.vid.size.h,
            1, (unsigned char*)1);

    // Following config taken from webRTC project.
    // vpx seems to support more configurable/complex settings.
    // could be interesting to have a look, but for now, consider
    // webRTC settings as optimized for our needs
#if defined(PJ_HAS_UNISTD_H) && PJ_HAS_UNISTD_H!=0
    if (enccfg.g_w * enccfg.g_h > 704 * 576
            && sysconf(_SC_NPROCESSORS_CONF) > 1) {
        // 2 threads when larger than 4CIF
        enccfg.g_threads = 2;
    } else
#endif
    {
        enccfg.g_threads = 1;
    }
    enccfg.g_lag_in_frames = 0;
    enccfg.g_pass = VPX_RC_ONE_PASS;
    enccfg.rc_end_usage = VPX_CBR;
    enccfg.rc_target_bitrate = vpx->param.enc_fmt.det.vid.avg_bps / 1000; // in kbit/s
    enccfg.g_timebase.num = 1;
    enccfg.g_timebase.den = 90000;
    // TODO : need a setting for 2 following ?
    enccfg.g_error_resilient = 0;
    enccfg.rc_resize_allowed = 1;
    enccfg.rc_min_quantizer = 2;
    enccfg.rc_max_quantizer = 56;
    enccfg.rc_undershoot_pct = 100;
    enccfg.rc_overshoot_pct = 15;
    enccfg.rc_buf_initial_sz = 500;
    enccfg.rc_buf_optimal_sz = 600;
    enccfg.rc_buf_sz = 1000;
    // Not use feedback_mode
    enccfg.kf_mode = VPX_KF_AUTO;
    enccfg.kf_max_dist = 3000;

    /* scalePar = 0.5; maxFrameRate = 30fps*/
    /* Don't go below 3 times the per frame bandwidth. */
    rc_max_intra_target = PJ_MAX(300, enccfg.rc_buf_sz * 0.5 * 30 / 10);
    // for android cpu speed set to -12
    // TODO : adjust for other platform as done in webRTC
    cpu_speed = -12;
    //flags |= VPX_CODEC_USE_OUTPUT_PARTITION;
    res = vpx_codec_enc_init(&vpx->encoder, vpx_codec_vp8_cx(), &enccfg, flags);
    if (res != VPX_CODEC_OK) {
        PJ_LOG(1,
                (THIS_FILE, "Failed to init vpx encoder : %s", vpx_codec_err_to_string(res)));
        return PJMEDIA_CODEC_EFAILED;
    }
    vpx_codec_control(&vpx->encoder, VP8E_SET_STATIC_THRESHOLD, 1);
    vpx_codec_control(&vpx->encoder, VP8E_SET_CPUUSED, cpu_speed);
    vpx_codec_control(&vpx->encoder, VP8E_SET_TOKEN_PARTITIONS,
            VP8_ONE_TOKENPARTITION);
    vpx_codec_control(&vpx->encoder, VP8E_SET_NOISE_SENSITIVITY, 1);
    vpx_codec_control(&vpx->encoder, VP8E_SET_MAX_INTRA_BITRATE_PCT,
            rc_max_intra_target);
    vpx->enc_iter = NULL;

    vpx->enc_buf_size = vpx->enc_vafp.framebytes;
    vpx->enc_buf = pj_pool_alloc(vpx->pool, vpx->enc_buf_size);

    vpx->dec_buf_size = vpx->dec_vafp.framebytes;
    vpx->dec_buf = pj_pool_alloc(vpx->pool, vpx->dec_buf_size);

    return PJ_SUCCESS;
}
static void parse_command_line(int argc, const char **argv_,
                               AppInput *app_input, SvcContext *svc_ctx,
                               vpx_codec_enc_cfg_t *enc_cfg) {
    struct arg arg;
    char **argv, **argi, **argj;
    vpx_codec_err_t res;

    // initialize SvcContext with parameters that will be passed to vpx_svc_init
    svc_ctx->log_level = SVC_LOG_DEBUG;
    svc_ctx->spatial_layers = default_spatial_layers;
    svc_ctx->encoding_mode = default_encoding_mode;

    // start with default encoder configuration
    res = vpx_codec_enc_config_default(vpx_codec_vp9_cx(), enc_cfg, 0);
    if (res) {
        die("Failed to get config: %s\n", vpx_codec_err_to_string(res));
    }
    // update enc_cfg with app default values
    enc_cfg->g_w = default_width;
    enc_cfg->g_h = default_height;
    enc_cfg->g_timebase.num = default_timebase_num;
    enc_cfg->g_timebase.den = default_timebase_den;
    enc_cfg->rc_target_bitrate = default_bitrate;
    enc_cfg->kf_min_dist = default_kf_dist;
    enc_cfg->kf_max_dist = default_kf_dist;

    // initialize AppInput with default values
    app_input->frames_to_code = default_frames_to_code;
    app_input->frames_to_skip = default_frames_to_skip;

    // process command line options
    argv = argv_dup(argc - 1, argv_ + 1);
    for (argi = argj = argv; (*argj = *argi); argi += arg.argv_step) {
        arg.argv_step = 1;

        if (arg_match(&arg, &encoding_mode_arg, argi)) {
            svc_ctx->encoding_mode = arg_parse_enum_or_int(&arg);
        } else if (arg_match(&arg, &frames_arg, argi)) {
            app_input->frames_to_code = arg_parse_uint(&arg);
        } else if (arg_match(&arg, &width_arg, argi)) {
            enc_cfg->g_w = arg_parse_uint(&arg);
        } else if (arg_match(&arg, &height_arg, argi)) {
            enc_cfg->g_h = arg_parse_uint(&arg);
        } else if (arg_match(&arg, &timebase_arg, argi)) {
            enc_cfg->g_timebase = arg_parse_rational(&arg);
        } else if (arg_match(&arg, &bitrate_arg, argi)) {
            enc_cfg->rc_target_bitrate = arg_parse_uint(&arg);
        } else if (arg_match(&arg, &skip_frames_arg, argi)) {
            app_input->frames_to_skip = arg_parse_uint(&arg);
        } else if (arg_match(&arg, &layers_arg, argi)) {
            svc_ctx->spatial_layers = arg_parse_uint(&arg);
        } else if (arg_match(&arg, &kf_dist_arg, argi)) {
            enc_cfg->kf_min_dist = arg_parse_uint(&arg);
            enc_cfg->kf_max_dist = enc_cfg->kf_min_dist;
        } else if (arg_match(&arg, &scale_factors_arg, argi)) {
            vpx_svc_set_scale_factors(svc_ctx, arg.val);
        } else if (arg_match(&arg, &quantizers_arg, argi)) {
            vpx_svc_set_quantizers(svc_ctx, arg.val);
        } else {
            ++argj;
        }
    }

    // Check for unrecognized options
    for (argi = argv; *argi; ++argi)
        if (argi[0][0] == '-' && strlen(argi[0]) > 1)
            die("Error: Unrecognized option %s\n", *argi);

    if (argv[0] == NULL || argv[1] == 0) {
        usage_exit();
    }
    app_input->input_ctx.filename = argv[0];
    app_input->output_filename = argv[1];
    free(argv);

    if (enc_cfg->g_w < 16 || enc_cfg->g_w % 2 || enc_cfg->g_h < 16 ||
            enc_cfg->g_h % 2)
        die("Invalid resolution: %d x %d\n", enc_cfg->g_w, enc_cfg->g_h);

    printf(
        "Codec %s\nframes: %d, skip: %d\n"
        "mode: %d, layers: %d\n"
        "width %d, height: %d,\n"
        "num: %d, den: %d, bitrate: %d,\n"
        "gop size: %d\n",
        vpx_codec_iface_name(vpx_codec_vp9_cx()), app_input->frames_to_code,
        app_input->frames_to_skip, svc_ctx->encoding_mode,
        svc_ctx->spatial_layers, enc_cfg->g_w, enc_cfg->g_h,
        enc_cfg->g_timebase.num, enc_cfg->g_timebase.den,
        enc_cfg->rc_target_bitrate, enc_cfg->kf_max_dist);
}
Esempio n. 26
0
int main(int argc, char **argv) {
  VpxVideoWriter *outfile[VPX_TS_MAX_LAYERS] = {NULL};
  vpx_codec_ctx_t codec;
  vpx_codec_enc_cfg_t cfg;
  int frame_cnt = 0;
  vpx_image_t raw;
  vpx_codec_err_t res;
  unsigned int width;
  unsigned int height;
  int speed;
  int frame_avail;
  int got_data;
  int flags = 0;
  unsigned int i;
  int pts = 0;  // PTS starts at 0.
  int frame_duration = 1;  // 1 timebase tick per frame.
  int layering_mode = 0;
  int layer_flags[VPX_TS_MAX_PERIODICITY] = {0};
  int flag_periodicity = 1;
#if VPX_ENCODER_ABI_VERSION > (4 + VPX_CODEC_ABI_VERSION)
  vpx_svc_layer_id_t layer_id = {0, 0};
#else
  vpx_svc_layer_id_t layer_id = {0};
#endif
  const VpxInterface *encoder = NULL;
  FILE *infile = NULL;
  struct RateControlMetrics rc;
  int64_t cx_time = 0;
  const int min_args_base = 11;
#if CONFIG_VP9_HIGHBITDEPTH
  vpx_bit_depth_t bit_depth = VPX_BITS_8;
  int input_bit_depth = 8;
  const int min_args = min_args_base + 1;
#else
  const int min_args = min_args_base;
#endif  // CONFIG_VP9_HIGHBITDEPTH
  double sum_bitrate = 0.0;
  double sum_bitrate2 = 0.0;
  double framerate  = 30.0;

  exec_name = argv[0];
  // Check usage and arguments.
  if (argc < min_args) {
#if CONFIG_VP9_HIGHBITDEPTH
    die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
        "<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> "
        "<Rate_0> ... <Rate_nlayers-1> <bit-depth> \n", argv[0]);
#else
    die("Usage: %s <infile> <outfile> <codec_type(vp8/vp9)> <width> <height> "
        "<rate_num> <rate_den> <speed> <frame_drop_threshold> <mode> "
        "<Rate_0> ... <Rate_nlayers-1> \n", argv[0]);
#endif  // CONFIG_VP9_HIGHBITDEPTH
  }

  encoder = get_vpx_encoder_by_name(argv[3]);
  if (!encoder)
    die("Unsupported codec.");

  printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));

  width = strtol(argv[4], NULL, 0);
  height = strtol(argv[5], NULL, 0);
  if (width < 16 || width % 2 || height < 16 || height % 2) {
    die("Invalid resolution: %d x %d", width, height);
  }

  layering_mode = strtol(argv[10], NULL, 0);
  if (layering_mode < 0 || layering_mode > 12) {
    die("Invalid layering mode (0..12) %s", argv[10]);
  }

  if (argc != min_args + mode_to_num_layers[layering_mode]) {
    die("Invalid number of arguments");
  }

#if CONFIG_VP9_HIGHBITDEPTH
  switch (strtol(argv[argc-1], NULL, 0)) {
    case 8:
      bit_depth = VPX_BITS_8;
      input_bit_depth = 8;
      break;
    case 10:
      bit_depth = VPX_BITS_10;
      input_bit_depth = 10;
      break;
    case 12:
      bit_depth = VPX_BITS_12;
      input_bit_depth = 12;
      break;
    default:
      die("Invalid bit depth (8, 10, 12) %s", argv[argc-1]);
  }
  if (!vpx_img_alloc(&raw,
                     bit_depth == VPX_BITS_8 ? VPX_IMG_FMT_I420 :
                                               VPX_IMG_FMT_I42016,
                     width, height, 32)) {
    die("Failed to allocate image", width, height);
  }
#else
  if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, width, height, 32)) {
    die("Failed to allocate image", width, height);
  }
#endif  // CONFIG_VP9_HIGHBITDEPTH

  // Populate encoder configuration.
  res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
  if (res) {
    printf("Failed to get config: %s\n", vpx_codec_err_to_string(res));
    return EXIT_FAILURE;
  }

  // Update the default configuration with our settings.
  cfg.g_w = width;
  cfg.g_h = height;

#if CONFIG_VP9_HIGHBITDEPTH
  if (bit_depth != VPX_BITS_8) {
    cfg.g_bit_depth = bit_depth;
    cfg.g_input_bit_depth = input_bit_depth;
    cfg.g_profile = 2;
  }
#endif  // CONFIG_VP9_HIGHBITDEPTH

  // Timebase format e.g. 30fps: numerator=1, demoninator = 30.
  cfg.g_timebase.num = strtol(argv[6], NULL, 0);
  cfg.g_timebase.den = strtol(argv[7], NULL, 0);

  speed = strtol(argv[8], NULL, 0);
  if (speed < 0) {
    die("Invalid speed setting: must be positive");
  }

  for (i = min_args_base;
       (int)i < min_args_base + mode_to_num_layers[layering_mode];
       ++i) {
    rc.layer_target_bitrate[i - 11] = strtol(argv[i], NULL, 0);
    if (strncmp(encoder->name, "vp8", 3) == 0)
      cfg.ts_target_bitrate[i - 11] = rc.layer_target_bitrate[i - 11];
    else if (strncmp(encoder->name, "vp9", 3) == 0)
      cfg.layer_target_bitrate[i - 11] = rc.layer_target_bitrate[i - 11];
  }

  // Real time parameters.
  cfg.rc_dropframe_thresh = strtol(argv[9], NULL, 0);
  cfg.rc_end_usage = VPX_CBR;
  cfg.rc_min_quantizer = 2;
  cfg.rc_max_quantizer = 56;
  if (strncmp(encoder->name, "vp9", 3) == 0)
    cfg.rc_max_quantizer = 52;
  cfg.rc_undershoot_pct = 50;
  cfg.rc_overshoot_pct = 50;
  cfg.rc_buf_initial_sz = 500;
  cfg.rc_buf_optimal_sz = 600;
  cfg.rc_buf_sz = 1000;

  // Disable dynamic resizing by default.
  cfg.rc_resize_allowed = 0;

  // Use 1 thread as default.
  cfg.g_threads = 1;

  // Enable error resilient mode.
  cfg.g_error_resilient = 1;
  cfg.g_lag_in_frames   = 0;
  cfg.kf_mode = VPX_KF_AUTO;

  // Disable automatic keyframe placement.
  cfg.kf_min_dist = cfg.kf_max_dist = 3000;

  cfg.temporal_layering_mode = VP9E_TEMPORAL_LAYERING_MODE_BYPASS;

  set_temporal_layer_pattern(layering_mode,
                             &cfg,
                             layer_flags,
                             &flag_periodicity);

  set_rate_control_metrics(&rc, &cfg);

  // Target bandwidth for the whole stream.
  // Set to layer_target_bitrate for highest layer (total bitrate).
  cfg.rc_target_bitrate = rc.layer_target_bitrate[cfg.ts_number_layers - 1];

  // Open input file.
  if (!(infile = fopen(argv[1], "rb"))) {
    die("Failed to open %s for reading", argv[1]);
  }

  framerate = cfg.g_timebase.den / cfg.g_timebase.num;
  // Open an output file for each stream.
  for (i = 0; i < cfg.ts_number_layers; ++i) {
    char file_name[PATH_MAX];
    VpxVideoInfo info;
    info.codec_fourcc = encoder->fourcc;
    info.frame_width = cfg.g_w;
    info.frame_height = cfg.g_h;
    info.time_base.numerator = cfg.g_timebase.num;
    info.time_base.denominator = cfg.g_timebase.den;

    snprintf(file_name, sizeof(file_name), "%s_%d.ivf", argv[2], i);
    outfile[i] = vpx_video_writer_open(file_name, kContainerIVF, &info);
    if (!outfile[i])
      die("Failed to open %s for writing", file_name);

    assert(outfile[i] != NULL);
  }
  // No spatial layers in this encoder.
  cfg.ss_number_layers = 1;

  // Initialize codec.
#if CONFIG_VP9_HIGHBITDEPTH
  if (vpx_codec_enc_init(
          &codec, encoder->codec_interface(), &cfg,
          bit_depth == VPX_BITS_8 ? 0 : VPX_CODEC_USE_HIGHBITDEPTH))
#else
  if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
#endif  // CONFIG_VP9_HIGHBITDEPTH
    die_codec(&codec, "Failed to initialize encoder");

  // configuration for vp8/vp9
  if (strncmp(encoder->name, "vp8", 3) == 0) {
    vpx_codec_control(&codec, VP8E_SET_CPUUSED, -speed);
    vpx_codec_control(&codec, VP8E_SET_NOISE_SENSITIVITY, kDenoiserOff);
    vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 0);
  } else if (strncmp(encoder->name, "vp9", 3) == 0) {
    vpx_svc_extra_cfg_t svc_params;
    vpx_codec_control(&codec, VP8E_SET_CPUUSED, speed);
    vpx_codec_control(&codec, VP9E_SET_AQ_MODE, 3);
    vpx_codec_control(&codec, VP9E_SET_FRAME_PERIODIC_BOOST, 0);
    vpx_codec_control(&codec, VP9E_SET_NOISE_SENSITIVITY, 0);
    vpx_codec_control(&codec, VP8E_SET_STATIC_THRESHOLD, 0);
    vpx_codec_control(&codec, VP9E_SET_TUNE_CONTENT, 0);
    vpx_codec_control(&codec, VP9E_SET_TILE_COLUMNS, (cfg.g_threads >> 1));
    if (vpx_codec_control(&codec, VP9E_SET_SVC, layering_mode > 0 ? 1: 0))
      die_codec(&codec, "Failed to set SVC");
    for (i = 0; i < cfg.ts_number_layers; ++i) {
      svc_params.max_quantizers[i] = cfg.rc_max_quantizer;
      svc_params.min_quantizers[i] = cfg.rc_min_quantizer;
    }
    svc_params.scaling_factor_num[0] = cfg.g_h;
    svc_params.scaling_factor_den[0] = cfg.g_h;
    vpx_codec_control(&codec, VP9E_SET_SVC_PARAMETERS, &svc_params);
  }
Esempio n. 27
0
int main(int argc, char **argv) {
  FILE *infile = NULL;
  vpx_codec_ctx_t codec;
  vpx_codec_enc_cfg_t cfg;
  int frame_count = 0;
  vpx_image_t raw;
  vpx_codec_err_t res;
  VpxVideoInfo info;
  VpxVideoWriter *writer = NULL;
  const VpxInterface *encoder = NULL;
  const int fps = 2;        // TODO(dkovalev) add command line argument
  const double bits_per_pixel_per_frame = 0.067;

  exec_name = argv[0];
  if (argc != 6)
    die("Invalid number of arguments");

  memset(&info, 0, sizeof(info));

  encoder = get_vpx_encoder_by_name(argv[1]);
  if (encoder == NULL) {
    die("Unsupported codec.");
  }
  assert(encoder != NULL);
  info.codec_fourcc = encoder->fourcc;
  info.frame_width = strtol(argv[2], NULL, 0);
  info.frame_height = strtol(argv[3], NULL, 0);
  info.time_base.numerator = 1;
  info.time_base.denominator = fps;

  if (info.frame_width <= 0 ||
      info.frame_height <= 0 ||
      (info.frame_width % 2) != 0 ||
      (info.frame_height % 2) != 0) {
    die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
  }

  if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, info.frame_width,
                                             info.frame_height, 1)) {
    die("Failed to allocate image.");
  }

  printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));

  res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
  if (res)
    die_codec(&codec, "Failed to get default codec config.");

  cfg.g_w = info.frame_width;
  cfg.g_h = info.frame_height;
  cfg.g_timebase.num = info.time_base.numerator;
  cfg.g_timebase.den = info.time_base.denominator;
  cfg.rc_target_bitrate = (unsigned int)(bits_per_pixel_per_frame * cfg.g_w *
                                         cfg.g_h * fps / 1000);
  cfg.g_lag_in_frames = 0;

  writer = vpx_video_writer_open(argv[5], kContainerIVF, &info);
  if (!writer)
    die("Failed to open %s for writing.", argv[5]);

  if (!(infile = fopen(argv[4], "rb")))
    die("Failed to open %s for reading.", argv[4]);

  if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
    die_codec(&codec, "Failed to initialize encoder");

  // Encode frames.
  while (vpx_img_read(&raw, infile)) {
    ++frame_count;

    if (frame_count == 22 && encoder->fourcc == VP8_FOURCC) {
      set_roi_map(&cfg, &codec);
    } else if (frame_count == 33) {
      set_active_map(&cfg, &codec);
    } else if (frame_count == 44) {
      unset_active_map(&cfg, &codec);
    }

    encode_frame(&codec, &raw, frame_count, writer);
  }

  // Flush encoder.
  while (encode_frame(&codec, NULL, -1, writer)) {}

  printf("\n");
  fclose(infile);
  printf("Processed %d frames.\n", frame_count);

  vpx_img_free(&raw);
  if (vpx_codec_destroy(&codec))
    die_codec(&codec, "Failed to destroy codec.");

  vpx_video_writer_close(writer);

  return EXIT_SUCCESS;
}
Esempio n. 28
0
static pj_status_t pj_vpx_encoder_open(vpx_private *vpx) {
    vpx_codec_flags_t flags = 0;
    /* XXX: use VPX_CODEC_USE_OUTPUT_PARTITION ? */
    const struct vpx_codec_iface *iface = &vpx_codec_vp8_cx_algo;
    struct vpx_codec_enc_cfg enccfg;
    int res;

    TRACE_((THIS_FILE, "vpx pj_vpx_encoder_open"));

    res = vpx_codec_enc_config_default(iface, &enccfg, 0);
    if (res != VPX_CODEC_OK) {
        PJ_LOG(1, (THIS_FILE, "Failed to get vpx default config : %s", vpx_codec_err_to_string(res)));
        return PJMEDIA_CODEC_EFAILED;
    }

    enccfg.g_w = vpx->param.enc_fmt.det.vid.size.w;
    enccfg.g_h = vpx->param.enc_fmt.det.vid.size.h;
    enccfg.g_timebase.num = vpx->param.enc_fmt.det.vid.fps.num;
    enccfg.g_timebase.den = vpx->param.enc_fmt.det.vid.fps.denum;
    //provide dummy value to initialize wrapper, values will be updated each _encode()
    vpx_img_wrap(&vpx->rawimg,
                 VPX_IMG_FMT_I420,
                 vpx->param.enc_fmt.det.vid.size.w,
                 vpx->param.enc_fmt.det.vid.size.h,
                 1,
                 NULL);

    enccfg.g_threads = number_of_threads(enccfg.g_w, enccfg.g_h, number_of_cores());
    PJ_LOG(4, (THIS_FILE, "Using %d threads for VPX encoding", enccfg.g_threads));

    enccfg.g_lag_in_frames = 0;
    enccfg.g_pass = VPX_RC_ONE_PASS;
    enccfg.rc_end_usage = VPX_CBR;
    enccfg.rc_target_bitrate = vpx->param.enc_fmt.det.vid.avg_bps / 1000; // in kbit/s
    enccfg.g_timebase.num = 1;
    enccfg.g_timebase.den = 90000;
    enccfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT;
    enccfg.rc_resize_allowed = 1;
    enccfg.rc_min_quantizer = 2;
    enccfg.rc_max_quantizer = 56;
    enccfg.rc_undershoot_pct = 100;
    enccfg.rc_overshoot_pct = 15;
    enccfg.rc_buf_initial_sz = 500;
    enccfg.rc_buf_optimal_sz = 600;
    enccfg.rc_buf_sz = 1000;
    enccfg.kf_mode = VPX_KF_AUTO;
    enccfg.kf_max_dist = 3000;

    vpx->rc_max_intra_target = PJ_MAX(300, enccfg.rc_buf_sz * 0.5 * enccfg.g_timebase.num / 10);

    res = vpx_codec_enc_init(&vpx->encoder, vpx_codec_vp8_cx(), &enccfg, flags);
    if (res != VPX_CODEC_OK) {
        PJ_LOG(1, (THIS_FILE, "Failed to init vpx encoder : %s", vpx_codec_err_to_string(res)));
        return PJMEDIA_CODEC_EFAILED;
    }

    vpx_codec_control(&vpx->encoder, VP8E_SET_STATIC_THRESHOLD, 1);
    vpx_codec_control(&vpx->encoder, VP8E_SET_CPUUSED, -6);   // XXX: test
    vpx_codec_control(&vpx->encoder, VP8E_SET_TOKEN_PARTITIONS, VP8_ONE_TOKENPARTITION);
    vpx_codec_control(&vpx->encoder, VP8E_SET_MAX_INTRA_BITRATE_PCT, vpx->rc_max_intra_target);
#ifdef VP8E_SET_SCREEN_CONTENT_MODE
    vpx_codec_control(&vpx->encoder, VP8E_SET_SCREEN_CONTENT_MODE, 0);
#endif
    vpx->enc_iter = NULL;

    vpx->enc_buf_size = vpx->enc_vafp.framebytes;
    vpx->enc_buf = pj_pool_alloc(vpx->pool, vpx->enc_buf_size);

    vpx->dec_buf_size = vpx->dec_vafp.framebytes;
    vpx->dec_buf = pj_pool_alloc(vpx->pool, vpx->dec_buf_size);

    return PJ_SUCCESS;
}
Esempio n. 29
0
static void enc_preprocess(MSFilter *f) {
	EncState *s = (EncState *)f->data;
	vpx_codec_err_t res;
	vpx_codec_caps_t caps;
	int cpuused=0;

	/* Populate encoder configuration */
	s->flags = 0;
	caps = vpx_codec_get_caps(s->iface);
	if ((s->avpf_enabled == TRUE) && (caps & VPX_CODEC_CAP_OUTPUT_PARTITION)) {
		s->flags |= VPX_CODEC_USE_OUTPUT_PARTITION;
	}
	res = vpx_codec_enc_config_default(s->iface, &s->cfg, 0);
	if (res) {
		ms_error("Failed to get config: %s", vpx_codec_err_to_string(res));
		return;
	}
	s->cfg.rc_target_bitrate = (unsigned int)(((float)s->vconf.required_bitrate) * 0.92f / 1024.0f); //0.92=take into account IP/UDP/RTP overhead, in average.
	s->cfg.g_pass = VPX_RC_ONE_PASS; /* -p 1 */
	s->cfg.g_timebase.num = 1;
	s->cfg.g_timebase.den = (int)s->vconf.fps;
	s->cfg.rc_end_usage = VPX_CBR; /* --end-usage=cbr */
	if (s->avpf_enabled == TRUE) {
		s->cfg.kf_mode = VPX_KF_DISABLED;
	} else {
		s->cfg.kf_mode = VPX_KF_AUTO; /* encoder automatically places keyframes */
		s->cfg.kf_max_dist = 10 * s->cfg.g_timebase.den; /* 1 keyframe each 10s. */
	}
#if TARGET_IPHONE_SIMULATOR
	s->cfg.g_threads = 1; /*workaround to remove crash on ipad simulator*/
#else
	s->cfg.g_threads = ms_factory_get_cpu_count(f->factory);
#endif
	ms_message("VP8 g_threads=%d", s->cfg.g_threads);
	s->cfg.rc_undershoot_pct = 95; /* --undershoot-pct=95 */
	s->cfg.g_error_resilient = VPX_ERROR_RESILIENT_DEFAULT|VPX_ERROR_RESILIENT_PARTITIONS;
	s->cfg.g_lag_in_frames = 0;


#if defined(ANDROID) || (TARGET_OS_IPHONE == 1) || defined(__arm__) || defined(_M_ARM)
	cpuused = 10 - s->cfg.g_threads; /*cpu/quality tradeoff: positive values decrease CPU usage at the expense of quality*/
	if (cpuused < 7) cpuused = 7; /*values beneath 7 consume too much CPU*/
	if( s->cfg.g_threads == 1 ){
		/* on mono-core iOS devices, we reduce the quality a bit more due to VP8 being slower with new Clang compilers */
		cpuused = 16;
	}
#endif

	s->cfg.g_w = s->vconf.vsize.width;
	s->cfg.g_h = s->vconf.vsize.height;

	/* Initialize codec */
	res =  vpx_codec_enc_init(&s->codec, s->iface, &s->cfg, s->flags);
	if (res) {
		ms_error("vpx_codec_enc_init failed: %s (%s)", vpx_codec_err_to_string(res), vpx_codec_error_detail(&s->codec));
		return;
	}
	vpx_codec_control(&s->codec, VP8E_SET_CPUUSED, cpuused);
	vpx_codec_control(&s->codec, VP8E_SET_STATIC_THRESHOLD, 0);
	vpx_codec_control(&s->codec, VP8E_SET_ENABLEAUTOALTREF, !s->avpf_enabled);
	vpx_codec_control(&s->codec, VP8E_SET_MAX_INTRA_BITRATE_PCT, 400); /*limite iFrame size to 4 pframe*/
	if (s->flags & VPX_CODEC_USE_OUTPUT_PARTITION) {
		vpx_codec_control(&s->codec, VP8E_SET_TOKEN_PARTITIONS, 2); /* Output 4 partitions per frame */
	} else {
		vpx_codec_control(&s->codec, VP8E_SET_TOKEN_PARTITIONS, 0);
	}

	s->invalid_frame_reported = FALSE;
	vp8rtpfmt_packer_init(&s->packer);
	if (s->avpf_enabled == TRUE) {
		s->force_keyframe = TRUE;
	} else if (s->frame_count == 0) {
		ms_video_starter_init(&s->starter);
	}
	s->ready = TRUE;
}
Esempio n. 30
-2
int main(int argc, char **argv) {
  FILE *infile = NULL;
  vpx_codec_ctx_t codec;
  vpx_codec_enc_cfg_t cfg;
  int frame_count = 0;
  vpx_image_t raw;
  vpx_codec_err_t res;
  VpxVideoInfo info;
  VpxVideoWriter *writer = NULL;
  const VpxInterface *encoder = NULL;
  int update_frame_num = 0;
  const int fps = 30;       // TODO(dkovalev) add command line argument
  const int bitrate = 200;  // kbit/s TODO(dkovalev) add command line argument

  vp8_zero(codec);
  vp8_zero(cfg);
  vp8_zero(info);

  exec_name = argv[0];

  if (argc != 6) die("Invalid number of arguments");

  // TODO(dkovalev): add vp9 support and rename the file accordingly
  encoder = get_vpx_encoder_by_name("vp8");
  if (!encoder) die("Unsupported codec.");

  update_frame_num = atoi(argv[5]);
  if (!update_frame_num) die("Couldn't parse frame number '%s'\n", argv[5]);

  info.codec_fourcc = encoder->fourcc;
  info.frame_width = (int)strtol(argv[1], NULL, 0);
  info.frame_height = (int)strtol(argv[2], NULL, 0);
  info.time_base.numerator = 1;
  info.time_base.denominator = fps;

  if (info.frame_width <= 0 || info.frame_height <= 0 ||
      (info.frame_width % 2) != 0 || (info.frame_height % 2) != 0) {
    die("Invalid frame size: %dx%d", info.frame_width, info.frame_height);
  }

  if (!vpx_img_alloc(&raw, VPX_IMG_FMT_I420, info.frame_width,
                     info.frame_height, 1)) {
    die("Failed to allocate image.");
  }

  printf("Using %s\n", vpx_codec_iface_name(encoder->codec_interface()));

  res = vpx_codec_enc_config_default(encoder->codec_interface(), &cfg, 0);
  if (res) die_codec(&codec, "Failed to get default codec config.");

  cfg.g_w = info.frame_width;
  cfg.g_h = info.frame_height;
  cfg.g_timebase.num = info.time_base.numerator;
  cfg.g_timebase.den = info.time_base.denominator;
  cfg.rc_target_bitrate = bitrate;

  writer = vpx_video_writer_open(argv[4], kContainerIVF, &info);
  if (!writer) die("Failed to open %s for writing.", argv[4]);

  if (!(infile = fopen(argv[3], "rb")))
    die("Failed to open %s for reading.", argv[3]);

  if (vpx_codec_enc_init(&codec, encoder->codec_interface(), &cfg, 0))
    die_codec(&codec, "Failed to initialize encoder");

  // Encode frames.
  while (vpx_img_read(&raw, infile)) {
    if (frame_count + 1 == update_frame_num) {
      vpx_ref_frame_t ref;
      ref.frame_type = VP8_LAST_FRAME;
      ref.img = raw;
      if (vpx_codec_control(&codec, VP8_SET_REFERENCE, &ref))
        die_codec(&codec, "Failed to set reference frame");
    }

    encode_frame(&codec, &raw, frame_count++, writer);
  }

  // Flush encoder.
  while (encode_frame(&codec, NULL, -1, writer)) {
  }

  printf("\n");
  fclose(infile);
  printf("Processed %d frames.\n", frame_count);

  vpx_img_free(&raw);
  if (vpx_codec_destroy(&codec)) die_codec(&codec, "Failed to destroy codec.");

  vpx_video_writer_close(writer);

  return EXIT_SUCCESS;
}