Modified H.264 elementary stream parsing code to work with remux framework.

Change-Id: I81dfe0952073c4a5cd6f5fcaf14fe21050d26cb6
This commit is contained in:
Thomas Inskip 2014-04-07 17:39:14 -07:00
parent 8df0e1ad0a
commit cbf4978ffa
18 changed files with 160 additions and 137 deletions

View File

@ -88,6 +88,8 @@
'muxer.h',
'muxer_options.cc',
'muxer_options.h',
'offset_byte_queue.cc',
'offset_byte_queue.h',
'producer_consumer_queue.h',
'request_signer.cc',
'request_signer.h',
@ -121,6 +123,7 @@
'container_names_unittest.cc',
'fake_prng.cc', # For rsa_key_unittest
'fake_prng.h', # For rsa_key_unittest
'offset_byte_queue_unittest.cc',
'producer_consumer_queue_unittest.cc',
'rsa_key_unittest.cc',
'rsa_test_data.cc', # For rsa_key_unittest

View File

@ -2,7 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "media/formats/mp4/offset_byte_queue.h"
#include "media/base/offset_byte_queue.h"
#include "base/basictypes.h"
#include "base/logging.h"

View File

@ -2,8 +2,8 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef MEDIA_FORMATS_MP4_OFFSET_BYTE_QUEUE_H_
#define MEDIA_FORMATS_MP4_OFFSET_BYTE_QUEUE_H_
#ifndef MEDIA_BASE_OFFSET_BYTE_QUEUE_H_
#define MEDIA_BASE_OFFSET_BYTE_QUEUE_H_
#include "base/basictypes.h"
#include "media/base/byte_queue.h"
@ -66,4 +66,4 @@ class OffsetByteQueue {
} // namespace media
#endif // MEDIA_FORMATS_MP4_OFFSET_BYTE_QUEUE_H_
#endif // MEDIA_BASE_OFFSET_BYTE_QUEUE_H_

View File

@ -6,7 +6,7 @@
#include "base/basictypes.h"
#include "base/memory/scoped_ptr.h"
#include "media/formats/mp4/offset_byte_queue.h"
#include "media/base/offset_byte_queue.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace media {

View File

@ -17,7 +17,7 @@ namespace mp2t {
class EsParser {
public:
typedef base::Callback<void(scoped_refptr<MediaSample>)> EmitSampleCB;
typedef base::Callback<void(scoped_refptr<MediaSample>&)> EmitSampleCB;
EsParser(uint32 track_id) : track_id_(track_id) {}
virtual ~EsParser() {}

View File

@ -52,7 +52,7 @@ static bool LookForSyncWord(const uint8* raw_es, int raw_es_size,
DCHECK_GE(pos, 0);
DCHECK_LE(pos, raw_es_size);
int max_offset = raw_es_size - kADTSHeaderMinSize;
int max_offset = raw_es_size - kAdtsHeaderMinSize;
if (pos >= max_offset) {
// Do not change the position if:
// - max_offset < 0: not enough bytes to get a full header
@ -73,7 +73,7 @@ static bool LookForSyncWord(const uint8* raw_es, int raw_es_size,
continue;
int frame_size = ExtractAdtsFrameSize(cur_buf);
if (frame_size < kADTSHeaderMinSize) {
if (frame_size < kAdtsHeaderMinSize) {
// Too short to be an ADTS frame.
continue;
}
@ -136,7 +136,7 @@ bool EsParserAdts::Parse(const uint8* buf, int size, int64 pts, int64 dts) {
<< " frame_size=" << frame_size;
DVLOG(LOG_LEVEL_ES)
<< "ADTS header: "
<< base::HexEncode(&raw_es[es_position], kADTSHeaderMinSize);
<< base::HexEncode(&raw_es[es_position], kAdtsHeaderMinSize);
// Do not process the frame if this one is a partial frame.
int remaining_size = raw_es_size - es_position;
@ -144,7 +144,7 @@ bool EsParserAdts::Parse(const uint8* buf, int size, int64 pts, int64 dts) {
break;
// Update the audio configuration if needed.
DCHECK_GE(frame_size, kADTSHeaderMinSize);
DCHECK_GE(frame_size, kAdtsHeaderMinSize);
if (!UpdateAudioConfiguration(&raw_es[es_position]))
return false;
@ -202,7 +202,7 @@ bool EsParserAdts::UpdateAudioConfiguration(const uint8* adts_header) {
}
size_t frequency_index = ExtractAdtsFrequencyIndex(adts_header);
if (frequency_index >= kADTSFrequencyTableSize) {
if (frequency_index >= kAdtsFrequencyTableSize) {
// Frequency index 13 & 14 are reserved
// while 15 means that the frequency is explicitly written
// (not supported).
@ -211,14 +211,14 @@ bool EsParserAdts::UpdateAudioConfiguration(const uint8* adts_header) {
size_t channel_configuration = ExtractAdtsChannelConfig(adts_header);
if (channel_configuration == 0 ||
channel_configuration >= kADTSChannelLayoutTableSize) {
channel_configuration >= kAdtsNumChannelsTableSize) {
// TODO(damienv): Add support for inband channel configuration.
return false;
}
// TODO(damienv): support HE-AAC frequency doubling (SBR)
// based on the incoming ADTS profile.
int samples_per_second = kADTSFrequencyTable[frequency_index];
int samples_per_second = kAdtsFrequencyTable[frequency_index];
int adts_profile = (adts_header[2] >> 6) & 0x3;
// The following code is written according to ISO 14496 Part 3 Table 1.11 and
@ -229,8 +229,8 @@ bool EsParserAdts::UpdateAudioConfiguration(const uint8* adts_header) {
? std::min(2 * samples_per_second, 48000)
: samples_per_second;
last_audio_decoder_config_ = scoped_refptr<AudioStreamInfo>
(new AudioStreamInfo(
last_audio_decoder_config_ = scoped_refptr<AudioStreamInfo>(
new AudioStreamInfo(
track_id(),
kMpeg2Timescale,
kInfiniteDuration,
@ -238,7 +238,7 @@ bool EsParserAdts::UpdateAudioConfiguration(const uint8* adts_header) {
std::string(), // TODO(tinskip): calculate codec string.
std::string(),
16,
kADTSChannelLayoutTable[channel_configuration],
kAdtsNumChannelsTable[channel_configuration],
samples_per_second,
NULL, // TODO(tinskip): calculate AudioSpecificConfig.
0,

View File

@ -25,7 +25,8 @@ namespace mp2t {
class EsParserAdts : public EsParser {
public:
typedef base::Callback<void(scoped_refptr<AudioStreamInfo>&)> NewAudioConfigCB;
typedef base::Callback<void(
scoped_refptr<AudioStreamInfo>&)> NewAudioConfigCB;
EsParserAdts(uint32 track_id,
const NewAudioConfigCB& new_audio_config_cb,

View File

@ -7,39 +7,50 @@
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/numerics/safe_conversions.h"
#include "media/base/buffers.h"
#include "media/base/stream_parser_buffer.h"
#include "media/base/video_frame.h"
#include "media/base/media_sample.h"
#include "media/base/offset_byte_queue.h"
#include "media/base/timestamp.h"
#include "media/base/video_stream_info.h"
#include "media/filters/h264_parser.h"
#include "media/formats/common/offset_byte_queue.h"
#include "media/formats/mp2t/mp2t_common.h"
#include "ui/gfx/rect.h"
#include "ui/gfx/size.h"
using media::filters::H264Parser;
using media::filters::H264PPS;
using media::filters::H264SliceHeader;
using media::filters::H264SPS;
using media::filters::H264NALU;
namespace media {
namespace mp2t {
namespace {
// An AUD NALU is at least 4 bytes:
// 3 bytes for the start code + 1 byte for the NALU type.
const int kMinAUDSize = 4;
// Size of H.264 NALU length output by this SDK.
const uint8 kCommonNaluLengthSize = 4;
} // anonymous namespace
EsParserH264::EsParserH264(
uint32 track_id,
const NewVideoConfigCB& new_video_config_cb,
const EmitBufferCB& emit_buffer_cb)
: new_video_config_cb_(new_video_config_cb),
emit_buffer_cb_(emit_buffer_cb),
es_queue_(new media::OffsetByteQueue()),
h264_parser_(new H264Parser()),
current_access_unit_pos_(0),
next_access_unit_pos_(0) {
const EmitSampleCB& emit_sample_cb)
: EsParser(track_id),
new_video_config_cb_(new_video_config_cb),
emit_sample_cb_(emit_sample_cb),
es_queue_(new media::OffsetByteQueue()),
h264_parser_(new H264Parser()),
current_access_unit_pos_(0),
next_access_unit_pos_(0) {
}
EsParserH264::~EsParserH264() {
}
bool EsParserH264::Parse(const uint8* buf, int size,
base::TimeDelta pts,
base::TimeDelta dts) {
bool EsParserH264::Parse(const uint8* buf, int size, int64 pts, int64 dts) {
// Note: Parse is invoked each time a PES packet has been reassembled.
// Unfortunately, a PES packet does not necessarily map
// to an h264 access unit, although the HLS recommendation is to use one PES
@ -49,11 +60,11 @@ bool EsParserH264::Parse(const uint8* buf, int size,
// HLS recommendation: "In AVC video, you should have both a DTS and a
// PTS in each PES header".
// However, some streams do not comply with this recommendation.
DVLOG_IF(1, pts == kNoTimestamp()) << "Each video PES should have a PTS";
if (pts != kNoTimestamp()) {
DVLOG_IF(1, pts == kNoTimestamp) << "Each video PES should have a PTS";
if (pts != kNoTimestamp) {
TimingDesc timing_desc;
timing_desc.pts = pts;
timing_desc.dts = (dts != kNoTimestamp()) ? dts : pts;
timing_desc.dts = (dts != kNoTimestamp) ? dts : pts;
// Link the end of the byte queue with the incoming timing descriptor.
timing_desc_list_.push_back(
@ -84,7 +95,7 @@ void EsParserH264::Reset() {
current_access_unit_pos_ = 0;
next_access_unit_pos_ = 0;
timing_desc_list_.clear();
last_video_decoder_config_ = VideoDecoderConfig();
last_video_decoder_config_ = scoped_refptr<VideoStreamInfo>();
}
bool EsParserH264::FindAUD(int64* stream_pos) {
@ -203,7 +214,7 @@ bool EsParserH264::ParseInternal() {
// does not necessarily start with an SPS/PPS/IDR.
// TODO(damienv): Should be able to differentiate a missing SPS/PPS
// from a slice header parsing error.
if (last_video_decoder_config_.IsValidConfig())
if (last_video_decoder_config_)
return false;
} else {
pps_id_for_access_unit = shdr.pic_parameter_set_id;
@ -228,13 +239,13 @@ bool EsParserH264::ParseInternal() {
bool EsParserH264::EmitFrame(int64 access_unit_pos, int access_unit_size,
bool is_key_frame, int pps_id) {
// Get the access unit timing info.
TimingDesc current_timing_desc = {kNoTimestamp(), kNoTimestamp()};
TimingDesc current_timing_desc = {kNoTimestamp, kNoTimestamp};
while (!timing_desc_list_.empty() &&
timing_desc_list_.front().first <= access_unit_pos) {
current_timing_desc = timing_desc_list_.front().second;
timing_desc_list_.pop_front();
}
if (current_timing_desc.pts == kNoTimestamp())
if (current_timing_desc.pts == kNoTimestamp)
return false;
// Update the video decoder configuration if needed.
@ -245,7 +256,7 @@ bool EsParserH264::EmitFrame(int64 access_unit_pos, int access_unit_size,
// In this case, the initial frames are conveyed to the upper layer with
// an invalid VideoDecoderConfig and it's up to the upper layer
// to process this kind of frame accordingly.
if (last_video_decoder_config_.IsValidConfig())
if (last_video_decoder_config_)
return false;
} else {
const H264SPS* sps = h264_parser_->GetSPS(pps->seq_parameter_set_id);
@ -264,69 +275,58 @@ bool EsParserH264::EmitFrame(int64 access_unit_pos, int access_unit_size,
// TODO(wolenetz/acolwell): Validate and use a common cross-parser TrackId
// type and allow multiple video tracks. See https://crbug.com/341581.
scoped_refptr<StreamParserBuffer> stream_parser_buffer =
StreamParserBuffer::CopyFrom(
scoped_refptr<MediaSample> media_sample =
MediaSample::CopyFrom(
es,
access_unit_size,
is_key_frame,
DemuxerStream::VIDEO,
0);
stream_parser_buffer->SetDecodeTimestamp(current_timing_desc.dts);
stream_parser_buffer->set_timestamp(current_timing_desc.pts);
emit_buffer_cb_.Run(stream_parser_buffer);
is_key_frame);
media_sample->set_dts(current_timing_desc.dts);
media_sample->set_pts(current_timing_desc.pts);
emit_sample_cb_.Run(media_sample);
return true;
}
bool EsParserH264::UpdateVideoDecoderConfig(const H264SPS* sps) {
// Set the SAR to 1 when not specified in the H264 stream.
int sar_width = (sps->sar_width == 0) ? 1 : sps->sar_width;
int sar_height = (sps->sar_height == 0) ? 1 : sps->sar_height;
// TODO(tinskip): Generate an error if video configuration change is detected.
if (last_video_decoder_config_) {
// Varying video configurations currently not supported. Just assume that
// the video configuration has not changed.
return true;
}
// TODO(damienv): a MAP unit can be either 16 or 32 pixels.
// although it's 16 pixels for progressive non MBAFF frames.
gfx::Size coded_size((sps->pic_width_in_mbs_minus1 + 1) * 16,
(sps->pic_height_in_map_units_minus1 + 1) * 16);
gfx::Rect visible_rect(
sps->frame_crop_left_offset,
sps->frame_crop_top_offset,
(coded_size.width() - sps->frame_crop_right_offset) -
sps->frame_crop_left_offset,
(coded_size.height() - sps->frame_crop_bottom_offset) -
sps->frame_crop_top_offset);
if (visible_rect.width() <= 0 || visible_rect.height() <= 0)
return false;
gfx::Size natural_size(
(visible_rect.width() * sar_width) / sar_height,
visible_rect.height());
if (natural_size.width() == 0)
return false;
uint16 width = (sps->pic_width_in_mbs_minus1 + 1) * 16;
uint16 height = (sps->pic_height_in_map_units_minus1 + 1) * 16;
VideoDecoderConfig video_decoder_config(
kCodecH264,
VIDEO_CODEC_PROFILE_UNKNOWN,
VideoFrame::YV12,
coded_size,
visible_rect,
natural_size,
NULL, 0,
false);
last_video_decoder_config_ = scoped_refptr<VideoStreamInfo>(
new VideoStreamInfo(
track_id(),
kMpeg2Timescale,
kInfiniteDuration,
kCodecH264,
std::string(), // TODO(tinskip): calculate codec string.
std::string(),
width,
height,
kCommonNaluLengthSize,
NULL, // TODO(tinskip): calculate AVCDecoderConfigurationRecord.
0,
false));
DVLOG(1) << "Profile IDC: " << sps->profile_idc;
DVLOG(1) << "Level IDC: " << sps->level_idc;
DVLOG(1) << "Pic width: " << width;
DVLOG(1) << "Pic height: " << height;
DVLOG(1) << "log2_max_frame_num_minus4: "
<< sps->log2_max_frame_num_minus4;
DVLOG(1) << "SAR: width=" << sps->sar_width
<< " height=" << sps->sar_height;
if (!video_decoder_config.Matches(last_video_decoder_config_)) {
DVLOG(1) << "Profile IDC: " << sps->profile_idc;
DVLOG(1) << "Level IDC: " << sps->level_idc;
DVLOG(1) << "Pic width: " << coded_size.width();
DVLOG(1) << "Pic height: " << coded_size.height();
DVLOG(1) << "log2_max_frame_num_minus4: "
<< sps->log2_max_frame_num_minus4;
DVLOG(1) << "SAR: width=" << sps->sar_width
<< " height=" << sps->sar_height;
last_video_decoder_config_ = video_decoder_config;
new_video_config_cb_.Run(video_decoder_config);
}
// Video config notification.
new_video_config_cb_.Run(last_video_decoder_config_);
return true;
}
} // namespace mp2t
} // namespace media

View File

@ -12,16 +12,17 @@
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/time/time.h"
#include "media/base/media_export.h"
#include "media/base/video_decoder_config.h"
#include "media/formats/mp2t/es_parser.h"
namespace media {
class OffsetByteQueue;
class VideoStreamInfo;
namespace filters {
class H264Parser;
struct H264SPS;
class OffsetByteQueue;
}
} // namespace filters
} // namespace media
namespace media {
namespace mp2t {
@ -31,25 +32,25 @@ namespace mp2t {
// Mpeg2 TS spec: "2.14 Carriage of Rec. ITU-T H.264 | ISO/IEC 14496-10 video"
// "Each AVC access unit shall contain an access unit delimiter NAL Unit;"
//
class MEDIA_EXPORT EsParserH264 : NON_EXPORTED_BASE(public EsParser) {
class EsParserH264 : public EsParser {
public:
typedef base::Callback<void(const VideoDecoderConfig&)> NewVideoConfigCB;
typedef base::Callback<void(
scoped_refptr<VideoStreamInfo>&)> NewVideoConfigCB;
EsParserH264(const NewVideoConfigCB& new_video_config_cb,
const EmitBufferCB& emit_buffer_cb);
EsParserH264(uint32 track_id,
const NewVideoConfigCB& new_video_config_cb,
const EmitSampleCB& emit_sample_cb);
virtual ~EsParserH264();
// EsParser implementation.
virtual bool Parse(const uint8* buf, int size,
base::TimeDelta pts,
base::TimeDelta dts) OVERRIDE;
virtual bool Parse(const uint8* buf, int size, int64 pts, int64 dts) OVERRIDE;
virtual void Flush() OVERRIDE;
virtual void Reset() OVERRIDE;
private:
struct TimingDesc {
base::TimeDelta dts;
base::TimeDelta pts;
int64 dts;
int64 pts;
};
// Find the AUD located at or after |*stream_pos|.
@ -70,11 +71,11 @@ class MEDIA_EXPORT EsParserH264 : NON_EXPORTED_BASE(public EsParser) {
// Update the video decoder config based on an H264 SPS.
// Return true if successful.
bool UpdateVideoDecoderConfig(const H264SPS* sps);
bool UpdateVideoDecoderConfig(const filters::H264SPS* sps);
// Callbacks to pass the stream configuration and the frames.
NewVideoConfigCB new_video_config_cb_;
EmitBufferCB emit_buffer_cb_;
EmitSampleCB emit_sample_cb_;
// Bytes of the ES stream that have not been emitted yet.
scoped_ptr<media::OffsetByteQueue> es_queue_;
@ -83,16 +84,15 @@ class MEDIA_EXPORT EsParserH264 : NON_EXPORTED_BASE(public EsParser) {
// H264 parser state.
// - |current_access_unit_pos_| is pointing to an annexB syncword
// representing the first NALU of an H264 access unit.
scoped_ptr<H264Parser> h264_parser_;
scoped_ptr<filters::H264Parser> h264_parser_;
int64 current_access_unit_pos_;
int64 next_access_unit_pos_;
// Last video decoder config.
VideoDecoderConfig last_video_decoder_config_;
scoped_refptr<VideoStreamInfo> last_video_decoder_config_;
};
} // namespace mp2t
} // namespace media
#endif

View File

@ -10,14 +10,21 @@
#include "base/files/memory_mapped_file.h"
#include "base/logging.h"
#include "base/path_service.h"
#include "media/base/stream_parser_buffer.h"
#include "media/base/test_data_util.h"
#include "media/base/media_sample.h"
#include "media/base/timestamp.h"
#include "media/filters/h264_parser.h"
#include "media/formats/mp2t/es_parser_h264.h"
#include "media/test/test_data_util.h"
#include "testing/gtest/include/gtest/gtest.h"
using media::filters::H264Parser;
using media::filters::H264PPS;
using media::filters::H264SliceHeader;
using media::filters::H264SPS;
using media::filters::H264NALU;
namespace media {
class VideoDecoderConfig;
class VideoStreamInfo;
namespace mp2t {
@ -116,20 +123,20 @@ void AppendAUD(
class EsParserH264Test : public testing::Test {
public:
EsParserH264Test() : buffer_count_(0) {
EsParserH264Test() : sample_count_(0) {
}
void LoadStream(const char* filename);
void ProcessPesPackets(const std::vector<Packet>& pes_packets);
void EmitBuffer(scoped_refptr<StreamParserBuffer> buffer) {
buffer_count_++;
void EmitSample(scoped_refptr<MediaSample>& sample) {
sample_count_++;
}
void NewVideoConfig(const VideoDecoderConfig& config) {
void NewVideoConfig(scoped_refptr<VideoStreamInfo>& config) {
}
size_t buffer_count() const { return buffer_count_; }
size_t sample_count() const { return sample_count_; }
// Stream with AUD NALUs.
std::vector<uint8> stream_;
@ -138,7 +145,7 @@ class EsParserH264Test : public testing::Test {
std::vector<Packet> access_units_;
protected:
size_t buffer_count_;
size_t sample_count_;
};
void EsParserH264Test::LoadStream(const char* filename) {
@ -159,9 +166,13 @@ void EsParserH264Test::LoadStream(const char* filename) {
void EsParserH264Test::ProcessPesPackets(
const std::vector<Packet>& pes_packets) {
// Duration of one 25fps video frame in 90KHz clock units.
const uint32 kMpegTicksPerFrame = 3600;
EsParserH264 es_parser(
0,
base::Bind(&EsParserH264Test::NewVideoConfig, base::Unretained(this)),
base::Bind(&EsParserH264Test::EmitBuffer, base::Unretained(this)));
base::Bind(&EsParserH264Test::EmitSample, base::Unretained(this)));
size_t au_idx = 0;
for (size_t k = 0; k < pes_packets.size(); k++) {
@ -177,11 +188,11 @@ void EsParserH264Test::ProcessPesPackets(
// Check whether the PES packet includes the start of an access unit.
// The timings are relevant only in this case.
base::TimeDelta pts = kNoTimestamp();
base::TimeDelta dts = kNoTimestamp();
int64 pts = kNoTimestamp;
int64 dts = kNoTimestamp;
if (cur_pes_offset <= access_units_[au_idx].offset &&
cur_pes_offset + cur_pes_size > access_units_[au_idx].offset) {
pts = base::TimeDelta::FromMilliseconds(au_idx * 40u);
pts = au_idx * kMpegTicksPerFrame;
}
ASSERT_TRUE(
@ -199,7 +210,7 @@ TEST_F(EsParserH264Test, OneAccessUnitPerPes) {
// Process each PES packet.
ProcessPesPackets(pes_packets);
ASSERT_EQ(buffer_count(), access_units_.size());
ASSERT_EQ(sample_count(), access_units_.size());
}
TEST_F(EsParserH264Test, NonAlignedPesPacket) {
@ -223,7 +234,7 @@ TEST_F(EsParserH264Test, NonAlignedPesPacket) {
// Process each PES packet.
ProcessPesPackets(pes_packets);
ASSERT_EQ(buffer_count(), access_units_.size());
ASSERT_EQ(sample_count(), access_units_.size());
}
TEST_F(EsParserH264Test, SeveralPesPerAccessUnit) {
@ -253,9 +264,8 @@ TEST_F(EsParserH264Test, SeveralPesPerAccessUnit) {
// Process each PES packet.
ProcessPesPackets(pes_packets);
ASSERT_EQ(buffer_count(), access_units_.size());
ASSERT_EQ(sample_count(), access_units_.size());
}
} // namespace mp2t
} // namespace media

View File

@ -22,6 +22,8 @@
'es_parser.h',
'es_parser_adts.cc',
'es_parser_adts.h',
'es_parser_h264.cc',
'es_parser_h264.h',
],
'dependencies': [
'../../base/media_base.gyp:base',
@ -31,10 +33,12 @@
'target_name': 'mp2t_unittest',
'type': '<(gtest_target_type)',
'sources': [
'es_parser_h264_unittest.cc',
],
'dependencies': [
'../../../testing/gtest.gyp:gtest',
'../../../testing/gmock.gyp:gmock',
'../../filters/filters.gyp:filters',
'../../test/media_test.gyp:media_test_support',
'mp2t',
]

View File

@ -48,8 +48,6 @@
'mp4_muxer.h',
'multi_segment_segmenter.cc',
'multi_segment_segmenter.h',
'offset_byte_queue.cc',
'offset_byte_queue.h',
'rcheck.h',
'segmenter.cc',
'segmenter.h',
@ -76,7 +74,6 @@
'decoding_time_iterator_unittest.cc',
'es_descriptor_unittest.cc',
'mp4_media_parser_unittest.cc',
'offset_byte_queue_unittest.cc',
'sync_sample_iterator_unittest.cc',
'track_run_iterator_unittest.cc',
],

View File

@ -14,7 +14,7 @@
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "media/base/media_parser.h"
#include "media/formats/mp4/offset_byte_queue.h"
#include "media/base/offset_byte_queue.h"
namespace media {

View File

@ -17,8 +17,8 @@ const size_t kADTSFrequencyTableSize = arraysize(kADTSFrequencyTable);
// The following conversion table is extracted from ISO 14496 Part 3 -
// Table 1.17 - Channel Configuration.
const int kADTSChannelLayoutTable[] = {
const int kADTSNumChannelsTable[] = {
0, 1, 2, 2, 4, 5, 6, 8 };
const size_t kADTSChannelLayoutTableSize = arraysize(kADTSChannelLayoutTable);
const size_t kADTSNumChannelsTableSize = arraysize(kADTSNumChannelsTable);
} // namespace media

View File

@ -10,15 +10,15 @@
namespace media {
enum {
kADTSHeaderMinSize = 7,
kAdtsHeaderMinSize = 7,
kSamplesPerAACFrame = 1024,
};
extern const int kADTSFrequencyTable[];
extern const size_t kADTSFrequencyTableSize;
extern const int kAdtsFrequencyTable[];
extern const size_t kAdtsFrequencyTableSize;
extern const int kADTSChannelLayoutTable[];
extern const size_t kADTSChannelLayoutTableSize;
extern const int kAdtsNumChannelsTable[];
extern const size_t kAdtsNumChannelsTableSize;
} // namespace media

View File

@ -63,3 +63,10 @@ test-25fps.h264:
with:
ffmpeg -i third_party/WebKit/LayoutTests/media/content/test-25fps.mp4 \
-vcodec copy -vbsf h264_mp4toannexb -an test-25fps.h264
// VDA test files: bear
bear.h264:
Using ffmpeg version 0.8.6-4:0.8.6-0ubuntu0.12.04.1, generated with
bear.mp4 (https://chromiumcodereview.appspot.com/10805089):
ffmpeg -i bear.mp4 -vcodec copy -vbsf h264_mp4toannexb \
-an bear.h264

BIN
media/test/data/bear.h264 Normal file

Binary file not shown.

View File

@ -76,6 +76,7 @@
'media/event/media_event.gyp:media_event_unittest',
'media/file/file.gyp:file_unittest',
'media/filters/filters.gyp:filters_unittest',
'media/formats/mp2t/mp2t.gyp:mp2t_unittest',
'media/formats/mp4/mp4.gyp:mp4_unittest',
'mpd/mpd.gyp:mpd_unittest',
'packager_test',