2015-10-08 21:48:07 +00:00
|
|
|
// Copyright 2014 The Chromium Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
|
|
// found in the LICENSE file.
|
|
|
|
|
2017-12-20 00:56:36 +00:00
|
|
|
#ifndef PACKAGER_MEDIA_FORMATS_WEBM_WEBM_PARSER_H_
|
|
|
|
#define PACKAGER_MEDIA_FORMATS_WEBM_WEBM_PARSER_H_
|
2015-10-08 21:48:07 +00:00
|
|
|
|
2015-10-14 22:46:23 +00:00
|
|
|
#include <stdint.h>
|
|
|
|
|
2015-10-08 21:48:07 +00:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
2022-12-17 05:40:00 +00:00
|
|
|
#include "packager/macros.h"
|
2015-10-08 21:48:07 +00:00
|
|
|
|
2016-05-20 21:19:33 +00:00
|
|
|
namespace shaka {
|
2015-10-08 21:48:07 +00:00
|
|
|
namespace media {
|
|
|
|
|
2015-10-15 22:39:16 +00:00
|
|
|
/// Interface for receiving WebM parser events.
|
|
|
|
///
|
|
|
|
/// Each method is called when an element of the specified type is parsed.
|
|
|
|
/// The ID of the element that was parsed is given along with the value
|
|
|
|
/// stored in the element. List elements generate calls at the start and
|
|
|
|
/// end of the list. Any pointers passed to these methods are only guaranteed
|
|
|
|
/// to be valid for the life of that call. Each method (except for OnListStart)
|
|
|
|
/// returns a bool that indicates whether the parsed data is valid. OnListStart
|
|
|
|
/// returns a pointer to a WebMParserClient object, which should be used to
|
|
|
|
/// handle elements parsed out of the list being started. If false (or NULL by
|
|
|
|
/// OnListStart) is returned then the parse is immediately terminated and an
|
|
|
|
/// error is reported by the parser.
|
2015-10-14 22:46:23 +00:00
|
|
|
class WebMParserClient {
|
2015-10-08 21:48:07 +00:00
|
|
|
public:
|
|
|
|
virtual ~WebMParserClient();
|
|
|
|
|
|
|
|
virtual WebMParserClient* OnListStart(int id);
|
|
|
|
virtual bool OnListEnd(int id);
|
2015-10-14 22:46:23 +00:00
|
|
|
virtual bool OnUInt(int id, int64_t val);
|
2015-10-08 21:48:07 +00:00
|
|
|
virtual bool OnFloat(int id, double val);
|
2015-10-14 22:46:23 +00:00
|
|
|
virtual bool OnBinary(int id, const uint8_t* data, int size);
|
2015-10-08 21:48:07 +00:00
|
|
|
virtual bool OnString(int id, const std::string& str);
|
|
|
|
|
|
|
|
protected:
|
|
|
|
WebMParserClient();
|
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(WebMParserClient);
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ListElementInfo;
|
|
|
|
|
2015-10-15 22:39:16 +00:00
|
|
|
/// Parses a WebM list element and all of its children. This
|
|
|
|
/// class supports incremental parsing of the list so Parse()
|
|
|
|
/// can be called multiple times with pieces of the list.
|
|
|
|
/// IsParsingComplete() will return true once the entire list has
|
|
|
|
/// been parsed.
|
2015-10-14 22:46:23 +00:00
|
|
|
class WebMListParser {
|
2015-10-08 21:48:07 +00:00
|
|
|
public:
|
2015-10-15 22:39:16 +00:00
|
|
|
/// @param id Element ID of the list we intend to parse.
|
|
|
|
/// @param client Called as different elements in the list are parsed.
|
2015-10-08 21:48:07 +00:00
|
|
|
WebMListParser(int id, WebMParserClient* client);
|
|
|
|
~WebMListParser();
|
|
|
|
|
2015-10-15 22:39:16 +00:00
|
|
|
/// Resets the state of the parser so it can start parsing a new list.
|
2015-10-08 21:48:07 +00:00
|
|
|
void Reset();
|
|
|
|
|
2015-10-15 22:39:16 +00:00
|
|
|
/// Parses list data contained in |buf|.
|
|
|
|
/// @return < 0 if the parse fails.
|
|
|
|
/// @return 0 if more data is needed.
|
|
|
|
/// @return > 0 indicates success & the number of bytes parsed.
|
2015-10-14 22:46:23 +00:00
|
|
|
int Parse(const uint8_t* buf, int size);
|
2015-10-08 21:48:07 +00:00
|
|
|
|
2015-10-15 22:39:16 +00:00
|
|
|
/// @return true if the entire list has been parsed.
|
2015-10-08 21:48:07 +00:00
|
|
|
bool IsParsingComplete() const;
|
|
|
|
|
|
|
|
private:
|
|
|
|
enum State {
|
|
|
|
NEED_LIST_HEADER,
|
|
|
|
INSIDE_LIST,
|
|
|
|
DONE_PARSING_LIST,
|
|
|
|
PARSE_ERROR,
|
|
|
|
};
|
|
|
|
|
|
|
|
struct ListState {
|
|
|
|
int id_;
|
2015-10-14 22:46:23 +00:00
|
|
|
int64_t size_;
|
|
|
|
int64_t bytes_parsed_;
|
2015-10-08 21:48:07 +00:00
|
|
|
const ListElementInfo* element_info_;
|
|
|
|
WebMParserClient* client_;
|
|
|
|
};
|
|
|
|
|
|
|
|
void ChangeState(State new_state);
|
|
|
|
|
|
|
|
// Parses a single element in the current list.
|
|
|
|
//
|
|
|
|
// |header_size| - The size of the element header
|
|
|
|
// |id| - The ID of the element being parsed.
|
|
|
|
// |element_size| - The size of the element body.
|
|
|
|
// |data| - Pointer to the element contents.
|
|
|
|
// |size| - Number of bytes in |data|
|
|
|
|
// |client| - Client to pass the parsed data to.
|
|
|
|
//
|
|
|
|
// Returns < 0 if the parse fails.
|
|
|
|
// Returns 0 if more data is needed.
|
|
|
|
// Returning > 0 indicates success & the number of bytes parsed.
|
|
|
|
int ParseListElement(int header_size,
|
2015-10-14 22:46:23 +00:00
|
|
|
int id,
|
|
|
|
int64_t element_size,
|
|
|
|
const uint8_t* data,
|
|
|
|
int size);
|
2015-10-08 21:48:07 +00:00
|
|
|
|
|
|
|
// Called when starting to parse a new list.
|
|
|
|
//
|
|
|
|
// |id| - The ID of the new list.
|
|
|
|
// |size| - The size of the new list.
|
|
|
|
// |client| - The client object to notify that a new list is being parsed.
|
|
|
|
//
|
|
|
|
// Returns true if this list can be started in the current context. False
|
|
|
|
// if starting this list causes some sort of parse error.
|
2015-10-14 22:46:23 +00:00
|
|
|
bool OnListStart(int id, int64_t size);
|
2015-10-08 21:48:07 +00:00
|
|
|
|
|
|
|
// Called when the end of the current list has been reached. This may also
|
|
|
|
// signal the end of the current list's ancestors if the current list happens
|
|
|
|
// to be at the end of its parent.
|
|
|
|
//
|
|
|
|
// Returns true if no errors occurred while ending this list(s).
|
|
|
|
bool OnListEnd();
|
|
|
|
|
|
|
|
// Checks to see if |id_b| is a sibling or ancestor of |id_a|.
|
|
|
|
bool IsSiblingOrAncestor(int id_a, int id_b) const;
|
|
|
|
|
|
|
|
State state_;
|
|
|
|
|
|
|
|
// Element ID passed to the constructor.
|
|
|
|
const int root_id_;
|
|
|
|
|
|
|
|
// Element level for |root_id_|. Used to verify that elements appear at
|
|
|
|
// the correct level.
|
|
|
|
const int root_level_;
|
|
|
|
|
|
|
|
// WebMParserClient to handle the root list.
|
|
|
|
WebMParserClient* const root_client_;
|
|
|
|
|
|
|
|
// Stack of state for all the lists currently being parsed. Lists are
|
|
|
|
// added and removed from this stack as they are parsed.
|
|
|
|
std::vector<ListState> list_state_stack_;
|
|
|
|
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(WebMListParser);
|
|
|
|
};
|
|
|
|
|
2015-10-15 22:39:16 +00:00
|
|
|
/// Parses an element header & returns the ID and element size.
|
|
|
|
/// @param[out] id contains the element ID on success and is undefined otherwise.
|
|
|
|
/// @param[out] element_size contains the element size on success and is
|
|
|
|
/// undefined otherwise.
|
|
|
|
/// @return < 0 if the parse fails.
|
|
|
|
/// @return 0 if more data is needed.
|
|
|
|
/// @return > 0 indicates success & the number of bytes parsed.
|
2015-10-14 22:46:23 +00:00
|
|
|
int WebMParseElementHeader(const uint8_t* buf,
|
|
|
|
int size,
|
|
|
|
int* id,
|
|
|
|
int64_t* element_size);
|
2015-10-08 21:48:07 +00:00
|
|
|
|
|
|
|
} // namespace media
|
2016-05-20 21:19:33 +00:00
|
|
|
} // namespace shaka
|
2015-10-08 21:48:07 +00:00
|
|
|
|
2017-12-20 00:56:36 +00:00
|
|
|
#endif // PACKAGER_MEDIA_FORMATS_WEBM_WEBM_PARSER_H_
|