Просмотр исходного кода

update:amr库的malloc和free映射到luat_heap
add:预留amr编码功能

alienwalker 3 лет назад
Родитель
Сommit
1b6f46e40f

+ 10 - 1
components/multimedia/amr_decode/oscl/oscl_mem.h

@@ -25,12 +25,21 @@ extern "C" {
 
 #include <stdlib.h>
 #include <string.h>
+#ifdef __LUATOS__
+#include "luat_base.h"
+#include "luat_malloc.h"
+#define oscl_malloc luat_heap_malloc
+#define oscl_free luat_heap_free
+#define oscl_memset memset
+#define oscl_memmove memmove
+#define oscl_memcpy memcpy
+#else
 #define oscl_malloc malloc
 #define oscl_free free
 #define oscl_memset memset
 #define oscl_memmove memmove
 #define oscl_memcpy memcpy
-
+#endif
 #ifdef __cplusplus
 }
 #endif

+ 6 - 1
components/multimedia/amr_decode/src/amrnb_wrapper.c

@@ -23,7 +23,12 @@
 #include "interf_dec.h"
 #include "interf_enc.h"
 #include <stdlib.h>
-
+#ifdef __LUATOS__
+#include "luat_base.h"
+#include "luat_malloc.h"
+#define malloc luat_heap_malloc
+#define free luat_heap_free
+#endif
 
 void* Decoder_Interface_init(void) {
 	void* ptr = NULL;

+ 6 - 1
components/multimedia/amr_decode/src/amrwb_wrapper.c

@@ -23,7 +23,12 @@
 #include <pvamrwbdecoder.h>
 #include <pvamrwbdecoder_cnst.h>
 #include <dtx.h>
-
+#ifdef __LUATOS__
+#include "luat_base.h"
+#include "luat_malloc.h"
+#define malloc luat_heap_malloc
+#define free luat_heap_free
+#endif
 /* This is basically a C rewrite of decode_amr_wb.cpp */
 
 struct state {

+ 98 - 3
components/multimedia/luat_lib_multimedia_codec.c

@@ -13,7 +13,10 @@
 #include "luat_zbuff.h"
 #define LUAT_LOG_TAG "codec"
 #include "luat_log.h"
-
+#ifdef LUAT_SUPPORT_AMR
+#include "interf_enc.h"
+#include "interf_dec.h"
+#endif
 
 /**
 创建编解码用的codec
@@ -51,6 +54,22 @@ static int l_codec_create(lua_State *L) {
         	}
 
     	}
+    	else
+    	{
+        	switch (type) {
+#ifdef LUAT_SUPPORT_AMR
+        	case MULTIMEDIA_DATA_TYPE_AMR_NB:
+            	coder->amr_coder = Encoder_Interface_init(0);
+            	if (!coder->amr_coder) {
+            		lua_pushnil(L);
+            		return 1;
+            	}
+            	break;
+#endif
+        	default:
+        		break;
+        	}
+    	}
     	luaL_setmetatable(L, LUAT_M_CODE_TYPE);
     }
     return 1;
@@ -59,7 +78,7 @@ static int l_codec_create(lua_State *L) {
 /**
 decoder从文件中解析出音频信息
 @api codec.info(decoder, file_path)
-@coder 解码用的decoder
+@userdata 解码用的decoder
 @string 文件路径
 @return boolean 是否成功解析
 @return int 音频格式
@@ -190,7 +209,7 @@ static int l_codec_get_audio_info(lua_State *L) {
 /**
 decoder从文件中解析出原始音频数据,比如从MP3文件里解析出PCM数据,这里的文件路径已经在codec.info传入,不需要再次传入
 @api codec.data(decoder, out_buff)
-@coder 解码用的decoder
+@userdata 解码用的decoder
 @zbuff 存放输出数据的zbuff,空间必须不少于16KB
 @return
 @boolean 是否成功解析
@@ -291,6 +310,69 @@ GET_MP3_DATA:
 	return 1;
 }
 
+
+/**
+编码音频数据,由于flash和ram空间一般比较有限,目前只支持amr-nb编码
+@api codec.encode(coder, in_buffer, out_buffer, mode)
+@userdata codec.create创建的编解码用的coder
+@zbuff 输入的数据,zbuff形式,从0到used
+@zbuff 输出的数据,zbuff形式,自动添加到buff的尾部,如果空间大小不足,会自动扩展,但是会额外消耗时间,甚至会失败,所以尽量一开始就给足空间
+@int amr_nb的编码等级 0~7(即 MR475~MR122)值越大消耗的空间越多,音质越高,默认0
+@result boolean,成功返回true,失败返回false
+@usage
+codec.encode(amr_coder, inbuf, outbuf, codec.AMR_)
+ */
+static int l_codec_encode_audio_data(lua_State *L) {
+#ifdef LUAT_SUPPORT_AMR
+	luat_multimedia_codec_t *coder = (luat_multimedia_codec_t *)luaL_checkudata(L, 1, LUAT_M_CODE_TYPE);
+	luat_zbuff_t *in_buff = ((luat_zbuff_t *)luaL_checkudata(L, 2, LUAT_ZBUFF_TYPE));
+	luat_zbuff_t *out_buff = ((luat_zbuff_t *)luaL_checkudata(L, 3, LUAT_ZBUFF_TYPE));
+	int mode = luaL_optinteger(L, 4, MR475);
+	if (!coder || !in_buff || !out_buff || (coder->type != MULTIMEDIA_DATA_TYPE_AMR_NB) || coder->is_decoder)
+	{
+		lua_pushboolean(L, 0);
+		return 1;
+	}
+	if (mode > MR122)
+	{
+		mode = MR475;
+	}
+	uint8_t outbuf[64];
+	int16_t *pcm = (int16_t *)in_buff->addr;
+	uint32_t total_len = in_buff->used >> 1;
+	uint32_t done_len = 0;
+	int out_len;
+	while ((total_len - done_len) >= 160)
+	{
+		out_len = Encoder_Interface_Encode(coder->amr_coder, mode, &pcm[done_len], outbuf, 0);
+		if (out_len <= 0)
+		{
+			LLOGE("encode error in %d,result %d", done_len, out_len);
+		}
+		else
+		{
+			if ((out_buff->len - out_buff->used) < out_len)
+			{
+				if (__zbuff_resize(out_buff, out_buff->len * 2 + out_len))
+				{
+					lua_pushboolean(L, 0);
+					return 1;
+				}
+			}
+			memcpy(out_buff->addr + out_buff->used, outbuf, out_len);
+			out_buff->used += out_len;
+		}
+		done_len += 160;
+	}
+	lua_pushboolean(L, 1);
+	return 1;
+#else
+	lua_pushboolean(L, 0);
+	return 1;
+#endif
+}
+
+
 static int l_codec_gc(lua_State *L)
 {
 	luat_multimedia_codec_t *coder = ((luat_multimedia_codec_t *)luaL_checkudata(L, 1, LUAT_M_CODE_TYPE));
@@ -310,6 +392,14 @@ static int l_codec_gc(lua_State *L)
 			coder->mp3_decoder = NULL;
 		}
 		break;
+#ifdef LUAT_SUPPORT_AMR
+	case MULTIMEDIA_DATA_TYPE_AMR_NB:
+		if (!coder->is_decoder && coder->amr_coder) {
+			Encoder_Interface_exit(coder->amr_coder);
+			coder->amr_coder = NULL;
+		}
+		break;
+#endif
 	}
     return 0;
 }
@@ -331,11 +421,16 @@ static const rotable_Reg_t reg_codec[] =
 
     { "info" , 		 ROREG_FUNC(l_codec_get_audio_info)},
     { "data",  		 ROREG_FUNC(l_codec_get_audio_data)},
+	{ "encode",  		 ROREG_FUNC(l_codec_encode_audio_data)},
     { "release",         ROREG_FUNC(l_codec_release)},
     //@const MP3 number MP3格式
 	{ "MP3",             ROREG_INT(MULTIMEDIA_DATA_TYPE_MP3)},
     //@const WAV number WAV格式
 	{ "WAV",             ROREG_INT(MULTIMEDIA_DATA_TYPE_WAV)},
+	//@const AMR number AMR-NB格式,一般意义上的AMR
+	{ "AMR",             ROREG_INT(MULTIMEDIA_DATA_TYPE_AMR_NB)},
+	//@const AMR_WB number AMR-WB格式
+	{ "AMR_WB",             ROREG_INT(MULTIMEDIA_DATA_TYPE_AMR_WB)},
 	{ NULL,              {}}
 };
 

+ 1 - 1
components/multimedia/luat_multimedia.h

@@ -38,7 +38,6 @@ int l_multimedia_raw_handler(lua_State *L, void* ptr);
 #include <stddef.h>
 #include "mp3_decode/minimp3.h"
 
-
 typedef struct
 {
 
@@ -46,6 +45,7 @@ typedef struct
 	{
 		mp3dec_t *mp3_decoder;
 		uint32_t read_len;
+		void *amr_coder;
 	};
 	FILE* fd;
 	luat_zbuff_t buff;