1 // Copyright 2014 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 #ifndef MEDIA_FORMATS_MP4_MP4_STREAM_PARSER_H_ 6 #define MEDIA_FORMATS_MP4_MP4_STREAM_PARSER_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 #include <set> 12 #include <vector> 13 14 #include "base/callback.h" 15 #include "base/compiler_specific.h" 16 #include "base/macros.h" 17 #include "media/base/media_export.h" 18 #include "media/base/stream_parser.h" 19 #include "media/formats/common/offset_byte_queue.h" 20 #include "media/formats/mp4/parse_result.h" 21 #include "media/formats/mp4/track_run_iterator.h" 22 23 #if BUILDFLAG(USE_PROPRIETARY_CODECS) 24 #include "media/formats/mp4/aac.h" 25 #endif 26 27 namespace media { 28 namespace mp4 { 29 30 struct Movie; 31 struct MovieHeader; 32 struct TrackHeader; 33 class BoxReader; 34 35 class MEDIA_EXPORT MP4StreamParser : public StreamParser { 36 public: 37 MP4StreamParser(const std::set<int>& audio_object_types, 38 bool has_sbr, 39 bool has_flac); 40 ~MP4StreamParser() override; 41 42 void Init(InitCB init_cb, 43 const NewConfigCB& config_cb, 44 const NewBuffersCB& new_buffers_cb, 45 bool ignore_text_tracks, 46 const EncryptedMediaInitDataCB& encrypted_media_init_data_cb, 47 const NewMediaSegmentCB& new_segment_cb, 48 const EndMediaSegmentCB& end_of_segment_cb, 49 MediaLog* media_log) override; 50 void Flush() override; 51 bool GetGenerateTimestampsFlag() const override; 52 bool Parse(const uint8_t* buf, int size) override; 53 54 // Calculates the rotation value from the track header display matricies. 55 VideoTransformation CalculateRotation(const TrackHeader& track, 56 const MovieHeader& movie); 57 58 private: 59 enum State { 60 kWaitingForInit, 61 kParsingBoxes, 62 kWaitingForSampleData, 63 kEmittingSamples, 64 kError 65 }; 66 67 ParseResult ParseBox(); 68 bool ParseMoov(mp4::BoxReader* reader); 69 bool ParseMoof(mp4::BoxReader* reader); 70 71 void OnEncryptedMediaInitData( 72 const std::vector<ProtectionSystemSpecificHeader>& headers); 73 74 // To retain proper framing, each 'mdat' atom must be read; to limit memory 75 // usage, the atom's data needs to be discarded incrementally as frames are 76 // extracted from the stream. This function discards data from the stream up 77 // to |max_clear_offset|, updating the |mdat_tail_| value so that framing can 78 // be retained after all 'mdat' information has been read. |max_clear_offset| 79 // is the upper bound on what can be removed from |queue_|. Anything below 80 // this offset is no longer needed by the parser. 81 // Returns 'true' on success, 'false' if there was an error. 82 bool ReadAndDiscardMDATsUntil(int64_t max_clear_offset); 83 84 void ChangeState(State new_state); 85 86 bool EmitConfigs(); 87 #if BUILDFLAG(USE_PROPRIETARY_CODECS) 88 bool PrepareAACBuffer(const AAC& aac_config, 89 std::vector<uint8_t>* frame_buf, 90 std::vector<SubsampleEntry>* subsamples) const; 91 #endif 92 ParseResult EnqueueSample(BufferQueueMap* buffers); 93 bool SendAndFlushSamples(BufferQueueMap* buffers); 94 95 void Reset(); 96 97 // Checks to see if we have enough data in |queue_| to transition to 98 // kEmittingSamples and start enqueuing samples. 99 bool HaveEnoughDataToEnqueueSamples(); 100 101 // Sets |highest_end_offset_| based on the data in |moov_| 102 // and |moof|. Returns true if |highest_end_offset_| was successfully 103 // computed. 104 bool ComputeHighestEndOffset(const MovieFragment& moof); 105 106 State state_; 107 InitCB init_cb_; 108 NewConfigCB config_cb_; 109 NewBuffersCB new_buffers_cb_; 110 EncryptedMediaInitDataCB encrypted_media_init_data_cb_; 111 NewMediaSegmentCB new_segment_cb_; 112 EndMediaSegmentCB end_of_segment_cb_; 113 MediaLog* media_log_; 114 115 OffsetByteQueue queue_; 116 117 // These two parameters are only valid in the |kEmittingSegments| state. 118 // 119 // |moof_head_| is the offset of the start of the most recently parsed moof 120 // block. All byte offsets in sample information are relative to this offset, 121 // as mandated by the Media Source spec. 122 int64_t moof_head_; 123 // |mdat_tail_| is the stream offset of the end of the current 'mdat' box. 124 // Valid iff it is greater than the head of the queue. 125 int64_t mdat_tail_; 126 127 // The highest end offset in the current moof. This offset is 128 // relative to |moof_head_|. This value is used to make sure we have collected 129 // enough bytes to parse all samples and aux_info in the current moof. 130 int64_t highest_end_offset_; 131 132 std::unique_ptr<mp4::Movie> moov_; 133 std::unique_ptr<mp4::TrackRunIterator> runs_; 134 135 bool has_audio_; 136 bool has_video_; 137 std::set<uint32_t> audio_track_ids_; 138 std::set<uint32_t> video_track_ids_; 139 // The object types allowed for audio tracks. For FLAC indication, use 140 // |has_flac_|; 141 const std::set<int> audio_object_types_; 142 const bool has_sbr_; 143 const bool has_flac_; 144 145 // Tracks the number of MEDIA_LOGS for skipping empty trun samples. 146 int num_empty_samples_skipped_; 147 148 // Tracks the number of MEDIA_LOGS for invalid bitstream conversion. 149 int num_invalid_conversions_; 150 151 // Tracks the number of MEDIA_LOGS for video keyframe MP4<->frame mismatch. 152 int num_video_keyframe_mismatches_; 153 154 DISALLOW_COPY_AND_ASSIGN(MP4StreamParser); 155 }; 156 157 } // namespace mp4 158 } // namespace media 159 160 #endif // MEDIA_FORMATS_MP4_MP4_STREAM_PARSER_H_ 161