Example #1
0
int vc_reconfigure_encoder(VCSession *vc, uint32_t bit_rate, uint16_t width, uint16_t height, int16_t kf_max_dist)
{
    if (!vc) {
        return -1;
    }

    vpx_codec_enc_cfg_t cfg2 = *vc->encoder->config.enc;
    vpx_codec_err_t rc;

    if (cfg2.rc_target_bitrate == bit_rate && cfg2.g_w == width && cfg2.g_h == height && kf_max_dist == -1) {
        return 0; /* Nothing changed */
    }

    if (cfg2.g_w == width && cfg2.g_h == height && kf_max_dist == -1) {
        /* Only bit rate changed */
        LOGGER_INFO(vc->log, "bitrate change from: %u to: %u", (uint32_t)cfg2.rc_target_bitrate, (uint32_t)bit_rate);
        cfg2.rc_target_bitrate = bit_rate;
        rc = vpx_codec_enc_config_set(vc->encoder, &cfg2);

        if (rc != VPX_CODEC_OK) {
            LOGGER_ERROR(vc->log, "Failed to set encoder control setting: %s", vpx_codec_err_to_string(rc));
            return -1;
        }
    } else {
        /* Resolution is changed, must reinitialize encoder since libvpx v1.4 doesn't support
         * reconfiguring encoder to use resolutions greater than initially set.
         */
        LOGGER_DEBUG(vc->log, "Have to reinitialize vpx encoder on session %p", (void *)vc);
        vpx_codec_ctx_t new_c;
        vpx_codec_enc_cfg_t  cfg;
        vc_init_encoder_cfg(vc->log, &cfg, kf_max_dist);
        cfg.rc_target_bitrate = bit_rate;
        cfg.g_w = width;
        cfg.g_h = height;

        LOGGER_DEBUG(vc->log, "Using VP8 codec for encoder");
        rc = vpx_codec_enc_init(&new_c, video_codec_encoder_interface(), &cfg, VPX_CODEC_USE_FRAME_THREADING);

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

        int cpu_used_value = VP8E_SET_CPUUSED_VALUE;

        rc = vpx_codec_control(&new_c, VP8E_SET_CPUUSED, cpu_used_value);

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

        vpx_codec_destroy(vc->encoder);
        memcpy(vc->encoder, &new_c, sizeof(new_c));
    }

    return 0;
}
Example #2
0
RefPtr<MediaDataDecoder::DecodePromise>
VPXDecoder::ProcessDecode(MediaRawData* aSample)
{
  MOZ_ASSERT(mTaskQueue->IsCurrentThreadIn());

  if (vpx_codec_err_t r = vpx_codec_decode(&mVPX, aSample->Data(), aSample->Size(), nullptr, 0)) {
    LOG("VPX Decode error: %s", vpx_codec_err_to_string(r));
    return DecodePromise::CreateAndReject(
      MediaResult(NS_ERROR_DOM_MEDIA_DECODE_ERR,
                  RESULT_DETAIL("VPX error: %s", vpx_codec_err_to_string(r))),
      __func__);
  }

  vpx_codec_iter_t iter = nullptr;
  vpx_image_t *img;
  vpx_image_t *img_alpha = nullptr;
  bool alpha_decoded = false;
  DecodedData results;

  while ((img = vpx_codec_get_frame(&mVPX, &iter))) {
    NS_ASSERTION(img->fmt == VPX_IMG_FMT_I420 ||
                 img->fmt == VPX_IMG_FMT_I444,
                 "WebM image format not I420 or I444");
    NS_ASSERTION(!alpha_decoded,
                 "Multiple frames per packet that contains alpha");

    if (aSample->AlphaSize() > 0) {
      if (!alpha_decoded){
        MediaResult rv = DecodeAlpha(&img_alpha, aSample);
        if (NS_FAILED(rv)) {
          return DecodePromise::CreateAndReject(rv, __func__);
        }
        alpha_decoded = true;
      }
    }
    // Chroma shifts are rounded down as per the decoding examples in the SDK
    VideoData::YCbCrBuffer b;
    b.mPlanes[0].mData = img->planes[0];
    b.mPlanes[0].mStride = img->stride[0];
    b.mPlanes[0].mHeight = img->d_h;
    b.mPlanes[0].mWidth = img->d_w;
    b.mPlanes[0].mOffset = b.mPlanes[0].mSkip = 0;

    b.mPlanes[1].mData = img->planes[1];
    b.mPlanes[1].mStride = img->stride[1];
    b.mPlanes[1].mOffset = b.mPlanes[1].mSkip = 0;

    b.mPlanes[2].mData = img->planes[2];
    b.mPlanes[2].mStride = img->stride[2];
    b.mPlanes[2].mOffset = b.mPlanes[2].mSkip = 0;

    if (img->fmt == VPX_IMG_FMT_I420) {
      b.mPlanes[1].mHeight = (img->d_h + 1) >> img->y_chroma_shift;
      b.mPlanes[1].mWidth = (img->d_w + 1) >> img->x_chroma_shift;

      b.mPlanes[2].mHeight = (img->d_h + 1) >> img->y_chroma_shift;
      b.mPlanes[2].mWidth = (img->d_w + 1) >> img->x_chroma_shift;
    } else if (img->fmt == VPX_IMG_FMT_I444) {
Example #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 *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;

}
Example #4
0
/**
 * @brief Encode video frame
 *
 * @param av Handler
 * @param dest Where to
 * @param dest_max Max size
 * @param input What to encode
 * @return int
 * @retval ToxAvError On error.
 * @retval >0 On success
 */
inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, vpx_image_t *input)
{
    CallSpecific *call = &av->calls[call_index];

    int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US);

    if ( rc != VPX_CODEC_OK) {
        fprintf(stderr, "Could not encode video frame: %s\n", vpx_codec_err_to_string(rc));
        return ErrorInternal;
    }

    ++call->cs->frame_counter;

    vpx_codec_iter_t iter = NULL;
    const vpx_codec_cx_pkt_t *pkt;
    int copied = 0;

    while ( (pkt = vpx_codec_get_cx_data(&call->cs->v_encoder, &iter)) ) {
        if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
            if ( copied + pkt->data.frame.sz > dest_max ) return ErrorPacketTooLarge;

            mempcpy(dest + copied, pkt->data.frame.buf, pkt->data.frame.sz);
            copied += pkt->data.frame.sz;
        }
    }

    return copied;
}
Example #5
0
/**
 * @brief Receive decoded video packet.
 *
 * @param av Handler.
 * @param output Storage.
 * @return int
 * @retval 0 Success.
 * @retval ToxAvError On Error.
 */
inline__ int toxav_recv_video ( ToxAv *av, vpx_image_t **output)
{
    if ( !output ) return ErrorInternal;

    uint8_t packet [RTP_PAYLOAD_SIZE];
    int recved_size = 0;
    int error;
    
    do {
        recved_size = toxav_recv_rtp_payload(av, TypeVideo, packet);

        if (recved_size > 0 && ( error = vpx_codec_decode(&av->cs->v_decoder, packet, recved_size, NULL, 0) ) != VPX_CODEC_OK) 
            fprintf(stderr, "Error decoding: %s\n", vpx_codec_err_to_string(error));
        
    } while (recved_size > 0);

    vpx_codec_iter_t iter = NULL;
    vpx_image_t *img;
    img = vpx_codec_get_frame(&av->cs->v_decoder, &iter);

    *output = img;
    return 0;
    /* Yeah, i set output to be NULL if nothing received
     */
}
Example #6
0
/**
 * @brief Receive decoded video packet.
 *
 * @param av Handler.
 * @param output Storage.
 * @return int
 * @retval 0 Success.
 * @retval ToxAvError On Error.
 */
inline__ int toxav_recv_video ( ToxAv *av, int32_t call_index, vpx_image_t **output)
{
    if ( !output ) return ErrorInternal;

    if (cii(call_index, av->msi_session)) return ErrorNoCall;

    uint8_t packet [RTP_PAYLOAD_SIZE];
    int recved_size = 0;
    int rc;
    CallSpecific *call = &av->calls[call_index];

    do {
        recved_size = toxav_recv_rtp_payload(av, call_index, TypeVideo, packet);

        if (recved_size > 0 && ( rc = vpx_codec_decode(&call->cs->v_decoder, packet, recved_size, NULL, 0) ) != VPX_CODEC_OK) {
            LOGGER_ERROR("Error decoding video: %s\n", vpx_codec_err_to_string(rc));
            return ErrorInternal;
        }

    } while (recved_size > 0);

    vpx_codec_iter_t iter = NULL;
    vpx_image_t *img;
    img = vpx_codec_get_frame(&call->cs->v_decoder, &iter);

    *output = img;
    return 0;
}
Example #7
0
int cs_set_video_encoder_resolution(CSSession *cs, uint16_t width, uint16_t height)
{
    vpx_codec_enc_cfg_t cfg = *cs->v_encoder.config.enc;

    if (cfg.g_w == width && cfg.g_h == height)
        return 0;

    if (width * height > cs->max_width * cs->max_height) {
        vpx_codec_ctx_t v_encoder = cs->v_encoder;

        if (init_video_encoder(cs, width, height, cs->video_bitrate) == -1) {
            cs->v_encoder = v_encoder;
            return cs_ErrorSettingVideoResolution;
        }

        vpx_codec_destroy(&v_encoder);
        return 0;
    }

    LOGGER_DEBUG("New video resolution: %u %u", width, height);
    cfg.g_w = width;
    cfg.g_h = height;
    int rc = vpx_codec_enc_config_set(&cs->v_encoder, &cfg);

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

    return 0;
}
Example #8
0
/**
 * @brief Encode video frame
 *
 * @param av Handler
 * @param dest Where to
 * @param dest_max Max size
 * @param input What to encode
 * @return int
 * @retval ToxAvError On error.
 * @retval >0 On success
 */
inline__ int toxav_prepare_video_frame(ToxAv *av, int32_t call_index, uint8_t *dest, int dest_max, vpx_image_t *input)
{
    if (cii(call_index, av->msi_session) || !av->calls[call_index].call_active) {
        LOGGER_WARNING("Action on inactive call: %d", call_index);
        return ErrorNoCall;
    }


    CallSpecific *call = &av->calls[call_index];
    reconfigure_video_encoder_resolution(call->cs, input->d_w, input->d_h);

    int rc = vpx_codec_encode(&call->cs->v_encoder, input, call->cs->frame_counter, 1, 0, MAX_ENCODE_TIME_US);

    if ( rc != VPX_CODEC_OK) {
        LOGGER_ERROR("Could not encode video frame: %s\n", vpx_codec_err_to_string(rc));
        return ErrorInternal;
    }

    ++call->cs->frame_counter;

    vpx_codec_iter_t iter = NULL;
    const vpx_codec_cx_pkt_t *pkt;
    int copied = 0;

    while ( (pkt = vpx_codec_get_cx_data(&call->cs->v_encoder, &iter)) ) {
        if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
            if ( copied + pkt->data.frame.sz > dest_max ) return ErrorPacketTooLarge;

            memcpy(dest + copied, pkt->data.frame.buf, pkt->data.frame.sz);
            copied += pkt->data.frame.sz;
        }
    }

    return copied;
}
Example #9
0
static void enc_process(MSFilter *f) {
	mblk_t *im,*om;
	uint64_t timems=f->ticker->time;
	uint32_t timestamp=timems*90;
	EncState *s=(EncState*)f->data;
	unsigned int flags = 0;
	vpx_codec_err_t err;
	YuvBuf yuv;

	ms_filter_lock(f);
	while((im=ms_queue_get(f->inputs[0]))!=NULL){
		vpx_image_t img;

		om = NULL;
		flags = 0;

		ms_yuv_buf_init_from_mblk(&yuv, im);
		vpx_img_wrap(&img, VPX_IMG_FMT_I420, s->vconf.vsize.width, s->vconf.vsize.height, 1, yuv.planes[0]);
		
		if (video_starter_need_i_frame (&s->starter,f->ticker->time)){
			/*sends an I frame at 2 seconds and 4 seconds after the beginning of the call*/
			s->req_vfu=TRUE;
		}
		if (s->req_vfu){
			flags = VPX_EFLAG_FORCE_KF;
			s->req_vfu=FALSE;
		}

		err = vpx_codec_encode(&s->codec, &img, s->frame_count, 1, flags, VPX_DL_REALTIME);

		if (err) {
			ms_error("vpx_codec_encode failed : %d %s (%s)\n", err, vpx_codec_err_to_string(err), vpx_codec_error_detail(&s->codec));
		} else {
			vpx_codec_iter_t iter = NULL;
			const vpx_codec_cx_pkt_t *pkt;

			s->frame_count++;
			if (s->frame_count==1){
				video_starter_first_frame (&s->starter,f->ticker->time);
			}

			while( (pkt = vpx_codec_get_cx_data(&s->codec, &iter)) ) {
				if (pkt->kind == VPX_CODEC_CX_FRAME_PKT) {
					if (pkt->data.frame.sz > 0) {
						om = allocb(pkt->data.frame.sz,0);
						memcpy(om->b_wptr, pkt->data.frame.buf, pkt->data.frame.sz);
						om->b_wptr += pkt->data.frame.sz;
						#ifdef FRAGMENT_ON_PARTITIONS
						vp8_fragment_and_send(f, s, om, timestamp, pkt, (pkt->data.frame.partition_id == s->token_partition_count));
						#else
						vp8_fragment_and_send(f, s, om, timestamp, pkt, 1);
						#endif
					}
				}
			}
		}
		freemsg(im);
	}
	ms_filter_unlock(f);
}
Example #10
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;
}
Example #11
0
void krad_vpx_encoder_config_set (krad_vpx_encoder_t *vpx,
                                  vpx_codec_enc_cfg_t *cfg) {
  int ret;

  ret = vpx_codec_enc_config_set (&vpx->encoder, cfg);

  if (ret != VPX_CODEC_OK) {
    printke ("VPX Config problem: %s\n", vpx_codec_err_to_string (ret));
  }
}
Example #12
0
void vc_iterate(VCSession *vc)
{
    if (!vc) {
        return;
    }

    pthread_mutex_lock(vc->queue_mutex);

    struct RTPMessage *p;

    if (!rb_read(vc->vbuf_raw, (void **)&p)) {
        LOGGER_TRACE(vc->log, "no Video frame data available");
        pthread_mutex_unlock(vc->queue_mutex);
        return;
    }

    pthread_mutex_unlock(vc->queue_mutex);
    const struct RTPHeader *const header = &p->header;

    uint32_t full_data_len;

    if (header->flags & RTP_LARGE_FRAME) {
        full_data_len = header->data_length_full;
        LOGGER_DEBUG(vc->log, "vc_iterate:001:full_data_len=%d", (int)full_data_len);
    } else {
        full_data_len = p->len;
        LOGGER_DEBUG(vc->log, "vc_iterate:002");
    }

    LOGGER_DEBUG(vc->log, "vc_iterate: rb_read p->len=%d p->header.xe=%d", (int)full_data_len, p->header.xe);
    LOGGER_DEBUG(vc->log, "vc_iterate: rb_read rb size=%d", (int)rb_size(vc->vbuf_raw));
    const vpx_codec_err_t rc = vpx_codec_decode(vc->decoder, p->data, full_data_len, nullptr, MAX_DECODE_TIME_US);
    free(p);

    if (rc != VPX_CODEC_OK) {
        LOGGER_ERROR(vc->log, "Error decoding video: %d %s", (int)rc, vpx_codec_err_to_string(rc));
        return;
    }

    /* Play decoded images */
    vpx_codec_iter_t iter = nullptr;

    for (vpx_image_t *dest = vpx_codec_get_frame(vc->decoder, &iter);
            dest != nullptr;
            dest = vpx_codec_get_frame(vc->decoder, &iter)) {
        if (vc->vcb) {
            vc->vcb(vc->av, vc->friend_number, dest->d_w, dest->d_h,
                    (const uint8_t *)dest->planes[0], (const uint8_t *)dest->planes[1], (const uint8_t *)dest->planes[2],
                    dest->stride[0], dest->stride[1], dest->stride[2], vc->vcb_user_data);
        }

        vpx_img_free(dest); // is this needed? none of the VPx examples show that
    }
}
Example #13
0
static int init_video_decoder(CSSession *cs)
{
    int rc = vpx_codec_dec_init_ver(&cs->v_decoder, VIDEO_CODEC_DECODER_INTERFACE, NULL, 0, VPX_DECODER_ABI_VERSION);

    if ( rc != VPX_CODEC_OK) {
        LOGGER_ERROR("Init video_decoder failed: %s", vpx_codec_err_to_string(rc));
        return -1;
    }

    return 0;
}
Example #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;
}
Example #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 rc = vpx_codec_enc_config_default(VIDEO_CODEC_ENCODER_INTERFACE, &cfg, 0);

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

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

    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;
    }

    return 0;
}
Example #16
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;
}
Example #17
0
int rxs_decoder_init(rxs_decoder* dec) {

  vpx_codec_err_t err;

  if (!dec) { return -1; } 

  err = vpx_codec_dec_init(&dec->ctx, vpx_dx_interface, NULL, 0);
  if (err) {
    printf("Error: cannot initialize the decoder: %s.\n", vpx_codec_err_to_string(err));
    return -2; 
  }

  dec->img = NULL;

  return 0;
}
Example #18
0
static pj_status_t pj_vpx_codec_encode_begin(pjmedia_vid_codec *codec,
        const pjmedia_vid_encode_opt *opt, const pjmedia_frame *input,
        unsigned out_size, pjmedia_frame *output, pj_bool_t *has_more) {
    vpx_private *vpx = (vpx_private*) codec->codec_data;
    pj_status_t status;
    vpx_image_t *rawimg;
    vpx_enc_frame_flags_t flags = 0;
    pj_uint8_t *p;
    int i, res;

    PJ_ASSERT_RETURN(codec && input, PJ_EINVAL);

    p = (pj_uint8_t*) input->buf;

    *has_more = PJ_FALSE;

    rawimg = &vpx->rawimg;
    // TODO : make sure it's I420 ?
    if(input->size < vpx->enc_vafp.framebytes){
        PJ_LOG(1, (THIS_FILE, "Frame provided is too small !"));
        return PJ_ETOOSMALL;
    }

    for (i = 0; i < vpx->enc_vfi->plane_cnt; ++i) {
        rawimg->planes[i] = p;
        rawimg->stride[i] = vpx->enc_vafp.strides[i];
        p += vpx->enc_vafp.plane_bytes[i];
    }

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

    res = vpx_codec_encode(&vpx->encoder, rawimg, input->timestamp.u64, 1, flags,
            VPX_DL_REALTIME);
    if (res != VPX_CODEC_OK) {
        PJ_LOG(1, (THIS_FILE, "Failed to encode : %s %s",
                      vpx_codec_err_to_string(res), vpx->encoder.err_detail));
        return PJMEDIA_CODEC_EFAILED;
    }

    vpx->enc_iter = NULL;
    vpx->enc_frame_len = 0;
    vpx->enc_processed = 0;
    return pj_vpx_codec_encode_more(codec, out_size, output, has_more);
}
Example #19
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");
    }
}
Example #20
0
static pj_status_t pj_vpx_decoder_open(vpx_private *vpx) {
    vpx_codec_flags_t flags = 0;
    vpx_codec_dec_cfg_t cfg;
    int res;

    cfg.threads = 1;
    cfg.h = 0;
    cfg.w = 0;

    res = vpx_codec_dec_init(&vpx->decoder, vpx_codec_vp8_dx(), &cfg, flags);
    if (res != VPX_CODEC_OK) {
        PJ_LOG(1, (THIS_FILE, "Failed to init vpx decoder : %s", vpx_codec_err_to_string(res)));
        return PJ_ENOMEM;
    }

    return PJ_SUCCESS;
}
Example #21
0
int reconfigure_video_encoder_bitrate(CodecState *cs, uint32_t video_bitrate)
{
    vpx_codec_enc_cfg_t cfg = *cs->v_encoder.config.enc;

    if (cfg.rc_target_bitrate == video_bitrate)
        return 0;

    LOGGER_DEBUG("New video bitrate: %u", video_bitrate);
    cfg.rc_target_bitrate = video_bitrate;
    int rc = vpx_codec_enc_config_set(&cs->v_encoder, &cfg);

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

    return 0;
}
Example #22
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;
		}
	}
}
/*
 * Method:    codec_err_to_string
 */
JNIEXPORT jint JNICALL
Java_org_jitsi_impl_neomedia_codec_video_VPX_codec_1err_1to_1string
    (JNIEnv *env,
     jclass clazz,
     jint err,
     jbyteArray buf,
     jint buf_size)
{
    const char *err_str = vpx_codec_err_to_string((vpx_codec_err_t) err);
    jbyte *buf_ptr = (*env)->GetByteArrayElements(env, buf, NULL);

    int i;
    for(i = 0; i < buf_size-1 && err_str[i] != '\0'; i++)
        buf_ptr[i] = (jbyte) err_str[i];
    buf_ptr[i] = (jbyte) '\0';

    (*env)->ReleaseByteArrayElements(env, buf, buf_ptr, 0);

    return i;
}
Example #24
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;
}
Example #25
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;
			}
		}
	}
Example #26
0
static void decode_video(ToxAv *av, CallSpecific *call, DECODE_PACKET *p)
{
    int32_t call_index = call - av->calls;

    int rc = vpx_codec_decode(&call->cs->v_decoder, p->data, p->size, NULL, MAX_DECODE_TIME_US);

    if (rc != VPX_CODEC_OK) {
        LOGGER_ERROR("Error decoding video: %s\n", vpx_codec_err_to_string(rc));
    }

    vpx_codec_iter_t iter = NULL;
    vpx_image_t *img;
    img = vpx_codec_get_frame(&call->cs->v_decoder, &iter);

    if (img && av->video_callback) {
        av->video_callback(av, call_index, img, av->video_callback_userdata);
    } else {
        LOGGER_WARNING("Video packet dropped due to missing callback or no image!");
    }

    free(p);
}
Example #27
0
int reconfigure_video_encoder_resolution(CodecState *cs, uint16_t width, uint16_t height)
{
    vpx_codec_enc_cfg_t cfg = *cs->v_encoder.config.enc;

    if (cfg.g_w == width && cfg.g_h == height)
        return 0;

    if (width * height > cs->max_width * cs->max_height)
        return -1;

    LOGGER_DEBUG("New video resolution: %u %u", width, height);
    cfg.g_w = width;
    cfg.g_h = height;
    int rc = vpx_codec_enc_config_set(&cs->v_encoder, &cfg);

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

    return 0;
}
Example #28
0
/*
 
  Decode the given data. Note that on linux libvpx 
  will crash at this moment when the first partition 
  you pass into this function is not a key frame. 

 */
int rxs_decoder_decode(rxs_decoder* dec, uint8_t* buffer, uint32_t nbytes) {

  vpx_codec_iter_t iter = NULL;
  vpx_codec_err_t err;

  if (!dec) { return -1; } 
  if (!buffer) { return -2; } 
  if (!nbytes) { return -3; } 

  dec->img = NULL;

  err = vpx_codec_decode(&dec->ctx, buffer, nbytes, NULL, 0);
  if (err) {
    printf("Error: cannot decode buffer: %s\n", vpx_codec_err_to_string(err));
    return -4;
  }

  while ( (dec->img = vpx_codec_get_frame(&dec->ctx, &iter)) ) {
    dec->on_image(dec, dec->img);
  }

  return 0;
}
Example #29
0
static void enc_preprocess(MSFilter *f) {
	vpx_codec_err_t res;
	EncState *s=(EncState*)f->data;

	s->cfg.g_w = s->vconf.vsize.width;
	s->cfg.g_h = s->vconf.vsize.height;
	s->cfg.g_timebase.den=s->vconf.fps;
	/* Initialize codec */
	#ifdef FRAGMENT_ON_PARTITIONS
	/* VPX_CODEC_USE_OUTPUT_PARTITION: output 1 frame per partition */
	res =  vpx_codec_enc_init(&s->codec, interface, &s->cfg, VPX_CODEC_USE_OUTPUT_PARTITION);
	#else
	res =  vpx_codec_enc_init(&s->codec, interface, &s->cfg, 0);
	#endif
	if (res) {
		ms_error("vpx_codec_enc_init failed: %s (%s)n", vpx_codec_err_to_string(res), vpx_codec_error_detail(&s->codec));
	}
	/*cpu/quality tradeoff: positive values decrease CPU usage at the expense of quality*/
	vpx_codec_control(&s->codec, VP8E_SET_CPUUSED, (s->cfg.g_threads > 1) ? 10 : 10); 
	vpx_codec_control(&s->codec, VP8E_SET_STATIC_THRESHOLD, 0);
	vpx_codec_control(&s->codec, VP8E_SET_ENABLEAUTOALTREF, 1);
	if (s->cfg.g_threads > 1) {
		if (vpx_codec_control(&s->codec, VP8E_SET_TOKEN_PARTITIONS, 2) != VPX_CODEC_OK) {
			ms_error("VP8: failed to set multiple token partition");
		} else {
			ms_message("VP8: multiple token partitions used");
		}
	}
	#ifdef FRAGMENT_ON_PARTITIONS
	vpx_codec_control(&s->codec, VP8E_SET_TOKEN_PARTITIONS, 0x3);
	s->token_partition_count = 8;
	#endif
	/* vpx_codec_control(&s->codec, VP8E_SET_CPUUSED, 0);*/ /* -16 (quality) .. 16 (speed) */

	video_starter_init(&s->starter);
	s->ready=TRUE;
}
Example #30
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;
}