Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(53)

Side by Side Diff: content/common/gpu/media/vaapi_video_encode_accelerator.cc

Issue 1040513003: VAVDA: Use the new, generic video decoder and accelerator infrastructure. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix whitespace Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/common/gpu/media/vaapi_video_encode_accelerator.h" 5 #include "content/common/gpu/media/vaapi_video_encode_accelerator.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/callback.h" 8 #include "base/callback.h"
9 #include "base/message_loop/message_loop_proxy.h" 9 #include "base/message_loop/message_loop_proxy.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 void VaapiVideoEncodeAccelerator::RecycleVASurfaceID( 254 void VaapiVideoEncodeAccelerator::RecycleVASurfaceID(
255 VASurfaceID va_surface_id) { 255 VASurfaceID va_surface_id) {
256 DVLOGF(4) << "va_surface_id: " << va_surface_id; 256 DVLOGF(4) << "va_surface_id: " << va_surface_id;
257 DCHECK(encoder_thread_proxy_->BelongsToCurrentThread()); 257 DCHECK(encoder_thread_proxy_->BelongsToCurrentThread());
258 258
259 available_va_surface_ids_.push_back(va_surface_id); 259 available_va_surface_ids_.push_back(va_surface_id);
260 EncodeFrameTask(); 260 EncodeFrameTask();
261 } 261 }
262 262
263 void VaapiVideoEncodeAccelerator::BeginFrame(bool force_keyframe) { 263 void VaapiVideoEncodeAccelerator::BeginFrame(bool force_keyframe) {
264 memset(&current_pic_, 0, sizeof(current_pic_)); 264 current_pic_ = new H264Picture();
kcwu 2015/03/31 15:20:09 Is EndFrame() always paired with BeginFrame() ? If
Pawel Osciak 2015/04/03 07:06:00 Yes, I considered that, but I thought it would be
265 265
266 // If the current picture is an IDR picture, frame_num shall be equal to 0. 266 // If the current picture is an IDR picture, frame_num shall be equal to 0.
267 if (force_keyframe) 267 if (force_keyframe)
268 frame_num_ = 0; 268 frame_num_ = 0;
269 269
270 current_pic_.frame_num = frame_num_++; 270 current_pic_->frame_num = frame_num_++;
271 frame_num_ %= idr_period_; 271 frame_num_ %= idr_period_;
272 272
273 if (current_pic_.frame_num == 0) { 273 if (current_pic_->frame_num == 0) {
274 current_pic_.idr = true; 274 current_pic_->idr = true;
275 // H264 spec mandates idr_pic_id to differ between two consecutive IDRs. 275 // H264 spec mandates idr_pic_id to differ between two consecutive IDRs.
276 idr_pic_id_ ^= 1; 276 idr_pic_id_ ^= 1;
277 ref_pic_list0_.clear(); 277 ref_pic_list0_.clear();
278 } 278 }
279 279
280 if (current_pic_.frame_num % i_period_ == 0) 280 if (current_pic_->frame_num % i_period_ == 0)
281 current_pic_.type = media::H264SliceHeader::kISlice; 281 current_pic_->type = media::H264SliceHeader::kISlice;
282 else 282 else
283 current_pic_.type = media::H264SliceHeader::kPSlice; 283 current_pic_->type = media::H264SliceHeader::kPSlice;
284 284
285 if (current_pic_.type != media::H264SliceHeader::kBSlice) 285 if (current_pic_->type != media::H264SliceHeader::kBSlice)
286 current_pic_.ref = true; 286 current_pic_->ref = true;
287 287
288 current_pic_.pic_order_cnt = current_pic_.frame_num * 2; 288 current_pic_->pic_order_cnt = current_pic_->frame_num * 2;
289 current_pic_.top_field_order_cnt = current_pic_.pic_order_cnt; 289 current_pic_->top_field_order_cnt = current_pic_->pic_order_cnt;
290 current_pic_.pic_order_cnt_lsb = current_pic_.pic_order_cnt; 290 current_pic_->pic_order_cnt_lsb = current_pic_->pic_order_cnt;
291 291
292 current_encode_job_->keyframe = current_pic_.idr; 292 current_encode_job_->keyframe = current_pic_->idr;
293 293
294 DVLOGF(4) << "Starting a new frame, type: " << current_pic_.type 294 DVLOGF(4) << "Starting a new frame, type: " << current_pic_->type
295 << (force_keyframe ? " (forced keyframe)" : "") 295 << (force_keyframe ? " (forced keyframe)" : "")
296 << " frame_num: " << current_pic_.frame_num 296 << " frame_num: " << current_pic_->frame_num
297 << " POC: " << current_pic_.pic_order_cnt; 297 << " POC: " << current_pic_->pic_order_cnt;
298 } 298 }
299 299
300 void VaapiVideoEncodeAccelerator::EndFrame() { 300 void VaapiVideoEncodeAccelerator::EndFrame() {
301 DCHECK(current_pic_);
301 // Store the picture on the list of reference pictures and keep the list 302 // Store the picture on the list of reference pictures and keep the list
302 // below maximum size, dropping oldest references. 303 // below maximum size, dropping oldest references.
303 if (current_pic_.ref) 304 if (current_pic_->ref)
304 ref_pic_list0_.push_front(current_encode_job_->recon_surface); 305 ref_pic_list0_.push_front(current_encode_job_->recon_surface);
305 size_t max_num_ref_frames = 306 size_t max_num_ref_frames =
306 base::checked_cast<size_t>(current_sps_.max_num_ref_frames); 307 base::checked_cast<size_t>(current_sps_.max_num_ref_frames);
307 while (ref_pic_list0_.size() > max_num_ref_frames) 308 while (ref_pic_list0_.size() > max_num_ref_frames)
308 ref_pic_list0_.pop_back(); 309 ref_pic_list0_.pop_back();
309 310
310 submitted_encode_jobs_.push(make_linked_ptr(current_encode_job_.release())); 311 submitted_encode_jobs_.push(make_linked_ptr(current_encode_job_.release()));
311 } 312 }
312 313
313 static void InitVAPicture(VAPictureH264* va_pic) { 314 static void InitVAPicture(VAPictureH264* va_pic) {
314 memset(va_pic, 0, sizeof(*va_pic)); 315 memset(va_pic, 0, sizeof(*va_pic));
315 va_pic->picture_id = VA_INVALID_ID; 316 va_pic->picture_id = VA_INVALID_ID;
316 va_pic->flags = VA_PICTURE_H264_INVALID; 317 va_pic->flags = VA_PICTURE_H264_INVALID;
317 } 318 }
318 319
319 bool VaapiVideoEncodeAccelerator::SubmitFrameParameters() { 320 bool VaapiVideoEncodeAccelerator::SubmitFrameParameters() {
321 DCHECK(current_pic_);
320 VAEncSequenceParameterBufferH264 seq_param; 322 VAEncSequenceParameterBufferH264 seq_param;
321 memset(&seq_param, 0, sizeof(seq_param)); 323 memset(&seq_param, 0, sizeof(seq_param));
322 324
323 #define SPS_TO_SP(a) seq_param.a = current_sps_.a; 325 #define SPS_TO_SP(a) seq_param.a = current_sps_.a;
324 SPS_TO_SP(seq_parameter_set_id); 326 SPS_TO_SP(seq_parameter_set_id);
325 SPS_TO_SP(level_idc); 327 SPS_TO_SP(level_idc);
326 328
327 seq_param.intra_period = i_period_; 329 seq_param.intra_period = i_period_;
328 seq_param.intra_idr_period = idr_period_; 330 seq_param.intra_idr_period = idr_period_;
329 seq_param.ip_period = ip_period_; 331 seq_param.ip_period = ip_period_;
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
362 364
363 if (!vaapi_wrapper_->SubmitBuffer(VAEncSequenceParameterBufferType, 365 if (!vaapi_wrapper_->SubmitBuffer(VAEncSequenceParameterBufferType,
364 sizeof(seq_param), 366 sizeof(seq_param),
365 &seq_param)) 367 &seq_param))
366 return false; 368 return false;
367 369
368 VAEncPictureParameterBufferH264 pic_param; 370 VAEncPictureParameterBufferH264 pic_param;
369 memset(&pic_param, 0, sizeof(pic_param)); 371 memset(&pic_param, 0, sizeof(pic_param));
370 372
371 pic_param.CurrPic.picture_id = current_encode_job_->recon_surface->id(); 373 pic_param.CurrPic.picture_id = current_encode_job_->recon_surface->id();
372 pic_param.CurrPic.TopFieldOrderCnt = current_pic_.top_field_order_cnt; 374 pic_param.CurrPic.TopFieldOrderCnt = current_pic_->top_field_order_cnt;
373 pic_param.CurrPic.BottomFieldOrderCnt = current_pic_.bottom_field_order_cnt; 375 pic_param.CurrPic.BottomFieldOrderCnt = current_pic_->bottom_field_order_cnt;
374 pic_param.CurrPic.flags = 0; 376 pic_param.CurrPic.flags = 0;
375 377
376 for (size_t i = 0; i < arraysize(pic_param.ReferenceFrames); ++i) 378 for (size_t i = 0; i < arraysize(pic_param.ReferenceFrames); ++i)
377 InitVAPicture(&pic_param.ReferenceFrames[i]); 379 InitVAPicture(&pic_param.ReferenceFrames[i]);
378 380
379 DCHECK_LE(ref_pic_list0_.size(), arraysize(pic_param.ReferenceFrames)); 381 DCHECK_LE(ref_pic_list0_.size(), arraysize(pic_param.ReferenceFrames));
380 RefPicList::const_iterator iter = ref_pic_list0_.begin(); 382 RefPicList::const_iterator iter = ref_pic_list0_.begin();
381 for (size_t i = 0; 383 for (size_t i = 0;
382 i < arraysize(pic_param.ReferenceFrames) && iter != ref_pic_list0_.end(); 384 i < arraysize(pic_param.ReferenceFrames) && iter != ref_pic_list0_.end();
383 ++iter, ++i) { 385 ++iter, ++i) {
384 pic_param.ReferenceFrames[i].picture_id = (*iter)->id(); 386 pic_param.ReferenceFrames[i].picture_id = (*iter)->id();
385 pic_param.ReferenceFrames[i].flags = 0; 387 pic_param.ReferenceFrames[i].flags = 0;
386 } 388 }
387 389
388 pic_param.coded_buf = current_encode_job_->coded_buffer; 390 pic_param.coded_buf = current_encode_job_->coded_buffer;
389 pic_param.pic_parameter_set_id = current_pps_.pic_parameter_set_id; 391 pic_param.pic_parameter_set_id = current_pps_.pic_parameter_set_id;
390 pic_param.seq_parameter_set_id = current_pps_.seq_parameter_set_id; 392 pic_param.seq_parameter_set_id = current_pps_.seq_parameter_set_id;
391 pic_param.frame_num = current_pic_.frame_num; 393 pic_param.frame_num = current_pic_->frame_num;
392 pic_param.pic_init_qp = qp_; 394 pic_param.pic_init_qp = qp_;
393 pic_param.num_ref_idx_l0_active_minus1 = max_ref_idx_l0_size_ - 1; 395 pic_param.num_ref_idx_l0_active_minus1 = max_ref_idx_l0_size_ - 1;
394 pic_param.pic_fields.bits.idr_pic_flag = current_pic_.idr; 396 pic_param.pic_fields.bits.idr_pic_flag = current_pic_->idr;
395 pic_param.pic_fields.bits.reference_pic_flag = current_pic_.ref; 397 pic_param.pic_fields.bits.reference_pic_flag = current_pic_->ref;
396 #define PPS_TO_PP_PF(a) pic_param.pic_fields.bits.a = current_pps_.a; 398 #define PPS_TO_PP_PF(a) pic_param.pic_fields.bits.a = current_pps_.a;
397 PPS_TO_PP_PF(entropy_coding_mode_flag); 399 PPS_TO_PP_PF(entropy_coding_mode_flag);
398 PPS_TO_PP_PF(transform_8x8_mode_flag); 400 PPS_TO_PP_PF(transform_8x8_mode_flag);
399 PPS_TO_PP_PF(deblocking_filter_control_present_flag); 401 PPS_TO_PP_PF(deblocking_filter_control_present_flag);
400 #undef PPS_TO_PP_PF 402 #undef PPS_TO_PP_PF
401 403
402 if (!vaapi_wrapper_->SubmitBuffer(VAEncPictureParameterBufferType, 404 if (!vaapi_wrapper_->SubmitBuffer(VAEncPictureParameterBufferType,
403 sizeof(pic_param), 405 sizeof(pic_param),
404 &pic_param)) 406 &pic_param))
405 return false; 407 return false;
406 408
407 VAEncSliceParameterBufferH264 slice_param; 409 VAEncSliceParameterBufferH264 slice_param;
408 memset(&slice_param, 0, sizeof(slice_param)); 410 memset(&slice_param, 0, sizeof(slice_param));
409 411
410 slice_param.num_macroblocks = mb_width_ * mb_height_; 412 slice_param.num_macroblocks = mb_width_ * mb_height_;
411 slice_param.macroblock_info = VA_INVALID_ID; 413 slice_param.macroblock_info = VA_INVALID_ID;
412 slice_param.slice_type = current_pic_.type; 414 slice_param.slice_type = current_pic_->type;
413 slice_param.pic_parameter_set_id = current_pps_.pic_parameter_set_id; 415 slice_param.pic_parameter_set_id = current_pps_.pic_parameter_set_id;
414 slice_param.idr_pic_id = idr_pic_id_; 416 slice_param.idr_pic_id = idr_pic_id_;
415 slice_param.pic_order_cnt_lsb = current_pic_.pic_order_cnt_lsb; 417 slice_param.pic_order_cnt_lsb = current_pic_->pic_order_cnt_lsb;
416 slice_param.num_ref_idx_active_override_flag = true; 418 slice_param.num_ref_idx_active_override_flag = true;
417 419
418 for (size_t i = 0; i < arraysize(slice_param.RefPicList0); ++i) 420 for (size_t i = 0; i < arraysize(slice_param.RefPicList0); ++i)
419 InitVAPicture(&slice_param.RefPicList0[i]); 421 InitVAPicture(&slice_param.RefPicList0[i]);
420 422
421 for (size_t i = 0; i < arraysize(slice_param.RefPicList1); ++i) 423 for (size_t i = 0; i < arraysize(slice_param.RefPicList1); ++i)
422 InitVAPicture(&slice_param.RefPicList1[i]); 424 InitVAPicture(&slice_param.RefPicList1[i]);
423 425
424 DCHECK_LE(ref_pic_list0_.size(), arraysize(slice_param.RefPicList0)); 426 DCHECK_LE(ref_pic_list0_.size(), arraysize(slice_param.RefPicList0));
425 iter = ref_pic_list0_.begin(); 427 iter = ref_pic_list0_.begin();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
465 hrd_param.initial_buffer_fullness = cpb_size_ / 2; 467 hrd_param.initial_buffer_fullness = cpb_size_ / 2;
466 if (!vaapi_wrapper_->SubmitVAEncMiscParamBuffer(VAEncMiscParameterTypeHRD, 468 if (!vaapi_wrapper_->SubmitVAEncMiscParamBuffer(VAEncMiscParameterTypeHRD,
467 sizeof(hrd_param), 469 sizeof(hrd_param),
468 &hrd_param)) 470 &hrd_param))
469 return false; 471 return false;
470 472
471 return true; 473 return true;
472 } 474 }
473 475
474 bool VaapiVideoEncodeAccelerator::SubmitHeadersIfNeeded() { 476 bool VaapiVideoEncodeAccelerator::SubmitHeadersIfNeeded() {
475 if (current_pic_.type != media::H264SliceHeader::kISlice) 477 DCHECK(current_pic_);
478 if (current_pic_->type != media::H264SliceHeader::kISlice)
476 return true; 479 return true;
477 480
478 // Submit PPS. 481 // Submit PPS.
479 VAEncPackedHeaderParameterBuffer par_buffer; 482 VAEncPackedHeaderParameterBuffer par_buffer;
480 memset(&par_buffer, 0, sizeof(par_buffer)); 483 memset(&par_buffer, 0, sizeof(par_buffer));
481 par_buffer.type = VAEncPackedHeaderSequence; 484 par_buffer.type = VAEncPackedHeaderSequence;
482 par_buffer.bit_length = packed_sps_.BytesInBuffer() * 8; 485 par_buffer.bit_length = packed_sps_.BytesInBuffer() * 8;
483 486
484 if (!vaapi_wrapper_->SubmitBuffer(VAEncPackedHeaderParameterBufferType, 487 if (!vaapi_wrapper_->SubmitBuffer(VAEncPackedHeaderParameterBufferType,
485 sizeof(par_buffer), 488 sizeof(par_buffer),
(...skipping 17 matching lines...) Expand all
503 506
504 if (!vaapi_wrapper_->SubmitBuffer(VAEncPackedHeaderDataBufferType, 507 if (!vaapi_wrapper_->SubmitBuffer(VAEncPackedHeaderDataBufferType,
505 packed_pps_.BytesInBuffer(), 508 packed_pps_.BytesInBuffer(),
506 packed_pps_.data())) 509 packed_pps_.data()))
507 return false; 510 return false;
508 511
509 return true; 512 return true;
510 } 513 }
511 514
512 bool VaapiVideoEncodeAccelerator::ExecuteEncode() { 515 bool VaapiVideoEncodeAccelerator::ExecuteEncode() {
513 DVLOGF(3) << "Encoding frame_num: " << current_pic_.frame_num; 516 DCHECK(current_pic_);
517 DVLOGF(3) << "Encoding frame_num: " << current_pic_->frame_num;
514 return vaapi_wrapper_->ExecuteAndDestroyPendingBuffers( 518 return vaapi_wrapper_->ExecuteAndDestroyPendingBuffers(
515 current_encode_job_->input_surface->id()); 519 current_encode_job_->input_surface->id());
516 } 520 }
517 521
518 bool VaapiVideoEncodeAccelerator::UploadFrame( 522 bool VaapiVideoEncodeAccelerator::UploadFrame(
519 const scoped_refptr<media::VideoFrame>& frame) { 523 const scoped_refptr<media::VideoFrame>& frame) {
520 return vaapi_wrapper_->UploadVideoFrameToSurface( 524 return vaapi_wrapper_->UploadVideoFrameToSurface(
521 frame, current_encode_job_->input_surface->id()); 525 frame, current_encode_job_->input_surface->id());
522 } 526 }
523 527
(...skipping 538 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 } 1066 }
1063 1067
1064 VaapiVideoEncodeAccelerator::EncodeJob::EncodeJob() 1068 VaapiVideoEncodeAccelerator::EncodeJob::EncodeJob()
1065 : coded_buffer(VA_INVALID_ID), keyframe(false) { 1069 : coded_buffer(VA_INVALID_ID), keyframe(false) {
1066 } 1070 }
1067 1071
1068 VaapiVideoEncodeAccelerator::EncodeJob::~EncodeJob() { 1072 VaapiVideoEncodeAccelerator::EncodeJob::~EncodeJob() {
1069 } 1073 }
1070 1074
1071 } // namespace content 1075 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698