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/webvtt/webvtt_media_parser.h"
22 #include "packager/media/formats/wvm/wvm_media_parser.h"
25 const size_t kInitBufSize = 0x10000;
27 const size_t kBufSize = 0x200000;
30 namespace edash_packager {
34 : file_name_(file_name),
36 init_event_received_(false),
37 container_name_(CONTAINER_UNKNOWN),
38 buffer_(new uint8_t[kBufSize]),
45 STLDeleteElements(&streams_);
49 key_source_ = key_source.Pass();
54 DCHECK(!init_event_received_);
56 LOG(INFO) <<
"Initialize Demuxer for file '" << file_name_ <<
"'.";
58 media_file_ =
File::Open(file_name_.c_str(),
"r");
60 return Status(error::FILE_FAILURE,
61 "Cannot open file for reading " + file_name_);
65 size_t bytes_read = 0;
66 while (bytes_read < kInitBufSize) {
68 media_file_->
Read(buffer_.get() + bytes_read, kInitBufSize);
70 return Status(error::FILE_FAILURE,
"Cannot read file " + file_name_);
73 bytes_read += read_result;
75 container_name_ = DetermineContainer(buffer_.get(), bytes_read);
78 switch (container_name_) {
82 case CONTAINER_MPEG2TS:
85 case CONTAINER_MPEG2PS:
91 case CONTAINER_WEBVTT:
96 return Status(error::UNIMPLEMENTED,
"Container not supported.");
99 parser_->Init(base::Bind(&Demuxer::ParserInitEvent, base::Unretained(
this)),
100 base::Bind(&Demuxer::NewSampleEvent, base::Unretained(
this)),
104 if (container_name_ == CONTAINER_MOV)
107 if (!parser_->Parse(buffer_.get(), bytes_read)) {
108 init_parsing_status_ =
109 Status(error::PARSER_FAILURE,
"Cannot parse media file " + file_name_);
113 while (!init_event_received_ && init_parsing_status_.ok())
114 init_parsing_status_ =
Parse();
116 return init_event_received_ ? Status::OK : init_parsing_status_;
119 void Demuxer::ParserInitEvent(
120 const std::vector<scoped_refptr<StreamInfo> >& streams) {
121 init_event_received_ =
true;
123 std::vector<scoped_refptr<StreamInfo> >::const_iterator it =
streams.begin();
124 for (; it !=
streams.end(); ++it) {
129 bool Demuxer::NewSampleEvent(uint32_t track_id,
130 const scoped_refptr<MediaSample>& sample) {
131 std::vector<MediaStream*>::iterator it = streams_.begin();
132 for (; it != streams_.end(); ++it) {
133 if (track_id == (*it)->info()->track_id()) {
134 return (*it)->PushSample(sample).ok();
143 LOG(INFO) <<
"Demuxer::Run() on file '" << file_name_ <<
"'.";
146 for (std::vector<MediaStream*>::iterator it = streams_.begin();
147 it != streams_.end();
149 status = (*it)->Start(MediaStream::kPush);
154 while (!cancelled_ && (status =
Parse()).ok())
157 if (cancelled_ && status.ok())
158 return Status(error::CANCELLED,
"Demuxer run cancelled");
160 if (status.error_code() == error::END_OF_STREAM) {
163 for (std::vector<MediaStream*>::iterator it = streams_.begin();
164 it != streams_.end();
166 status = (*it)->PushSample(sample);
181 if (!init_parsing_status_.ok())
182 return init_parsing_status_;
184 int64_t bytes_read = media_file_->
Read(buffer_.get(), kBufSize);
185 if (bytes_read == 0) {
187 return Status(error::END_OF_STREAM,
"");
188 }
else if (bytes_read < 0) {
189 return Status(error::FILE_FAILURE,
"Cannot read file " + file_name_);
192 return parser_->Parse(buffer_.get(), bytes_read)
194 :
Status(error::PARSER_FAILURE,
195 "Cannot parse media file " + file_name_);