1 // Copyright 2014 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "media/ffmpeg/ffmpeg_common.h"
9 #include "media/ffmpeg/scoped_av_packet.h"
10 #include "media/filters/ffmpeg_aac_bitstream_converter.h"
11 #include "testing/gtest/include/gtest/gtest.h"
16 const int kAacMainProfile = 0;
17 const int kAacLowComplexityProfile = 1;
20 // Class for testing the FFmpegAACBitstreamConverter.
21 class FFmpegAACBitstreamConverterTest : public testing::Test {
23 FFmpegAACBitstreamConverterTest(const FFmpegAACBitstreamConverterTest&) =
25 FFmpegAACBitstreamConverterTest& operator=(
26 const FFmpegAACBitstreamConverterTest&) = delete;
29 FFmpegAACBitstreamConverterTest() {
30 // Minimal extra data header
31 memset(extradata_header_, 0, sizeof(extradata_header_));
33 // Set up reasonable aac parameters
34 memset(&test_parameters_, 0, sizeof(AVCodecParameters));
35 test_parameters_.codec_id = AV_CODEC_ID_AAC;
36 test_parameters_.profile = FF_PROFILE_AAC_MAIN;
37 test_parameters_.ch_layout.nb_channels = 2;
38 test_parameters_.extradata = extradata_header_;
39 test_parameters_.extradata_size = sizeof(extradata_header_);
42 void CreatePacket(AVPacket* packet, const uint8_t* data, uint32_t data_size) {
43 // Create new packet sized of |data_size| from |data|.
44 EXPECT_EQ(av_new_packet(packet, data_size), 0);
45 memcpy(packet->data, data, data_size);
48 // Variable to hold valid dummy parameters for testing.
49 AVCodecParameters test_parameters_;
52 uint8_t extradata_header_[2];
55 TEST_F(FFmpegAACBitstreamConverterTest, Conversion_Success) {
56 FFmpegAACBitstreamConverter converter(&test_parameters_);
58 uint8_t dummy_packet[1000];
59 // Fill dummy packet with junk data. aac converter doesn't look into packet
60 // data, just header, so can fill with whatever we want for test.
61 for(size_t i = 0; i < sizeof(dummy_packet); i++) {
62 dummy_packet[i] = i & 0xFF; // Repeated sequences of 0-255
65 auto test_packet = ScopedAVPacket::Allocate();
66 CreatePacket(test_packet.get(), dummy_packet,
67 sizeof(dummy_packet));
69 // Try out the actual conversion (should be successful and allocate new
70 // packet and destroy the old one).
71 EXPECT_TRUE(converter.ConvertPacket(test_packet.get()));
73 // Check that a header was added and that packet data was preserved
74 EXPECT_EQ(static_cast<long>(test_packet->size),
75 static_cast<long>(sizeof(dummy_packet) +
76 FFmpegAACBitstreamConverter::kAdtsHeaderSize));
78 reinterpret_cast<void*>(test_packet->data +
79 FFmpegAACBitstreamConverter::kAdtsHeaderSize),
80 reinterpret_cast<void*>(dummy_packet),
81 sizeof(dummy_packet)), 0);
84 TEST_F(FFmpegAACBitstreamConverterTest, Conversion_FailureNullParams) {
85 // Set up AVCConfigurationRecord to represent NULL data.
86 AVCodecParameters dummy_parameters;
87 dummy_parameters.extradata = nullptr;
88 dummy_parameters.extradata_size = 0;
89 FFmpegAACBitstreamConverter converter(&dummy_parameters);
91 uint8_t dummy_packet[1000] = {0};
93 // Try out the actual conversion with NULL parameter.
94 EXPECT_FALSE(converter.ConvertPacket(NULL));
96 // Create new packet to test actual conversion.
97 auto test_packet = ScopedAVPacket::Allocate();
98 CreatePacket(test_packet.get(), dummy_packet, sizeof(dummy_packet));
100 // Try out the actual conversion. This should fail due to missing extradata.
101 EXPECT_FALSE(converter.ConvertPacket(test_packet.get()));
104 TEST_F(FFmpegAACBitstreamConverterTest, Conversion_AudioProfileType) {
105 FFmpegAACBitstreamConverter converter(&test_parameters_);
107 uint8_t dummy_packet[1000] = {0};
109 auto test_packet = ScopedAVPacket::Allocate();
110 CreatePacket(test_packet.get(), dummy_packet,
111 sizeof(dummy_packet));
113 EXPECT_TRUE(converter.ConvertPacket(test_packet.get()));
115 // Check that the ADTS header profile matches the parameters
116 int profile = ((test_packet->data[2] & 0xC0) >> 6);
118 EXPECT_EQ(profile, kAacMainProfile);
120 test_parameters_.profile = FF_PROFILE_AAC_HE;
121 FFmpegAACBitstreamConverter converter_he(&test_parameters_);
123 test_packet = ScopedAVPacket::Allocate();
124 CreatePacket(test_packet.get(), dummy_packet,
125 sizeof(dummy_packet));
127 EXPECT_TRUE(converter_he.ConvertPacket(test_packet.get()));
129 profile = ((test_packet->data[2] & 0xC0) >> 6);
131 EXPECT_EQ(profile, kAacLowComplexityProfile);
133 test_parameters_.profile = FF_PROFILE_AAC_ELD;
134 FFmpegAACBitstreamConverter converter_eld(&test_parameters_);
136 test_packet = ScopedAVPacket::Allocate();
137 CreatePacket(test_packet.get(), dummy_packet,
138 sizeof(dummy_packet));
140 EXPECT_FALSE(converter_eld.ConvertPacket(test_packet.get()));
143 TEST_F(FFmpegAACBitstreamConverterTest, Conversion_MultipleLength) {
144 FFmpegAACBitstreamConverter converter(&test_parameters_);
146 uint8_t dummy_packet[1000];
148 auto test_packet = ScopedAVPacket::Allocate();
149 CreatePacket(test_packet.get(), dummy_packet,
150 sizeof(dummy_packet));
152 // Try out the actual conversion (should be successful and allocate new
153 // packet and destroy the old one).
154 EXPECT_TRUE(converter.ConvertPacket(test_packet.get()));
156 // Check that the ADTS header frame length matches the packet size
157 int frame_length = ((test_packet->data[3] & 0x03) << 11) |
158 ((test_packet->data[4] & 0xFF) << 3) |
159 ((test_packet->data[5] & 0xE0) >> 5);
161 EXPECT_EQ(frame_length, test_packet->size);
163 // Create a second packet that is 1 byte smaller than the first one
164 auto second_test_packet = ScopedAVPacket::Allocate();
165 CreatePacket(second_test_packet.get(), dummy_packet,
166 sizeof(dummy_packet) - 1);
168 // Try out the actual conversion (should be successful and allocate new
169 // packet and destroy the old one).
170 EXPECT_TRUE(converter.ConvertPacket(second_test_packet.get()));
172 // Check that the ADTS header frame length matches the packet size
173 frame_length = ((second_test_packet->data[3] & 0x03) << 11) |
174 ((second_test_packet->data[4] & 0xFF) << 3) |
175 ((second_test_packet->data[5] & 0xE0) >> 5);
177 EXPECT_EQ(frame_length, second_test_packet->size);