summaryrefslogtreecommitdiffstats
path: root/content
diff options
context:
space:
mode:
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(