From 9bec823f22dad07e2ba13543947807a7ed9bb8a8 Mon Sep 17 00:00:00 2001
From: paxc <pax.cao@icloud.com>
Date: Sun, 12 Jan 2020 13:44:48 +0400
Subject: [PATCH] [mod_openh264] Fix stap-a size issue and add unit test.

---
 src/mod/codecs/mod_openh264/Makefile.am       |  13 ++
 src/mod/codecs/mod_openh264/mod_openh264.cpp  |  10 +-
 .../mod_openh264/test/conf/freeswitch.xml     |  38 +++
 .../mod_openh264/test/data/case1.packet1.264  |   1 +
 .../mod_openh264/test/data/case1.packet2.264  |   1 +
 .../mod_openh264/test/data/case1.packet3.264  | Bin 0 -> 1826 bytes
 .../mod_openh264/test/data/case1.packet4.264  | Bin 0 -> 2323 bytes
 .../mod_openh264/test/data/case1.packet5.264  | Bin 0 -> 89 bytes
 .../mod_openh264/test/data/case2.packet1.264  |   1 +
 .../mod_openh264/test/data/case2.packet2.264  |   1 +
 .../mod_openh264/test/data/case2.packet3.264  | Bin 0 -> 4156 bytes
 .../mod_openh264/test/data/case2.packet4.264  | Bin 0 -> 89 bytes
 .../mod_openh264/test/test_mod_openh264.cpp   | 220 ++++++++++++++++++
 13 files changed, 280 insertions(+), 5 deletions(-)
 create mode 100644 src/mod/codecs/mod_openh264/test/conf/freeswitch.xml
 create mode 100755 src/mod/codecs/mod_openh264/test/data/case1.packet1.264
 create mode 100755 src/mod/codecs/mod_openh264/test/data/case1.packet2.264
 create mode 100755 src/mod/codecs/mod_openh264/test/data/case1.packet3.264
 create mode 100755 src/mod/codecs/mod_openh264/test/data/case1.packet4.264
 create mode 100755 src/mod/codecs/mod_openh264/test/data/case1.packet5.264
 create mode 100755 src/mod/codecs/mod_openh264/test/data/case2.packet1.264
 create mode 100755 src/mod/codecs/mod_openh264/test/data/case2.packet2.264
 create mode 100755 src/mod/codecs/mod_openh264/test/data/case2.packet3.264
 create mode 100755 src/mod/codecs/mod_openh264/test/data/case2.packet4.264
 create mode 100644 src/mod/codecs/mod_openh264/test/test_mod_openh264.cpp

diff --git a/src/mod/codecs/mod_openh264/Makefile.am b/src/mod/codecs/mod_openh264/Makefile.am
index c541e9563f..c9f6c743d7 100644
--- a/src/mod/codecs/mod_openh264/Makefile.am
+++ b/src/mod/codecs/mod_openh264/Makefile.am
@@ -8,3 +8,16 @@ mod_openh264_la_SOURCES  = mod_openh264.cpp
 mod_openh264_la_CXXFLAGS   = $(AM_CXXFLAGS) -I$(OPENH264_DIR)/include/wels
 mod_openh264_la_LIBADD   = $(switch_builddir)/libfreeswitch.la
 mod_openh264_la_LDFLAGS  = -L$(OPENH264_DIR)/lib/ -lopenh264 -avoid-version -module -no-undefined -shared
+
+noinst_LTLIBRARIES = libmodopenh264.la
+
+libmodopenh264_la_SOURCES  = $(mod_openh264_la_SOURCES)
+libmodopenh264_la_CXXFLAGS   = $(AM_CXXFLAGS) -I$(OPENH264_DIR)/include/wels
+
+noinst_PROGRAMS = test/test_mod_openh264
+test_test_mod_openh264_SOURCES = test/test_mod_openh264.cpp
+test_test_mod_openh264_CXXFLAGS = $(AM_CXXFLAGS) -I.
+test_test_mod_openh264_LDFLAGS = -L$(OPENH264_DIR)/lib/ -lopenh264 -avoid-version -module
+test_test_mod_openh264_LDADD = libmodopenh264.la $(switch_builddir)/libfreeswitch.la
+
+TESTS = $(noinst_PROGRAMS)
diff --git a/src/mod/codecs/mod_openh264/mod_openh264.cpp b/src/mod/codecs/mod_openh264/mod_openh264.cpp
index 841e9efcd7..8770a71818 100644
--- a/src/mod/codecs/mod_openh264/mod_openh264.cpp
+++ b/src/mod/codecs/mod_openh264/mod_openh264.cpp
@@ -243,8 +243,8 @@ static switch_size_t buffer_h264_nalu(h264_codec_context_t *context, switch_fram
 		if (start) {
 			//uint8_t nalu_idc = (nalu_hdr & 0x60) >> 5;
 			nalu_type |= (nalu_idc << 5);
-			size = switch_buffer_write(buffer, sync_bytes, sizeof(sync_bytes));
-			size = switch_buffer_write(buffer, &nalu_type, 1);
+			switch_buffer_write(buffer, sync_bytes, sizeof(sync_bytes));
+			switch_buffer_write(buffer, &nalu_type, 1);
 			context->nalu_28_start = 1;
 		}
 
@@ -273,14 +273,14 @@ static switch_size_t buffer_h264_nalu(h264_codec_context_t *context, switch_fram
 
 			if (context->got_sps <= 0 && nalu_type == 7) context->got_sps = 1;
 
-			size += switch_buffer_write(buffer, sync_bytes, sizeof(sync_bytes));
-			size += switch_buffer_write(buffer, (void *)data, nalu_size);
+			switch_buffer_write(buffer, sync_bytes, sizeof(sync_bytes));
+			size = switch_buffer_write(buffer, (void *)data, nalu_size);
 			data += nalu_size;
 			left -= nalu_size;
 			goto again;
 		}
 	} else {
-		size = switch_buffer_write(buffer, sync_bytes, sizeof(sync_bytes));
+		switch_buffer_write(buffer, sync_bytes, sizeof(sync_bytes));
 		size = switch_buffer_write(buffer, frame->data, frame->datalen);
 		context->nalu_28_start = 0;
 	}
diff --git a/src/mod/codecs/mod_openh264/test/conf/freeswitch.xml b/src/mod/codecs/mod_openh264/test/conf/freeswitch.xml
new file mode 100644
index 0000000000..b0ba4da969
--- /dev/null
+++ b/src/mod/codecs/mod_openh264/test/conf/freeswitch.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0"?>
+<document type="freeswitch/xml">
+
+  <section name="configuration" description="Various Configuration">
+    <configuration name="modules.conf" description="Modules">
+      <modules>
+        <load module="mod_console"/>
+      </modules>
+    </configuration>
+
+    <configuration name="console.conf" description="Console Logger">
+      <mappings>
+        <map name="all" value="console,debug,info,notice,warning,err,crit,alert"/>
+      </mappings>
+      <settings>
+        <param name="colorize" value="true"/>
+        <param name="loglevel" value="debug"/>
+      </settings>
+    </configuration>
+
+    <configuration name="timezones.conf" description="Timezones">
+      <timezones>
+          <zone name="GMT" value="GMT0" />
+      </timezones>
+    </configuration>
+
+  </section>
+
+  <section name="dialplan" description="Regex/XML Dialplan">
+    <context name="default">
+      <extension name="sample">
+        <condition>
+          <action application="info"/>
+        </condition>
+      </extension>
+    </context>
+  </section>
+</document>
diff --git a/src/mod/codecs/mod_openh264/test/data/case1.packet1.264 b/src/mod/codecs/mod_openh264/test/data/case1.packet1.264
new file mode 100755
index 0000000000..4e076d8d91
--- /dev/null
+++ b/src/mod/codecs/mod_openh264/test/data/case1.packet1.264
@@ -0,0 +1 @@
+'B��X���0�{�
\ No newline at end of file
diff --git a/src/mod/codecs/mod_openh264/test/data/case1.packet2.264 b/src/mod/codecs/mod_openh264/test/data/case1.packet2.264
new file mode 100755
index 0000000000..d244d3b546
--- /dev/null
+++ b/src/mod/codecs/mod_openh264/test/data/case1.packet2.264
@@ -0,0 +1 @@
+(�	�
\ No newline at end of file
diff --git a/src/mod/codecs/mod_openh264/test/data/case1.packet3.264 b/src/mod/codecs/mod_openh264/test/data/case1.packet3.264
new file mode 100755
index 0000000000000000000000000000000000000000..b17dd27676c96dd72344c46e3736f67a43c50ed7
GIT binary patch
literal 1826
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
Q`Grs)sgTB3V1{;GAQDbx>Hq)$

literal 0
HcmV?d00001

diff --git a/src/mod/codecs/mod_openh264/test/data/case1.packet4.264 b/src/mod/codecs/mod_openh264/test/data/case1.packet4.264
new file mode 100755
index 0000000000000000000000000000000000000000..1b9c51c18507e1ae66ee129b699ea72cc33e74c7
GIT binary patch
literal 2323
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

literal 0
HcmV?d00001

diff --git a/src/mod/codecs/mod_openh264/test/data/case1.packet5.264 b/src/mod/codecs/mod_openh264/test/data/case1.packet5.264
new file mode 100755
index 0000000000000000000000000000000000000000..27264044f63ead3710e5438dd74a37f4027b68fe
GIT binary patch
literal 89
zcmV-f0H*&T;ROR^{~UZzP01a(`uF~em;XfeKVD9fbo|8rEl_OJer|gHd%u4Df78M;
v_kI!mzyJUM0U-uhK|uBI|M&0z|5;Q{{d)hB9m(tcd;j2u?|wHYUaqwyg99<a

literal 0
HcmV?d00001

diff --git a/src/mod/codecs/mod_openh264/test/data/case2.packet1.264 b/src/mod/codecs/mod_openh264/test/data/case2.packet1.264
new file mode 100755
index 0000000000..4e076d8d91
--- /dev/null
+++ b/src/mod/codecs/mod_openh264/test/data/case2.packet1.264
@@ -0,0 +1 @@
+'B��X���0�{�
\ No newline at end of file
diff --git a/src/mod/codecs/mod_openh264/test/data/case2.packet2.264 b/src/mod/codecs/mod_openh264/test/data/case2.packet2.264
new file mode 100755
index 0000000000..d244d3b546
--- /dev/null
+++ b/src/mod/codecs/mod_openh264/test/data/case2.packet2.264
@@ -0,0 +1 @@
+(�	�
\ No newline at end of file
diff --git a/src/mod/codecs/mod_openh264/test/data/case2.packet3.264 b/src/mod/codecs/mod_openh264/test/data/case2.packet3.264
new file mode 100755
index 0000000000000000000000000000000000000000..5157759b7f901fb84183c2953b507b0dba0388d4
GIT binary patch
literal 4156
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
GfB*n1z@T6N

literal 0
HcmV?d00001

diff --git a/src/mod/codecs/mod_openh264/test/data/case2.packet4.264 b/src/mod/codecs/mod_openh264/test/data/case2.packet4.264
new file mode 100755
index 0000000000000000000000000000000000000000..27264044f63ead3710e5438dd74a37f4027b68fe
GIT binary patch
literal 89
zcmV-f0H*&T;ROR^{~UZzP01a(`uF~em;XfeKVD9fbo|8rEl_OJer|gHd%u4Df78M;
v_kI!mzyJUM0U-uhK|uBI|M&0z|5;Q{{d)hB9m(tcd;j2u?|wHYUaqwyg99<a

literal 0
HcmV?d00001

diff --git a/src/mod/codecs/mod_openh264/test/test_mod_openh264.cpp b/src/mod/codecs/mod_openh264/test/test_mod_openh264.cpp
new file mode 100644
index 0000000000..729f77be84
--- /dev/null
+++ b/src/mod/codecs/mod_openh264/test/test_mod_openh264.cpp
@@ -0,0 +1,220 @@
+/*
+ * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ * Copyright (C) 2005-2018, Anthony Minessale II <anthm@freeswitch.org>
+ *
+ * Version: MPL 1.1
+ *
+ * The contents of this file are subject to the Mozilla Public License Version
+ * 1.1 (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ * http://www.mozilla.org/MPL/
+ *
+ * Software distributed under the License is distributed on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
+ * for the specific language governing rights and limitations under the
+ * License.
+ *
+ * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
+ *
+ * The Initial Developer of the Original Code is
+ * Seven Du <dujinfang@gmail.com>
+ * Portions created by the Initial Developer are Copyright (C)
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Pax Cao <yiping.cao@msn.com>
+ *
+ * mod_openh264_test -- mod_openh264 tests
+ *
+ */
+
+#include <test/switch_test.h>
+
+#define 	TEST_SIMU_RTP_MAX_LEN 		4200
+
+/* Add our command line options. */
+static fctcl_init_t my_cl_options[] = {
+	{"--disable-hw",                 /* long_opt */
+	 NULL,                           /* short_opt (optional) */
+	 FCTCL_STORE_TRUE  ,             /* action */
+	 "disable hardware encoder"     /* help */
+	 },
+
+	FCTCL_INIT_NULL /* Sentinel */
+};
+
+FST_CORE_BEGIN("conf")
+{
+	fctcl_install(my_cl_options);
+
+	FST_MODULE_BEGIN(mod_openh264, mod_openh264_test)
+	{
+		FST_SETUP_BEGIN()
+		{
+			fst_requires_module("mod_openh264");
+		}
+		FST_SETUP_END()
+
+		FST_TEST_BEGIN(decoder_testcase)
+		{
+			switch_status_t status;
+			switch_codec_t codec = { 0 };
+			switch_codec_settings_t codec_settings = {{ 0 }};
+			switch_image_t *img;
+			uint8_t buf[TEST_SIMU_RTP_MAX_LEN + 12] = {0};
+			switch_frame_t frame = { 0 };
+			int packets = 0;
+			switch_status_t decode_status;
+			FILE *fp = NULL;
+			long file_size = 0;
+			switch_bool_t		fh_status = SWITCH_FALSE;
+			int   file_count = 1;
+			switch_set_string(codec_settings.video.config_profile_name, "test-decoder-1");
+
+			if (!fctcl_is("--disable-hw")) {
+				codec_settings.video.try_hardware_encoder = 1;
+			}
+
+			status = switch_core_codec_init(&codec,
+							   "H264",
+							   NULL,
+							   NULL,
+							   0,
+							   0,
+							   1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
+							   &codec_settings, fst_pool);
+			fst_check(status == SWITCH_STATUS_SUCCESS);
+			
+			frame.packet = buf;
+			frame.packetlen = TEST_SIMU_RTP_MAX_LEN + 12;
+			frame.data = buf + 12;
+			frame.datalen = TEST_SIMU_RTP_MAX_LEN;
+			frame.payload = 96;
+			frame.m = SWITCH_FALSE;
+			frame.seq = 0;
+			frame.timestamp = 375233;
+			frame.img = (switch_image_t*)NULL;
+			do {
+				switch_size_t len = TEST_SIMU_RTP_MAX_LEN;
+				char  file_name[128] = { 0 };
+				frame.seq++;
+				switch_snprintf(file_name, 128, "./data/case1.packet%d.264", file_count);
+
+				fp = fopen(file_name, "rb");
+				if (!fp) {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
+						 "read video file %s failed \n", file_name);
+					break;
+				}
+				fseek(fp, 0, SEEK_END);
+				file_size = ftell(fp);
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
+						 "file %s length: %ld \n", file_name, file_size);
+				fseek(fp, 0, SEEK_SET);	 
+				
+				frame.datalen = fread(frame.data, sizeof(char), file_size, fp);
+				fst_check(frame.datalen == file_size);
+
+				if (4 == file_count ) {
+					frame.m = SWITCH_TRUE;
+				} 
+				if (5 == file_count) {
+					frame.m = SWITCH_TRUE;
+					frame.timestamp = 380633;
+				}
+				decode_status = switch_core_codec_decode_video(&codec, &frame);
+				fst_check(decode_status == SWITCH_STATUS_SUCCESS || decode_status == SWITCH_STATUS_MORE_DATA);
+				
+				if (frame.img != NULL) {
+					// write down the decoded
+					status = switch_img_write_png(frame.img, (char *)"case1.output.qcif.png");
+					fst_check(status == SWITCH_STATUS_SUCCESS);
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
+						 "write output file done! \n");
+					
+				}
+				fclose(fp);
+				file_count++;
+			} while (decode_status == SWITCH_STATUS_MORE_DATA && file_count < 6);
+			
+			switch_core_codec_destroy(&codec);
+
+			file_count = 1;
+			status = switch_core_codec_init(&codec,
+							   "H264",
+							   NULL,
+							   NULL,
+							   0,
+							   0,
+							   1, SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
+							   &codec_settings, fst_pool);
+			fst_check(status == SWITCH_STATUS_SUCCESS);
+			
+			frame.packet = buf;
+			frame.packetlen = TEST_SIMU_RTP_MAX_LEN + 12;
+			frame.data = buf + 12;
+			frame.datalen = TEST_SIMU_RTP_MAX_LEN;
+			frame.payload = 96;
+			frame.m = SWITCH_FALSE;
+			frame.seq = 0;
+			frame.timestamp = 375233;
+			frame.img = (switch_image_t*)NULL;
+			do {
+				switch_size_t len = TEST_SIMU_RTP_MAX_LEN;
+				char  file_name[128] = { 0 };
+				frame.seq++;
+				switch_snprintf(file_name, 128, "./data/case2.packet%d.264", file_count);
+
+				fp = fopen(file_name, "rb");
+				if (!fp) {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
+						 "read video file %s failed \n", file_name);
+					break;
+				}
+				fseek(fp, 0, SEEK_END);
+				file_size = ftell(fp);
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
+						 "file %s length: %ld \n", file_name, file_size);
+				fseek(fp, 0, SEEK_SET);	 
+				
+				frame.datalen = fread(frame.data, sizeof(char), file_size, fp);
+				fst_check(frame.datalen == file_size);
+
+				if (3 == file_count) {
+					frame.m = SWITCH_TRUE;
+				} 
+				if (4 == file_count) {
+					frame.m = SWITCH_TRUE;
+					frame.timestamp = 380633;
+				} 
+				decode_status = switch_core_codec_decode_video(&codec, &frame);
+				fst_check(decode_status == SWITCH_STATUS_SUCCESS || decode_status == SWITCH_STATUS_MORE_DATA);
+				if (frame.img != NULL) {
+					// write down the decoded
+					status = switch_img_write_png(frame.img, (char *)"case2.output.qcif.png");
+					fst_check(status == SWITCH_STATUS_SUCCESS);
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,
+						 "write output file done! \n");
+					
+				}
+				fclose(fp);
+				file_count++;
+			} while (decode_status == SWITCH_STATUS_MORE_DATA && file_count < 5);
+			
+			switch_core_codec_destroy(&codec);
+
+		}
+		FST_TEST_END()
+
+
+		FST_TEARDOWN_BEGIN()
+		{
+			const char *err = NULL;
+			switch_sleep(1000000);
+			fst_check(switch_loadable_module_unload_module(SWITCH_GLOBAL_dirs.mod_dir, (char *)"mod_openh264", SWITCH_TRUE, &err) == SWITCH_STATUS_SUCCESS);
+		}
+		FST_TEARDOWN_END()
+	}
+	FST_MODULE_END()
+}
+FST_CORE_END()