summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryuli@chromium.org <yuli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-29 22:17:59 +0000
committeryuli@chromium.org <yuli@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-29 22:17:59 +0000
commitaa72609f2bcec9f314939a4dd987db9b8926539f (patch)
tree73960aea735cdca9e3783096e120c3ec98c73bf9
parent1455be7dc5b61cca5dff7a510725fe72c2daec0a (diff)
downloadchromium_src-aa72609f2bcec9f314939a4dd987db9b8926539f.zip
chromium_src-aa72609f2bcec9f314939a4dd987db9b8926539f.tar.gz
chromium_src-aa72609f2bcec9f314939a4dd987db9b8926539f.tar.bz2
Narrow VDA Decode() API and remove multi-frame tests.
BUG=chrome-os-partner:20275 TEST=build and run the test on daisy Review URL: https://codereview.chromium.org/48413004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@231652 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/common/gpu/media/video_decode_accelerator_unittest.cc162
-rw-r--r--media/video/video_decode_accelerator.h6
-rw-r--r--ppapi/api/dev/ppb_video_decoder_dev.idl3
-rw-r--r--ppapi/c/dev/ppb_video_decoder_dev.h5
4 files changed, 71 insertions, 105 deletions
diff --git a/content/common/gpu/media/video_decode_accelerator_unittest.cc b/content/common/gpu/media/video_decode_accelerator_unittest.cc
index 4a67162..4c2ce95 100644
--- a/content/common/gpu/media/video_decode_accelerator_unittest.cc
+++ b/content/common/gpu/media/video_decode_accelerator_unittest.cc
@@ -15,7 +15,6 @@
// infrastructure.
#include <fcntl.h>
-#include <math.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <deque>
@@ -400,7 +399,6 @@ class GLRenderingVDAClient
public:
// Doesn't take ownership of |rendering_helper| or |note|, which must outlive
// |*this|.
- // |num_fragments_per_decode| counts NALUs for h264 and frames for VP8.
// |num_play_throughs| indicates how many times to play through the video.
// |reset_after_frame_num| can be a frame number >=0 indicating a mid-stream
// Reset() should be done after that frame number is delivered, or
@@ -419,7 +417,6 @@ class GLRenderingVDAClient
int rendering_window_id,
ClientStateNotification<ClientState>* note,
const std::string& encoded_data,
- int num_fragments_per_decode,
int num_in_flight_decodes,
int num_play_throughs,
int reset_after_frame_num,
@@ -468,24 +465,23 @@ class GLRenderingVDAClient
void DeleteDecoder();
// Compute & return the first encoded bytes (including a start frame) to send
- // to the decoder, starting at |start_pos| and returning
- // |num_fragments_per_decode| units. Skips to the first decodable position.
- std::string GetBytesForFirstFragments(size_t start_pos, size_t* end_pos);
- // Compute & return the next encoded bytes to send to the decoder (based on
- // |start_pos| & |num_fragments_per_decode_|).
- std::string GetBytesForNextFragments(size_t start_pos, size_t* end_pos);
- // Helpers for GetRangeForNextFragments above.
+ // to the decoder, starting at |start_pos| and returning one fragment. Skips
+ // to the first decodable position.
+ std::string GetBytesForFirstFragment(size_t start_pos, size_t* end_pos);
+ // Compute & return the encoded bytes of next fragment to send to the decoder
+ // (based on |start_pos|).
+ std::string GetBytesForNextFragment(size_t start_pos, size_t* end_pos);
+ // Helpers for GetBytesForNextFragment above.
void GetBytesForNextNALU(size_t start_pos, size_t* end_pos); // For h.264.
- std::string GetBytesForNextFrames(
+ std::string GetBytesForNextFrame(
size_t start_pos, size_t* end_pos); // For VP8.
- // Request decode of the next batch of fragments in the encoded data.
- void DecodeNextFragments();
+ // Request decode of the next fragment in the encoded data.
+ void DecodeNextFragment();
RenderingHelper* rendering_helper_;
int rendering_window_id_;
std::string encoded_data_;
- const int num_fragments_per_decode_;
const int num_in_flight_decodes_;
int outstanding_decodes_;
size_t encoded_data_next_pos_to_decode_;
@@ -517,7 +513,6 @@ GLRenderingVDAClient::GLRenderingVDAClient(
int rendering_window_id,
ClientStateNotification<ClientState>* note,
const std::string& encoded_data,
- int num_fragments_per_decode,
int num_in_flight_decodes,
int num_play_throughs,
int reset_after_frame_num,
@@ -531,7 +526,6 @@ GLRenderingVDAClient::GLRenderingVDAClient(
: rendering_helper_(rendering_helper),
rendering_window_id_(rendering_window_id),
encoded_data_(encoded_data),
- num_fragments_per_decode_(num_fragments_per_decode),
num_in_flight_decodes_(num_in_flight_decodes),
outstanding_decodes_(0),
encoded_data_next_pos_to_decode_(0),
@@ -548,7 +542,6 @@ GLRenderingVDAClient::GLRenderingVDAClient(
profile_(profile),
suppress_rendering_(suppress_rendering),
delay_reuse_after_frame_num_(delay_reuse_after_frame_num) {
- CHECK_GT(num_fragments_per_decode, 0);
CHECK_GT(num_in_flight_decodes, 0);
CHECK_GT(num_play_throughs, 0);
CHECK_GE(rendering_fps, 0);
@@ -697,7 +690,7 @@ void GLRenderingVDAClient::NotifyInitializeDone() {
}
for (int i = 0; i < num_in_flight_decodes_; ++i)
- DecodeNextFragments();
+ DecodeNextFragment();
DCHECK_EQ(outstanding_decodes_, num_in_flight_decodes_);
}
@@ -709,7 +702,7 @@ void GLRenderingVDAClient::NotifyEndOfBitstreamBuffer(
// VaapiVideoDecodeAccelerator::FinishReset()).
++num_done_bitstream_buffers_;
--outstanding_decodes_;
- DecodeNextFragments();
+ DecodeNextFragment();
}
void GLRenderingVDAClient::NotifyFlushDone() {
@@ -730,12 +723,12 @@ void GLRenderingVDAClient::NotifyResetDone() {
if (reset_after_frame_num_ == MID_STREAM_RESET) {
reset_after_frame_num_ = END_OF_STREAM_RESET;
- DecodeNextFragments();
+ DecodeNextFragment();
return;
} else if (reset_after_frame_num_ == START_OF_STREAM_RESET) {
reset_after_frame_num_ = END_OF_STREAM_RESET;
for (int i = 0; i < num_in_flight_decodes_; ++i)
- DecodeNextFragments();
+ DecodeNextFragment();
return;
}
@@ -801,13 +794,13 @@ void GLRenderingVDAClient::DeleteDecoder() {
SetState(static_cast<ClientState>(i));
}
-std::string GLRenderingVDAClient::GetBytesForFirstFragments(
+std::string GLRenderingVDAClient::GetBytesForFirstFragment(
size_t start_pos, size_t* end_pos) {
if (profile_ < media::H264PROFILE_MAX) {
*end_pos = start_pos;
while (*end_pos + 4 < encoded_data_.size()) {
if ((encoded_data_[*end_pos + 4] & 0x1f) == 0x7) // SPS start frame
- return GetBytesForNextFragments(*end_pos, end_pos);
+ return GetBytesForNextFragment(*end_pos, end_pos);
GetBytesForNextNALU(*end_pos, end_pos);
num_skipped_fragments_++;
}
@@ -815,25 +808,21 @@ std::string GLRenderingVDAClient::GetBytesForFirstFragments(
return std::string();
}
DCHECK_LE(profile_, media::VP8PROFILE_MAX);
- return GetBytesForNextFragments(start_pos, end_pos);
+ return GetBytesForNextFragment(start_pos, end_pos);
}
-std::string GLRenderingVDAClient::GetBytesForNextFragments(
+std::string GLRenderingVDAClient::GetBytesForNextFragment(
size_t start_pos, size_t* end_pos) {
if (profile_ < media::H264PROFILE_MAX) {
- size_t new_end_pos = start_pos;
*end_pos = start_pos;
- for (int i = 0; i < num_fragments_per_decode_; ++i) {
- GetBytesForNextNALU(*end_pos, &new_end_pos);
- if (*end_pos == new_end_pos)
- break;
- *end_pos = new_end_pos;
+ GetBytesForNextNALU(*end_pos, end_pos);
+ if (start_pos != *end_pos) {
num_queued_fragments_++;
}
return encoded_data_.substr(start_pos, *end_pos - start_pos);
}
DCHECK_LE(profile_, media::VP8PROFILE_MAX);
- return GetBytesForNextFrames(start_pos, end_pos);
+ return GetBytesForNextFrame(start_pos, end_pos);
}
void GLRenderingVDAClient::GetBytesForNextNALU(
@@ -851,26 +840,22 @@ void GLRenderingVDAClient::GetBytesForNextNALU(
*end_pos = encoded_data_.size();
}
-std::string GLRenderingVDAClient::GetBytesForNextFrames(
+std::string GLRenderingVDAClient::GetBytesForNextFrame(
size_t start_pos, size_t* end_pos) {
// Helpful description: http://wiki.multimedia.cx/index.php?title=IVF
std::string bytes;
if (start_pos == 0)
start_pos = 32; // Skip IVF header.
*end_pos = start_pos;
- for (int i = 0; i < num_fragments_per_decode_; ++i) {
- uint32 frame_size = *reinterpret_cast<uint32*>(&encoded_data_[*end_pos]);
- *end_pos += 12; // Skip frame header.
- bytes.append(encoded_data_.substr(*end_pos, frame_size));
- *end_pos += frame_size;
- num_queued_fragments_++;
- if (*end_pos + 12 >= encoded_data_.size())
- return bytes;
- }
+ uint32 frame_size = *reinterpret_cast<uint32*>(&encoded_data_[*end_pos]);
+ *end_pos += 12; // Skip frame header.
+ bytes.append(encoded_data_.substr(*end_pos, frame_size));
+ *end_pos += frame_size;
+ num_queued_fragments_++;
return bytes;
}
-void GLRenderingVDAClient::DecodeNextFragments() {
+void GLRenderingVDAClient::DecodeNextFragment() {
if (decoder_deleted())
return;
if (encoded_data_next_pos_to_decode_ == encoded_data_.size()) {
@@ -883,14 +868,14 @@ void GLRenderingVDAClient::DecodeNextFragments() {
size_t end_pos;
std::string next_fragment_bytes;
if (encoded_data_next_pos_to_decode_ == 0) {
- next_fragment_bytes = GetBytesForFirstFragments(0, &end_pos);
+ next_fragment_bytes = GetBytesForFirstFragment(0, &end_pos);
} else {
next_fragment_bytes =
- GetBytesForNextFragments(encoded_data_next_pos_to_decode_, &end_pos);
+ GetBytesForNextFragment(encoded_data_next_pos_to_decode_, &end_pos);
}
size_t next_fragment_size = next_fragment_bytes.size();
- // Populate the shared memory buffer w/ the fragments, duplicate its handle,
+ // Populate the shared memory buffer w/ the fragment, duplicate its handle,
// and hand it off to the decoder.
base::SharedMemory shm;
CHECK(shm.CreateAndMapAnonymous(next_fragment_size));
@@ -924,7 +909,6 @@ double GLRenderingVDAClient::frames_per_second() {
}
// Test parameters:
-// - Number of fragments per Decode() call.
// - Number of concurrent decoders.
// - Number of concurrent in-flight Decode() calls per decoder.
// - Number of play-throughs.
@@ -934,16 +918,16 @@ double GLRenderingVDAClient::frames_per_second() {
// - whether the video frames are rendered as thumbnails.
class VideoDecodeAcceleratorTest
: public ::testing::TestWithParam<
- Tuple8<int, int, int, int, ResetPoint, ClientState, bool, bool> > {
+ Tuple7<int, int, int, ResetPoint, ClientState, bool, bool> > {
};
// Helper so that gtest failures emit a more readable version of the tuple than
// its byte representation.
::std::ostream& operator<<(
::std::ostream& os,
- const Tuple8<int, int, int, int, ResetPoint, ClientState, bool, bool>& t) {
+ const Tuple7<int, int, int, ResetPoint, ClientState, bool, bool>& t) {
return os << t.a << ", " << t.b << ", " << t.c << ", " << t.d << ", " << t.e
- << ", " << t.f << ", " << t.g << ", " << t.h;
+ << ", " << t.f << ", " << t.g;
}
// Wait for |note| to report a state and if it's not |expected_state| then
@@ -970,14 +954,13 @@ TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) {
// Required for Thread to work. Not used otherwise.
base::ShadowingAtExitManager at_exit_manager;
- const int num_fragments_per_decode = GetParam().a;
- const size_t num_concurrent_decoders = GetParam().b;
- const size_t num_in_flight_decodes = GetParam().c;
- const int num_play_throughs = GetParam().d;
- const int reset_point = GetParam().e;
- const int delete_decoder_state = GetParam().f;
- bool test_reuse_delay = GetParam().g;
- const bool render_as_thumbnails = GetParam().h;
+ const size_t num_concurrent_decoders = GetParam().a;
+ const size_t num_in_flight_decodes = GetParam().b;
+ const int num_play_throughs = GetParam().c;
+ const int reset_point = GetParam().d;
+ const int delete_decoder_state = GetParam().e;
+ bool test_reuse_delay = GetParam().f;
+ const bool render_as_thumbnails = GetParam().g;
std::vector<TestVideoFile*> test_video_files;
ParseAndReadTestVideoData(g_test_video_data,
@@ -986,10 +969,7 @@ TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) {
&test_video_files);
// Suppress GL rendering for all tests when the "--disable_rendering" is set.
- // Otherwise, suppress rendering in all but a few tests, to cut down overall
- // test runtime.
- const bool suppress_rendering =
- num_fragments_per_decode > 1 || g_disable_rendering;
+ const bool suppress_rendering = g_disable_rendering;
std::vector<ClientStateNotification<ClientState>*>
notes(num_concurrent_decoders, NULL);
@@ -1056,7 +1036,6 @@ TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) {
index,
note,
video_file->data_str,
- num_fragments_per_decode,
num_in_flight_decodes,
num_play_throughs,
video_file->reset_after_frame_num,
@@ -1136,8 +1115,7 @@ TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) {
EXPECT_EQ(video_file->num_fragments, client->num_skipped_fragments() +
client->num_queued_fragments());
EXPECT_EQ(client->num_done_bitstream_buffers(),
- ceil(static_cast<double>(client->num_queued_fragments()) /
- num_fragments_per_decode));
+ client->num_queued_fragments());
}
LOG(INFO) << "Decoder " << i << " fps: " << client->frames_per_second();
if (!render_as_thumbnails) {
@@ -1230,7 +1208,7 @@ TEST_P(VideoDecodeAcceleratorTest, TestSimpleDecode) {
INSTANTIATE_TEST_CASE_P(
ReplayAfterEOS, VideoDecodeAcceleratorTest,
::testing::Values(
- MakeTuple(1, 1, 1, 4, END_OF_STREAM_RESET, CS_RESET, false, false)));
+ MakeTuple(1, 1, 4, END_OF_STREAM_RESET, CS_RESET, false, false)));
// This hangs on Exynos, preventing further testing and wasting test machine
// time.
@@ -1240,7 +1218,7 @@ INSTANTIATE_TEST_CASE_P(
INSTANTIATE_TEST_CASE_P(
ResetBeforeDecode, VideoDecodeAcceleratorTest,
::testing::Values(
- MakeTuple(1, 1, 1, 1, START_OF_STREAM_RESET, CS_RESET, false, false)));
+ MakeTuple(1, 1, 1, START_OF_STREAM_RESET, CS_RESET, false, false)));
#endif // ARCH_CPU_X86_FAMILY
// Test that Reset() mid-stream works fine and doesn't affect decoding even when
@@ -1248,53 +1226,39 @@ INSTANTIATE_TEST_CASE_P(
INSTANTIATE_TEST_CASE_P(
MidStreamReset, VideoDecodeAcceleratorTest,
::testing::Values(
- MakeTuple(1, 1, 1, 1, MID_STREAM_RESET, CS_RESET, false, false)));
+ MakeTuple(1, 1, 1, MID_STREAM_RESET, CS_RESET, false, false)));
INSTANTIATE_TEST_CASE_P(
SlowRendering, VideoDecodeAcceleratorTest,
::testing::Values(
- MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET, true, false)));
+ MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET, true, false)));
// Test that Destroy() mid-stream works fine (primarily this is testing that no
// crashes occur).
INSTANTIATE_TEST_CASE_P(
TearDownTiming, VideoDecodeAcceleratorTest,
::testing::Values(
- MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_DECODER_SET, false,
- false),
- MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_INITIALIZED, false,
- false),
- MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_FLUSHING, false, false),
- MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_FLUSHED, false, false),
- MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_RESETTING, false, false),
- MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, false),
- MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET,
+ MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_DECODER_SET, false, false),
+ MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_INITIALIZED, false, false),
+ MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_FLUSHING, false, false),
+ MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_FLUSHED, false, false),
+ MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESETTING, false, false),
+ MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, false),
+ MakeTuple(1, 1, 1, END_OF_STREAM_RESET,
static_cast<ClientState>(-1), false, false),
- MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET,
+ MakeTuple(1, 1, 1, END_OF_STREAM_RESET,
static_cast<ClientState>(-10), false, false),
- MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET,
+ MakeTuple(1, 1, 1, END_OF_STREAM_RESET,
static_cast<ClientState>(-100), false, false)));
-// Test that decoding various variation works: multiple fragments per Decode()
-// call and multiple in-flight decodes.
+// Test that decoding various variation works with multiple in-flight decodes.
INSTANTIATE_TEST_CASE_P(
DecodeVariations, VideoDecodeAcceleratorTest,
::testing::Values(
- MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, false),
- MakeTuple(1, 1, 10, 1, END_OF_STREAM_RESET, CS_RESET, false, false),
+ MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, false),
+ MakeTuple(1, 10, 1, END_OF_STREAM_RESET, CS_RESET, false, false),
// Tests queuing.
- MakeTuple(1, 1, 15, 1, END_OF_STREAM_RESET, CS_RESET, false, false),
- MakeTuple(2, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, false),
- MakeTuple(3, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, false),
- MakeTuple(5, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, false),
- MakeTuple(8, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, false),
- // TODO(fischman): decoding more than 15 NALUs at once breaks decode -
- // visual artifacts are introduced as well as spurious frames are
- // delivered (more pictures are returned than NALUs are fed to the
- // decoder). Increase the "15" below when
- // http://code.google.com/p/chrome-os-partner/issues/detail?id=4378 is
- // fixed.
- MakeTuple(15, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, false)));
+ MakeTuple(1, 15, 1, END_OF_STREAM_RESET, CS_RESET, false, false)));
// Find out how many concurrent decoders can go before we exhaust system
// resources.
@@ -1302,16 +1266,16 @@ INSTANTIATE_TEST_CASE_P(
ResourceExhaustion, VideoDecodeAcceleratorTest,
::testing::Values(
// +0 hack below to promote enum to int.
- MakeTuple(1, kMinSupportedNumConcurrentDecoders + 0, 1, 1,
+ MakeTuple(kMinSupportedNumConcurrentDecoders + 0, 1, 1,
END_OF_STREAM_RESET, CS_RESET, false, false),
- MakeTuple(1, kMinSupportedNumConcurrentDecoders + 1, 1, 1,
+ MakeTuple(kMinSupportedNumConcurrentDecoders + 1, 1, 1,
END_OF_STREAM_RESET, CS_RESET, false, false)));
// Thumbnailing test
INSTANTIATE_TEST_CASE_P(
Thumbnail, VideoDecodeAcceleratorTest,
::testing::Values(
- MakeTuple(1, 1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, true)));
+ MakeTuple(1, 1, 1, END_OF_STREAM_RESET, CS_RESET, false, true)));
// TODO(fischman, vrk): add more tests! In particular:
// - Test life-cycle: Seek/Stop/Pause/Play for a single decoder.
diff --git a/media/video/video_decode_accelerator.h b/media/video/video_decode_accelerator.h
index 1aa0954..5212db2 100644
--- a/media/video/video_decode_accelerator.h
+++ b/media/video/video_decode_accelerator.h
@@ -90,9 +90,9 @@ class MEDIA_EXPORT VideoDecodeAccelerator
// Returns true when command successfully accepted. Otherwise false.
virtual bool Initialize(VideoCodecProfile profile) = 0;
- // Decodes given bitstream buffer. Once decoder is done with processing
- // |bitstream_buffer| it will call NotifyEndOfBitstreamBuffer() with the
- // bitstream buffer id.
+ // Decodes given bitstream buffer that contains at most one frame. Once
+ // decoder is done with processing |bitstream_buffer| it will call
+ // NotifyEndOfBitstreamBuffer() with the bitstream buffer id.
// Parameters:
// |bitstream_buffer| is the input bitstream that is sent for decoding.
virtual void Decode(const BitstreamBuffer& bitstream_buffer) = 0;
diff --git a/ppapi/api/dev/ppb_video_decoder_dev.idl b/ppapi/api/dev/ppb_video_decoder_dev.idl
index 5b1a94e..da408c9 100644
--- a/ppapi/api/dev/ppb_video_decoder_dev.idl
+++ b/ppapi/api/dev/ppb_video_decoder_dev.idl
@@ -62,7 +62,8 @@ interface PPB_VideoDecoder_Dev {
*
* Parameters:
* |video_decoder| is the previously created handle to the decoder resource.
- * |bitstream_buffer| is the bitstream buffer that contains the input data.
+ * |bitstream_buffer| is the bitstream buffer that contains at most one
+ * input frame.
* |callback| will be called when |bitstream_buffer| has been processed by
* the decoder.
*
diff --git a/ppapi/c/dev/ppb_video_decoder_dev.h b/ppapi/c/dev/ppb_video_decoder_dev.h
index fa57fd4..8b15fb0 100644
--- a/ppapi/c/dev/ppb_video_decoder_dev.h
+++ b/ppapi/c/dev/ppb_video_decoder_dev.h
@@ -3,7 +3,7 @@
* found in the LICENSE file.
*/
-/* From dev/ppb_video_decoder_dev.idl modified Wed Dec 14 18:08:00 2011. */
+/* From dev/ppb_video_decoder_dev.idl modified Tue Oct 29 00:32:59 2013. */
#ifndef PPAPI_C_DEV_PPB_VIDEO_DECODER_DEV_H_
#define PPAPI_C_DEV_PPB_VIDEO_DECODER_DEV_H_
@@ -78,7 +78,8 @@ struct PPB_VideoDecoder_Dev_0_16 {
*
* Parameters:
* |video_decoder| is the previously created handle to the decoder resource.
- * |bitstream_buffer| is the bitstream buffer that contains the input data.
+ * |bitstream_buffer| is the bitstream buffer that contains at most one
+ * input frame.
* |callback| will be called when |bitstream_buffer| has been processed by
* the decoder.
*