alienwalker 1 месяц назад
Родитель
Сommit
108d291734
1 измененных файлов с 143 добавлено и 10 удалено
  1. 143 10
      components/multimedia/luat_lib_multimedia_codec.c

+ 143 - 10
components/multimedia/luat_lib_multimedia_codec.c

@@ -18,6 +18,10 @@
 #ifdef LUAT_SUPPORT_AMR
 #include "interf_enc.h"
 #include "interf_dec.h"
+#include "dec_if.h"
+static const uint8_t  amr_nb_byte_len[16] = {12, 13, 15, 17, 19, 20, 26, 31, 5, 0, 0, 0, 0, 0, 0, 0};
+static const uint8_t  amr_wb_byte_len[16] = {17, 23, 32, 36, 40, 46, 50, 58, 60, 5,0, 0, 0, 0, 0, 0};
+typedef void (*amr_decode_fun_t)(void* state, const unsigned char* in, short* out, int bfi);
 #endif
 
 #ifdef LUAT_USE_AUDIO_G711
@@ -39,6 +43,12 @@
 @int 编码等级,部分bsp有内部编解码器,可能需要提前输入编解码等级,不知道的就填7
 @return userdata 成功返回一个数据结构,否则返回nil
 @usage
+-- 目前支持:
+-- codec.MP3 解码
+-- codec.AMR 编码+解码
+-- codec.AMR_WB 编码(部分BSP支持,例如Air780EHM,Air8000)+解码
+-- codec.WAV WAV本身就是PCM数据,无需编解码
+-- codec.ULAW codec.ALAW 编码+解码
 -- 创建解码器
 local decoder = codec.create(codec.MP3)--创建一个mp3的decoder
 -- 创建编码器
@@ -86,6 +96,22 @@ static int l_codec_create(lua_State *L) {
             		return 1;
             	}
             	break;
+#ifdef LUAT_SUPPORT_AMR
+        	case LUAT_MULTIMEDIA_DATA_TYPE_AMR_NB:
+        		coder->amr_coder = Decoder_Interface_init();
+            	if (!coder->amr_coder) {
+            		lua_pushnil(L);
+            		return 1;
+            	}
+         		break;
+         	case LUAT_MULTIMEDIA_DATA_TYPE_AMR_WB:
+        		coder->amr_coder = D_IF_init();
+            	if (!coder->amr_coder) {
+            		lua_pushnil(L);
+            		return 1;
+            	}
+             	break;
+#endif
 #ifdef LUAT_USE_AUDIO_G711
          	case LUAT_MULTIMEDIA_DATA_TYPE_ULAW:
          	case LUAT_MULTIMEDIA_DATA_TYPE_ALAW:
@@ -257,6 +283,46 @@ static int l_codec_get_audio_info(lua_State *L) {
 				LLOGD("head error");
 			}
 			break;
+#ifdef LUAT_SUPPORT_AMR
+		case LUAT_MULTIMEDIA_DATA_TYPE_AMR_NB:
+			luat_fs_fread(temp, 6, 1, fd);
+			if (!memcmp(temp, "#!AMR\n", 6))
+			{
+				coder->buff.addr = luat_heap_malloc(320);
+				if (coder->buff.addr)
+				{
+					num_channels = 1;
+					sample_rate = 8000;
+					audio_format = LUAT_MULTIMEDIA_DATA_TYPE_PCM;
+					result = 1;
+				}
+
+			}
+			else
+			{
+				result = 0;
+			}
+			break;
+		case LUAT_MULTIMEDIA_DATA_TYPE_AMR_WB:
+			luat_fs_fread(temp, 9, 1, fd);
+			if (!memcmp(temp, "#!AMR-WB\n", 9))
+			{
+				coder->buff.addr = luat_heap_malloc(640);
+				if (coder->buff.addr)
+				{
+					num_channels = 1;
+					sample_rate = 16000;
+					audio_format = LUAT_MULTIMEDIA_DATA_TYPE_PCM;
+					result = 1;
+				}
+
+			}
+			else
+			{
+				result = 0;
+			}
+			break;
+#endif
 #ifdef LUAT_USE_AUDIO_G711
 		case LUAT_MULTIMEDIA_DATA_TYPE_ULAW:
 		case LUAT_MULTIMEDIA_DATA_TYPE_ALAW:
@@ -300,13 +366,20 @@ decoder从文件中解析出原始音频数据,比如从MP3文件里解析出P
 @usage
 -- 大内存设备
 local buff = zbuff.create(16*1024)
-local result = codec.data(coder, buff)
+local result = codec.data(coder, buff, 8192)
 -- 小内存设备
 local buff = zbuff.create(8*1024)
 local result = codec.data(coder, buff, 4096)
  */
 static int l_codec_get_audio_data(lua_State *L) {
 	luat_multimedia_codec_t *coder = (luat_multimedia_codec_t *)luaL_checkudata(L, 1, LUAT_M_CODE_TYPE);
+#ifdef LUAT_SUPPORT_AMR
+	amr_decode_fun_t decode_if;
+	uint32_t frame_len;
+	uint8_t *size_table;
+	uint8_t size;
+	uint8_t temp[64];
+#endif
 	uint32_t pos = 0;
 	int read_len;
 	int result = 0;
@@ -400,6 +473,47 @@ GET_MP3_DATA:
 			}
 
 			break;
+#ifdef LUAT_SUPPORT_AMR
+        	case LUAT_MULTIMEDIA_DATA_TYPE_AMR_NB:
+         	case LUAT_MULTIMEDIA_DATA_TYPE_AMR_WB:
+         		if (coder->type == LUAT_MULTIMEDIA_DATA_TYPE_AMR_NB)
+         		{
+         			frame_len = 320;
+         			size_table = amr_nb_byte_len;
+         			decode_if = Decoder_Interface_Decode;
+         		}
+         		else
+         		{
+         			frame_len = 640;
+         			size_table = amr_wb_byte_len;
+         			decode_if = D_IF_decode;
+         		}
+
+         		while ((out_buff->used < mini_output) && is_not_end && ((out_buff->len - out_buff->used) >= frame_len))
+				{
+         			read_len = luat_fs_fread(temp, 1, 1, coder->fd);
+    				if (read_len <= 0)
+    				{
+    					is_not_end = 0;
+    					break;
+    				}
+    				size = size_table[(temp[0] >> 3) & 0x0f];
+    				if (size > 0)
+					{
+						read_len = luat_fs_fread(temp + 1, 1, size, coder->fd);
+						if (read_len <= 0)
+						{
+	    					is_not_end = 0;
+	    					break;
+						}
+					}
+    				decode_if(coder->amr_coder, temp, coder->buff.addr, 0);
+    				memcpy(out_buff->addr + out_buff->used, coder->buff.addr, frame_len);
+    				out_buff->used += frame_len;
+				}
+         		result = 1;
+             	break;
+#endif
 #ifdef LUAT_USE_AUDIO_G711
 		case LUAT_MULTIMEDIA_DATA_TYPE_ULAW:
 		case LUAT_MULTIMEDIA_DATA_TYPE_ALAW:
@@ -446,7 +560,7 @@ GET_MP3_DATA:
 
 
 /**
-编码音频数据,由于flash和ram空间一般比较有限,除了部分bsp有内部amr编码功能,目前只支持amr-nb编码
+编码音频数据,由于flash和ram空间一般比较有限,除了部分bsp有内部amr编码功能以外只支持amr-nb编码
 @api codec.encode(coder, in_buffer, out_buffer, mode)
 @userdata codec.create创建的编解码用的coder
 @zbuff 输入的数据,zbuff形式,从0到used
@@ -644,23 +758,42 @@ static int l_codec_gc(lua_State *L)
 		}
 		break;
 #ifdef LUAT_SUPPORT_AMR
-#ifdef LUAT_USE_INTER_AMR
 	case LUAT_MULTIMEDIA_DATA_TYPE_AMR_NB:
-	case LUAT_MULTIMEDIA_DATA_TYPE_AMR_WB:
-		if (!coder->is_decoder && coder->amr_coder) {
-			luat_audio_inter_amr_coder_deinit(coder->amr_coder);
+		if (coder->amr_coder)
+		{
+			if (!coder->is_decoder)
+			{
+#ifdef LUAT_USE_INTER_AMR
+				luat_audio_inter_amr_coder_deinit(coder->amr_coder);
+#else
+				Encoder_Interface_exit(coder->amr_coder);
+#endif
+			}
+			else
+			{
+				Decoder_Interface_exit(coder->amr_coder);
+			}
 			coder->amr_coder = NULL;
 		}
 		break;
+	case LUAT_MULTIMEDIA_DATA_TYPE_AMR_WB:
+		if (coder->amr_coder)
+		{
+			if (!coder->is_decoder)
+			{
+#ifdef LUAT_USE_INTER_AMR
+				luat_audio_inter_amr_coder_deinit(coder->amr_coder);
 #else
-	case LUAT_MULTIMEDIA_DATA_TYPE_AMR_NB:
-		if (!coder->is_decoder && coder->amr_coder) {
-			Encoder_Interface_exit(coder->amr_coder);
+#endif
+			}
+			else
+			{
+				D_IF_exit(coder->amr_coder);
+			}
 			coder->amr_coder = NULL;
 		}
 		break;
 #endif
-#endif
 #ifdef LUAT_USE_AUDIO_G711
  	case LUAT_MULTIMEDIA_DATA_TYPE_ULAW:
  	case LUAT_MULTIMEDIA_DATA_TYPE_ALAW: