Move TS encrypted audio setup for HLS to hls_audio_util
Change-Id: Ibbc1fe2a8013abded6df2f2f57701ec328d3e5c6
This commit is contained in:
parent
8333908df1
commit
5965b3e136
|
@ -39,6 +39,8 @@
|
||||||
'h26x_byte_to_unit_stream_converter.h',
|
'h26x_byte_to_unit_stream_converter.h',
|
||||||
'hevc_decoder_configuration_record.cc',
|
'hevc_decoder_configuration_record.cc',
|
||||||
'hevc_decoder_configuration_record.h',
|
'hevc_decoder_configuration_record.h',
|
||||||
|
'hls_audio_util.cc',
|
||||||
|
'hls_audio_util.h',
|
||||||
'nal_unit_to_byte_stream_converter.cc',
|
'nal_unit_to_byte_stream_converter.cc',
|
||||||
'nal_unit_to_byte_stream_converter.h',
|
'nal_unit_to_byte_stream_converter.h',
|
||||||
'nalu_reader.cc',
|
'nalu_reader.cc',
|
||||||
|
@ -73,6 +75,7 @@
|
||||||
'h265_parser_unittest.cc',
|
'h265_parser_unittest.cc',
|
||||||
'h26x_bit_reader_unittest.cc',
|
'h26x_bit_reader_unittest.cc',
|
||||||
'hevc_decoder_configuration_record_unittest.cc',
|
'hevc_decoder_configuration_record_unittest.cc',
|
||||||
|
'hls_audio_util_unittest.cc',
|
||||||
'nal_unit_to_byte_stream_converter_unittest.cc',
|
'nal_unit_to_byte_stream_converter_unittest.cc',
|
||||||
'nalu_reader_unittest.cc',
|
'nalu_reader_unittest.cc',
|
||||||
'video_slice_header_parser_unittest.cc',
|
'video_slice_header_parser_unittest.cc',
|
||||||
|
|
|
@ -0,0 +1,84 @@
|
||||||
|
// Copyright 2018 Google LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://developers.google.com/open-source/licenses/bsd
|
||||||
|
|
||||||
|
#include "packager/media/codecs/hls_audio_util.h"
|
||||||
|
|
||||||
|
#include "packager/media/base/buffer_writer.h"
|
||||||
|
#include "packager/media/base/fourccs.h"
|
||||||
|
#include "packager/media/codecs/aac_audio_specific_config.h"
|
||||||
|
|
||||||
|
namespace shaka {
|
||||||
|
namespace media {
|
||||||
|
|
||||||
|
bool WriteAudioSetupInformation(Codec codec,
|
||||||
|
const uint8_t* audio_specific_config,
|
||||||
|
size_t audio_specific_config_size,
|
||||||
|
BufferWriter* audio_setup_information) {
|
||||||
|
uint32_t audio_type = FOURCC_NULL;
|
||||||
|
switch (codec) {
|
||||||
|
case kCodecAAC: {
|
||||||
|
AACAudioSpecificConfig config;
|
||||||
|
const bool result = config.Parse(std::vector<uint8_t>(
|
||||||
|
audio_specific_config,
|
||||||
|
audio_specific_config + audio_specific_config_size));
|
||||||
|
|
||||||
|
AACAudioSpecificConfig::AudioObjectType audio_object_type;
|
||||||
|
if (!result) {
|
||||||
|
LOG(WARNING) << "Failed to parse config. Assuming AAC-LC.";
|
||||||
|
audio_object_type = AACAudioSpecificConfig::AOT_AAC_LC;
|
||||||
|
} else {
|
||||||
|
audio_object_type = config.GetAudioObjectType();
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (audio_object_type) {
|
||||||
|
case AACAudioSpecificConfig::AOT_AAC_LC:
|
||||||
|
audio_type = FOURCC_zaac;
|
||||||
|
break;
|
||||||
|
case AACAudioSpecificConfig::AOT_SBR:
|
||||||
|
audio_type = FOURCC_zach;
|
||||||
|
break;
|
||||||
|
case AACAudioSpecificConfig::AOT_PS:
|
||||||
|
audio_type = FOURCC_zacp;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG(ERROR) << "Unknown object type for aac " << audio_object_type;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case kCodecAC3:
|
||||||
|
audio_type = FOURCC_zac3;
|
||||||
|
break;
|
||||||
|
case kCodecEAC3:
|
||||||
|
audio_type = FOURCC_zec3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOG(ERROR) << "Codec " << codec << " is not supported in encrypted TS.";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DCHECK_NE(audio_type, FOURCC_NULL);
|
||||||
|
audio_setup_information->AppendInt(audio_type);
|
||||||
|
// Priming. Since no info from encoder, set it to 0x0000.
|
||||||
|
audio_setup_information->AppendInt(static_cast<uint16_t>(0x0000));
|
||||||
|
// Version is always 0x01.
|
||||||
|
audio_setup_information->AppendInt(static_cast<uint8_t>(0x01));
|
||||||
|
|
||||||
|
// Size is one byte.
|
||||||
|
if (audio_specific_config_size > 0xFF) {
|
||||||
|
LOG(ERROR) << "Audio specific config should not be larger than one byte "
|
||||||
|
<< audio_specific_config_size;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
audio_setup_information->AppendInt(
|
||||||
|
static_cast<uint8_t>(audio_specific_config_size));
|
||||||
|
|
||||||
|
audio_setup_information->AppendArray(audio_specific_config,
|
||||||
|
audio_specific_config_size);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace media
|
||||||
|
} // namespace shaka
|
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright 2018 Google LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://developers.google.com/open-source/licenses/bsd
|
||||||
|
|
||||||
|
#ifndef PACKAGER_MEDIA_CODECS_HLS_AUDIO_UTIL_H_
|
||||||
|
#define PACKAGER_MEDIA_CODECS_HLS_AUDIO_UTIL_H_
|
||||||
|
|
||||||
|
#include "packager/media/base/stream_info.h"
|
||||||
|
|
||||||
|
namespace shaka {
|
||||||
|
namespace media {
|
||||||
|
|
||||||
|
class BufferWriter;
|
||||||
|
|
||||||
|
/// Write "Audio Setup Information" according to the specification at
|
||||||
|
/// https://goo.gl/X35ZRE MPEG-2 Stream Encryption Format for HTTP Live
|
||||||
|
/// Streaming 2.3.2.
|
||||||
|
/// @return true on success.
|
||||||
|
bool WriteAudioSetupInformation(Codec codec,
|
||||||
|
const uint8_t* audio_specific_config,
|
||||||
|
size_t audio_specific_config_size,
|
||||||
|
BufferWriter* audio_setup_information);
|
||||||
|
|
||||||
|
} // namespace media
|
||||||
|
} // namespace shaka
|
||||||
|
|
||||||
|
#endif // PACKAGER_MEDIA_CODECS_HLS_AUDIO_UTIL_H_
|
|
@ -0,0 +1,100 @@
|
||||||
|
// Copyright 2018 Google LLC. All rights reserved.
|
||||||
|
//
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file or at
|
||||||
|
// https://developers.google.com/open-source/licenses/bsd
|
||||||
|
|
||||||
|
#include "packager/media/codecs/hls_audio_util.h"
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include "packager/media/base/buffer_writer.h"
|
||||||
|
|
||||||
|
namespace shaka {
|
||||||
|
namespace media {
|
||||||
|
|
||||||
|
TEST(HlsAudioUtilAudioSetupTest, AacAudioConfigLcProfile) {
|
||||||
|
const uint8_t kAacLcConfig[] = {12, 10};
|
||||||
|
const uint8_t kExpectedAudioSetupInformation[]{
|
||||||
|
'z', 'a', 'a', 'c', 0, 0, 1, 2, 12, 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
BufferWriter buffer_writer;
|
||||||
|
ASSERT_TRUE(WriteAudioSetupInformation(kCodecAAC, kAacLcConfig,
|
||||||
|
sizeof(kAacLcConfig), &buffer_writer));
|
||||||
|
EXPECT_EQ(
|
||||||
|
std::vector<uint8_t>(std::begin(kExpectedAudioSetupInformation),
|
||||||
|
std::end(kExpectedAudioSetupInformation)),
|
||||||
|
std::vector<uint8_t>(buffer_writer.Buffer(),
|
||||||
|
buffer_writer.Buffer() + buffer_writer.Size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(HlsAudioUtilAudioSetupTest, AacAudioConfigHeProfile) {
|
||||||
|
const uint8_t kAacHeConfig[] = {0x2B, 0x92, 8, 0};
|
||||||
|
const uint8_t kExpectedAudioSetupInformation[]{
|
||||||
|
'z', 'a', 'c', 'h', 0, 0, 1, 4, 0x2B, 0x92, 8, 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
BufferWriter buffer_writer;
|
||||||
|
ASSERT_TRUE(WriteAudioSetupInformation(kCodecAAC, kAacHeConfig,
|
||||||
|
sizeof(kAacHeConfig), &buffer_writer));
|
||||||
|
EXPECT_EQ(
|
||||||
|
std::vector<uint8_t>(std::begin(kExpectedAudioSetupInformation),
|
||||||
|
std::end(kExpectedAudioSetupInformation)),
|
||||||
|
std::vector<uint8_t>(buffer_writer.Buffer(),
|
||||||
|
buffer_writer.Buffer() + buffer_writer.Size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(HlsAudioUtilAudioSetupTest, AC3) {
|
||||||
|
const uint8_t kAudioSpecificConfig[] = {
|
||||||
|
'a', 'u', 'd', 'i', 'o', '_', 'c', 'o', 'n', 'f',
|
||||||
|
};
|
||||||
|
const uint8_t kExpectedAudioSetupInformation[]{
|
||||||
|
'z', 'a', 'c', '3', 0, 0, 1, 10, 'a',
|
||||||
|
'u', 'd', 'i', 'o', '_', 'c', 'o', 'n', 'f',
|
||||||
|
};
|
||||||
|
|
||||||
|
BufferWriter buffer_writer;
|
||||||
|
ASSERT_TRUE(WriteAudioSetupInformation(kCodecAC3, kAudioSpecificConfig,
|
||||||
|
sizeof(kAudioSpecificConfig),
|
||||||
|
&buffer_writer));
|
||||||
|
EXPECT_EQ(
|
||||||
|
std::vector<uint8_t>(std::begin(kExpectedAudioSetupInformation),
|
||||||
|
std::end(kExpectedAudioSetupInformation)),
|
||||||
|
std::vector<uint8_t>(buffer_writer.Buffer(),
|
||||||
|
buffer_writer.Buffer() + buffer_writer.Size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(HlsAudioUtilAudioSetupTest, EAC3) {
|
||||||
|
const uint8_t kAudioSpecificConfig[] = {
|
||||||
|
'a', 'u', 'd', 'i', 'o', '_', 'c', 'o', 'n', 'f',
|
||||||
|
};
|
||||||
|
const uint8_t kExpectedAudioSetupInformation[]{
|
||||||
|
'z', 'e', 'c', '3', 0, 0, 1, 10, 'a',
|
||||||
|
'u', 'd', 'i', 'o', '_', 'c', 'o', 'n', 'f',
|
||||||
|
};
|
||||||
|
|
||||||
|
BufferWriter buffer_writer;
|
||||||
|
ASSERT_TRUE(WriteAudioSetupInformation(kCodecEAC3, kAudioSpecificConfig,
|
||||||
|
sizeof(kAudioSpecificConfig),
|
||||||
|
&buffer_writer));
|
||||||
|
EXPECT_EQ(
|
||||||
|
std::vector<uint8_t>(std::begin(kExpectedAudioSetupInformation),
|
||||||
|
std::end(kExpectedAudioSetupInformation)),
|
||||||
|
std::vector<uint8_t>(buffer_writer.Buffer(),
|
||||||
|
buffer_writer.Buffer() + buffer_writer.Size()));
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(HlsAudioUtilAudioSetupTest, FLAC_NotSupported) {
|
||||||
|
const uint8_t kAudioSpecificConfig[] = {
|
||||||
|
'a', 'u', 'd', 'i', 'o', '_', 'c', 'o', 'n', 'f',
|
||||||
|
};
|
||||||
|
|
||||||
|
BufferWriter buffer_writer;
|
||||||
|
ASSERT_FALSE(WriteAudioSetupInformation(kCodecFlac, kAudioSpecificConfig,
|
||||||
|
sizeof(kAudioSpecificConfig),
|
||||||
|
&buffer_writer));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace media
|
||||||
|
} // namespace shaka
|
|
@ -11,7 +11,7 @@
|
||||||
#include "packager/base/logging.h"
|
#include "packager/base/logging.h"
|
||||||
#include "packager/media/base/buffer_writer.h"
|
#include "packager/media/base/buffer_writer.h"
|
||||||
#include "packager/media/base/fourccs.h"
|
#include "packager/media/base/fourccs.h"
|
||||||
#include "packager/media/codecs/aac_audio_specific_config.h"
|
#include "packager/media/codecs/hls_audio_util.h"
|
||||||
#include "packager/media/formats/mp2t/ts_packet_writer_util.h"
|
#include "packager/media/formats/mp2t/ts_packet_writer_util.h"
|
||||||
#include "packager/media/formats/mp2t/ts_stream_type.h"
|
#include "packager/media/formats/mp2t/ts_stream_type.h"
|
||||||
|
|
||||||
|
@ -130,65 +130,6 @@ void WritePrivateDataIndicatorDescriptor(FourCC fourcc, BufferWriter* output) {
|
||||||
output->AppendInt(fourcc);
|
output->AppendInt(fourcc);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool WriteAudioSetupInformation(Codec codec,
|
|
||||||
const uint8_t* audio_specific_config,
|
|
||||||
size_t audio_specific_config_size,
|
|
||||||
BufferWriter* audio_setup_information) {
|
|
||||||
uint32_t audio_type = FOURCC_NULL;
|
|
||||||
switch (codec) {
|
|
||||||
case kCodecAAC: {
|
|
||||||
AACAudioSpecificConfig config;
|
|
||||||
const bool result = config.Parse(std::vector<uint8_t>(
|
|
||||||
audio_specific_config,
|
|
||||||
audio_specific_config + audio_specific_config_size));
|
|
||||||
|
|
||||||
AACAudioSpecificConfig::AudioObjectType audio_object_type;
|
|
||||||
if (!result) {
|
|
||||||
LOG(WARNING) << "Failed to parse config. Assuming AAC-LC.";
|
|
||||||
audio_object_type = AACAudioSpecificConfig::AOT_AAC_LC;
|
|
||||||
} else {
|
|
||||||
audio_object_type = config.GetAudioObjectType();
|
|
||||||
}
|
|
||||||
|
|
||||||
switch (audio_object_type) {
|
|
||||||
case AACAudioSpecificConfig::AOT_AAC_LC:
|
|
||||||
audio_type = FOURCC_zaac;
|
|
||||||
break;
|
|
||||||
case AACAudioSpecificConfig::AOT_SBR:
|
|
||||||
audio_type = FOURCC_zach;
|
|
||||||
break;
|
|
||||||
case AACAudioSpecificConfig::AOT_PS:
|
|
||||||
audio_type = FOURCC_zacp;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(ERROR) << "Unknown object type for aac " << audio_object_type;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} break;
|
|
||||||
case kCodecAC3:
|
|
||||||
audio_type = FOURCC_zac3;
|
|
||||||
break;
|
|
||||||
case kCodecEAC3:
|
|
||||||
audio_type = FOURCC_zec3;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
LOG(ERROR) << "Codec " << codec << " is not supported in encrypted TS.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
DCHECK_NE(audio_type, FOURCC_NULL);
|
|
||||||
audio_setup_information->AppendInt(audio_type);
|
|
||||||
// Priming. Since no info from encoder, set it to 0x0000.
|
|
||||||
audio_setup_information->AppendInt(static_cast<uint16_t>(0x0000));
|
|
||||||
// Version is always 0x01.
|
|
||||||
audio_setup_information->AppendInt(static_cast<uint8_t>(0x01));
|
|
||||||
audio_setup_information->AppendInt(
|
|
||||||
static_cast<uint8_t>(audio_specific_config_size));
|
|
||||||
audio_setup_information->AppendArray(audio_specific_config,
|
|
||||||
audio_specific_config_size);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WriteRegistrationDescriptorForEncryptedAudio(Codec codec,
|
bool WriteRegistrationDescriptorForEncryptedAudio(Codec codec,
|
||||||
const uint8_t* setup_data,
|
const uint8_t* setup_data,
|
||||||
size_t setup_data_size,
|
size_t setup_data_size,
|
||||||
|
|
Loading…
Reference in New Issue