| OLD | NEW |
| 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 <algorithm> | 5 #include <algorithm> |
| 6 | 6 |
| 7 #include <CoreVideo/CoreVideo.h> | 7 #include <CoreVideo/CoreVideo.h> |
| 8 #include <OpenGL/CGLIOSurface.h> | 8 #include <OpenGL/CGLIOSurface.h> |
| 9 #include <OpenGL/gl.h> | 9 #include <OpenGL/gl.h> |
| 10 | 10 |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 } | 352 } |
| 353 const uint8_t* buf = static_cast<uint8_t*>(memory.memory()); | 353 const uint8_t* buf = static_cast<uint8_t*>(memory.memory()); |
| 354 | 354 |
| 355 // NALUs are stored with Annex B format in the bitstream buffer (start codes), | 355 // NALUs are stored with Annex B format in the bitstream buffer (start codes), |
| 356 // but VideoToolbox expects AVC format (length headers), so we must rewrite | 356 // but VideoToolbox expects AVC format (length headers), so we must rewrite |
| 357 // the data. | 357 // the data. |
| 358 // | 358 // |
| 359 // Locate relevant NALUs and compute the size of the rewritten data. Also | 359 // Locate relevant NALUs and compute the size of the rewritten data. Also |
| 360 // record any parameter sets for VideoToolbox initialization. | 360 // record any parameter sets for VideoToolbox initialization. |
| 361 bool config_changed = false; | 361 bool config_changed = false; |
| 362 bool has_slice = false; |
| 362 size_t data_size = 0; | 363 size_t data_size = 0; |
| 363 std::vector<media::H264NALU> nalus; | 364 std::vector<media::H264NALU> nalus; |
| 364 parser_.SetStream(buf, size); | 365 parser_.SetStream(buf, size); |
| 365 media::H264NALU nalu; | 366 media::H264NALU nalu; |
| 366 while (true) { | 367 while (true) { |
| 367 media::H264Parser::Result result = parser_.AdvanceToNextNALU(&nalu); | 368 media::H264Parser::Result result = parser_.AdvanceToNextNALU(&nalu); |
| 368 if (result == media::H264Parser::kEOStream) | 369 if (result == media::H264Parser::kEOStream) |
| 369 break; | 370 break; |
| 370 if (result != media::H264Parser::kOk) { | 371 if (result != media::H264Parser::kOk) { |
| 371 DLOG(ERROR) << "Failed to find H.264 NALU"; | 372 DLOG(ERROR) << "Failed to find H.264 NALU"; |
| (...skipping 24 matching lines...) Expand all Loading... |
| 396 if (parser_.ParsePPS(&last_pps_id_) != media::H264Parser::kOk) { | 397 if (parser_.ParsePPS(&last_pps_id_) != media::H264Parser::kOk) { |
| 397 DLOG(ERROR) << "Could not parse PPS"; | 398 DLOG(ERROR) << "Could not parse PPS"; |
| 398 NotifyError(UNREADABLE_INPUT); | 399 NotifyError(UNREADABLE_INPUT); |
| 399 return; | 400 return; |
| 400 } | 401 } |
| 401 break; | 402 break; |
| 402 | 403 |
| 403 case media::H264NALU::kSliceDataA: | 404 case media::H264NALU::kSliceDataA: |
| 404 case media::H264NALU::kSliceDataB: | 405 case media::H264NALU::kSliceDataB: |
| 405 case media::H264NALU::kSliceDataC: | 406 case media::H264NALU::kSliceDataC: |
| 406 DLOG(ERROR) << "Coded slide data partitions not implemented."; | |
| 407 NotifyError(PLATFORM_FAILURE); | |
| 408 return; | |
| 409 | |
| 410 case media::H264NALU::kNonIDRSlice: | 407 case media::H264NALU::kNonIDRSlice: |
| 411 // TODO(sandersd): Check that there has been an IDR slice since the | 408 // TODO(sandersd): Check that there has been an IDR slice since the |
| 412 // last reset. | 409 // last reset. |
| 413 case media::H264NALU::kIDRSlice: | 410 case media::H264NALU::kIDRSlice: |
| 414 { | 411 // Compute the |pic_order_cnt| for the picture from the first slice. |
| 415 // TODO(sandersd): Make sure this only happens once per frame. | 412 // TODO(sandersd): Make sure that any further slices are part of the |
| 416 DCHECK_EQ(frame->pic_order_cnt, 0); | 413 // same picture or a redundant coded picture. |
| 417 | 414 if (!has_slice) { |
| 418 media::H264SliceHeader slice_hdr; | 415 media::H264SliceHeader slice_hdr; |
| 419 result = parser_.ParseSliceHeader(nalu, &slice_hdr); | 416 result = parser_.ParseSliceHeader(nalu, &slice_hdr); |
| 420 if (result != media::H264Parser::kOk) { | 417 if (result != media::H264Parser::kOk) { |
| 421 DLOG(ERROR) << "Could not parse slice header"; | 418 DLOG(ERROR) << "Could not parse slice header"; |
| 422 NotifyError(UNREADABLE_INPUT); | 419 NotifyError(UNREADABLE_INPUT); |
| 423 return; | 420 return; |
| 424 } | 421 } |
| 425 | 422 |
| 426 // TODO(sandersd): Maintain a cache of configurations and reconfigure | 423 // TODO(sandersd): Maintain a cache of configurations and reconfigure |
| 427 // only when a slice references a new config. | 424 // only when a slice references a new config. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 446 NotifyError(UNREADABLE_INPUT); | 443 NotifyError(UNREADABLE_INPUT); |
| 447 return; | 444 return; |
| 448 } | 445 } |
| 449 | 446 |
| 450 if (sps->vui_parameters_present_flag && | 447 if (sps->vui_parameters_present_flag && |
| 451 sps->bitstream_restriction_flag) { | 448 sps->bitstream_restriction_flag) { |
| 452 frame->reorder_window = std::min(sps->max_num_reorder_frames, | 449 frame->reorder_window = std::min(sps->max_num_reorder_frames, |
| 453 kMaxReorderQueueSize - 1); | 450 kMaxReorderQueueSize - 1); |
| 454 } | 451 } |
| 455 } | 452 } |
| 453 has_slice = true; |
| 456 default: | 454 default: |
| 457 nalus.push_back(nalu); | 455 nalus.push_back(nalu); |
| 458 data_size += kNALUHeaderLength + nalu.size; | 456 data_size += kNALUHeaderLength + nalu.size; |
| 459 break; | 457 break; |
| 460 } | 458 } |
| 461 } | 459 } |
| 462 | 460 |
| 463 // Initialize VideoToolbox. | 461 // Initialize VideoToolbox. |
| 464 // TODO(sandersd): Instead of assuming that the last SPS and PPS units are | 462 // TODO(sandersd): Instead of assuming that the last SPS and PPS units are |
| 465 // always the correct ones, maintain a cache of recent SPS and PPS units and | 463 // always the correct ones, maintain a cache of recent SPS and PPS units and |
| 466 // select from them using the slice header. | 464 // select from them using the slice header. |
| 467 if (config_changed) { | 465 if (config_changed) { |
| 468 if (last_sps_.size() == 0 || last_pps_.size() == 0) { | 466 if (last_sps_.size() == 0 || last_pps_.size() == 0) { |
| 469 DLOG(ERROR) << "Invalid configuration data"; | 467 DLOG(ERROR) << "Invalid configuration data"; |
| 470 NotifyError(INVALID_ARGUMENT); | 468 NotifyError(INVALID_ARGUMENT); |
| 471 return; | 469 return; |
| 472 } | 470 } |
| 473 if (!ConfigureDecoder()) | 471 if (!ConfigureDecoder()) |
| 474 return; | 472 return; |
| 475 } | 473 } |
| 476 | 474 |
| 477 // If there are no non-configuration units, drop the bitstream buffer by | 475 // If there are no image slices, drop the bitstream buffer by returning an |
| 478 // returning an empty frame. | 476 // empty frame. |
| 479 if (!data_size) { | 477 if (!has_slice) { |
| 480 if (!FinishDelayedFrames()) | 478 if (!FinishDelayedFrames()) |
| 481 return; | 479 return; |
| 482 gpu_task_runner_->PostTask(FROM_HERE, base::Bind( | 480 gpu_task_runner_->PostTask(FROM_HERE, base::Bind( |
| 483 &VTVideoDecodeAccelerator::DecodeDone, weak_this_, frame)); | 481 &VTVideoDecodeAccelerator::DecodeDone, weak_this_, frame)); |
| 484 return; | 482 return; |
| 485 } | 483 } |
| 486 | 484 |
| 487 // If the session is not configured by this point, fail. | 485 // If the session is not configured by this point, fail. |
| 488 if (!session_) { | 486 if (!session_) { |
| 489 DLOG(ERROR) << "Image slice without configuration"; | 487 DLOG(ERROR) << "Image slice without configuration"; |
| (...skipping 397 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 887 assigned_bitstream_ids_.clear(); | 885 assigned_bitstream_ids_.clear(); |
| 888 state_ = STATE_DESTROYING; | 886 state_ = STATE_DESTROYING; |
| 889 QueueFlush(TASK_DESTROY); | 887 QueueFlush(TASK_DESTROY); |
| 890 } | 888 } |
| 891 | 889 |
| 892 bool VTVideoDecodeAccelerator::CanDecodeOnIOThread() { | 890 bool VTVideoDecodeAccelerator::CanDecodeOnIOThread() { |
| 893 return false; | 891 return false; |
| 894 } | 892 } |
| 895 | 893 |
| 896 } // namespace content | 894 } // namespace content |
| OLD | NEW |