summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
authorashokm@nvidia.com <ashokm@nvidia.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-23 20:28:24 +0000
committerashokm@nvidia.com <ashokm@nvidia.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-08-23 20:28:24 +0000
commit01c8ffaa051ca46c4a99d44acc4c62bc6f69f735 (patch)
tree36a1b3cb44953c8f1e5590fb9e8e5463ca7fb4c6 /content
parent59e1c15b1ee0e29742a2479527de09715a2e5525 (diff)
downloadchromium_src-01c8ffaa051ca46c4a99d44acc4c62bc6f69f735.zip
chromium_src-01c8ffaa051ca46c4a99d44acc4c62bc6f69f735.tar.gz
chromium_src-01c8ffaa051ca46c4a99d44acc4c62bc6f69f735.tar.bz2
ovda: check the resource availability with hw decoder
Add the code to check the availability of resources with the nvidia hw decoder. This ensures that all the required resources to start decode are available. BUG= TEST=ovdatest, gles2 Review URL: http://codereview.chromium.org/7205002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@97907 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'content')
-rw-r--r--content/common/gpu/media/omx_video_decode_accelerator.cc66
-rw-r--r--content/common/gpu/media/omx_video_decode_accelerator.h5
-rw-r--r--content/common/gpu/media/omx_video_decode_accelerator_unittest.cc35
3 files changed, 93 insertions, 13 deletions
diff --git a/content/common/gpu/media/omx_video_decode_accelerator.cc b/content/common/gpu/media/omx_video_decode_accelerator.cc
index 27903c9..3c52456 100644
--- a/content/common/gpu/media/omx_video_decode_accelerator.cc
+++ b/content/common/gpu/media/omx_video_decode_accelerator.cc
@@ -5,6 +5,7 @@
#include "content/common/gpu/media/omx_video_decode_accelerator.h"
#include "base/debug/trace_event.h"
+#include "base/logging.h"
#include "base/stl_util.h"
#include "base/string_util.h"
#include "content/common/gpu/gpu_channel.h"
@@ -45,6 +46,38 @@ static bool AreOMXFunctionPointersInitialized() {
omx_free_handle && omx_deinit);
}
+// Maps the media::H264Profile members to the OMX_VIDEO_AVCPROFILETYPE members.
+static OMX_U32 MapH264ProfileToOMXAVCProfile(uint32 profile) {
+ switch (profile) {
+ case media::H264PROFILE_NONE:
+ return OMX_VIDEO_AVCProfileMax;
+ case media::H264PROFILE_BASELINE:
+ return OMX_VIDEO_AVCProfileBaseline;
+ case media::H264PROFILE_MAIN:
+ return OMX_VIDEO_AVCProfileMain;
+ case media::H264PROFILE_EXTENDED:
+ return OMX_VIDEO_AVCProfileExtended;
+ case media::H264PROFILE_HIGH:
+ return OMX_VIDEO_AVCProfileHigh;
+ case media::H264PROFILE_HIGH10PROFILE:
+ return OMX_VIDEO_AVCProfileHigh10;
+ case media::H264PROFILE_HIGH422PROFILE:
+ return OMX_VIDEO_AVCProfileHigh422;
+ case media::H264PROFILE_HIGH444PREDICTIVEPROFILE:
+ return OMX_VIDEO_AVCProfileHigh444;
+ // Below enums don't have equivalent enum in Openmax.
+ case media::H264PROFILE_SCALABLEBASELINE:
+ case media::H264PROFILE_SCALABLEHIGH:
+ case media::H264PROFILE_STEREOHIGH:
+ case media::H264PROFILE_MULTIVIEWHIGH:
+ // Nvidia OMX video decoder requires the same resources (as that of the
+ // High profile) in every profile higher to the Main profile.
+ return OMX_VIDEO_AVCProfileHigh444;
+ }
+ NOTREACHED();
+ return OMX_VIDEO_AVCProfileMax;
+}
+
// Helper macros for dealing with failure. If |result| evaluates false, emit
// |log| to ERROR, register |error| with the decoder, and return |ret_val|
// (which may be omitted for functions that return void).
@@ -76,7 +109,9 @@ OmxVideoDecodeAccelerator::OmxVideoDecodeAccelerator(
input_buffers_at_component_(0),
output_port_(0),
output_buffers_at_component_(0),
- client_(client) {
+ client_(client),
+ profile_(OMX_VIDEO_AVCProfileMax),
+ component_name_is_nvidia_h264ext_(false) {
RETURN_ON_FAILURE(AreOMXFunctionPointersInitialized(),
"Failed to load openmax library", PLATFORM_FAILURE,);
RETURN_ON_OMX_FAILURE(omx_init(), "Failed to init OpenMAX core",
@@ -126,6 +161,9 @@ bool OmxVideoDecodeAccelerator::VerifyConfigs(
v == media::H264PROFILE_HIGH)) ||
(n == media::VIDEOATTRIBUTEKEY_VIDEOCOLORFORMAT &&
v == media::VIDEOCOLORFORMAT_RGBA)) {
+ if (n == media::VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_H264_PROFILE) {
+ profile_ = v;
+ }
continue;
}
return false;
@@ -189,6 +227,10 @@ bool OmxVideoDecodeAccelerator::CreateComponent() {
PLATFORM_FAILURE, false);
client_state_ = OMX_StateLoaded;
+ component_name_is_nvidia_h264ext_ = !strcmp(
+ reinterpret_cast<char *>(component.get()),
+ "OMX.Nvidia.h264ext.decode");
+
// Get the port information. This will obtain information about the number of
// ports and index of the first port.
OMX_PORT_PARAM_TYPE port_param;
@@ -271,7 +313,6 @@ bool OmxVideoDecodeAccelerator::CreateComponent() {
buffer->nOutputPortIndex = output_port_;
CHECK(fake_output_buffers_.insert(buffer).second);
}
-
return true;
}
@@ -473,6 +514,27 @@ void OmxVideoDecodeAccelerator::BeginTransitionToState(
void OmxVideoDecodeAccelerator::OnReachedIdleInInitializing() {
DCHECK_EQ(client_state_, OMX_StateLoaded);
client_state_ = OMX_StateIdle;
+ // Query the resources with the component.
+ if (component_name_is_nvidia_h264ext_) {
+ OMX_INDEXTYPE extension_index;
+ OMX_ERRORTYPE result = OMX_GetExtensionIndex(
+ component_handle_,
+ const_cast<char*>("OMX.Nvidia.index.config.checkresources"),
+ &extension_index);
+ RETURN_ON_OMX_FAILURE(result,
+ "Failed to get the extension",
+ PLATFORM_FAILURE,);
+ OMX_VIDEO_PARAM_PROFILELEVELTYPE video_profile_level;
+ InitParam(*this, &video_profile_level);
+ video_profile_level.eProfile = MapH264ProfileToOMXAVCProfile(profile_);
+ RETURN_ON_FAILURE(video_profile_level.eProfile != OMX_VIDEO_AVCProfileMax,
+ "Unexpected profile", INVALID_ARGUMENT,);
+ result = OMX_SetConfig(component_handle_, extension_index,
+ &video_profile_level);
+ RETURN_ON_OMX_FAILURE(result,
+ "Resource Allocation failed",
+ PLATFORM_FAILURE,);
+ }
BeginTransitionToState(OMX_StateExecuting);
}
diff --git a/content/common/gpu/media/omx_video_decode_accelerator.h b/content/common/gpu/media/omx_video_decode_accelerator.h
index 357aca0..b744068 100644
--- a/content/common/gpu/media/omx_video_decode_accelerator.h
+++ b/content/common/gpu/media/omx_video_decode_accelerator.h
@@ -184,6 +184,11 @@ class OmxVideoDecodeAccelerator : public media::VideoDecodeAccelerator {
// NOTE: all calls to this object *MUST* be executed in message_loop_.
Client* client_;
+ // These two members are only used during Initialization.
+ // OMX_VIDEO_AVCProfile requested during Initialization.
+ uint32 profile_;
+ bool component_name_is_nvidia_h264ext_;
+
// Method to handle events
void EventHandlerCompleteTask(OMX_EVENTTYPE event,
OMX_U32 data1,
diff --git a/content/common/gpu/media/omx_video_decode_accelerator_unittest.cc b/content/common/gpu/media/omx_video_decode_accelerator_unittest.cc
index dde60b1..49498e5 100644
--- a/content/common/gpu/media/omx_video_decode_accelerator_unittest.cc
+++ b/content/common/gpu/media/omx_video_decode_accelerator_unittest.cc
@@ -58,8 +58,9 @@ namespace {
// - |minFPSwithRender| and |minFPSnoRender| are minimum frames/second speeds
// expected to be achieved with and without rendering to the screen, resp.
// (the latter tests just decode speed).
+// - |profile| is the media::H264Profile set during Initialization.
// An empty value for a numeric field means "ignore".
-const char* test_video_data = "test-25fps.h264:320:240:250:258:50:175";
+const char* test_video_data = "test-25fps.h264:320:240:250:258:50:175:1";
// Parse |data| into its constituent parts and set the various output fields
// accordingly. CHECK-fails on unexpected or missing required data.
@@ -70,14 +71,16 @@ void ParseTestVideoData(std::string data,
int* num_frames,
int* num_NALUs,
int* min_fps_render,
- int* min_fps_no_render) {
+ int* min_fps_no_render,
+ int* profile) {
std::vector<std::string> elements;
base::SplitString(data, ':', &elements);
CHECK_GE(elements.size(), 1U) << data;
- CHECK_LE(elements.size(), 7U) << data;
+ CHECK_LE(elements.size(), 8U) << data;
*file_name = elements[0];
*width = *height = *num_frames = *num_NALUs = -1;
*min_fps_render = *min_fps_no_render = -1;
+ *profile = -1;
if (!elements[1].empty())
CHECK(base::StringToInt(elements[1], width));
if (!elements[2].empty())
@@ -90,6 +93,8 @@ void ParseTestVideoData(std::string data,
CHECK(base::StringToInt(elements[5], min_fps_render));
if (!elements[6].empty())
CHECK(base::StringToInt(elements[6], min_fps_no_render));
+ if (!elements[7].empty())
+ CHECK(base::StringToInt(elements[7], profile));
}
@@ -464,7 +469,8 @@ class EglRenderingVDAClient : public VideoDecodeAccelerator::Client {
int num_NALUs_per_decode,
int num_in_flight_decodes,
int reset_after_frame_num,
- int delete_decoder_state);
+ int delete_decoder_state,
+ int profile);
virtual ~EglRenderingVDAClient();
void CreateDecoder();
@@ -526,6 +532,7 @@ class EglRenderingVDAClient : public VideoDecodeAccelerator::Client {
PictureBufferById picture_buffers_by_id_;
base::TimeTicks initialize_done_ticks_;
base::TimeTicks last_frame_delivered_ticks_;
+ int profile_;
};
EglRenderingVDAClient::EglRenderingVDAClient(
@@ -536,7 +543,8 @@ EglRenderingVDAClient::EglRenderingVDAClient(
int num_NALUs_per_decode,
int num_in_flight_decodes,
int reset_after_frame_num,
- int delete_decoder_state)
+ int delete_decoder_state,
+ int profile)
: rendering_helper_(rendering_helper),
rendering_window_id_(rendering_window_id),
encoded_data_(encoded_data), num_NALUs_per_decode_(num_NALUs_per_decode),
@@ -545,7 +553,8 @@ EglRenderingVDAClient::EglRenderingVDAClient(
note_(note), reset_after_frame_num_(reset_after_frame_num),
delete_decoder_state_(delete_decoder_state),
state_(CS_CREATED),
- num_decoded_frames_(0), num_done_bitstream_buffers_(0) {
+ num_decoded_frames_(0), num_done_bitstream_buffers_(0),
+ profile_(profile) {
CHECK_GT(num_NALUs_per_decode, 0);
CHECK_GT(num_in_flight_decodes, 0);
}
@@ -572,7 +581,11 @@ void EglRenderingVDAClient::CreateDecoder() {
media::VIDEOATTRIBUTEKEY_VIDEOCOLORFORMAT, media::VIDEOCOLORFORMAT_RGBA,
};
std::vector<int32> config(
- config_array, config_array + arraysize(config_array));
+ config_array, config_array + arraysize(config_array));
+ if (profile_ != -1) {
+ config.push_back(media::VIDEOATTRIBUTEKEY_BITSTREAMFORMAT_H264_PROFILE);
+ config.push_back(profile_);
+ }
CHECK(decoder_->Initialize(config));
}
@@ -798,7 +811,7 @@ static void AssertWaitForStateOrDeleted(ClientStateNotification* note,
// We assert the exact number of concurrent decoders we expect to succeed and
// that one more than that fails initialization.
-enum { kMaxSupportedNumConcurrentDecoders = 5 };
+enum { kMaxSupportedNumConcurrentDecoders = 3 };
// Test the most straightforward case possible: data is decoded from a single
// chunk and rendered to the screen.
@@ -817,10 +830,10 @@ TEST_P(OmxVideoDecodeAcceleratorTest, TestSimpleDecode) {
std::string test_video_file;
int frame_width, frame_height;
- int num_frames, num_NALUs, min_fps_render, min_fps_no_render;
+ int num_frames, num_NALUs, min_fps_render, min_fps_no_render, profile;
ParseTestVideoData(test_video_data, &test_video_file, &frame_width,
&frame_height, &num_frames, &num_NALUs,
- &min_fps_render, &min_fps_no_render);
+ &min_fps_render, &min_fps_no_render, &profile);
min_fps_render /= num_concurrent_decoders;
min_fps_no_render /= num_concurrent_decoders;
@@ -862,7 +875,7 @@ TEST_P(OmxVideoDecodeAcceleratorTest, TestSimpleDecode) {
&rendering_helper, index,
note, data_str, num_NALUs_per_decode,
num_in_flight_decodes,
- reset_after_frame_num, delete_decoder_state);
+ reset_after_frame_num, delete_decoder_state, profile);
clients[index] = client;
rendering_thread.message_loop()->PostTask(