| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // A test program that drives an OpenMAX video decoder module. This program | 5 // A test program that drives an OpenMAX video decoder module. This program |
| 6 // will take video in elementary stream and read into the decoder. | 6 // will take video in elementary stream and read into the decoder. |
| 7 // | 7 // |
| 8 // Run the following command to see usage: | 8 // Run the following command to see usage: |
| 9 // ./omx_test | 9 // ./omx_test |
| 10 | 10 |
| 11 #include "base/at_exit.h" | 11 #include "base/at_exit.h" |
| 12 #include "base/callback.h" | 12 #include "base/callback.h" |
| 13 #include "base/command_line.h" | 13 #include "base/command_line.h" |
| 14 #include "base/message_loop.h" | 14 #include "base/message_loop.h" |
| 15 #include "base/scoped_ptr.h" | 15 #include "base/scoped_ptr.h" |
| 16 #include "base/time.h" | 16 #include "base/time.h" |
| 17 #include "media/base/media.h" | 17 #include "media/base/media.h" |
| 18 #include "media/ffmpeg/ffmpeg_common.h" | 18 #include "media/ffmpeg/ffmpeg_common.h" |
| 19 #include "media/ffmpeg/file_protocol.h" | 19 #include "media/ffmpeg/file_protocol.h" |
| 20 #include "media/filters/bitstream_converter.h" | 20 #include "media/filters/bitstream_converter.h" |
| 21 #include "media/omx/omx_codec.h" | 21 #include "media/omx/omx_codec.h" |
| 22 #include "media/base/data_buffer.h" | 22 #include "media/base/data_buffer.h" |
| 23 #include "media/omx/omx_output_sink.h" | |
| 24 #include "media/tools/omx_test/color_space_util.h" | 23 #include "media/tools/omx_test/color_space_util.h" |
| 25 #include "media/tools/omx_test/file_reader_util.h" | 24 #include "media/tools/omx_test/file_reader_util.h" |
| 26 #include "media/tools/omx_test/file_sink.h" | 25 #include "media/tools/omx_test/file_sink.h" |
| 27 | 26 |
| 28 using media::BlockFileReader; | 27 using media::BlockFileReader; |
| 29 using media::FFmpegFileReader; | 28 using media::FFmpegFileReader; |
| 30 using media::FileReader; | 29 using media::FileReader; |
| 31 using media::FileSink; | 30 using media::FileSink; |
| 32 using media::H264FileReader; | 31 using media::H264FileReader; |
| 33 using media::OmxCodec; | 32 using media::OmxCodec; |
| 34 using media::OmxConfigurator; | 33 using media::OmxConfigurator; |
| 35 using media::OmxDecoderConfigurator; | 34 using media::OmxDecoderConfigurator; |
| 36 using media::OmxEncoderConfigurator; | 35 using media::OmxEncoderConfigurator; |
| 37 using media::OmxOutputSink; | |
| 38 using media::YuvFileReader; | 36 using media::YuvFileReader; |
| 39 using media::Buffer; | 37 using media::Buffer; |
| 40 using media::DataBuffer; | 38 using media::DataBuffer; |
| 41 | 39 |
| 42 // This is the driver object to feed the decoder with data from a file. | 40 // This is the driver object to feed the decoder with data from a file. |
| 43 // It also provides callbacks for the decoder to receive events from the | 41 // It also provides callbacks for the decoder to receive events from the |
| 44 // decoder. | 42 // decoder. |
| 45 class TestApp { | 43 class TestApp { |
| 46 public: | 44 public: |
| 47 TestApp(OmxConfigurator* configurator, FileSink* file_sink, | 45 TestApp(OmxConfigurator* configurator, FileSink* file_sink, |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 104 // We receive this callback when the decoder has consumed an input buffer. | 102 // We receive this callback when the decoder has consumed an input buffer. |
| 105 // In this case, delete the previous buffer and enqueue a new one. | 103 // In this case, delete the previous buffer and enqueue a new one. |
| 106 // There are some conditions we don't want to enqueue, for example when | 104 // There are some conditions we don't want to enqueue, for example when |
| 107 // the last buffer is an end-of-stream buffer, when we have stopped, and | 105 // the last buffer is an end-of-stream buffer, when we have stopped, and |
| 108 // when we have received an error. | 106 // when we have received an error. |
| 109 bool eos = buffer->IsEndOfStream(); | 107 bool eos = buffer->IsEndOfStream(); |
| 110 if (!eos && !stopped_ && !error_) | 108 if (!eos && !stopped_ && !error_) |
| 111 FeedInputBuffer(); | 109 FeedInputBuffer(); |
| 112 } | 110 } |
| 113 | 111 |
| 114 void ReadCompleteCallback(int buffer, | 112 void ReadCompleteCallback(OMX_BUFFERHEADERTYPE* buffer) { |
| 115 FileSink::BufferUsedCallback* callback) { | |
| 116 // This callback is received when the decoder has completed a decoding | 113 // This callback is received when the decoder has completed a decoding |
| 117 // task and given us some output data. The buffer is owned by the decoder. | 114 // task and given us some output data. The buffer is owned by the decoder. |
| 118 if (stopped_ || error_) | 115 if (stopped_ || error_) |
| 119 return; | 116 return; |
| 120 | 117 |
| 121 if (!frame_count_) | 118 if (!frame_count_) |
| 122 first_sample_delivered_time_ = base::TimeTicks::HighResNow(); | 119 first_sample_delivered_time_ = base::TimeTicks::HighResNow(); |
| 123 | 120 |
| 124 // If we are readding to the end, then stop. | 121 // If we are readding to the end, then stop. |
| 125 if (buffer == OmxCodec::kEosBuffer) { | 122 if (buffer == NULL) { |
| 126 codec_->Stop(NewCallback(this, &TestApp::StopCallback)); | 123 codec_->Stop(NewCallback(this, &TestApp::StopCallback)); |
| 127 return; | 124 return; |
| 128 } | 125 } |
| 129 | 126 |
| 130 // Read one more from the decoder. | 127 // Read one more from the decoder. |
| 131 codec_->Read(NewCallback(this, &TestApp::ReadCompleteCallback)); | 128 codec_->Read(NewCallback(this, &TestApp::ReadCompleteCallback)); |
| 132 | 129 |
| 133 if (file_sink_.get()) | 130 if (file_sink_.get()) |
| 134 file_sink_->BufferReady(buffer, callback); | 131 file_sink_->BufferReady(buffer->nFilledLen, buffer->pBuffer); |
| 135 | 132 |
| 136 // could OMX IL return patial sample for decoder? | 133 // could OMX IL return patial sample for decoder? |
| 137 frame_count_++; | 134 frame_count_++; |
| 138 } | 135 } |
| 139 | 136 |
| 140 void FeedInputBuffer() { | 137 void FeedInputBuffer() { |
| 141 uint8* data; | 138 uint8* data; |
| 142 int read; | 139 int read; |
| 143 file_reader_->Read(&data, &read); | 140 file_reader_->Read(&data, &read); |
| 144 codec_->Feed(new DataBuffer(data, read), | 141 codec_->Feed(new DataBuffer(data, read), |
| 145 NewCallback(this, &TestApp::FeedCallback)); | 142 NewCallback(this, &TestApp::FeedCallback)); |
| 146 } | 143 } |
| 147 | 144 |
| 148 void Run() { | 145 void Run() { |
| 149 StartProfiler(); | 146 StartProfiler(); |
| 150 | 147 |
| 151 // Setup the |codec_| with the message loop of the current thread. Also | 148 // Setup the |codec_| with the message loop of the current thread. Also |
| 152 // setup component name, codec format and callbacks. | 149 // setup component name, codec format and callbacks. |
| 153 codec_ = new OmxCodec(&message_loop_); | 150 codec_ = new OmxCodec(&message_loop_); |
| 154 codec_->Setup(configurator_.get(), file_sink_.get()); | 151 codec_->Setup(configurator_.get()); |
| 155 codec_->SetErrorCallback(NewCallback(this, &TestApp::ErrorCallback)); | 152 codec_->SetErrorCallback(NewCallback(this, &TestApp::ErrorCallback)); |
| 156 codec_->SetFormatCallback(NewCallback(this, &TestApp::FormatCallback)); | 153 codec_->SetFormatCallback(NewCallback(this, &TestApp::FormatCallback)); |
| 157 | 154 |
| 158 // Start the |codec_|. | 155 // Start the |codec_|. |
| 159 codec_->Start(); | 156 codec_->Start(); |
| 160 for (int i = 0; i < 20; ++i) | 157 for (int i = 0; i < 20; ++i) |
| 161 FeedInputBuffer(); | 158 FeedInputBuffer(); |
| 162 codec_->Read(NewCallback(this, &TestApp::ReadCompleteCallback)); | 159 codec_->Read(NewCallback(this, &TestApp::ReadCompleteCallback)); |
| 163 | 160 |
| 164 // Execute the message loop so that we can run tasks on it. This call | 161 // Execute the message loop so that we can run tasks on it. This call |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 375 if (!test.Initialize()) { | 372 if (!test.Initialize()) { |
| 376 LOG(ERROR) << "can't initialize this application"; | 373 LOG(ERROR) << "can't initialize this application"; |
| 377 return -1; | 374 return -1; |
| 378 } | 375 } |
| 379 | 376 |
| 380 // This will run the decoder until EOS is reached or an error | 377 // This will run the decoder until EOS is reached or an error |
| 381 // is encountered. | 378 // is encountered. |
| 382 test.Run(); | 379 test.Run(); |
| 383 return 0; | 380 return 0; |
| 384 } | 381 } |
| OLD | NEW |