Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <deque> | 5 #include <deque> |
| 6 | 6 |
| 7 #include "media/base/mock_ffmpeg.h" | 7 #include "base/file_util.h" |
| 8 #include "base/path_service.h" | |
| 9 #include "media/base/media.h" | |
| 8 #include "media/ffmpeg/ffmpeg_common.h" | 10 #include "media/ffmpeg/ffmpeg_common.h" |
| 9 #include "media/filters/bitstream_converter.h" | 11 #include "media/filters/bitstream_converter.h" |
| 10 #include "testing/gtest/include/gtest/gtest.h" | 12 #include "testing/gtest/include/gtest/gtest.h" |
| 11 | 13 |
| 12 using ::testing::DoAll; | |
| 13 using ::testing::Mock; | |
| 14 using ::testing::Return; | |
| 15 using ::testing::ReturnNull; | |
| 16 using ::testing::SetArgumentPointee; | |
| 17 using ::testing::StrEq; | |
| 18 using ::testing::StrictMock; | |
| 19 using ::testing::_; | |
| 20 | |
| 21 namespace media { | 14 namespace media { |
| 22 | 15 |
| 23 class BitstreamConverterTest : public testing::Test { | 16 class BitstreamConverterTest : public testing::Test { |
| 17 public: | |
| 18 static int DoFilter(AVBitStreamFilterContext *bsfc, | |
|
scherkus (not reviewing)
2011/08/11 01:26:29
nit: instead of having everything be a static insi
acolwell GONE FROM CHROMIUM
2011/08/11 23:54:40
Done.
| |
| 19 AVCodecContext *avctx, | |
| 20 const char *args, | |
| 21 uint8_t **poutbuf, | |
| 22 int *poutbuf_size, | |
| 23 const uint8_t *buf, | |
| 24 int buf_size, | |
| 25 int keyframe); | |
| 26 | |
| 27 static void DoClose(AVBitStreamFilterContext *bsfc); | |
| 28 | |
| 24 protected: | 29 protected: |
| 25 BitstreamConverterTest() { | 30 BitstreamConverterTest() { |
| 26 memset(&test_stream_context_, 0, sizeof(test_stream_context_)); | 31 memset(&test_stream_context_, 0, sizeof(test_stream_context_)); |
| 27 memset(&test_filter_, 0, sizeof(test_filter_)); | |
| 28 memset(&test_packet_, 0, sizeof(test_packet_)); | 32 memset(&test_packet_, 0, sizeof(test_packet_)); |
| 29 test_packet_.data = kData1; | 33 test_packet_.data = kFailData; |
| 30 test_packet_.size = kTestSize1; | 34 test_packet_.size = kFailSize; |
| 35 | |
| 36 FilePath file_path; | |
| 37 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &file_path)); | |
| 38 InitializeMediaLibrary(file_path); | |
|
scherkus (not reviewing)
2011/08/11 01:26:29
InitializeMediaLibraryForTest() ?
acolwell GONE FROM CHROMIUM
2011/08/11 23:54:40
Done.
| |
| 39 | |
| 40 if (!stream_filter_.next) | |
| 41 av_register_bitstream_filter(&stream_filter_); | |
|
scherkus (not reviewing)
2011/08/11 01:26:29
does this prevent duplicate registration?
perhaps
acolwell GONE FROM CHROMIUM
2011/08/11 23:54:40
Done.
| |
| 31 } | 42 } |
| 32 | 43 |
| 33 virtual ~BitstreamConverterTest() {} | 44 virtual ~BitstreamConverterTest() {} |
| 34 | 45 |
| 35 AVCodecContext test_stream_context_; | 46 AVCodecContext test_stream_context_; |
| 36 AVBitStreamFilterContext test_filter_; | |
| 37 AVPacket test_packet_; | 47 AVPacket test_packet_; |
| 38 | 48 |
| 39 StrictMock<MockFFmpeg> mock_ffmpeg_; | |
| 40 | |
| 41 static const char kTestFilterName[]; | 49 static const char kTestFilterName[]; |
| 42 static uint8_t kData1[]; | 50 static uint8_t kFailData[]; |
| 43 static uint8_t kData2[]; | 51 static uint8_t kNewBufferData[]; |
| 44 static const int kTestSize1; | 52 static uint8_t kInPlaceData[]; |
| 45 static const int kTestSize2; | 53 static const int kFailSize; |
| 54 static const int kNewBufferSize; | |
| 55 static const int kInPlaceSize; | |
| 56 static AVBitStreamFilter stream_filter_; | |
| 46 | 57 |
| 47 private: | 58 private: |
| 48 DISALLOW_COPY_AND_ASSIGN(BitstreamConverterTest); | 59 DISALLOW_COPY_AND_ASSIGN(BitstreamConverterTest); |
| 49 }; | 60 }; |
| 50 | 61 |
| 51 const char BitstreamConverterTest::kTestFilterName[] = "test_filter"; | 62 const char BitstreamConverterTest::kTestFilterName[] = "test_filter"; |
| 52 uint8_t BitstreamConverterTest::kData1[] = { 1 }; | 63 uint8_t BitstreamConverterTest::kFailData[] = { 3, 2, 1 }; |
| 53 uint8_t BitstreamConverterTest::kData2[] = { 2 }; | 64 uint8_t BitstreamConverterTest::kNewBufferData[] = { 2, 1 }; |
| 54 const int BitstreamConverterTest::kTestSize1 = 1; | 65 uint8_t BitstreamConverterTest::kInPlaceData[] = { 1 }; |
| 55 const int BitstreamConverterTest::kTestSize2 = 2; | 66 const int BitstreamConverterTest::kFailSize = 3; |
| 67 const int BitstreamConverterTest::kNewBufferSize = 2; | |
| 68 const int BitstreamConverterTest::kInPlaceSize = 1; | |
| 69 AVBitStreamFilter BitstreamConverterTest::stream_filter_ = { | |
| 70 BitstreamConverterTest::kTestFilterName, | |
| 71 0, // Private Data Size | |
| 72 BitstreamConverterTest::DoFilter, | |
| 73 BitstreamConverterTest::DoClose, | |
| 74 0, | |
| 75 }; | |
| 56 | 76 |
| 57 TEST_F(BitstreamConverterTest, Initialize) { | 77 //static |
|
scherkus (not reviewing)
2011/08/11 01:26:29
// static
acolwell GONE FROM CHROMIUM
2011/08/11 23:54:40
Done.
| |
| 78 int BitstreamConverterTest::DoFilter(AVBitStreamFilterContext *bsfc, | |
|
scherkus (not reviewing)
2011/08/11 01:26:29
pointers w/ types + docs on what this test filter
acolwell GONE FROM CHROMIUM
2011/08/11 23:54:40
Done.
| |
| 79 AVCodecContext *avctx, | |
| 80 const char *args, | |
| 81 uint8_t **poutbuf, | |
| 82 int *poutbuf_size, | |
| 83 const uint8_t *buf, | |
| 84 int buf_size, | |
| 85 int keyframe) { | |
| 86 if (buf_size == kNewBufferSize && | |
| 87 !memcmp(buf, kNewBufferData, kNewBufferSize)) { | |
| 88 *poutbuf_size = buf_size + 1; | |
| 89 *poutbuf = static_cast<uint8*>(av_malloc(*poutbuf_size)); | |
| 90 *poutbuf[0] = 0; | |
| 91 memcpy((*poutbuf) + 1, buf, buf_size); | |
| 92 return 0; | |
| 93 } else if (buf_size == kInPlaceSize && | |
| 94 !memcmp(buf, kInPlaceData, kInPlaceSize)) { | |
| 95 return 0; | |
| 96 } | |
| 97 | |
| 98 return -1; | |
| 99 } | |
| 100 | |
| 101 //static | |
|
scherkus (not reviewing)
2011/08/11 01:26:29
// static
acolwell GONE FROM CHROMIUM
2011/08/11 23:54:40
Done.
| |
| 102 void BitstreamConverterTest::DoClose(AVBitStreamFilterContext *bsfc) {} | |
| 103 | |
| 104 TEST_F(BitstreamConverterTest, InitializeFailed) { | |
| 105 FFmpegBitstreamConverter converter("BAD_FILTER_NAME", &test_stream_context_); | |
| 106 | |
| 107 EXPECT_FALSE(converter.Initialize()); | |
| 108 } | |
| 109 | |
| 110 TEST_F(BitstreamConverterTest, InitializeSuccess) { | |
| 58 FFmpegBitstreamConverter converter(kTestFilterName, &test_stream_context_); | 111 FFmpegBitstreamConverter converter(kTestFilterName, &test_stream_context_); |
| 59 | |
| 60 // Test Initialize returns false on a bad initialization, and cleanup is not | |
| 61 // done. | |
| 62 EXPECT_CALL(mock_ffmpeg_, AVBitstreamFilterInit(StrEq(kTestFilterName))) | |
| 63 .WillOnce(ReturnNull()); | |
| 64 EXPECT_FALSE(converter.Initialize()); | |
| 65 | |
| 66 EXPECT_TRUE(Mock::VerifyAndClearExpectations(&mock_ffmpeg_)); | |
| 67 | |
| 68 // Test Initialize returns true on successful initialization, and cleanup is | |
| 69 // done. The cleanup will be activated when the converter object goes out of | |
| 70 // scope. | |
| 71 EXPECT_CALL(mock_ffmpeg_, AVBitstreamFilterInit(StrEq(kTestFilterName))) | |
| 72 .WillOnce(Return(&test_filter_)); | |
| 73 EXPECT_CALL(mock_ffmpeg_, AVBitstreamFilterClose(&test_filter_)); | |
| 74 EXPECT_TRUE(converter.Initialize()); | 112 EXPECT_TRUE(converter.Initialize()); |
| 75 } | 113 } |
| 76 | 114 |
| 77 TEST_F(BitstreamConverterTest, ConvertPacket_NotInitialized) { | 115 TEST_F(BitstreamConverterTest, ConvertPacket_NotInitialized) { |
| 78 FFmpegBitstreamConverter converter(kTestFilterName, &test_stream_context_); | 116 FFmpegBitstreamConverter converter(kTestFilterName, &test_stream_context_); |
| 79 | 117 |
| 80 EXPECT_FALSE(converter.ConvertPacket(&test_packet_)); | 118 EXPECT_FALSE(converter.ConvertPacket(&test_packet_)); |
| 81 } | 119 } |
| 82 | 120 |
| 83 TEST_F(BitstreamConverterTest, ConvertPacket_FailedFilter) { | 121 TEST_F(BitstreamConverterTest, ConvertPacket_FailedFilter) { |
| 84 FFmpegBitstreamConverter converter(kTestFilterName, &test_stream_context_); | 122 FFmpegBitstreamConverter converter(kTestFilterName, &test_stream_context_); |
| 85 | 123 |
| 86 // Inject mock filter instance. | 124 EXPECT_TRUE(converter.Initialize()); |
| 87 converter.stream_filter_ = &test_filter_; | |
| 88 | |
| 89 // Simulate a successful filter call, that allocates a new data buffer. | |
| 90 EXPECT_CALL(mock_ffmpeg_, | |
| 91 AVBitstreamFilterFilter(&test_filter_, &test_stream_context_, | |
| 92 NULL, _, _, | |
| 93 test_packet_.data, test_packet_.size, _)) | |
| 94 .WillOnce(Return(AVERROR(EINVAL))); | |
| 95 | 125 |
| 96 EXPECT_FALSE(converter.ConvertPacket(&test_packet_)); | 126 EXPECT_FALSE(converter.ConvertPacket(&test_packet_)); |
| 97 | |
| 98 // Uninject mock filter instance to avoid cleanup code on destruction of | |
| 99 // converter. | |
| 100 converter.stream_filter_ = NULL; | |
| 101 } | 127 } |
| 102 | 128 |
| 103 TEST_F(BitstreamConverterTest, ConvertPacket_Success) { | 129 TEST_F(BitstreamConverterTest, ConvertPacket_Success) { |
| 104 FFmpegBitstreamConverter converter(kTestFilterName, &test_stream_context_); | 130 FFmpegBitstreamConverter converter(kTestFilterName, &test_stream_context_); |
| 105 | 131 |
| 106 // Inject mock filter instance. | 132 EXPECT_TRUE(converter.Initialize()); |
| 107 converter.stream_filter_ = &test_filter_; | |
| 108 | 133 |
| 109 // Ensure our packet doesn't already have a destructor. | 134 // Ensure our packet doesn't already have a destructor. |
| 110 ASSERT_TRUE(test_packet_.destruct == NULL); | 135 ASSERT_TRUE(test_packet_.destruct == NULL); |
| 111 | 136 |
| 112 // Simulate a successful filter call, that allocates a new data buffer. | 137 test_packet_.data = kNewBufferData; |
| 113 EXPECT_CALL(mock_ffmpeg_, | 138 test_packet_.size = kNewBufferSize; |
| 114 AVBitstreamFilterFilter(&test_filter_, &test_stream_context_, | |
| 115 NULL, _, _, | |
| 116 test_packet_.data, test_packet_.size, _)) | |
| 117 .WillOnce(DoAll(SetArgumentPointee<3>(&kData2[0]), | |
| 118 SetArgumentPointee<4>(kTestSize2), | |
| 119 Return(0))); | |
| 120 EXPECT_CALL(mock_ffmpeg_, AVFreePacket(&test_packet_)); | |
| 121 | 139 |
| 122 EXPECT_TRUE(converter.ConvertPacket(&test_packet_)); | 140 EXPECT_TRUE(converter.ConvertPacket(&test_packet_)); |
| 123 EXPECT_EQ(kData2, test_packet_.data); | 141 EXPECT_NE(kNewBufferData, test_packet_.data); |
| 124 EXPECT_EQ(kTestSize2, test_packet_.size); | 142 EXPECT_EQ(kNewBufferSize + 1, test_packet_.size); |
| 125 EXPECT_TRUE(test_packet_.destruct != NULL); | 143 EXPECT_TRUE(test_packet_.destruct != NULL); |
| 126 | |
| 127 // Uninject mock filter instance to avoid cleanup code on destruction of | |
| 128 // converter. | |
| 129 converter.stream_filter_ = NULL; | |
| 130 } | 144 } |
| 131 | 145 |
| 132 TEST_F(BitstreamConverterTest, ConvertPacket_SuccessInPlace) { | 146 TEST_F(BitstreamConverterTest, ConvertPacket_SuccessInPlace) { |
| 133 FFmpegBitstreamConverter converter(kTestFilterName, &test_stream_context_); | 147 FFmpegBitstreamConverter converter(kTestFilterName, &test_stream_context_); |
| 134 | 148 |
| 135 // Inject mock filter instance. | 149 EXPECT_TRUE(converter.Initialize()); |
| 136 converter.stream_filter_ = &test_filter_; | |
| 137 | 150 |
| 138 // Ensure our packet is in a sane start state. | 151 // Ensure our packet is in a sane start state. |
| 139 ASSERT_TRUE(test_packet_.destruct == NULL); | 152 ASSERT_TRUE(test_packet_.destruct == NULL); |
| 140 ASSERT_EQ(kData1, test_packet_.data); | 153 test_packet_.data = kInPlaceData; |
| 141 ASSERT_EQ(kTestSize1, test_packet_.size); | 154 test_packet_.size = kInPlaceSize; |
| 142 | |
| 143 // Simulate a successful filter call, that reuses the input buffer. We should | |
| 144 // not free the packet here or alter the packet's destructor. | |
| 145 EXPECT_CALL(mock_ffmpeg_, | |
| 146 AVBitstreamFilterFilter(&test_filter_, &test_stream_context_, | |
| 147 NULL, _, _, | |
| 148 test_packet_.data, test_packet_.size, _)) | |
| 149 .WillOnce(DoAll(SetArgumentPointee<3>(test_packet_.data), | |
| 150 SetArgumentPointee<4>(test_packet_.size), | |
| 151 Return(0))); | |
| 152 | 155 |
| 153 EXPECT_TRUE(converter.ConvertPacket(&test_packet_)); | 156 EXPECT_TRUE(converter.ConvertPacket(&test_packet_)); |
| 154 EXPECT_EQ(kData1, test_packet_.data); | 157 EXPECT_EQ(kInPlaceData, test_packet_.data); |
| 155 EXPECT_EQ(kTestSize1, test_packet_.size); | 158 EXPECT_EQ(kInPlaceSize, test_packet_.size); |
| 156 EXPECT_TRUE(test_packet_.destruct == NULL); | 159 EXPECT_TRUE(test_packet_.destruct == NULL); |
| 157 | |
| 158 // Uninject mock filter instance to avoid cleanup code on destruction of | |
| 159 // converter. | |
| 160 converter.stream_filter_ = NULL; | |
| 161 } | 160 } |
| 162 | 161 |
| 163 } // namespace media | 162 } // namespace media |
| OLD | NEW |