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; }
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; }
int krad_vpx_encoder_write (krad_vpx_encoder_t *kradvpx, unsigned char **packet, int *keyframe) { if (kradvpx->update_config == 1) { krad_vpx_encoder_config_set (kradvpx, &kradvpx->cfg); kradvpx->update_config = 0; //krad_vpx_encoder_print_config (kradvpx); } #ifdef BENCHMARK krad_vpx_benchmark_start(kradvpx); #endif if (vpx_codec_encode(&kradvpx->encoder, kradvpx->image, kradvpx->frames, 1, kradvpx->flags, kradvpx->deadline)) { krad_vpx_fail (&kradvpx->encoder, "Failed to encode frame"); } kradvpx->frames++; kradvpx->flags = 0; kradvpx->iter = NULL; while ((kradvpx->pkt = vpx_codec_get_cx_data (&kradvpx->encoder, &kradvpx->iter))) { //printkd ("Got packet\n"); if (kradvpx->pkt->kind == VPX_CODEC_CX_FRAME_PKT) { *packet = kradvpx->pkt->data.frame.buf; *keyframe = kradvpx->pkt->data.frame.flags & VPX_FRAME_IS_KEY; if (*keyframe == 0) { kradvpx->frames_since_keyframe++; } else { kradvpx->frames_since_keyframe = 0; //printkd ("keyframe is %d pts is -%ld-\n", *keyframe, kradvpx->pkt->data.frame.pts); } #ifdef BENCHMARK krad_vpx_benchmark_finish(kradvpx); #endif return kradvpx->pkt->data.frame.sz; } } return 0; }
int krad_vpx_encoder_write (krad_vpx_encoder_t *vpx, unsigned char **packet, int *keyframe) { if (vpx->update_config == 1) { krad_vpx_encoder_config_set (vpx, &vpx->cfg); vpx->update_config = 0; krad_vpx_encoder_print_config (vpx); } if (vpx_codec_encode (&vpx->encoder, vpx->image, vpx->frames, 1, vpx->flags, vpx->deadline)) { krad_vpx_fail (&vpx->encoder, "Failed to encode frame"); } vpx->frames++; vpx->flags = 0; vpx->iter = NULL; while ((vpx->pkt = vpx_codec_get_cx_data (&vpx->encoder, &vpx->iter))) { //printkd ("Got packet\n"); if (vpx->pkt->kind == VPX_CODEC_CX_FRAME_PKT) { *packet = vpx->pkt->data.frame.buf; *keyframe = vpx->pkt->data.frame.flags & VPX_FRAME_IS_KEY; if (*keyframe == 0) { vpx->frames_since_keyframe++; } else { vpx->frames_since_keyframe = 0; //printkd ("keyframe is %d pts is -%ld-\n", // *keyframe, vpx->pkt->data.frame.pts); } vpx->bytes += vpx->pkt->data.frame.sz; return vpx->pkt->data.frame.sz; } } return 0; }