Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(697)

Side by Side Diff: media/tools/omx_test/file_reader_util.cc

Issue 7066071: Removing defunct OpenMAX code. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src
Patch Set: removed tab Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « media/tools/omx_test/file_reader_util.h ('k') | media/tools/omx_test/file_sink.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "media/tools/omx_test/file_reader_util.h"
6
7 #include <stdio.h>
8 #include <string>
9
10 #include "base/file_util.h"
11 #include "base/logging.h"
12 #include "base/string_util.h"
13 #include "media/ffmpeg/ffmpeg_common.h"
14 #include "media/ffmpeg/file_protocol.h"
15 #include "media/filters/bitstream_converter.h"
16 #include "media/tools/omx_test/color_space_util.h"
17
18 namespace media {
19
20 //////////////////////////////////////////////////////////////////////////////
21 // BasicFileReader
22 BasicFileReader::BasicFileReader(const FilePath& path)
23 : path_(path),
24 file_(NULL) {
25 }
26
27 bool BasicFileReader::Initialize() {
28 file_.Set(file_util::OpenFile(path_, "rb"));
29 if (!file_.get()) {
30 LOG(ERROR) << "unable to open " << path_.value();
31 }
32 return file_.get() != NULL;
33 }
34
35 //////////////////////////////////////////////////////////////////////////////
36 // YuvFileReader
37 YuvFileReader::YuvFileReader(const FilePath& path,
38 int width,
39 int height,
40 int loop_count,
41 bool enable_csc)
42 : BasicFileReader(path),
43 width_(width),
44 height_(height),
45 loop_count_(loop_count),
46 output_nv21_(enable_csc) {
47 }
48
49 YuvFileReader::~YuvFileReader() {}
50
51 void YuvFileReader::Read(uint8** output, int* size) {
52 if (!file()) {
53 *size = 0;
54 *output = NULL;
55 return;
56 }
57
58 while (true) {
59 scoped_array<uint8> data;
60 int bytes_read = 0;
61
62 // OMX require encoder input are delivered in frames (or planes).
63 // Assume the input file is I420 YUV file.
64 const int kFrameSize = width_ * height_ * 3 / 2;
65 data.reset(new uint8[kFrameSize]);
66
67 if (output_nv21_) {
68 if (!csc_buf_.get())
69 csc_buf_.reset(new uint8[kFrameSize]);
70 bytes_read = fread(csc_buf_.get(), 1, kFrameSize, file());
71
72 // We do not convert partial frames.
73 if (bytes_read == kFrameSize)
74 IYUVtoNV21(csc_buf_.get(), data.get(), width_, height_);
75 else
76 bytes_read = 0; // force cleanup or loop around.
77 } else {
78 bytes_read = fread(data.get(), 1, kFrameSize, file());
79 }
80
81 if (bytes_read) {
82 *size = bytes_read;
83 *output = data.release();
84 break;
85 }
86
87 // Encounter the end of file.
88 if (loop_count_ == 1) {
89 // Signal end of stream.
90 *size = 0;
91 *output = data.release();
92 }
93
94 --loop_count_;
95 fseek(file(), 0, SEEK_SET);
96 }
97 }
98
99 //////////////////////////////////////////////////////////////////////////////
100 // BlockFileReader
101 BlockFileReader::BlockFileReader(const FilePath& path,
102 int block_size)
103 : BasicFileReader(path),
104 block_size_(block_size) {
105 }
106
107 void BlockFileReader::Read(uint8** output, int* size) {
108 CHECK(file());
109 *output = new uint8[block_size_];
110 *size = fread(*output, 1, block_size_, file());
111 }
112
113 //////////////////////////////////////////////////////////////////////////////
114 // FFmpegFileReader
115 FFmpegFileReader::FFmpegFileReader(const FilePath& path)
116 : path_(path),
117 format_context_(NULL),
118 codec_context_(NULL),
119 target_stream_(-1),
120 converter_(NULL) {
121 }
122
123 FFmpegFileReader::~FFmpegFileReader() {
124 if (format_context_)
125 av_close_input_file(format_context_);
126 }
127
128 bool FFmpegFileReader::Initialize() {
129 // av_open_input_file wants a char*, which can't work with wide paths.
130 // So we assume ASCII on Windows. On other platforms we can pass the
131 // path bytes through verbatim.
132 #if defined(OS_WIN)
133 std::string string_path = WideToASCII(path_.value());
134 #else
135 const std::string& string_path = path_.value();
136 #endif
137 int result = av_open_input_file(&format_context_, string_path.c_str(),
138 NULL, 0, NULL);
139 if (result < 0) {
140 switch (result) {
141 case AVERROR_NOFMT:
142 LOG(ERROR) << "Error: File format not supported "
143 << path_.value() << std::endl;
144 break;
145 default:
146 LOG(ERROR) << "Error: Could not open input for "
147 << path_.value() << std::endl;
148 break;
149 }
150 return false;
151 }
152 if (av_find_stream_info(format_context_) < 0) {
153 LOG(ERROR) << "can't use FFmpeg to parse stream info";
154 return false;
155 }
156
157 for (size_t i = 0; i < format_context_->nb_streams; ++i) {
158 codec_context_ = format_context_->streams[i]->codec;
159
160 // Find the video stream.
161 if (codec_context_->codec_type == CODEC_TYPE_VIDEO) {
162 target_stream_ = i;
163 break;
164 }
165 }
166 if (target_stream_ == -1) {
167 LOG(ERROR) << "no video in the stream";
168 return false;
169 }
170
171 // Initialize the bitstream filter if needed.
172 // TODO(hclam): find a better way to identify mp4 container.
173 if (codec_context_->codec_id == CODEC_ID_H264) {
174 converter_.reset(new media::FFmpegBitstreamConverter(
175 "h264_mp4toannexb", codec_context_));
176 } else if (codec_context_->codec_id == CODEC_ID_MPEG4) {
177 converter_.reset(new media::FFmpegBitstreamConverter(
178 "mpeg4video_es", codec_context_));
179 } else if (codec_context_->codec_id == CODEC_ID_WMV3) {
180 converter_.reset(new media::FFmpegBitstreamConverter(
181 "vc1_asftorcv", codec_context_));
182 } else if (codec_context_->codec_id == CODEC_ID_VC1) {
183 converter_.reset(new media::FFmpegBitstreamConverter(
184 "vc1_asftoannexg", codec_context_));
185 }
186
187 if (converter_.get() && !converter_->Initialize()) {
188 converter_.reset();
189 LOG(ERROR) << "failed to initialize h264_mp4toannexb filter";
190 return false;
191 }
192 return true;
193 }
194
195 void FFmpegFileReader::Read(uint8** output, int* size) {
196 if (!format_context_ || !codec_context_ || target_stream_ == -1) {
197 *size = 0;
198 *output = NULL;
199 return;
200 }
201
202 AVPacket packet;
203 bool found = false;
204 while (!found) {
205 int result = av_read_frame(format_context_, &packet);
206 if (result < 0) {
207 *output = NULL;
208 *size = 0;
209 return;
210 }
211 if (packet.stream_index == target_stream_) {
212 if (converter_.get() && !converter_->ConvertPacket(&packet)) {
213 LOG(ERROR) << "failed to convert AVPacket";
214 }
215 *output = new uint8[packet.size];
216 *size = packet.size;
217 memcpy(*output, packet.data, packet.size);
218 found = true;
219 }
220 av_free_packet(&packet);
221 }
222 }
223
224 //////////////////////////////////////////////////////////////////////////////
225 // H264FileReader
226 const int kH264ReadSize = 1024 * 1024;
227
228 H264FileReader::H264FileReader(const FilePath& path)
229 : BasicFileReader(path),
230 read_buf_(new uint8[kH264ReadSize]),
231 current_(0),
232 used_(0) {
233 }
234
235 H264FileReader::~H264FileReader() {}
236
237 void H264FileReader::Read(uint8** output, int *size) {
238 // Fill the buffer when it's less than half full.
239 int read = 0;
240 if (used_ < kH264ReadSize / 2) {
241 read = fread(read_buf_.get(), 1, kH264ReadSize - used_, file());
242 CHECK(read >= 0);
243 used_ += read;
244 }
245
246 // If we failed to read.
247 if (current_ == used_) {
248 *output = NULL;
249 *size = 0;
250 return;
251 }
252
253 // Try to find start code of 0x00, 0x00, 0x01.
254 bool found = false;
255 int pos = current_ + 3;
256 for (; pos < used_ - 2; ++pos) {
257 if (read_buf_[pos] == 0 &&
258 read_buf_[pos+1] == 0 &&
259 read_buf_[pos+2] == 1) {
260 found = true;
261 break;
262 }
263 }
264
265 // If next NALU is found.
266 if (found) {
267 CHECK(pos > current_);
268 *size = pos - current_;
269 *output = new uint8[*size];
270 memcpy(*output, read_buf_.get() + current_, *size);
271 current_ = pos;
272
273 // If we have used_ more than half of the available buffer.
274 // Then move the unused_ buffer to the front to give space
275 // for more incoming output.
276 if (current_ > used_ / 2) {
277 CHECK(used_ > current_);
278 memcpy(read_buf_.get(),
279 read_buf_.get() + current_,
280 used_ - current_);
281 used_ = used_ - current_;
282 current_ = 0;
283 }
284 return;
285 }
286
287 // If next NALU is not found, assume the remaining data is a NALU
288 // and return the data.
289 CHECK(used_ > current_);
290 *size = used_ - current_;
291 *output = new uint8[*size];
292 memcpy(*output, read_buf_.get() + current_, *size);
293 current_ = used_;
294 }
295
296 } // namespace media
OLDNEW
« no previous file with comments | « media/tools/omx_test/file_reader_util.h ('k') | media/tools/omx_test/file_sink.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698