Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(735)

Side by Side Diff: media/mpeg2/mpeg2ts_psi.cc

Issue 23566013: Mpeg2 TS stream parser for media source. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright (c) 2013 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 #include "media/mpeg2/mpeg2ts_psi.h"
6
7 #include "base/logging.h"
8 #include "media/base/bit_reader.h"
9 #include "media/mpeg2/mpeg2ts_crc.h"
10
11 namespace media {
12 namespace mpeg2ts {
13
14 Mpeg2TsPsiParser::Mpeg2TsPsiParser()
15 : wait_for_pusi_(true),
16 leading_bytes_to_discard_(0) {
17 }
18
19 Mpeg2TsPsiParser::~Mpeg2TsPsiParser() {
20 }
21
22 bool Mpeg2TsPsiParser::Parse(bool payload_unit_start_indicator,
23 const uint8* buf, int size) {
24 bool parse_result =
25 ParseInternal(payload_unit_start_indicator,
26 buf, size);
27 if (parse_result == false) {
28 ResetState();
29 }
30 return parse_result;
31 }
32
33 bool Mpeg2TsPsiParser::ParseInternal(bool payload_unit_start_indicator,
34 const uint8* buf, int size) {
35 if (wait_for_pusi_ && !payload_unit_start_indicator) {
36 // Ignore partial PSI.
37 return true;
38 }
39
40 if (payload_unit_start_indicator) {
41 // Reset the state of the PSI section.
42 LOG_IF(WARNING, raw_psi_.size() > 0)
43 << "Dropping state: len=" << raw_psi_.size();
44 ResetState();
45
46 // Update the state.
47 wait_for_pusi_ = false;
48 DCHECK_GE(size, 1);
49 int pointer_field = buf[0];
50 leading_bytes_to_discard_ = pointer_field;
51 buf++;
52 size--;
53 }
54
55 // Discard some leading bytes if needed.
56 if (leading_bytes_to_discard_ > 0) {
57 int nbytes_to_discard = std::min(leading_bytes_to_discard_, size);
58 buf += nbytes_to_discard;
59 size -= nbytes_to_discard;
60 leading_bytes_to_discard_ -= nbytes_to_discard;
61 }
62 if (size == 0) {
63 return true;
64 }
65
66 // Add the data to the parser state.
67 int old_size = raw_psi_.size();
68 raw_psi_.resize(old_size + size);
69 memcpy(&raw_psi_[old_size], buf, size);
70
71 // Check whether we have enough data to start parsing.
72 if (raw_psi_.size() < 3)
73 return true;
74 int section_length =
75 ((static_cast<int>(raw_psi_[1]) << 8) |
76 (static_cast<int>(raw_psi_[2]))) & 0xfff;
77 if (section_length >= 1021) {
78 return false;
79 }
80 int psi_length = section_length + 3;
81 if (static_cast<int>(raw_psi_.size()) < psi_length) {
82 // Don't throw an error when there is not enough data,
83 // just wait for more data to come.
84 return true;
85 }
86
87 // There should not be any trailing bytes after a PMT.
88 // Instead, the pointer field should be used to stuff bytes.
89 LOG_IF(WARNING, static_cast<int>(raw_psi_.size()) > psi_length)
90 << "Trailing bytes after a PSI section: "
91 << psi_length << " vs " << raw_psi_.size();
92
93 // Verify the CRC.
94 Mpeg2TsCrc crc;
95 for (int k = 0; k < psi_length; k++) {
96 crc.Update(raw_psi_[k], 8);
97 }
98 if (!crc.IsValid()) {
99 return false;
100 }
101
102 // Parse the PSI section.
103 BitReader bit_reader(&raw_psi_[0], raw_psi_.size());
104 bool status = ParsePsiSection(&bit_reader);
105 if (status) {
106 ResetState();
107 }
108
109 return status;
110 }
111
112 void Mpeg2TsPsiParser::Flush() {
113 ResetState();
114 }
115
116 void Mpeg2TsPsiParser::ResetState() {
117 wait_for_pusi_ = true;
118 raw_psi_.resize(0);
119 leading_bytes_to_discard_ = 0;
120 }
121
122 } // namespace mpeg2ts
123 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698