New issue
Advanced search Search tips

Issue 758931 link

Starred by 1 user

Issue metadata

Status: WontFix
Owner: ----
Closed: Aug 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Linux
Pri: 2
Type: Bug



Sign in to add a comment

No VP8 Hardware Encoder

Reported by getso...@gmail.com, Aug 25 2017

Issue description

UserAgent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.101 Safari/537.36

Steps to reproduce the problem:
1 Make WebRTC call having enbale the Hardware Accelators
2 Use vp8 a the only candinate in webrtc handshake

What is the expected behavior?
Encode the frames from the camera using vp8 HW accelator encoder

What went wrong?
VP8 hardware accelator has been implemented. That result in a crash when the VaapiWrapper::execute is called.

Did this work before? No 

Chrome version: 60.0.3112.101  Channel: dev
OS Version: Debian 9
Flash Version: Shockwave Flash 26.0 r0
 
Cc: emir...@chromium.org
Components: Internals>Media>Codecs Blink>WebRTC>Video
Labels: Needs-Triage-M60
getsoubl@ Thanks for the issue.

CC'ing emircan@ for further help in this issue and requesting Media team to look into this issue and help in further triaging.

Thanks..
What type of device are you encoding on?

Could you send us the crash ID from chrome://crashes please.

Comment 3 by getso...@gmail.com, Aug 28 2017

Hello 
We use a Beebox box that has an Intel Graphic card that support the latest driver i965
We have install a Debian 9 linux version and we have patched this in order to suport Hardware Accelaration
Unfortunately, we do not have the crash Id , because we have did changes 
But the chromium chrashes in VaapiVideoEncodeAccelerator::InitializeTask() line UpdateSPS.
When the UpdateSPS is called, the profile VP8 is not supported line 952
void VaapiVideoEncodeAccelerator::UpdateSPS() {
  memset(&current_sps_, 0, sizeof(H264SPS));

  // Spec A.2 and A.3.
  switch (profile_) {
    case H264PROFILE_BASELINE:
      // Due to crbug.com/345569, we don't distinguish between constrained
      // and non-constrained baseline profiles. Since many codecs can't do
      // non-constrained, and constrained is usually what we mean (and it's a
      // subset of non-constrained), default to it.
      current_sps_.profile_idc = H264SPS::kProfileIDCBaseline;
      current_sps_.constraint_set0_flag = true;
      break;
    case H264PROFILE_MAIN:
      current_sps_.profile_idc = H264SPS::kProfileIDCMain;
      current_sps_.constraint_set1_flag = true;
      break;
    case H264PROFILE_HIGH:
      current_sps_.profile_idc = H264SPS::kProfileIDCHigh;
      break;
    default:
     NOTIMPLEMENTED();
	  return;
  }
Components: -Platform>DevTools
Status: Untriaged (was: Unconfirmed)
SPS is a H.264 concept, and is not related to VP8. Quickly looking through the code, it looks like Chromium's VAAPI wrapper only supports H.264.

Emircan, do you know of any plans to support VP8 in the VAAPI wrapper?

Comment 6 by getso...@gmail.com, Aug 29 2017

Hello,
We have done some changes to support VP8
In details we  define tree new fuctions
void BeginFrame();
void EndVp8Frame();
bool SubmitFrameVP8Parameters();
The heart of encoding is the SubmitFrameVP8Parameters
bool VaapiVideoEncodeAccelerator::SubmitFrameVP8Parameters()
{
	//create reference surfaces//
   VAEncSequenceParameterBufferVP8 seq_param;
   memset(&seq_param, 0, sizeof(seq_param));
   seq_param.frame_width  = coded_size_.width();
   seq_param.frame_height = coded_size_.height();

   seq_param.frame_width_scale  = 0;
   seq_param.frame_height_scale = 0;
   seq_param.intra_period = i_period_;
   seq_param.bits_per_second = bitrate_;
    //seq_param.profile = 0;
   seq_param.error_resilient = 0;
   seq_param.kf_auto = 1;
   seq_param.kf_min_dist = 128;
   seq_param.kf_max_dist = 128;
    std::cout << "ref_pic_list0_.size():"<<ref_pic_list0_.size() << std::endl;
    if( ref_pic_list0_.size() > 0 && ref_pic_list0_.size() < 4)
	{
	RefPicList::const_iterator iter = ref_pic_list0_.begin();
		for (size_t i = 0;
			 i < arraysize(seq_param.reference_frames) && iter != ref_pic_list0_.end();
			 ++iter, ++i
			) 
		{
			seq_param.reference_frames[i] = (*iter)->id();
		}
	}
   if (!vaapi_wrapper_->SubmitBuffer(VAEncSequenceParameterBufferType,
                                    sizeof(seq_param), &seq_param))
    {
	  std::cout << "VAEncSequenceParameterBufferType::Error when try to submit the buffer" << std::endl;
      return false;
	}
	VAEncPictureParameterBufferVP8 pic_param;
	 memset(&pic_param, 0, sizeof(pic_param));
	#if 0
	if (!vaapi_wrapper_->CreateSurfaces(VA_RT_FORMAT_YUV420
									   ,coded_size_
                                       ,pic_param.reconstructed_frame)) 
	{
		NOTIFY_ERROR(kPlatformFailureError, "Failed creating VASurfaces");
		std::cout << "Error when try to CreateSurface " << std::endl;
		return false;
    }
	std::cout << "pic_param.reconstructed_frame " << std::hex 
			  << pic_param.reconstructed_frame << std::endl;
	#endif
	/////////////////////////////////////////////////////////////////////////////////
	pic_param.reconstructed_frame = current_encode_job_->recon_surface->id();
    std::cout << "recon_surface->id()"<< pic_param.reconstructed_frame << std::endl;
	pic_param.coded_buf = current_encode_job_->coded_buffer;
	pic_param.pic_flags.value = 0;
	pic_param.pic_flags.bits.refresh_entropy_probs = 0;
	//pic_param.sharpness_level = 2;
	//pic_param.pic_flags.bits.num_token_partitions = 2;
	if(   !current_vp8pic_->frame_num
	   || (!current_vp8pic_->frame_num % idr_period_)
	   || (!current_vp8pic_->frame_num % i_period_)
	   )
	   {
		    std::cout<< "Frame::" << frame_num_ << "is a key frame"<<std::endl;
            pic_param.pic_flags.bits.frame_type = 0;
		    pic_param.ref_flags.bits.force_kf = 1;
             pic_param.pic_flags.bits.refresh_last            = 1;
            pic_param.pic_flags.bits.refresh_golden_frame     = 1;
            pic_param.pic_flags.bits.refresh_alternate_frame  = 1;
            pic_param.pic_flags.bits.copy_buffer_to_alternate = 0;
            pic_param.pic_flags.bits.copy_buffer_to_golden    = 0;
			pic_param.ref_last_frame =
			pic_param.ref_gf_frame   =
			pic_param.ref_arf_frame  =
				VA_INVALID_SURFACE;
	   }
	else
	{
		std::cout<< "Frame:" << frame_num_ << "is a inter frame"  <<std::endl;
        pic_param.pic_flags.bits.frame_type = 1;
		pic_param.ref_flags.bits.force_kf    = 0;
		//pic_param.ref_flags.bits.no_ref_last = 0;
        //pic_param.ref_flags.bits.no_ref_gf   = 1;
        //pic_param.ref_flags.bits.no_ref_arf  = 1;
        pic_param.pic_flags.bits.refresh_last             = 1;
        pic_param.pic_flags.bits.refresh_golden_frame     = 0;
        pic_param.pic_flags.bits.refresh_alternate_frame  = 0;
        pic_param.pic_flags.bits.copy_buffer_to_alternate = 2;
        pic_param.pic_flags.bits.copy_buffer_to_golden    = 1;
        pic_param.ref_last_frame =
        pic_param.ref_gf_frame   =
        pic_param.ref_arf_frame  =
              (ref_pic_list0_.front().get()->id());
        std::cout <<  "pic_param.ref_arf_frame"<< pic_param.ref_arf_frame <<std::endl;
    }
	
    pic_param.pic_flags.bits.show_frame       = 1;
    pic_param.clamp_qindex_low                = 0;
    pic_param.clamp_qindex_high               = 127;
    pic_param.pic_flags.bits.version          = 1;
    pic_param.pic_flags.bits.loop_filter_type = 1;
    pic_param.sharpness_level                 = 3;
    for (int i = 0; i < 4; i++) 
    {
        pic_param.loop_filter_level[i] = 39;
    }
 //   pic_param.frame_width_src = coded_size_.width();
 //   pic_param.frame_height_src = coded_size_.height();
 //   pic_param.frame_width_dst = coded_size_.width();
 //    pic_param.frame_height_dst = coded_size_.height();
	if (!vaapi_wrapper_->SubmitBuffer(VAEncPictureParameterBufferType, sizeof(pic_param), &pic_param))
    {
	   std::cout << "VAEncPictureParameterBufferType::Error when try to submit the buffer" << std::endl;
	   return false;
	}
  VAQMatrixBufferVP8 quant;
  memset (&quant, 0, sizeof (VAQMatrixBufferVP8));
  for (int i = 0; i < 4; i++) 
  {
	  //IFRAME
	  if(   !current_vp8pic_->frame_num
	   || (!current_vp8pic_->frame_num % idr_period_)
	   || (!current_vp8pic_->frame_num % i_period_)
	   )
	   {
		    quant.quantization_index[i] = 4;
		   
	   }
	   else
	   {
		    quant.quantization_index[i] = 26;
		   
	   }
  }
  if (!vaapi_wrapper_->SubmitBuffer(VAQMatrixBufferType, sizeof(quant), &quant))
  {
	   std::cout << "VAEncPictureParameterBufferType::Error when try to submit the buffer" << std::endl;
	   return false;
  }
  VAEncMiscParameterRateControl rate_control_param;
  memset(&rate_control_param, 0, sizeof(rate_control_param));
  rate_control_param.bits_per_second = bitrate_;
  rate_control_param.target_percentage = 90;
  rate_control_param.window_size = kCPBWindowSizeMs;
  rate_control_param.initial_qp = qp_;
  rate_control_param.rc_flags.bits.disable_frame_skip = true;
  std::cout << "Frame Rate"<<bitrate_ <<std::endl;
  if (!vaapi_wrapper_->SubmitVAEncMiscParamBuffer(
          VAEncMiscParameterTypeRateControl, sizeof(rate_control_param),
          &rate_control_param))
  {
	std::cout << "VAEncMiscParameterTypeRateControl::Error when try to submit the buffer" << std::endl;
    return false;
  }
  VAEncMiscParameterFrameRate framerate_param;
  memset(&framerate_param, 0, sizeof(framerate_param));
  framerate_param.framerate = framerate_;
  if (!vaapi_wrapper_->SubmitVAEncMiscParamBuffer(
          VAEncMiscParameterTypeFrameRate, sizeof(framerate_param),
          &framerate_param))
  {
    std::cout << "VAEncMiscParameterFrameRate::Error when try to submit the buffer" << std::endl;
	return false;
  }

  VAEncMiscParameterHRD hrd_param;
  memset(&hrd_param, 0, sizeof(hrd_param));
  hrd_param.buffer_size = cpb_size_;
  hrd_param.initial_buffer_fullness = cpb_size_ / 2;
  if (!vaapi_wrapper_->SubmitVAEncMiscParamBuffer(
          VAEncMiscParameterTypeHRD, sizeof(hrd_param), &hrd_param))
  {
	 std::cout << "VAEncMiscParameterTypeHRD::Error when try to submit the buffer" << std::endl;
    return false;
  }
	std::cout << "VaapiVideoEncodeAccelerator:return true"<< std::endl;
	
	return true;
}

We can encode a frame in a video call but the video that receive the other party it is not in the best resolution.
Do you have any idea?
Thank you in advance

vaapi_video_encode_accelerator.cc
47.7 KB View Download
vaapi_video_encode_accelerator.h
9.6 KB View Download
Status: WontFix (was: Untriaged)
Sorry, we are not in a position where we can support local diffs. I'll close this bug, but feel free to file a new bug if you find problems with the code that exists in Chromium.

About your problem with the low resolution: this could be some problem with the ScalingSettings being returned from the encoder wrapper. This is how it's done for SW VP8: https://cs.chromium.org/chromium/src/third_party/webrtc/modules/video_coding/codecs/vp8/vp8_impl.cc?l=962&rcl=c205a943e9645b0d6addc475184f9aed24001aa7

Sign in to add a comment