7 #include "packager/media/base/demuxer.h"
9 #include "packager/base/bind.h"
10 #include "packager/base/logging.h"
11 #include "packager/base/stl_util.h"
12 #include "packager/media/base/decryptor_source.h"
13 #include "packager/media/base/key_source.h"
14 #include "packager/media/base/media_sample.h"
15 #include "packager/media/base/media_stream.h"
16 #include "packager/media/base/stream_info.h"
17 #include "packager/media/file/file.h"
18 #include "packager/media/formats/mp2t/mp2t_media_parser.h"
19 #include "packager/media/formats/mp4/mp4_media_parser.h"
20 #include "packager/media/formats/webm/webm_media_parser.h"
21 #include "packager/media/formats/wvm/wvm_media_parser.h"
24 const size_t kInitBufSize = 0x10000;
26 const size_t kBufSize = 0x200000;
29 namespace edash_packager {
33 : file_name_(file_name),
35 init_event_received_(false),
36 container_name_(CONTAINER_UNKNOWN),
37 buffer_(new uint8_t[kBufSize]),
44 STLDeleteElements(&streams_);
48 key_source_ = key_source.Pass();
53 DCHECK(!init_event_received_);
55 LOG(INFO) <<
"Initialize Demuxer for file '" << file_name_ <<
"'.";
57 media_file_ =
File::Open(file_name_.c_str(),
"r");
59 return Status(error::FILE_FAILURE,
60 "Cannot open file for reading " + file_name_);
64 size_t bytes_read = 0;
65 while (bytes_read < kInitBufSize) {
67 media_file_->
Read(buffer_.get() + bytes_read, kInitBufSize);
69 return Status(error::FILE_FAILURE,
"Cannot read file " + file_name_);
72 bytes_read += read_result;
74 container_name_ = DetermineContainer(buffer_.get(), bytes_read);
77 switch (container_name_) {
81 case CONTAINER_MPEG2TS:
84 case CONTAINER_MPEG2PS:
92 return Status(error::UNIMPLEMENTED,
"Container not supported.");
95 parser_->Init(base::Bind(&Demuxer::ParserInitEvent, base::Unretained(
this)),
96 base::Bind(&Demuxer::NewSampleEvent, base::Unretained(
this)),
100 if (container_name_ == CONTAINER_MOV)
103 if (!parser_->Parse(buffer_.get(), bytes_read)) {
104 init_parsing_status_ =
105 Status(error::PARSER_FAILURE,
"Cannot parse media file " + file_name_);
109 while (!init_event_received_ && init_parsing_status_.ok())
110 init_parsing_status_ =
Parse();
112 return init_event_received_ ? Status::OK : init_parsing_status_;
115 void Demuxer::ParserInitEvent(
116 const std::vector<scoped_refptr<StreamInfo> >& streams) {
117 init_event_received_ =
true;
119 std::vector<scoped_refptr<StreamInfo> >::const_iterator it =
streams.begin();
120 for (; it !=
streams.end(); ++it) {
125 bool Demuxer::NewSampleEvent(uint32_t track_id,
126 const scoped_refptr<MediaSample>& sample) {
127 std::vector<MediaStream*>::iterator it = streams_.begin();
128 for (; it != streams_.end(); ++it) {
129 if (track_id == (*it)->info()->track_id()) {
130 return (*it)->PushSample(sample).ok();
139 LOG(INFO) <<
"Demuxer::Run() on file '" << file_name_ <<
"'.";
142 for (std::vector<MediaStream*>::iterator it = streams_.begin();
143 it != streams_.end();
145 status = (*it)->Start(MediaStream::kPush);
150 while (!cancelled_ && (status =
Parse()).ok())
153 if (cancelled_ && status.ok())
154 return Status(error::CANCELLED,
"Demuxer run cancelled");
156 if (status.error_code() == error::END_OF_STREAM) {
159 for (std::vector<MediaStream*>::iterator it = streams_.begin();
160 it != streams_.end();
162 status = (*it)->PushSample(sample);
177 if (!init_parsing_status_.ok())
178 return init_parsing_status_;
180 int64_t bytes_read = media_file_->
Read(buffer_.get(), kBufSize);
181 if (bytes_read == 0) {
183 return Status(error::END_OF_STREAM,
"");
184 }
else if (bytes_read < 0) {
185 return Status(error::FILE_FAILURE,
"Cannot read file " + file_name_);
188 return parser_->Parse(buffer_.get(), bytes_read)
190 :
Status(error::PARSER_FAILURE,
191 "Cannot parse media file " + file_name_);