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