diff --git a/trunk/configure b/trunk/configure index 84fd651d3..3b366397f 100755 --- a/trunk/configure +++ b/trunk/configure @@ -323,7 +323,7 @@ fi if [ $SRS_UTEST = YES ]; then MODULE_FILES=("srs_utest" "srs_utest_amf0" "srs_utest_protocol" "srs_utest_kernel" "srs_utest_core" "srs_utest_config" "srs_utest_rtmp" "srs_utest_http" "srs_utest_avc" "srs_utest_reload" - "srs_utest_service" "srs_utest_app") + "srs_utest_mp4" "srs_utest_service" "srs_utest_app") ModuleLibIncs=(${SRS_OBJS_DIR} ${LibSTRoot} ${LibSSLRoot}) ModuleLibFiles=(${LibSTfile} ${LibSSLfile}) MODULE_DEPENDS=("CORE" "KERNEL" "PROTOCOL" "SERVICE" "APP") diff --git a/trunk/src/kernel/srs_kernel_mp4.cpp b/trunk/src/kernel/srs_kernel_mp4.cpp index dfc7f305e..ac7be290e 100644 --- a/trunk/src/kernel/srs_kernel_mp4.cpp +++ b/trunk/src/kernel/srs_kernel_mp4.cpp @@ -62,7 +62,7 @@ srs_error_t srs_mp4_write_box(ISrsWriter* writer, ISrsCodec* box) return err; } -stringstream& srs_padding(stringstream& ss, SrsMp4DumpContext dc, int tab = 4) +stringstream& srs_mp4_padding(stringstream& ss, SrsMp4DumpContext dc, int tab) { for (int i = 0; i < (int)dc.level; i++) { for (int j = 0; j < tab; j++) { @@ -78,127 +78,36 @@ stringstream& srs_print_mp4_type(stringstream& ss, uint32_t v) return ss; } -#define SrsSummaryCount 8 - -template -stringstream& srs_dumps_array(std::vector&arr, stringstream& ss, SrsMp4DumpContext dc, - void (*pfn)(T&, stringstream&, SrsMp4DumpContext), - void (*delimiter)(stringstream&,SrsMp4DumpContext)) +stringstream& srs_mp4_print_bytes(stringstream& ss, const char* p, int size, SrsMp4DumpContext dc, int line, int max) { - int limit = arr.size(); - if (dc.summary) { - limit = srs_min(SrsSummaryCount, limit); - } - - for (size_t i = 0; i < (size_t)limit; i++) { - T& elem = arr[i]; - - pfn(elem, ss, dc); - - if (i < limit - 1) { - delimiter(ss, dc); + int limit = srs_min((max<0?size:max), size); + + for (int i = 0; i < (int)limit; i += line) { + int nn_line_elems = srs_min(line, limit-i); + srs_dumps_array(p+i, nn_line_elems, ss, dc, srs_mp4_pfn_hex, srs_mp4_delimiter_inspace); + + if (i + line < limit) { + ss << "," << endl; + srs_mp4_padding(ss, dc); } } return ss; } -template -stringstream& srs_dumps_array(T* arr, int size, stringstream& ss, SrsMp4DumpContext dc, - void (*pfn)(T&, stringstream&, SrsMp4DumpContext), - void (*delimiter)(stringstream&, SrsMp4DumpContext)) -{ - int limit = size; - if (dc.summary) { - limit = srs_min(SrsSummaryCount, limit); - } - - for (size_t i = 0; i < (size_t)limit; i++) { - T& elem = arr[i]; - - pfn(elem, ss, dc); - - if (i < limit - 1) { - delimiter(ss, dc); - } - } - return ss; -} - -void srs_delimiter_inline(stringstream& ss, SrsMp4DumpContext dc) +void srs_mp4_delimiter_inline(stringstream& ss, SrsMp4DumpContext dc) { ss << ","; } -void srs_delimiter_inlinespace(stringstream& ss, SrsMp4DumpContext dc) +void srs_mp4_delimiter_inspace(stringstream& ss, SrsMp4DumpContext dc) { ss << ", "; } -void srs_delimiter_newline(stringstream& ss, SrsMp4DumpContext dc) +void srs_mp4_delimiter_newline(stringstream& ss, SrsMp4DumpContext dc) { ss << endl; - srs_padding(ss, dc); -} - -template -void srs_pfn_box(T& elem, stringstream& ss, SrsMp4DumpContext dc) -{ - elem.dumps(ss, dc); -} - -template -void srs_pfn_detail(T& elem, stringstream& ss, SrsMp4DumpContext dc) -{ - elem.dumps_detail(ss, dc); -} - -template -void srs_pfn_pbox(T*& elem, stringstream& ss, SrsMp4DumpContext dc) -{ - elem->dumps(ss, dc); -} - -template -void srs_pfn_pdetail(T*& elem, stringstream& ss, SrsMp4DumpContext dc) -{ - elem->dumps_detail(ss, dc); -} - -template -void srs_pfn_types(T& elem, stringstream& ss, SrsMp4DumpContext dc) -{ - srs_print_mp4_type(ss, (uint32_t)elem); -} - -template -void srs_pfn_hex(T& elem, stringstream& ss, SrsMp4DumpContext dc) -{ - ss << "0x" << std::setw(2) << std::setfill('0') << std::hex << (uint32_t)(uint8_t)elem << std::dec; -} - -template -void srs_pfn_elems(T& elem, stringstream& ss, SrsMp4DumpContext dc) -{ - ss << elem; -} - -stringstream& srs_print_bytes(stringstream& ss, const char* p, int size, SrsMp4DumpContext dc, int line = SrsSummaryCount, int max = -1) -{ - if (max == -1) { - max = size; - } - - for (int i = 0; i < (int)max; i++) { - ss << "0x" << std::setw(2) << std::setfill('0') << std::hex << (uint32_t)(uint8_t)p[i] << std::dec; - if (i < max -1) { - ss << ", "; - if (((i+1)%line) == 0) { - ss << endl; - srs_padding(ss, dc); - } - } - } - return ss; + srs_mp4_padding(ss, dc); } int srs_mp4_string_length(const string& v) @@ -238,6 +147,16 @@ srs_error_t srs_mp4_string_read(SrsBuffer* buf, string& v, int left) return err; } +SrsMp4DumpContext::SrsMp4DumpContext() +{ + level = 0; + summary = false; +} + +SrsMp4DumpContext::~SrsMp4DumpContext() +{ +} + SrsMp4DumpContext SrsMp4DumpContext::indent() { SrsMp4DumpContext ctx = *this; @@ -328,7 +247,7 @@ int SrsMp4Box::remove(SrsMp4BoxType bt) stringstream& SrsMp4Box::dumps(stringstream& ss, SrsMp4DumpContext dc) { - srs_padding(ss, dc); + srs_mp4_padding(ss, dc); srs_print_mp4_type(ss, (uint32_t)type); ss << ", " << sz(); @@ -802,7 +721,7 @@ stringstream& SrsMp4FileTypeBox::dumps_detail(stringstream& ss, SrsMp4DumpContex if (!compatible_brands.empty()) { ss << "("; - srs_dumps_array(compatible_brands, ss, dc, srs_pfn_types, srs_delimiter_inline); + srs_dumps_array(compatible_brands, ss, dc, srs_mp4_pfn_type, srs_mp4_delimiter_inline); ss << ")"; } return ss; @@ -1339,8 +1258,8 @@ stringstream& SrsMp4TrackFragmentRunBox::dumps_detail(stringstream& ss, SrsMp4Du if (sample_count > 0) { ss << endl; - srs_padding(ss, dc.indent()); - srs_dumps_array(entries, ss, dc.indent(), srs_pfn_pdetail, srs_delimiter_newline); + srs_mp4_padding(ss, dc.indent()); + srs_dumps_array(entries, ss, dc.indent(), srs_mp4_pfn_detail2, srs_mp4_delimiter_newline); } return ss; @@ -1458,8 +1377,8 @@ stringstream& SrsMp4FreeSpaceBox::dumps_detail(stringstream& ss, SrsMp4DumpConte if (!data.empty()) { ss << endl; - srs_padding(ss, dc.indent()); - srs_dumps_array(&data[0], (int)data.size(), ss, dc.indent(), srs_pfn_hex, srs_delimiter_inlinespace); + srs_mp4_padding(ss, dc.indent()); + srs_dumps_array(&data[0], (int)data.size(), ss, dc.indent(), srs_mp4_pfn_hex, srs_mp4_delimiter_inspace); } return ss; } @@ -2192,8 +2111,8 @@ stringstream& SrsMp4EditListBox::dumps_detail(stringstream& ss, SrsMp4DumpContex if (!entries.empty()) { ss << "(+)" << endl; - srs_padding(ss, dc.indent()); - srs_dumps_array(entries, ss, dc.indent(), srs_pfn_detail, srs_delimiter_newline); + srs_mp4_padding(ss, dc.indent()); + srs_dumps_array(entries, ss, dc.indent(), srs_mp4_pfn_detail, srs_mp4_delimiter_newline); } return ss; @@ -2872,8 +2791,8 @@ stringstream& SrsMp4DataReferenceBox::dumps_detail(stringstream& ss, SrsMp4DumpC ss << ", " << entries.size() << " childs"; if (!entries.empty()) { ss << "(+)" << endl; - srs_padding(ss, dc.indent()); - srs_dumps_array(entries, ss, dc.indent(), srs_pfn_pdetail, srs_delimiter_newline); + srs_mp4_padding(ss, dc.indent()); + srs_dumps_array(entries, ss, dc.indent(), srs_mp4_pfn_detail2, srs_mp4_delimiter_newline); } return ss; } @@ -3196,8 +3115,8 @@ stringstream& SrsMp4AvccBox::dumps_detail(stringstream& ss, SrsMp4DumpContext dc SrsMp4Box::dumps_detail(ss, dc); ss << ", AVC Config: " << (int)avc_config.size() << "B" << endl; - srs_padding(ss, dc.indent()); - srs_print_bytes(ss, (const char*)&avc_config[0], (int)avc_config.size(), dc.indent()); + srs_mp4_padding(ss, dc.indent()); + srs_mp4_print_bytes(ss, (const char*)&avc_config[0], (int)avc_config.size(), dc.indent()); return ss; } @@ -3444,8 +3363,8 @@ stringstream& SrsMp4DecoderSpecificInfo::dumps_detail(stringstream& ss, SrsMp4Du ss << ", ASC " << asc.size() << "B"; ss << endl; - srs_padding(ss, dc.indent()); - return srs_print_bytes(ss, (const char*)&asc[0], (int)asc.size(), dc.indent()); + srs_mp4_padding(ss, dc.indent()); + return srs_mp4_print_bytes(ss, (const char*)&asc[0], (int)asc.size(), dc.indent()); } SrsMp4DecoderConfigDescriptor::SrsMp4DecoderConfigDescriptor() : upStream(0), bufferSizeDB(0), maxBitrate(0), avgBitrate(0) @@ -3522,7 +3441,7 @@ stringstream& SrsMp4DecoderConfigDescriptor::dumps_detail(stringstream& ss, SrsM ss << ", type=" << objectTypeIndication << ", stream=" << streamType; ss << endl; - srs_padding(ss, dc.indent()); + srs_mp4_padding(ss, dc.indent()); ss << "decoder specific"; return decSpecificInfo->dumps_detail(ss, dc.indent()); @@ -3681,7 +3600,7 @@ stringstream& SrsMp4ES_Descriptor::dumps_detail(stringstream& ss, SrsMp4DumpCont ss << ", ID=" << ES_ID; ss << endl; - srs_padding(ss, dc.indent()); + srs_mp4_padding(ss, dc.indent()); ss << "decoder config"; decConfigDescr.dumps_detail(ss, dc.indent()); @@ -3887,7 +3806,7 @@ stringstream& SrsMp4SampleDescriptionBox::dumps_detail(stringstream& ss, SrsMp4D ss << ", " << entries.size() << " childs"; if (!entries.empty()) { ss << "(+)" << endl; - srs_dumps_array(entries, ss, dc.indent(), srs_pfn_pbox, srs_delimiter_newline); + srs_dumps_array(entries, ss, dc.indent(), srs_mp4_pfn_box2, srs_mp4_delimiter_newline); } return ss; } @@ -4003,8 +3922,8 @@ stringstream& SrsMp4DecodingTime2SampleBox::dumps_detail(stringstream& ss, SrsMp ss << ", " << entries.size() << " childs (+)"; if (!entries.empty()) { ss << endl; - srs_padding(ss, dc.indent()); - srs_dumps_array(entries, ss, dc.indent(), srs_pfn_detail, srs_delimiter_newline); + srs_mp4_padding(ss, dc.indent()); + srs_dumps_array(entries, ss, dc.indent(), srs_mp4_pfn_detail, srs_mp4_delimiter_newline); } return ss; } @@ -4128,8 +4047,8 @@ stringstream& SrsMp4CompositionTime2SampleBox::dumps_detail(stringstream& ss, Sr ss << ", " << entries.size() << " childs (+)"; if (!entries.empty()) { ss << endl; - srs_padding(ss, dc.indent()); - srs_dumps_array(entries, ss, dc.indent(), srs_pfn_detail, srs_delimiter_newline); + srs_mp4_padding(ss, dc.indent()); + srs_dumps_array(entries, ss, dc.indent(), srs_mp4_pfn_detail, srs_mp4_delimiter_newline); } return ss; } @@ -4205,8 +4124,8 @@ stringstream& SrsMp4SyncSampleBox::dumps_detail(stringstream& ss, SrsMp4DumpCont ss << ", count=" << entry_count; if (entry_count > 0) { ss << endl; - srs_padding(ss, dc.indent()); - srs_dumps_array(sample_numbers, entry_count, ss, dc.indent(), srs_pfn_elems, srs_delimiter_inlinespace); + srs_mp4_padding(ss, dc.indent()); + srs_dumps_array(sample_numbers, entry_count, ss, dc.indent(), srs_mp4_pfn_elem, srs_mp4_delimiter_inspace); } return ss; } @@ -4310,8 +4229,8 @@ stringstream& SrsMp4Sample2ChunkBox::dumps_detail(stringstream& ss, SrsMp4DumpCo ss << ", " << entry_count << " childs (+)"; if (entry_count > 0) { ss << endl; - srs_padding(ss, dc.indent()); - srs_dumps_array(entries, entry_count, ss, dc.indent(), srs_pfn_detail, srs_delimiter_newline); + srs_mp4_padding(ss, dc.indent()); + srs_dumps_array(entries, entry_count, ss, dc.indent(), srs_mp4_pfn_detail, srs_mp4_delimiter_newline); } return ss; } @@ -4376,8 +4295,8 @@ stringstream& SrsMp4ChunkOffsetBox::dumps_detail(stringstream& ss, SrsMp4DumpCon ss << ", " << entry_count << " childs (+)"; if (entry_count > 0) { ss << endl; - srs_padding(ss, dc.indent()); - srs_dumps_array(entries, entry_count, ss, dc.indent(), srs_pfn_elems, srs_delimiter_inlinespace); + srs_mp4_padding(ss, dc.indent()); + srs_dumps_array(entries, entry_count, ss, dc.indent(), srs_mp4_pfn_elem, srs_mp4_delimiter_inspace); } return ss; } @@ -4442,8 +4361,8 @@ stringstream& SrsMp4ChunkLargeOffsetBox::dumps_detail(stringstream& ss, SrsMp4Du ss << ", " << entry_count << " childs (+)"; if (entry_count > 0) { ss << endl; - srs_padding(ss, dc.indent()); - srs_dumps_array(entries, entry_count, ss, dc.indent(), srs_pfn_elems, srs_delimiter_inlinespace); + srs_mp4_padding(ss, dc.indent()); + srs_dumps_array(entries, entry_count, ss, dc.indent(), srs_mp4_pfn_elem, srs_mp4_delimiter_inspace); } return ss; } @@ -4531,8 +4450,8 @@ stringstream& SrsMp4SampleSizeBox::dumps_detail(stringstream& ss, SrsMp4DumpCont ss << ", size=" << sample_size << ", " << sample_count << " childs (+)"; if (!sample_size && sample_count> 0) { ss << endl; - srs_padding(ss, dc.indent()); - srs_dumps_array(entry_sizes, sample_count, ss, dc.indent(), srs_pfn_elems, srs_delimiter_inlinespace); + srs_mp4_padding(ss, dc.indent()); + srs_dumps_array(entry_sizes, sample_count, ss, dc.indent(), srs_mp4_pfn_elem, srs_mp4_delimiter_inspace); } return ss; } @@ -4591,8 +4510,8 @@ stringstream& SrsMp4UserDataBox::dumps_detail(stringstream& ss, SrsMp4DumpContex if (!data.empty()) { ss << endl; - srs_padding(ss, dc.indent()); - srs_dumps_array(&data[0], (int)data.size(), ss, dc.indent(), srs_pfn_hex, srs_delimiter_inlinespace); + srs_mp4_padding(ss, dc.indent()); + srs_dumps_array(&data[0], (int)data.size(), ss, dc.indent(), srs_mp4_pfn_hex, srs_mp4_delimiter_inspace); } return ss; } @@ -4702,7 +4621,7 @@ stringstream& SrsMp4SegmentIndexBox::dumps_detail(stringstream& ss, SrsMp4DumpCo SrsMp4SegmentIndexEntry& entry = entries.at(i); ss << endl; - srs_padding(ss, dc.indent()); + srs_mp4_padding(ss, dc.indent()); ss << "#" << i << ", ref=" << (int)entry.reference_type << "/" << entry.referenced_size << ", duration=" << entry.subsegment_duration << ", SAP=" << (int)entry.starts_with_SAP << "/" << (int)entry.SAP_type << "/" << entry.SAP_delta_time; diff --git a/trunk/src/kernel/srs_kernel_mp4.hpp b/trunk/src/kernel/srs_kernel_mp4.hpp index e004c5651..725f9dc13 100644 --- a/trunk/src/kernel/srs_kernel_mp4.hpp +++ b/trunk/src/kernel/srs_kernel_mp4.hpp @@ -28,6 +28,7 @@ #include #include +#include #include #include @@ -159,7 +160,10 @@ class SrsMp4DumpContext public: int level; bool summary; - + + SrsMp4DumpContext(); + virtual ~SrsMp4DumpContext(); + SrsMp4DumpContext indent(); }; @@ -2138,5 +2142,110 @@ public: virtual srs_error_t flush(uint64_t& dts); }; +///////////////////////////////////////////////////////////////////////////////// +// MP4 dumps functions. +///////////////////////////////////////////////////////////////////////////////// + +#include + +#define SrsMp4SummaryCount 8 + +extern std::stringstream& srs_mp4_padding(std::stringstream& ss, SrsMp4DumpContext dc, int tab = 4); + +extern void srs_mp4_delimiter_inline(std::stringstream& ss, SrsMp4DumpContext dc); +extern void srs_mp4_delimiter_inspace(std::stringstream& ss, SrsMp4DumpContext dc); +extern void srs_mp4_delimiter_newline(std::stringstream& ss, SrsMp4DumpContext dc); + +extern std::stringstream& srs_print_mp4_type(std::stringstream& ss, uint32_t v); +extern std::stringstream& srs_mp4_print_bytes(std::stringstream& ss, const char* p, int size, SrsMp4DumpContext dc, int line = SrsMp4SummaryCount, int max = -1); + +// TODO: FIXME: Extract to common utility. +template +std::stringstream& srs_dumps_array(std::vector&arr, std::stringstream& ss, SrsMp4DumpContext dc, + void (*pfn)(T&, std::stringstream&, SrsMp4DumpContext), + void (*delimiter)(std::stringstream&, SrsMp4DumpContext)) +{ + int limit = arr.size(); + if (dc.summary) { + limit = srs_min(SrsMp4SummaryCount, limit); + } + + for (size_t i = 0; i < (size_t)limit; i++) { + T& elem = arr[i]; + + pfn(elem, ss, dc); + + if (i < limit - 1) { + delimiter(ss, dc); + } + } + return ss; +} + +// TODO: FIXME: Extract to common utility. +template +std::stringstream& srs_dumps_array(T* arr, int size, std::stringstream& ss, SrsMp4DumpContext dc, + void (*pfn)(T&, std::stringstream&, SrsMp4DumpContext), + void (*delimiter)(std::stringstream&, SrsMp4DumpContext)) +{ + int limit = size; + if (dc.summary) { + limit = srs_min(SrsMp4SummaryCount, limit); + } + + for (size_t i = 0; i < (size_t)limit; i++) { + T& elem = arr[i]; + + pfn(elem, ss, dc); + + if (i < limit - 1) { + delimiter(ss, dc); + } + } + return ss; +} + +template +void srs_mp4_pfn_box(T& elem, std::stringstream& ss, SrsMp4DumpContext dc) +{ + elem.dumps(ss, dc); +} + +template +void srs_mp4_pfn_detail(T& elem, std::stringstream& ss, SrsMp4DumpContext dc) +{ + elem.dumps_detail(ss, dc); +} + +template +void srs_mp4_pfn_box2(T*& elem, std::stringstream& ss, SrsMp4DumpContext dc) +{ + elem->dumps(ss, dc); +} + +template +void srs_mp4_pfn_detail2(T*& elem, std::stringstream& ss, SrsMp4DumpContext dc) +{ + elem->dumps_detail(ss, dc); +} + +template +void srs_mp4_pfn_type(T& elem, std::stringstream& ss, SrsMp4DumpContext /*dc*/) +{ + srs_print_mp4_type(ss, (uint32_t)elem); +} + +template +void srs_mp4_pfn_hex(T& elem, std::stringstream& ss, SrsMp4DumpContext /*dc*/) +{ + ss << "0x" << std::setw(2) << std::setfill('0') << std::hex << (uint32_t)(uint8_t)elem << std::dec; +} + +template +void srs_mp4_pfn_elem(T& elem, std::stringstream& ss, SrsMp4DumpContext /*dc*/) +{ + ss << elem; +} + #endif diff --git a/trunk/src/utest/srs_utest_mp4.cpp b/trunk/src/utest/srs_utest_mp4.cpp new file mode 100644 index 000000000..08aada5a9 --- /dev/null +++ b/trunk/src/utest/srs_utest_mp4.cpp @@ -0,0 +1,200 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013-2020 Winlin + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ +#include + +#include +using namespace std; + +#include +#include +#include + +VOID TEST(KernelMp4Test, PrintPadding) +{ + stringstream ss; + SrsMp4DumpContext dc; + + srs_mp4_padding(ss, dc); + EXPECT_STREQ("", ss.str().c_str()); + + srs_mp4_padding(ss, dc.indent()); + EXPECT_STREQ(" ", ss.str().c_str()); + + srs_mp4_padding(ss, dc.indent()); + EXPECT_STREQ(" ", ss.str().c_str()); +} + +struct MockBox +{ +public: + MockBox() { + } + virtual ~MockBox() { + } + virtual void dumps(stringstream&ss, SrsMp4DumpContext /*dc*/) { + ss << "mock"; + } + virtual void dumps_detail(stringstream&ss, SrsMp4DumpContext /*dc*/) { + ss << "mock-detail"; + } +}; + +VOID TEST(KernelMp4Test, DumpsArray) +{ + if (true) { + char* p = (char*)"srs"; + vector arr(p, p+3); + + stringstream ss; + SrsMp4DumpContext dc; + srs_dumps_array(arr, ss, dc, srs_mp4_pfn_elem, srs_mp4_delimiter_inline); + + EXPECT_STREQ("s,r,s", ss.str().c_str()); + } + + if (true) { + char arr[] = {'s', 'r', 's'}; + + stringstream ss; + SrsMp4DumpContext dc; + srs_dumps_array(arr, 3, ss, dc, srs_mp4_pfn_elem, srs_mp4_delimiter_inline); + + EXPECT_STREQ("s,r,s", ss.str().c_str()); + } + + if (true) { + char arr[] = {'s', 'r', 's'}; + + stringstream ss; + SrsMp4DumpContext dc; + srs_dumps_array(arr, 3, ss, dc, srs_mp4_pfn_elem, srs_mp4_delimiter_inspace); + + EXPECT_STREQ("s, r, s", ss.str().c_str()); + } + + if (true) { + char arr[] = {'s', 'r', 's'}; + + stringstream ss; + SrsMp4DumpContext dc; + srs_dumps_array(arr, 3, ss, dc, srs_mp4_pfn_elem, srs_mp4_delimiter_newline); + + EXPECT_STREQ("s\nr\ns", ss.str().c_str()); + } + + if (true) { + MockBox arr[1]; + + stringstream ss; + SrsMp4DumpContext dc; + srs_dumps_array(arr, 1, ss, dc, srs_mp4_pfn_box, srs_mp4_delimiter_inline); + + EXPECT_STREQ("mock", ss.str().c_str()); + } + + if (true) { + MockBox arr[1]; + + stringstream ss; + SrsMp4DumpContext dc; + srs_dumps_array(arr, 1, ss, dc, srs_mp4_pfn_detail, srs_mp4_delimiter_inline); + + EXPECT_STREQ("mock-detail", ss.str().c_str()); + } + + if (true) { + MockBox* arr[1] = {new MockBox()}; + + stringstream ss; + SrsMp4DumpContext dc; + srs_dumps_array(arr, 1, ss, dc, srs_mp4_pfn_box2, srs_mp4_delimiter_inline); + + EXPECT_STREQ("mock", ss.str().c_str()); + srs_freep(arr[0]); + } + + if (true) { + MockBox* arr[1] = {new MockBox()}; + + stringstream ss; + SrsMp4DumpContext dc; + srs_dumps_array(arr, 1, ss, dc, srs_mp4_pfn_detail2, srs_mp4_delimiter_inline); + + EXPECT_STREQ("mock-detail", ss.str().c_str()); + srs_freep(arr[0]); + } + + if (true) { + SrsMp4BoxType arr[] = {SrsMp4BoxTypeUUID}; + + stringstream ss; + SrsMp4DumpContext dc; + srs_dumps_array(arr, 1, ss, dc, srs_mp4_pfn_type, srs_mp4_delimiter_inline); + + EXPECT_STREQ("uuid", ss.str().c_str()); + } + + if (true) { + uint8_t arr[] = {0xec}; + + stringstream ss; + SrsMp4DumpContext dc; + srs_dumps_array(arr, 1, ss, dc, srs_mp4_pfn_hex, srs_mp4_delimiter_inline); + + EXPECT_STREQ("0xec", ss.str().c_str()); + } +} + +VOID TEST(KernelMp4Test, PrintBytes) +{ + if (true) { + uint8_t arr[] = {0xec}; + + stringstream ss; + SrsMp4DumpContext dc; + srs_mp4_print_bytes(ss, (const char*)arr, 1, dc, 4, 8); + + EXPECT_STREQ("0xec", ss.str().c_str()); + } + + if (true) { + uint8_t arr[] = {0xc}; + + stringstream ss; + SrsMp4DumpContext dc; + srs_mp4_print_bytes(ss, (const char*)arr, 1, dc, 4, 8); + + EXPECT_STREQ("0x0c", ss.str().c_str()); + } + + if (true) { + uint8_t arr[] = {0xec, 0xb1, 0xa3, 0xe1, 0xab}; + + stringstream ss; + SrsMp4DumpContext dc; + srs_mp4_print_bytes(ss, (const char*)arr, 5, dc, 4, 8); + + EXPECT_STREQ("0xec, 0xb1, 0xa3, 0xe1,\n0xab", ss.str().c_str()); + } +} + diff --git a/trunk/src/utest/srs_utest_mp4.hpp b/trunk/src/utest/srs_utest_mp4.hpp new file mode 100644 index 000000000..e5ba3d2fa --- /dev/null +++ b/trunk/src/utest/srs_utest_mp4.hpp @@ -0,0 +1,33 @@ +/* +The MIT License (MIT) + +Copyright (c) 2013-2020 Winlin + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef SRS_UTEST_MP4_HPP +#define SRS_UTEST_MP4_HPP + +/* +#include +*/ +#include + +#endif +