5 #include "packager/media/formats/webm/webm_stream_parser.h"
9 #include "packager/base/callback.h"
10 #include "packager/base/callback_helpers.h"
11 #include "packager/base/logging.h"
12 #include "packager/media/base/timestamp.h"
13 #include "packager/media/formats/webm/webm_cluster_parser.h"
14 #include "packager/media/formats/webm/webm_constants.h"
15 #include "packager/media/formats/webm/webm_content_encodings.h"
16 #include "packager/media/formats/webm/webm_info_parser.h"
17 #include "packager/media/formats/webm/webm_tracks_parser.h"
19 namespace edash_packager {
22 WebMStreamParser::WebMStreamParser()
23 : state_(kWaitingForInit),
24 unknown_segment_size_(false) {
27 WebMStreamParser::~WebMStreamParser() {
31 const InitCB& init_cb,
34 DCHECK_EQ(state_, kWaitingForInit);
35 DCHECK(init_cb_.is_null());
36 DCHECK(!init_cb.is_null());
37 DCHECK(!new_sample_cb.is_null());
39 ChangeState(kParsingHeaders);
41 new_sample_cb_ = new_sample_cb;
42 decryption_key_source_ = decryption_key_source;
43 ignore_text_tracks_ =
true;
47 DCHECK_NE(state_, kWaitingForInit);
51 cluster_parser_->Reset();
52 if (state_ == kParsingClusters) {
53 ChangeState(kParsingHeaders);
58 DCHECK_NE(state_, kWaitingForInit);
63 byte_queue_.
Push(buf, size);
67 const uint8_t* cur = NULL;
70 byte_queue_.
Peek(&cur, &cur_size);
71 while (cur_size > 0) {
72 State oldState = state_;
75 result = ParseInfoAndTracks(cur, cur_size);
78 case kParsingClusters:
79 result = ParseCluster(cur, cur_size);
92 if (state_ == oldState && result == 0)
98 bytes_parsed += result;
101 byte_queue_.
Pop(bytes_parsed);
105 void WebMStreamParser::ChangeState(State new_state) {
106 DVLOG(1) <<
"ChangeState() : " << state_ <<
" -> " << new_state;
110 int WebMStreamParser::ParseInfoAndTracks(
const uint8_t* data,
int size) {
111 DVLOG(2) <<
"ParseInfoAndTracks()";
115 const uint8_t* cur = data;
117 int bytes_parsed = 0;
120 int64_t element_size;
121 int result = WebMParseElementHeader(cur, cur_size, &
id, &element_size);
127 case kWebMIdEBMLHeader:
128 case kWebMIdSeekHead:
132 case kWebMIdChapters:
134 case kWebMIdAttachments:
136 if (cur_size < (result + element_size)) {
141 return result + element_size;
144 if (!cluster_parser_) {
145 LOG(ERROR) <<
"Found Cluster element before Info.";
148 ChangeState(kParsingClusters);
153 if (element_size == kWebMUnknownSize)
154 unknown_segment_size_ =
true;
162 LOG(ERROR) <<
"Unexpected element ID 0x" << std::hex << id;
167 WebMInfoParser info_parser;
168 result = info_parser.Parse(cur, cur_size);
175 bytes_parsed += result;
177 WebMTracksParser tracks_parser(ignore_text_tracks_);
178 result = tracks_parser.Parse(cur, cur_size);
183 bytes_parsed += result;
185 double timecode_scale_in_us = info_parser.timecode_scale() / 1000.0;
186 int64_t duration_in_us = info_parser.duration() * timecode_scale_in_us;
188 std::vector<scoped_refptr<StreamInfo>> streams;
189 scoped_refptr<AudioStreamInfo> audio_stream_info =
190 tracks_parser.audio_stream_info();
191 streams.push_back(tracks_parser.audio_stream_info());
192 streams.back()->set_duration(duration_in_us);
193 if (streams.back()->is_encrypted())
194 OnEncryptedMediaInitData(tracks_parser.audio_encryption_key_id());
196 streams.push_back(tracks_parser.video_stream_info());
197 streams.back()->set_duration(duration_in_us);
198 if (streams.back()->is_encrypted())
199 OnEncryptedMediaInitData(tracks_parser.video_encryption_key_id());
201 init_cb_.Run(streams);
203 cluster_parser_.reset(
new WebMClusterParser(
204 info_parser.timecode_scale(), tracks_parser.audio_track_num(),
205 tracks_parser.GetAudioDefaultDuration(timecode_scale_in_us),
206 tracks_parser.video_track_num(),
207 tracks_parser.GetVideoDefaultDuration(timecode_scale_in_us),
208 tracks_parser.text_tracks(), tracks_parser.ignored_tracks(),
209 tracks_parser.audio_encryption_key_id(),
210 tracks_parser.video_encryption_key_id(), audio_stream_info->codec(),
216 int WebMStreamParser::ParseCluster(
const uint8_t* data,
int size) {
217 if (!cluster_parser_)
220 int bytes_parsed = cluster_parser_->Parse(data, size);
221 if (bytes_parsed < 0)
224 bool cluster_ended = cluster_parser_->cluster_ended();
226 ChangeState(kParsingHeaders);
232 void WebMStreamParser::OnEncryptedMediaInitData(
const std::string& key_id) {
233 NOTIMPLEMENTED() <<
"WebM decryption is not implemented yet.";