15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2014 The Chromium Authors. All rights reserved.
268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)// found in the LICENSE file.
468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/mp2t/ts_section_pmt.h"
668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include <map>
868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "base/logging.h"
1068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)#include "media/base/bit_reader.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "media/formats/mp2t/mp2t_common.h"
1268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace media {
1468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)namespace mp2t {
1568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
1668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TsSectionPmt::TsSectionPmt(const RegisterPesCb& register_pes_cb)
1768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    : register_pes_cb_(register_pes_cb) {
1868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
1968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)TsSectionPmt::~TsSectionPmt() {
2168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
2268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
2368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)bool TsSectionPmt::ParsePsiSection(BitReader* bit_reader) {
2468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Read up to |last_section_number|.
2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int table_id;
2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int section_syntax_indicator;
2768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int dummy_zero;
2868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int reserved;
2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int section_length;
3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int program_number;
3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int version_number;
3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int current_next_indicator;
3368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int section_number;
3468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int last_section_number;
3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->ReadBits(8, &table_id));
3668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->ReadBits(1, &section_syntax_indicator));
3768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->ReadBits(1, &dummy_zero));
3868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->ReadBits(2, &reserved));
3968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->ReadBits(12, &section_length));
4068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int section_start_marker = bit_reader->bits_available() / 8;
4168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->ReadBits(16, &program_number));
4368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->ReadBits(2, &reserved));
4468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->ReadBits(5, &version_number));
4568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->ReadBits(1, &current_next_indicator));
4668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->ReadBits(8, &section_number));
4768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->ReadBits(8, &last_section_number));
4868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
4968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Perform a few verifications:
5068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // - table ID should be 2 for a PMT.
5168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // - section_syntax_indicator should be one.
5268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // - section length should not exceed 1021.
5368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(table_id == 0x2);
5468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(section_syntax_indicator);
5568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(!dummy_zero);
5668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(section_length <= 1021);
5768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(section_number == 0);
5868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(last_section_number == 0);
5968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // TODO(damienv):
6168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Verify that there is no mismatch between the program number
6268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // and the program number that was provided in a PAT for the current PMT.
6368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
6468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Read the end of the fixed length section.
6568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int pcr_pid;
6668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int program_info_length;
6768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->ReadBits(3, &reserved));
6868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->ReadBits(13, &pcr_pid));
6968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->ReadBits(4, &reserved));
7068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->ReadBits(12, &program_info_length));
7168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(program_info_length < 1024);
7268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Read the program info descriptor.
7468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // TODO(damienv): check wether any of the descriptors could be useful.
7568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Defined in section 2.6 of ISO-13818.
7668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->SkipBits(8 * program_info_length));
7768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
7868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Read the ES description table.
7968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // The end of the PID map if 4 bytes away from the end of the section
8068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // (4 bytes = size of the CRC).
8168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int pid_map_end_marker = section_start_marker - section_length + 4;
8268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  std::map<int, int> pid_map;
8368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  while (bit_reader->bits_available() > 8 * pid_map_end_marker) {
8468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    int stream_type;
8568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    int reserved;
8668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    int pid_es;
8768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    int es_info_length;
8868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    RCHECK(bit_reader->ReadBits(8, &stream_type));
8968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    RCHECK(bit_reader->ReadBits(3, &reserved));
9068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    RCHECK(bit_reader->ReadBits(13, &pid_es));
9168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    RCHECK(bit_reader->ReadBits(4, &reserved));
9268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    RCHECK(bit_reader->ReadBits(12, &es_info_length));
9368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Do not register the PID right away.
9568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Wait for the end of the section to be fully parsed
9668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // to make sure there is no error.
9768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    pid_map.insert(std::pair<int, int>(pid_es, stream_type));
9868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
9968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Read the ES info descriptors.
10068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // TODO(damienv): check wether any of the descriptors could be useful.
10168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    // Defined in section 2.6 of ISO-13818.
10268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    RCHECK(bit_reader->SkipBits(8 * es_info_length));
10368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  }
10468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
10568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Read the CRC.
10668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  int crc32;
10768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  RCHECK(bit_reader->ReadBits(32, &crc32));
10868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
10968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  // Once the PMT has been proved to be correct, register the PIDs.
11068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  for (std::map<int, int>::iterator it = pid_map.begin();
11168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)       it != pid_map.end(); ++it)
11268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)    register_pes_cb_.Run(it->first, it->second);
11368043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11468043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)  return true;
11568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
11668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
11768043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)void TsSectionPmt::ResetPsiSection() {
11868043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}
11968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
12068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}  // namespace mp2t
12168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)}  // namespace media
12268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)
123