No VP8 Hardware Encoder
Reported by
getso...@gmail.com,
Aug 25 2017
|
||||
Issue descriptionUserAgent: 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
,
Aug 28 2017
What type of device are you encoding on? Could you send us the crash ID from chrome://crashes please.
,
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(¤t_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;
}
,
Aug 28 2017
,
Aug 29 2017
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?
,
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
,
Aug 29 2017
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 |
||||
Comment 1 by susanjuniab@chromium.org
, Aug 28 2017Components: Internals>Media>Codecs Blink>WebRTC>Video
Labels: Needs-Triage-M60