Example #1
0
static uint8_t
fatfs_dir_buf_add(FATFS_INFO * fatfs, TSK_INUM_T par_inum,
    TSK_INUM_T dir_inum)
{
    size_t q;

    for (q = 0; q < fatfs->dir_buf_next; q++) {
        if (fatfs->dir_buf[q] == dir_inum) {
            return 0;
        }
    }


    // make sure we have room
    if (fatfs->dir_buf_next == fatfs->dir_buf_size) {
        fatfs->dir_buf_size += 256;
        if ((fatfs->dir_buf =
                (TSK_INUM_T *) tsk_realloc(fatfs->dir_buf,
                    fatfs->dir_buf_size * sizeof(TSK_INUM_T))) == NULL) {
            return 1;
        }
        if ((fatfs->par_buf =
                (TSK_INUM_T *) tsk_realloc(fatfs->par_buf,
                    fatfs->dir_buf_size * sizeof(TSK_INUM_T))) == NULL) {
            return 1;
        }
    }

    //add them
    fatfs->dir_buf[fatfs->dir_buf_next] = dir_inum;
    fatfs->par_buf[fatfs->dir_buf_next] = par_inum;
    fatfs->dir_buf_next++;
    return 0;
}
Example #2
0
/**@ingroup tsk_buffer_group
* Appends new data to the buffer.
* @param self The buffer to append to. The buffer should be created using @ref tsk_buffer_create or @ref tsk_buffer_create_null.
* @param format A string with embedded tag to be substituted.
* @param ... List of parameters.
* @retval Zero if succeed and non-zero error code otherwise.
* @sa @ref tsk_buffer_append.
*
* @code
* tsk_buffer_t* buffer = tsk_buffer_create_null();
* tsk_buffer_append_2(buffer, "str1=%s, c1=%c and val1=%x", "str1", 'c', 0x2554);
* printf(TSK_BUFFER_TO_STRING(buffer));
* TSK_OBJECT_SAFE_FREE(buffer);
* @endcode
*/
int tsk_buffer_append_2(tsk_buffer_t* self, const char* format, ...)
{
	/*
	 * I suppose that sizeof(char) = 1-byte
	 */
	int len = 0;
	va_list ap;
	char *buffer;
	tsk_size_t oldsize;
    va_list ap2;

	if(!self){
		return -1;
	}

	oldsize = self->size;
	buffer = (char*)TSK_BUFFER_DATA(self);
	
	/* initialize variable arguments (needed for 64bit platforms where vsnprintf will change the va_list) */
	va_start(ap, format);
	va_start(ap2, format);
	
	/* compute destination len for windows mobile
	*/
#if defined(_WIN32_WCE)
	{
		int n;
		len = (tsk_strlen(format)*2);
		buffer = (char*)tsk_realloc(buffer, (oldsize+len));
		for(;;){
			if( (n = vsnprintf((char*)(buffer + oldsize), len, format, ap)) >= 0 && (n<=len) ){
				len = n;
				break;
			}
			else{
				len += 10;
				buffer = (char*)tsk_realloc(buffer, (oldsize+len));
			}
		}
	}
#else
    len = vsnprintf(tsk_null, 0, format, ap);
    buffer = (char*)tsk_realloc(buffer, oldsize+len+1);
    vsnprintf((buffer + oldsize), len
#if !defined(_MSC_VER) || defined(__GNUC__)
		+1
#endif
		, format, ap2);
#endif
	
	/* reset variable arguments */
	va_end(ap);
	va_end(ap2);

	self->data = buffer;
	self->size = (oldsize+len);
	
	return 0;
}
Example #3
0
/** \internal
 * Copy the contents of a TSK_FS_NAME structure to another
 * structure. 
 * @param a_fs_name_to Destination structure to copy to
 * @param a_fs_name_from Source structure to copy from
 * @returns 1 on error
 */
uint8_t
tsk_fs_name_copy(TSK_FS_NAME * a_fs_name_to,
    const TSK_FS_NAME * a_fs_name_from)
{
    if ((a_fs_name_to == NULL) || (a_fs_name_from == NULL))
        return 1;

    /* If the source has a full name,  copy it */
    if (a_fs_name_from->name) {
        // make sure there is enough space
        if (strlen(a_fs_name_from->name) >= a_fs_name_to->name_size) {
            a_fs_name_to->name_size = strlen(a_fs_name_from->name) + 16;
            a_fs_name_to->name =
                (char *) tsk_realloc(a_fs_name_to->name,
                a_fs_name_to->name_size);
            if (a_fs_name_to->name == NULL)
                return 1;
        }
        strncpy(a_fs_name_to->name, a_fs_name_from->name,
            a_fs_name_to->name_size);
    }
    else {
        if (a_fs_name_to->name_size > 0)
            a_fs_name_to->name[0] = '\0';
        else
            a_fs_name_to->name = NULL;
    }

    // copy the short name, if one exists
    if (a_fs_name_from->shrt_name) {
        if (strlen(a_fs_name_from->shrt_name) >=
            a_fs_name_to->shrt_name_size) {
            a_fs_name_to->shrt_name_size =
                strlen(a_fs_name_from->shrt_name) + 16;
            a_fs_name_to->shrt_name =
                (char *) tsk_realloc(a_fs_name_to->shrt_name,
                a_fs_name_to->shrt_name_size);
            if (a_fs_name_to->shrt_name == NULL)
                return 1;
        }
        strncpy(a_fs_name_to->shrt_name, a_fs_name_from->shrt_name,
            a_fs_name_to->shrt_name_size);
    }
    else {
        if (a_fs_name_to->shrt_name_size > 0)
            a_fs_name_to->shrt_name[0] = '\0';
        else
            a_fs_name_to->shrt_name = NULL;
    }

    a_fs_name_to->meta_addr = a_fs_name_from->meta_addr;
    a_fs_name_to->meta_seq = a_fs_name_from->meta_seq;
    a_fs_name_to->par_addr = a_fs_name_from->par_addr;
    a_fs_name_to->type = a_fs_name_from->type;
    a_fs_name_to->flags = a_fs_name_from->flags;

    return 0;
}
Example #4
0
static tsk_size_t tdav_codec_ilbc_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
{	
	tdav_codec_ilbc_t* ilbc = (tdav_codec_ilbc_t*)self;
	int k;
	
	if(!self || !in_data || !in_size || !out_data){
		TSK_DEBUG_ERROR("Invalid parameter");
		return 0;
	}
	
   /* convert signal to float */
	for(k=0; k<ilbc->encoder.blockl; k++){
       ilbc->encblock[k] = (float)((short*)in_data)[k];
	}
	
	/* allocate new buffer if needed */
	if((int)*out_max_size <ilbc->encoder.no_of_bytes){
		if(!(*out_data = tsk_realloc(*out_data, ilbc->encoder.no_of_bytes))){
			TSK_DEBUG_ERROR("Failed to allocate new buffer");
			*out_max_size = 0;
			return 0;
		}
		*out_max_size = ilbc->encoder.no_of_bytes;
	}
	
	/* do the actual encoding */
    iLBC_encode(*out_data, ilbc->encblock, &ilbc->encoder);
	
	return ilbc->encoder.no_of_bytes;
}
Example #5
0
tsk_size_t tdav_codec_speex_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
{	
	tdav_codec_speex_t* speex = (tdav_codec_speex_t*)self;
	tsk_size_t outsize = 0;
	
	if(!self || !in_data || !in_size || !out_data){
		TSK_DEBUG_ERROR("Invalid parameter");
		return 0;
	}
	
	speex_bits_reset(&speex->encoder.bits);
	speex_encode_int(speex->encoder.state, (spx_int16_t*)in_data, &speex->encoder.bits);

	if(*out_max_size <speex->encoder.size){
		if((*out_data = tsk_realloc(*out_data, speex->encoder.size))){
			*out_max_size = speex->encoder.size;
		}
		else{
			*out_max_size = 0;
			return 0;
		}
	}
	
	outsize = speex_bits_write(&speex->encoder.bits, *out_data, speex->encoder.size/2);

   return outsize;
}
Example #6
0
tsk_size_t tdav_codec_gsm_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
{
    tsk_size_t out_size;
    tdav_codec_gsm_t* gsm = (tdav_codec_gsm_t*)self;

    if(!self || !in_data || !in_size || !out_data) {
        TSK_DEBUG_ERROR("Invalid parameter");
        return 0;
    }

    out_size = ((in_size / (TMEDIA_CODEC_PCM_FRAME_SIZE(self) * sizeof(short))) * TDAV_GSM_FRAME_SIZE);

    /* allocate new buffer if needed */
    if(*out_max_size <out_size) {
        if(!(*out_data = tsk_realloc(*out_data, out_size))) {
            TSK_DEBUG_ERROR("Failed to allocate new buffer");
            *out_max_size = 0;
            return 0;
        }
        *out_max_size = out_size;
    }

    gsm_encode(gsm->encoder, (gsm_signal*)in_data, (gsm_byte*)*out_data);

    return out_size;
}
Example #7
0
/**@ingroup tsk_buffer_group
* Appends data to the buffer.
* @param self The buffer to append to. The buffer should be created using @ref tsk_buffer_create or @ref tsk_buffer_create_null.
* @param data The data to append to the buffer.
* @param size The size of the @a data to append.
* @retval Zero if succeed and non-zero error code otherwise.
* @sa @ref tsk_buffer_append_2.
*
* @code
* tsk_buffer_t* buffer = tsk_buffer_create_null();
* tsk_buffer_append(buffer, "doubango", tsk_strlen("doubango"));
* printf(TSK_BUFFER_TO_STRING(buffer));
* TSK_OBJECT_SAFE_FREE(buffer);
* @endcode
*/
int tsk_buffer_append(tsk_buffer_t* self, const void* data, tsk_size_t size)
{
	if(self && size){
		tsk_size_t oldsize = self->size;
		tsk_size_t newsize = oldsize + size;
		
		if(oldsize){
			self->data = tsk_realloc(self->data, newsize);
		}
		else{
			self->data = tsk_calloc(size, sizeof(uint8_t));
		}

		if(self->data){
			if(data){
				memcpy((void*)(TSK_BUFFER_TO_U8(self) + oldsize), data, size);
			}
			self->size = newsize;
			return 0;
		}
	}
	else{
		TSK_DEBUG_ERROR("Invalid parameter");
	}
	return -1;
}
Example #8
0
static tsk_size_t tdav_codec_g729ab_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
{	
	tsk_size_t ex_size, out_size = 0;
	tdav_codec_g729ab_t* g729a = (tdav_codec_g729ab_t*)self;
	int i, frame_count = (in_size / 160);
	

	if(!self || !in_data || !in_size || !out_data || (in_size % 160)){
		TSK_DEBUG_ERROR("Invalid parameter");
		return 0;
	}
	
	ex_size = (frame_count * 10);

	// allocate new buffer if needed
	if(*out_max_size <ex_size){
		if(!(*out_data = tsk_realloc(*out_data, ex_size))){
			TSK_DEBUG_ERROR("Failed to allocate new buffer");
			*out_max_size = 0;
			return 0;
		}
		*out_max_size = ex_size;
	}

	for(i=0; i<frame_count; i++){
		extern int16_t *new_speech;
		
		if(g729a->encoder.frame == 32767){
			g729a->encoder.frame = 256;
		}
		else{
			g729a->encoder.frame++;
		}
		
		memcpy(new_speech, &((uint8_t*)in_data)[i*L_FRAME*sizeof(int16_t)], sizeof(int16_t)*L_FRAME);
		
		Pre_Process(new_speech, L_FRAME);
		Coder_ld8a(g729a->encoder.prm, g729a->encoder.frame, g729a->encoder.vad_enable);
		prm2bits_ld8k(g729a->encoder.prm, g729a->encoder.serial);
		
		if(g729a->encoder.serial[1] == RATE_8000){
			pack_G729(&g729a->encoder.serial[2], &((uint8_t*)(*out_data))[out_size]);
			out_size += 10;
		}
		else if(g729a->encoder.serial[1] == RATE_SID_OCTET){
			pack_SID(&g729a->encoder.serial[2], &((uint8_t*)(*out_data))[out_size]);
			out_size += 2;
		}
		else{ // RATE_0
			//TSK_DEBUG_INFO("G729_RATE_0 - Not transmitted");
            if (!g729a->encoder.vad_enable) {
                // silence
                memset(&((uint8_t*)(*out_data))[out_size], 0, 10);
                out_size += 10;
            }
		}
	}

	return out_size;
}
Example #9
0
tsk_size_t tdav_codec_gsm_decode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size, const tsk_object_t* proto_hdr)
{
	tsk_size_t out_size;
	int ret;
	tdav_codec_gsm_t* gsm = (tdav_codec_gsm_t*)self;

	if(!self || !in_data || !in_size || !out_data || (in_size % TDAV_GSM_FRAME_SIZE)){
		TSK_DEBUG_ERROR("Invalid parameter");
		return 0;
	}
	
	out_size = (in_size / TDAV_GSM_FRAME_SIZE) * (TMEDIA_CODEC_PCM_FRAME_SIZE_AUDIO_DECODING(self) * sizeof(short));

	/* allocate new buffer if needed */
	if(*out_max_size <out_size){
		if(!(*out_data = tsk_realloc(*out_data, out_size))){
			TSK_DEBUG_ERROR("Failed to allocate new buffer");
			*out_max_size = 0;
			return 0;
		}
		*out_max_size = out_size;
	}

	ret = gsm_decode(gsm->decoder, (gsm_byte*)in_data, (gsm_signal*)*out_data);

	return out_size;
}
Example #10
0
/** \internal
* Make the buffer in the FS_DIR structure larger.
*
* @param a_fs_dir Structure to enhance
* @param a_cnt target number of FS_DENT entries to fit in
* @returns 1 on error and 0 on success
*/
uint8_t
tsk_fs_dir_realloc(TSK_FS_DIR * a_fs_dir, size_t a_cnt)
{
    size_t prev_cnt, i;
    if ((a_fs_dir == NULL) || (a_fs_dir->tag != TSK_FS_DIR_TAG))
        return 1;

    if (a_fs_dir->names_alloc >= a_cnt)
        return 0;
    prev_cnt = a_fs_dir->names_alloc;

    a_fs_dir->names_alloc = a_cnt;
    if ((a_fs_dir->names =
            (TSK_FS_NAME *) tsk_realloc((void *) a_fs_dir->names,
                sizeof(TSK_FS_NAME) * a_fs_dir->names_alloc)) == NULL) {
        return 1;
    }

    memset(&a_fs_dir->names[prev_cnt], 0,
        (a_cnt - prev_cnt) * sizeof(TSK_FS_NAME));
    for (i = prev_cnt; i < a_cnt; i++) {
        a_fs_dir->names[i].tag = TSK_FS_NAME_TAG;
    }
    return 0;
}
Example #11
0
/** \internal
 * Extend the number of addresses in the map buffer.
 * @param map map entry to extend
 * @returns 1 on error and 0 otherwise
 */
static uint8_t
ntfs_orphan_map_extend(NTFS_PAR_MAP * map)
{
    map->alloc_cnt += 8;
    if ((map->addrs =
            (TSK_INUM_T *) tsk_realloc(map->addrs,
                sizeof(TSK_INUM_T) * map->alloc_cnt)) == NULL)
        return 1;
    return 0;
}
Example #12
0
/**
 * \internal
 * Resize an existing TSK_FS_META structure -- changes the number of
 * block pointers. 
 *
 * @param fs_meta Structure to resize
 * @param a_buf_len Size of file system specific data that is used to store references to file content
 * @return NULL on error 
 */
TSK_FS_META *
tsk_fs_meta_realloc(TSK_FS_META * a_fs_meta, size_t a_buf_len)
{
    if (a_fs_meta->content_len != a_buf_len) {
        a_fs_meta->content_len = a_buf_len;
        a_fs_meta->content_ptr =
            tsk_realloc((char *) a_fs_meta->content_ptr, a_buf_len);
        if (a_fs_meta->content_ptr == NULL) {
            return NULL;
        }
    }
    return (a_fs_meta);
}
Example #13
0
/**
 * \ingroup baselib
 * Push a value to the top of TSK_STACK.
 * @param a_tsk_stack Pointer to stack to push onto
 * @param a_val Value to push on
 * @returns 1 on error 
 */
uint8_t
tsk_stack_push(TSK_STACK * a_tsk_stack, uint64_t a_val)
{
    if (a_tsk_stack->top == a_tsk_stack->len) {
        a_tsk_stack->len += 64;
        if ((a_tsk_stack->vals =
                (uint64_t *) tsk_realloc((char *) a_tsk_stack->vals,
                    a_tsk_stack->len * sizeof(uint64_t))) == NULL) {
            return 1;
        }
    }
    a_tsk_stack->vals[a_tsk_stack->top++] = a_val;
    return 0;
}
Example #14
0
/**@ingroup tsk_string_group
*/
int tsk_sprintf_2(char** str, const char* format, va_list* ap)
{
	int len = 0;
    va_list ap2;

	/* free previous value */
	if(*str){
		tsk_free((void**)str);
	}
	
	/* needed for 64bit platforms where vsnprintf will change the va_list */
    tsk_va_copy(ap2, *ap);
    
	/* compute destination len for windows mobile
	*/
#if defined(_WIN32_WCE)
	{
		int n;
		len = (tsk_strlen(format)*2);
		*str = (char*)tsk_calloc(1, len+1);
		for(;;){
			if( (n = vsnprintf(*str, len, format, *ap)) >= 0 && (n<len) ){
				len = n;
				goto done;
			}
			else{
				len += 10;
				*str = tsk_realloc(*str, len+1);
			}
		}
done:
		(*str)[len] = '\0';
	}
#else
    len = vsnprintf(0, 0, format, *ap);
    *str = (char*)tsk_calloc(1, len+1);
    vsnprintf(*str, len
#if !defined(_MSC_VER) || defined(__GNUC__)
		+1
#endif
		, format, ap2);
#endif
	
    va_end(ap2);
    
	return len;
}
Example #15
0
static tsk_size_t tdav_codec_opus_decode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size, const tsk_object_t* proto_hdr)
{
    tdav_codec_opus_t* opus = (tdav_codec_opus_t*)self;
    int frame_size;
    const trtp_rtp_header_t* rtp_hdr = proto_hdr;

    if(!self || !in_data || !in_size || !out_data) {
        TSK_DEBUG_ERROR("Invalid parameter");
        return 0;
    }

    if(!opus->decoder.inst) {
        TSK_DEBUG_ERROR("Decoder not ready");
        return 0;
    }

    /* Packet loss? */
    if(opus->decoder.last_seq != (rtp_hdr->seq_num - 1) && opus->decoder.last_seq) {
        if(opus->decoder.last_seq == rtp_hdr->seq_num) {
            // Could happen on some stupid emulators
            //TSK_DEBUG_INFO("Packet duplicated, seq_num=%d", rtp_hdr->seq_num);
            return 0;
        }
        TSK_DEBUG_INFO("[Opus] Packet loss, seq_num=%d", rtp_hdr->seq_num);
        opus_decode(opus->decoder.inst, tsk_null/*packet loss*/, (opus_int32)0, opus->decoder.buff, TDAV_OPUS_MAX_FRAME_SIZE_IN_SAMPLES, opus->decoder.fec_enabled);
    }
    opus->decoder.last_seq = rtp_hdr->seq_num;

    frame_size = opus_decode(opus->decoder.inst, (const unsigned char *)in_data, (opus_int32)in_size, opus->decoder.buff, TDAV_OPUS_MAX_FRAME_SIZE_IN_SAMPLES, opus->decoder.fec_enabled ? 1 : 0);
    if(frame_size > 0) {
        tsk_size_t frame_size_inbytes = (frame_size << 1);
        if(*out_max_size < frame_size_inbytes) {
            if(!(*out_data = tsk_realloc(*out_data, frame_size_inbytes))) {
                TSK_DEBUG_ERROR("Failed to allocate new buffer");
                *out_max_size = 0;
                return 0;
            }
            *out_max_size = frame_size_inbytes;
        }
        memcpy(*out_data, opus->decoder.buff, frame_size_inbytes);
        return frame_size_inbytes;
    }
    else {
        return 0;
    }
}
Example #16
0
/**@ingroup tsk_string_group
*/
void tsk_strncat(char** destination, const char* source, tsk_size_t n)
{
	tsk_size_t index = 0;
	tsk_size_t tsk_size_to_cat = (n > tsk_strlen(source)) ? tsk_strlen(source) : n;

	if(!source || !n){
		return;
	}

	if(!*destination){
		*destination = (char*)tsk_malloc(tsk_size_to_cat+1);
		strncpy(*destination, source, tsk_size_to_cat+1);
	}else{
		index = tsk_strlen(*destination);
		*destination = tsk_realloc(*destination, index + tsk_size_to_cat+1);
		strncpy(((*destination)+index), source, tsk_size_to_cat+1);
	}
	(*destination)[index + tsk_size_to_cat] = '\0';
}
Example #17
0
/**
 * \internal
 * returns 1 on error
 */
uint8_t
tsk_fs_name_realloc(TSK_FS_NAME * fs_name, size_t namelen)
{
    if ((fs_name == NULL) || (fs_name->tag != TSK_FS_NAME_TAG))
        return 1;

    if (fs_name->name_size >= namelen)
        return 0;

    fs_name->name = (char *) tsk_realloc(fs_name->name, namelen + 1);
    if (fs_name->name == NULL) {
        fs_name->name_size = 0;
        return 1;
    }

    fs_name->type = TSK_FS_NAME_TYPE_UNDEF;
    fs_name->name_size = namelen;

    return 0;
}
Example #18
0
/**@ingroup tsk_buffer_group
* Reallocates the buffer.
* @param self The buffer to realloc.
* @param size The new size.
* @retval Zero if succeed and non-zero error code otherwise.
*/
int tsk_buffer_realloc(tsk_buffer_t* self, tsk_size_t size)
{
	if(self)
	{
		if(size == 0){
			return tsk_buffer_cleanup(self);
		}

		if(self->size == 0){ // first time?
			self->data = tsk_calloc(size, sizeof(uint8_t));
		}
		else if(self->size != size){ // only realloc if different sizes
			self->data = tsk_realloc(self->data, size);
		}

		self->size = size;
		return 0;
	}
	return -1;
}
Example #19
0
/**
 * Add a name to an existing FS_DATA structure.  Will reallocate
 * space for the name if needed.
 *
 * @param fs_attr Structure to add name to
 * @param name UTF-8 name to add
 *
 * @return 1 on error and 0 on success
 */
static uint8_t
fs_attr_put_name(TSK_FS_ATTR * fs_attr, const char *name)
{
    if ((name == NULL) || (strlen(name) == 0)) {
        if (fs_attr->name_size > 0) {
            free(fs_attr->name);
            fs_attr->name_size = 0;
        }
        fs_attr->name = NULL;
        return 0;
    }

    if (fs_attr->name_size < (strlen(name) + 1)) {
        fs_attr->name = tsk_realloc(fs_attr->name, strlen(name) + 1);
        if (fs_attr->name == NULL)
            return 1;
        fs_attr->name_size = strlen(name) + 1;
    }
    strncpy(fs_attr->name, name, fs_attr->name_size);
    return 0;
}
Example #20
0
tsk_size_t tdav_codec_speex_decode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size, const tsk_object_t* proto_hdr)
{
	int ret;
	tsk_size_t out_size = 0;
	tdav_codec_speex_t* speex = (tdav_codec_speex_t*)self;

	if(!self || !in_data || !in_size || !out_data){
		TSK_DEBUG_ERROR("Invalid parameter");
		return 0;
	}

	// initializes the bit-stream 
	speex_bits_read_from(&speex->decoder.bits, (char*)in_data, in_size);

	do{
		// performs decode() 
		if((ret = speex_decode_int(speex->decoder.state, &speex->decoder.bits, speex->decoder.buffer))){
			TSK_DEBUG_ERROR("Failed to decode the buffer. retcode=%d", ret);
			break;
		}

		if(*out_max_size <(out_size + speex->decoder.size)){
			if((*out_data = tsk_realloc(*out_data, (out_size + speex->decoder.size)))){
				*out_max_size = (out_size + speex->decoder.size);
			}
			else{
				*out_max_size = 0;
				return 0;
			}
		}

		// copy output buffer 
		memcpy(&((uint8_t*)*out_data)[out_size], speex->decoder.buffer, speex->decoder.size);
		out_size += speex->decoder.size;
	}
	while(speex_bits_remaining(&speex->decoder.bits) >= 5);
	

	return out_size;
}
Example #21
0
/**
 * \internal
 * Copy resident data to an attribute. 
 *
 * @param a_fs_attr Attribute to add data to (cannot be NULL)
 * @param name Name of the attribute to set
 * @param type Type of the attribute to set
 * @param id Id of the attribute to set
 * @param res_data Pointer to where resident data is located (data will
 * be copied from here into FS_DATA)
 * @param len Length of resident data
 * @return 1 on error and 0 on success
 */
uint8_t
tsk_fs_attr_set_str(TSK_FS_FILE * a_fs_file, TSK_FS_ATTR * a_fs_attr,
    const char *name, TSK_FS_ATTR_TYPE_ENUM type, uint16_t id,
    void *res_data, size_t len)
{
    if (a_fs_attr == NULL) {
        tsk_error_reset();
        tsk_error_set_errno(TSK_ERR_FS_ARG);
        tsk_error_set_errstr("Null fs_attr in tsk_fs_attr_set_str");
        return 1;
    }

    a_fs_attr->fs_file = a_fs_file;
    a_fs_attr->flags = (TSK_FS_ATTR_INUSE | TSK_FS_ATTR_RES);
    a_fs_attr->type = type;
    a_fs_attr->id = id;
    a_fs_attr->nrd.compsize = 0;

    if (fs_attr_put_name(a_fs_attr, name)) {
        return 1;
    }

    if (a_fs_attr->rd.buf_size < len) {
        a_fs_attr->rd.buf =
            (uint8_t *) tsk_realloc((char *) a_fs_attr->rd.buf, len);
        if (a_fs_attr->rd.buf == NULL)
            return 1;
        a_fs_attr->rd.buf_size = len;
    }

    memset(a_fs_attr->rd.buf, 0, a_fs_attr->rd.buf_size);
    memcpy(a_fs_attr->rd.buf, res_data, len);
    a_fs_attr->size = len;

    return 0;
}
Example #22
0
static tsk_size_t tdav_codec_red_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
{
	tdav_codec_red_t *red = (tdav_codec_red_t *)self;
	tsk_size_t xsize = (in_size + 1);
	static const uint8_t __first_octet = 0x00; // F=1, PT=0. Up to the caller to update this first octet with the right PT.

	if(!red || !in_data || !in_size || !out_data || !out_max_size){
		TSK_DEBUG_ERROR("Invalid parameter");
		return 0;
	}

	if(*out_max_size < xsize){
		if(!(*out_data = tsk_realloc(*out_data, xsize))){
			TSK_DEBUG_ERROR("Failed to realloc data");
			*out_max_size = 0;
		}
		*out_max_size = xsize;
	}

	((uint8_t*)*out_data)[0] = __first_octet;
	memcpy(&((uint8_t*)*out_data)[1], in_data, in_size);

	return xsize;
}
Example #23
0
static tsk_size_t tdav_codec_opus_encode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size)
{
    tdav_codec_opus_t* opus = (tdav_codec_opus_t*)self;
    opus_int32 ret;

    if(!self || !in_data || !in_size || !out_data) {
        TSK_DEBUG_ERROR("Invalid parameter");
        return 0;
    }

    if(!opus->encoder.inst) {
        TSK_DEBUG_ERROR("Encoder not ready");
        return 0;
    }

    // we're sure that the output (encoded) size cannot be higher than the input (raw)
    if(*out_max_size < in_size) {
        if(!(*out_data = tsk_realloc(*out_data, in_size))) {
            TSK_DEBUG_ERROR("Failed to allocate buffer with size = %u", in_size);
            *out_max_size  = 0;
            return 0;
        }
        *out_max_size = in_size;
    }

    ret = opus_encode(opus->encoder.inst,
                      (const opus_int16 *)in_data, (int)(in_size >> 1),
                      (unsigned char *)*out_data, (opus_int32)*out_max_size);

    if(ret < 0) {
        TSK_DEBUG_ERROR("opus_encode() failed with error code = %d", ret);
        return 0;
    }

    return (tsk_size_t)ret;
}
static int tdav_webrtc_denoise_open(tmedia_denoise_t* self, uint32_t frame_size, uint32_t sampling_rate)
{
	tdav_webrtc_denoise_t *denoiser = (tdav_webrtc_denoise_t *)self;
	int ret;

	if(!denoiser){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}

	if(denoiser->AEC_inst || 
#if HAVE_SPEEX_DSP && PREFER_SPEEX_DENOISER
		denoiser->SpeexDenoiser_proc
#else
		denoiser->NS_inst
#endif
		){
		TSK_DEBUG_ERROR("Denoiser already initialized");
		return -2;
	}
	
	denoiser->echo_tail = TSK_CLAMP(WEBRTC_MIN_ECHO_TAIL, TMEDIA_DENOISE(denoiser)->echo_tail, WEBRTC_MAX_ECHO_TAIL);
	TSK_DEBUG_INFO("echo_tail=%d", denoiser->echo_tail);
	denoiser->echo_skew = TMEDIA_DENOISE(denoiser)->echo_skew;
	denoiser->frame_size = frame_size;
	denoiser->sampling_rate = sampling_rate;
	
	//
	//	AEC instance
	//
	if((ret = TDAV_WebRtcAec_Create(&denoiser->AEC_inst))){
		TSK_DEBUG_ERROR("WebRtcAec_Create failed with error code = %d", ret);
		return ret;
	}
	if((ret = TDAV_WebRtcAec_Init(denoiser->AEC_inst, denoiser->sampling_rate, denoiser->sampling_rate))){
		TSK_DEBUG_ERROR("WebRtcAec_Init failed with error code = %d", ret);
		return ret;
	}

#if WEBRTC_AEC_AGGRESSIVE
	{	
		AecConfig aecConfig;
		aecConfig.nlpMode = kAecNlpAggressive;
		aecConfig.skewMode = kAecTrue;
		aecConfig.metricsMode = kAecFalse;
		aecConfig.delay_logging = kAecFalse;

		if((ret = WebRtcAec_set_config(denoiser->AEC_inst, aecConfig))){
			TSK_DEBUG_ERROR("WebRtcAec_set_config failed with error code = %d", ret);
		}
	}
#endif
	
	//
	//	Noise Suppression instance
	//
	if(TMEDIA_DENOISE(denoiser)->noise_supp_enabled){
#if HAVE_SPEEX_DSP && PREFER_SPEEX_DENOISER
		if((denoiser->SpeexDenoiser_proc = speex_preprocess_state_init(denoiser->frame_size, denoiser->sampling_rate))){
			int i = 1;
			speex_preprocess_ctl(denoiser->SpeexDenoiser_proc, SPEEX_PREPROCESS_SET_DENOISE, &i);
			i = TMEDIA_DENOISE(denoiser)->noise_supp_level;
			speex_preprocess_ctl(denoiser->SpeexDenoiser_proc, SPEEX_PREPROCESS_SET_NOISE_SUPPRESS, &i);
		}
#else
		if((ret = TDAV_WebRtcNs_Create(&denoiser->NS_inst))){
			TSK_DEBUG_ERROR("WebRtcNs_Create failed with error code = %d", ret);
			return ret;
		}
		if((ret = TDAV_WebRtcNs_Init(denoiser->NS_inst, denoiser->sampling_rate))){
			TSK_DEBUG_ERROR("WebRtcNs_Init failed with error code = %d", ret);
			return ret;
		}
#endif
	}

	// allocate temp buffer for record processing
	if(!(denoiser->temp_rec_out = tsk_realloc(denoiser->temp_rec_out, denoiser->frame_size * kSizeOfWord16))){
		TSK_DEBUG_ERROR("Failed to allocate new buffer");
		return -3;
	}

	TSK_DEBUG_INFO("WebRTC denoiser opened");

	return ret;
}
Example #25
0
int tnet_tls_socket_recv(tnet_tls_socket_handle_t* self, void** data, tsk_size_t *size, tsk_bool_t *isEncrypted)
{
#if !HAVE_OPENSSL
	TSK_DEBUG_ERROR("You MUST enable OpenSSL");
	return -200;
#else
	int ret = -1;
	tsk_size_t read = 0;
	tsk_size_t to_read = *size;
	int rcount = TNET_TLS_RETRY_COUNT;
	tnet_tls_socket_t* socket = self;

	if(!self){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}
	
	tsk_safeobj_lock(socket);

	*isEncrypted = SSL_is_init_finished(socket->ssl) ? tsk_false : tsk_true;

	/* SSL handshake has completed? */
	if(*isEncrypted){
		char* buffer[1024];
		if((ret = SSL_read(socket->ssl, buffer, sizeof(buffer))) <= 0){
			ret = SSL_get_error(socket->ssl, ret);
			if(ret == SSL_ERROR_WANT_WRITE || ret == SSL_ERROR_WANT_READ){
				ret = 0;
			}
			else{
				TSK_DEBUG_ERROR("SSL_read failed [%d, %s]", ret, ERR_error_string(ERR_get_error(), tsk_null));
			}
			*size = 0;
		}
		else{
			*size = ret;
			ret = 0;
		}
		
		goto bail;
	}

	/* Read Application data */
ssl_read:	
	if(rcount && ((ret = SSL_read(socket->ssl, (((uint8_t*)*data)+read), (int)to_read)) <= 0)){
		ret = SSL_get_error(socket->ssl, ret);
		if(ret == SSL_ERROR_WANT_WRITE || ret == SSL_ERROR_WANT_READ){
			if(!(ret = tnet_sockfd_waitUntil(socket->fd, TNET_TLS_TIMEOUT, (ret == SSL_ERROR_WANT_WRITE)))){
				rcount--;
				goto ssl_read;
			}
		}
		else if(SSL_ERROR_ZERO_RETURN){ /* connection closed: do nothing, the transport layer will be alerted. */
			*size = 0;
			ret = 0;
			TSK_DEBUG_INFO("TLS connection closed.");
		}
		else{
			TSK_DEBUG_ERROR("SSL_read failed [%d, %s]", ret, ERR_error_string(ERR_get_error(), tsk_null));
		}
	}
	else if(ret >=0){
		read += (tsk_size_t)ret;

		if((ret = SSL_pending(socket->ssl)) > 0){
			void *ptr;
			to_read = ret;

			if((ptr = tsk_realloc(*data, (read + to_read)))){
				*data = ptr;
				goto ssl_read;
			}
		}
	}

bail:
	tsk_safeobj_unlock(socket);

	if(read){
		*size = read;
		return 0;
	}
	else{
		return ret;
	}
#endif
}
static int tdav_speex_jitterbuffer_put(tmedia_jitterbuffer_t* self, void* data, tsk_size_t data_size, const tsk_object_t* proto_hdr)
{
	tdav_speex_jitterbuffer_t *jb = (tdav_speex_jitterbuffer_t *)self;
    const trtp_rtp_header_t* rtp_hdr;
    JitterBufferPacket jb_packet;
	static uint16_t seq_num = 0;

    if(!data || !data_size || !proto_hdr){
        TSK_DEBUG_ERROR("Invalid parameter");
        return -1;
    }
    
    if(!jb->state){
        TSK_DEBUG_ERROR("Invalid state");
        return -2;
    }
    
    rtp_hdr = TRTP_RTP_HEADER(proto_hdr);

	jb_packet.user_data = 0;
	jb_packet.span = jb->frame_duration;
	jb_packet.len = jb->x_data_size;
    
	if(jb->x_data_size == data_size){ /* ptime match */
		jb_packet.data = data;
		jb_packet.sequence = rtp_hdr->seq_num;
		jb_packet.timestamp = (rtp_hdr->seq_num * jb_packet.span);
		jitter_buffer_put(jb->state, &jb_packet);
	}
	else{ /* ptime mismatch */
		tsk_size_t i;
		jb_packet.sequence = 0; // Ignore
		if((jb->buff.index + data_size) > jb->buff.size){
			if(!(jb->buff.ptr = tsk_realloc(jb->buff.ptr, (jb->buff.index + data_size)))){
				jb->buff.size = 0;
				jb->buff.index = 0;
				return 0;
			}
			jb->buff.size = (jb->buff.index + data_size);
		}

		memcpy(&jb->buff.ptr[jb->buff.index], data, data_size);
		jb->buff.index += data_size;

		if(jb->buff.index >= jb->x_data_size){
			tsk_size_t copied = 0;
			for(i = 0; (i + jb->x_data_size) <= jb->buff.index; i += jb->x_data_size){
				jb_packet.data = (char*)&jb->buff.ptr[i];
				jb_packet.timestamp = (++jb->fake_seqnum * jb_packet.span);// reassembled pkt will have fake seqnum
				jitter_buffer_put(jb->state, &jb_packet);
				copied += jb->x_data_size;
			}
			if(copied == jb->buff.index){
				// all copied
				jb->buff.index = 0;
			}
			else{
				memmove(&jb->buff.ptr[0], &jb->buff.ptr[copied], (jb->buff.index - copied));
				jb->buff.index -= copied;
			}
		}
	}
    
    return 0;
}
static int tdav_consumer_audiounit_prepare(tmedia_consumer_t* self, const tmedia_codec_t* codec)
{
	static UInt32 flagOne = 1;
	AudioStreamBasicDescription audioFormat;
#define kOutputBus  0
	
	tdav_consumer_audiounit_t* consumer = (tdav_consumer_audiounit_t*)self;
	OSStatus status = noErr;
	
	if(!consumer || !codec || !codec->plugin){
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}
	if(!consumer->audioUnitHandle){
		if(!(consumer->audioUnitHandle = tdav_audiounit_handle_create(TMEDIA_CONSUMER(consumer)->session_id))){
			TSK_DEBUG_ERROR("Failed to get audio unit instance for session with id=%lld", TMEDIA_CONSUMER(consumer)->session_id);
			return -3;
		}
	}

	// enable
	status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(consumer->audioUnitHandle), 
								  kAudioOutputUnitProperty_EnableIO, 
								  kAudioUnitScope_Output, 
								  kOutputBus,
								  &flagOne, 
								  sizeof(flagOne));
	if(status){
		TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_EnableIO) failed with status=%d", (int32_t)status);
		return -4;
	}
	else {
		
#if !TARGET_OS_IPHONE // strange: TARGET_OS_MAC is equal to '1' on Smulator
		UInt32 param;
		
		// disable input
		param = 0;
		status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(consumer->audioUnitHandle), kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &param, sizeof(UInt32));
		if(status != noErr){
			TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_EnableIO) failed with status=%ld", (signed long)status);
			return -4;
		}
		
		// set default audio device
		param = sizeof(AudioDeviceID);
		AudioDeviceID outputDeviceID;
		status = AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice, &param, &outputDeviceID);
		if(status != noErr){
			TSK_DEBUG_ERROR("AudioHardwareGetProperty(kAudioHardwarePropertyDefaultOutputDevice) failed with status=%ld", (signed long)status);
			return -4;
		}
		
		// set the current device to the default input unit
		status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(consumer->audioUnitHandle), 
									  kAudioOutputUnitProperty_CurrentDevice, 
									  kAudioUnitScope_Global, 
									  0, 
									  &outputDeviceID, 
									  sizeof(AudioDeviceID));
		if(status != noErr){
			TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_CurrentDevice) failed with status=%ld", (signed long)status);
			return -4;
		}
		
#endif

		TMEDIA_CONSUMER(consumer)->audio.ptime = TMEDIA_CODEC_PTIME_AUDIO_DECODING(codec);
		TMEDIA_CONSUMER(consumer)->audio.in.channels = TMEDIA_CODEC_CHANNELS_AUDIO_DECODING(codec);
		TMEDIA_CONSUMER(consumer)->audio.in.rate = TMEDIA_CODEC_RATE_DECODING(codec);
        
        TSK_DEBUG_INFO("AudioUnit consumer: in.channels=%d, out.channles=%d, in.rate=%d, out.rate=%d, ptime=%d",
                       TMEDIA_CONSUMER(consumer)->audio.in.channels,
                       TMEDIA_CONSUMER(consumer)->audio.out.channels,
                       TMEDIA_CONSUMER(consumer)->audio.in.rate,
                       TMEDIA_CONSUMER(consumer)->audio.out.rate,
                       TMEDIA_CONSUMER(consumer)->audio.ptime);
		
		audioFormat.mSampleRate = TMEDIA_CONSUMER(consumer)->audio.out.rate ? TMEDIA_CONSUMER(consumer)->audio.out.rate : TMEDIA_CONSUMER(consumer)->audio.in.rate;
		audioFormat.mFormatID = kAudioFormatLinearPCM;
		audioFormat.mFormatFlags = kAudioFormatFlagIsSignedInteger | kAudioFormatFlagIsPacked;
		audioFormat.mChannelsPerFrame = TMEDIA_CONSUMER(consumer)->audio.in.channels;
		audioFormat.mFramesPerPacket = 1;
		audioFormat.mBitsPerChannel = TMEDIA_CONSUMER(consumer)->audio.bits_per_sample;
		audioFormat.mBytesPerPacket = audioFormat.mBitsPerChannel / 8 * audioFormat.mChannelsPerFrame;
		audioFormat.mBytesPerFrame = audioFormat.mBytesPerPacket;
		audioFormat.mReserved = 0;
		status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(consumer->audioUnitHandle), 
									  kAudioUnitProperty_StreamFormat, 
									  kAudioUnitScope_Input, 
									  kOutputBus, 
									  &audioFormat, 
									  sizeof(audioFormat));
		
		if(status){
			TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioUnitProperty_StreamFormat) failed with status=%ld", (signed long)status);
			return -5;
		}
		else {
			// configure
			if(tdav_audiounit_handle_configure(consumer->audioUnitHandle, tsk_true, TMEDIA_CONSUMER(consumer)->audio.ptime, &audioFormat)){
				TSK_DEBUG_ERROR("tdav_audiounit_handle_set_rate(%d) failed", TMEDIA_CONSUMER(consumer)->audio.out.rate);
				return -4;
			}
			
			// set callback function
			AURenderCallbackStruct callback;
			callback.inputProc = __handle_output_buffer;
			callback.inputProcRefCon = consumer;
			status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(consumer->audioUnitHandle), 
										  kAudioUnitProperty_SetRenderCallback, 
										  kAudioUnitScope_Input, 
										  kOutputBus,
										  &callback, 
										  sizeof(callback));
			if(status){
				TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioOutputUnitProperty_SetInputCallback) failed with status=%ld", (signed long)status);
				return -6;
			}
		}
	}
	
	// allocate the chunck buffer and create the ring
	consumer->ring.chunck.size = (TMEDIA_CONSUMER(consumer)->audio.ptime * audioFormat.mSampleRate * audioFormat.mBytesPerFrame) / 1000;
	consumer->ring.size = kRingPacketCount * consumer->ring.chunck.size;
	if(!(consumer->ring.chunck.buffer = tsk_realloc(consumer->ring.chunck.buffer, consumer->ring.chunck.size))){
		TSK_DEBUG_ERROR("Failed to allocate new buffer");
		return -7;
	}
	if(!consumer->ring.buffer){
		consumer->ring.buffer = speex_buffer_init(consumer->ring.size);
	}
	else {
		int ret;
		if((ret = speex_buffer_resize(consumer->ring.buffer, consumer->ring.size)) < 0){
			TSK_DEBUG_ERROR("speex_buffer_resize(%d) failed with error code=%d", consumer->ring.size, ret);
			return ret;
		}
	}
	if(!consumer->ring.buffer){
		TSK_DEBUG_ERROR("Failed to create a new ring buffer with size = %d", consumer->ring.size);
		return -8;
	}
	if(!consumer->ring.mutex && !(consumer->ring.mutex = tsk_mutex_create_2(tsk_false))){
		TSK_DEBUG_ERROR("Failed to create mutex");
		return -9;
	}

	// set maximum frames per slice as buffer size
	//UInt32 numFrames = (UInt32)consumer->ring.chunck.size;
	//status = AudioUnitSetProperty(tdav_audiounit_handle_get_instance(consumer->audioUnitHandle), 
	//							  kAudioUnitProperty_MaximumFramesPerSlice,
	//							  kAudioUnitScope_Global, 
	//							  0, 
	//							  &numFrames, 
	//							  sizeof(numFrames));
	//if(status){
	//	TSK_DEBUG_ERROR("AudioUnitSetProperty(kAudioUnitProperty_MaximumFramesPerSlice, %u) failed with status=%d", (unsigned)numFrames, (int32_t)status);
	//	return -6;
	//}
	
	TSK_DEBUG_INFO("AudioUnit consumer prepared");
    return tdav_audiounit_handle_signal_consumer_prepared(consumer->audioUnitHandle);
}
Example #28
0
int tnet_dtls_socket_do_handshake(tnet_dtls_socket_handle_t* handle, const struct sockaddr_storage* remote_addr)
{
#if !HAVE_OPENSSL || !HAVE_OPENSSL_DTLS
	TSK_DEBUG_ERROR("OpenSSL or DTLS not enabled");
	return -1;

#else
	tnet_dtls_socket_t *socket = handle;
	int ret = 0, len;
	void* out_data;

	if (!socket) {
		TSK_DEBUG_ERROR("Invalid parameter");
		return -1;
	}

	tsk_safeobj_lock(socket);

	// update remote address even if handshaking is completed
	if (remote_addr) {
		socket->remote.addr = *remote_addr;
	}

	if (socket->handshake_completed) {
		TSK_DEBUG_INFO("Handshake completed");
		ret = 0;
		goto bail;
	}

	if (!socket->handshake_started) {
		if ((ret = SSL_do_handshake(socket->ssl)) != 1) {
			switch ((ret = SSL_get_error(socket->ssl, ret))) {
			case SSL_ERROR_WANT_READ:
			case SSL_ERROR_WANT_WRITE:
			case SSL_ERROR_NONE:
				break;
			default:
				TSK_DEBUG_ERROR("DTLS handshake failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
				_tnet_dtls_socket_raise_event_dataless(socket, tnet_dtls_socket_event_type_handshake_failed);
				ret = -2;
				goto bail;
			}
		}
		socket->handshake_started = (ret == SSL_ERROR_NONE); // TODO: reset for renegotiation
	}

	if ((len = (int)BIO_get_mem_data(socket->wbio, &out_data)) > 0 && out_data) {
		if (socket->handshake_storedata) { // e.g. when TURN is enabled we have to query handshaking data and sent it via the negotiated channel
			if ((int)socket->handshake_data.size < len) {
				if (!(socket->handshake_data.ptr = tsk_realloc(socket->handshake_data.ptr, len))) {
					socket->handshake_data.size = 0;
					socket->handshake_data.count = 0;
					ret = -5;
					goto bail;
				}
				socket->handshake_data.size = len;
			}
			socket->handshake_data.count = len;
			memcpy(socket->handshake_data.ptr, out_data, len);
		}
		else {
			int sentlen = 0;
			tnet_port_t port;
			tnet_ip_t ip;
			tsk_bool_t is_dgram = TNET_SOCKET_TYPE_IS_DGRAM(socket->wrapped_sock->type);
			const uint8_t *record_ptr, *records_ptr = out_data;
			tsk_size_t record_size;
			int records_len = len;

			tnet_get_sockip_n_port((const struct sockaddr *)&socket->remote.addr, &ip, &port);
			TSK_DEBUG_INFO("DTLS data handshake to send with len = %d, from(%.*s/%d) to(%.*s/%d)", len, (int)sizeof(socket->wrapped_sock->ip), socket->wrapped_sock->ip, socket->wrapped_sock->port, (int)sizeof(ip), ip, port);

			//!\ IP fragmentation issues must be avoided even if the local transport is TCP/TLS because the relayed (TURN) transport could be UDP
			while (records_len > 0 && (ret = tnet_dtls_socket_get_record_first(records_ptr, (tsk_size_t)records_len, &record_ptr, &record_size)) == 0) {
				if (is_dgram) {
					sentlen += tnet_sockfd_sendto(socket->wrapped_sock->fd, (const struct sockaddr *)&socket->remote.addr, record_ptr, record_size);
				}
				else {
					sentlen += tnet_socket_send_stream(socket->wrapped_sock, record_ptr, record_size);
				}
				records_len -= (int)record_size;
				records_ptr += record_size;
			}
			TSK_DEBUG_INFO("DTLS data handshake sent len = %d", sentlen);
		}
	}

	BIO_reset(socket->rbio);
	BIO_reset(socket->wbio);

	if ((socket->handshake_completed = SSL_is_init_finished(socket->ssl))) {
		TSK_DEBUG_INFO("DTLS handshake completed");

#if HAVE_OPENSSL_DTLS_SRTP
		if (socket->use_srtp){
#if !defined(SRTP_MAX_KEY_LEN)
#	define cipher_key_length (128 >> 3) // rfc5764 4.1.2.  SRTP Protection Profiles
#	define cipher_salt_length (112 >> 3) // rfc5764 4.1.2.  SRTP Protection Profiles
			// "cipher_key_length" is also equal to srtp_profile_get_master_key_length(srtp_profile_aes128_cm_sha1_80)
			// "cipher_salt_length" is also srtp_profile_get_master_salt_length(srtp_profile_aes128_cm_sha1_80)
#	define SRTP_MAX_KEY_LEN (cipher_key_length + cipher_salt_length)
#endif /* SRTP_MAX_KEY_LEN */
#define EXTRACTOR_dtls_srtp_text "EXTRACTOR-dtls_srtp"
#define EXTRACTOR_dtls_srtp_text_len 19
			uint8_t keying_material[SRTP_MAX_KEY_LEN << 1];
			static const tsk_size_t keying_material_size = sizeof(keying_material);
			/*if(socket->use_srtp)*/{
				SRTP_PROTECTION_PROFILE *p = SSL_get_selected_srtp_profile(socket->ssl);
				if (!p) {
					TSK_DEBUG_ERROR("SSL_get_selected_srtp_profile() returned null [%s]", ERR_error_string(ERR_get_error(), tsk_null));
					ret = -2;
					goto bail;
				}
				// alert user
				_tnet_dtls_socket_raise_event(socket, tnet_dtls_socket_event_type_dtls_srtp_profile_selected, p->name, tsk_strlen(p->name));

				memset(keying_material, 0, sizeof(keying_material));

				// rfc5764 - 4.2.  Key Derivation
				ret = SSL_export_keying_material(socket->ssl, keying_material, sizeof(keying_material), EXTRACTOR_dtls_srtp_text, EXTRACTOR_dtls_srtp_text_len, tsk_null, 0, 0);
				if (ret != 1) {
					// alert listener
					_tnet_dtls_socket_raise_event_dataless(socket, tnet_dtls_socket_event_type_error);
					TSK_DEBUG_ERROR("SSL_export_keying_material() failed [%s]", ERR_error_string(ERR_get_error(), tsk_null));
					ret = -2;
					goto bail;
				}
			}
			// alert listener
			_tnet_dtls_socket_raise_event(socket, tnet_dtls_socket_event_type_dtls_srtp_data, keying_material, keying_material_size);
		}
#endif /* HAVE_OPENSSL_DTLS_SRTP */
		_tnet_dtls_socket_raise_event_dataless(socket, tnet_dtls_socket_event_type_handshake_succeed);
	}
	ret = 0; // clear "ret", error will directly jump to "bail:"
bail:
	tsk_safeobj_unlock(socket);
	return ret;
#endif
}
Example #29
0
tsk_size_t tdav_codec_mp4ves_decode(tmedia_codec_t* _self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size, const tsk_object_t* proto_hdr)
{ 
	tdav_codec_mp4ves_t* self = (tdav_codec_mp4ves_t*)_self;
	const trtp_rtp_header_t* rtp_hdr = proto_hdr;

	tsk_size_t xsize, retsize = 0;
	int got_picture_ptr;
	int ret;

	if(!self || !in_data || !in_size || !out_data || !self->decoder.context){
		TSK_DEBUG_ERROR("Invalid parameter");
		return 0;
	}

	// get expected size
	xsize = avpicture_get_size(self->decoder.context->pix_fmt, self->decoder.context->width, self->decoder.context->height);

	/* Packet lost? */
	if(self->decoder.last_seq != (rtp_hdr->seq_num - 1) && self->decoder.last_seq){
		if(self->decoder.last_seq == rtp_hdr->seq_num){
			// Could happen on some stupid emulators
			TSK_DEBUG_INFO("Packet duplicated, seq_num=%d", rtp_hdr->seq_num);
			return 0;
		}
		TSK_DEBUG_INFO("Packet lost, seq_num=%d", rtp_hdr->seq_num);
	}
	self->decoder.last_seq = rtp_hdr->seq_num;

	if((self->decoder.accumulator_pos + in_size) <= xsize){
		memcpy(&((uint8_t*)self->decoder.accumulator)[self->decoder.accumulator_pos], in_data, in_size);
		self->decoder.accumulator_pos += in_size;
	}
	else{
		TSK_DEBUG_WARN("Buffer overflow");
		self->decoder.accumulator_pos = 0;
		return 0;
	}

	if(rtp_hdr->marker){
		AVPacket packet;
		/* allocate destination buffer */
		if(*out_max_size <xsize){
			if(!(*out_data = tsk_realloc(*out_data, xsize))){
				TSK_DEBUG_ERROR("Failed to allocate new buffer");
				self->decoder.accumulator_pos = 0;
				*out_max_size = 0;
				return 0;
			}
			*out_max_size = xsize;
		}		

		av_init_packet(&packet);
		packet.size = (int)self->decoder.accumulator_pos;
		packet.data = self->decoder.accumulator;
		ret = avcodec_decode_video2(self->decoder.context, self->decoder.picture, &got_picture_ptr, &packet);

		if(ret < 0){
			TSK_DEBUG_WARN("Failed to decode the buffer with error code = %d", ret);
			if(TMEDIA_CODEC_VIDEO(self)->in.callback){
				TMEDIA_CODEC_VIDEO(self)->in.result.type = tmedia_video_decode_result_type_error;
				TMEDIA_CODEC_VIDEO(self)->in.result.proto_hdr = proto_hdr;
				TMEDIA_CODEC_VIDEO(self)->in.callback(&TMEDIA_CODEC_VIDEO(self)->in.result);
			}
		}
		else if(got_picture_ptr){
			retsize = xsize;
			TMEDIA_CODEC_VIDEO(self)->in.width = self->decoder.context->width;
			TMEDIA_CODEC_VIDEO(self)->in.height = self->decoder.context->height;

			/* copy picture into a linear buffer */
			avpicture_layout((AVPicture *)self->decoder.picture, self->decoder.context->pix_fmt, (int)self->decoder.context->width, (int)self->decoder.context->height,
				*out_data, (int)retsize);
		}
		/* in all cases: reset accumulator */
		self->decoder.accumulator_pos = 0;		
	}

	return retsize;
}
Example #30
0
static tsk_size_t tdav_codec_h264_decode(tmedia_codec_t* self, const void* in_data, tsk_size_t in_size, void** out_data, tsk_size_t* out_max_size, const tsk_object_t* proto_hdr)
{
	tdav_codec_h264_t* h264 = (tdav_codec_h264_t*)self;
	const trtp_rtp_header_t* rtp_hdr = (const trtp_rtp_header_t*)proto_hdr;
	
	const uint8_t* pay_ptr = tsk_null;
	tsk_size_t pay_size = 0;
	int ret;
	tsk_bool_t sps_or_pps, append_scp, end_of_unit;
	tsk_size_t retsize = 0, size_to_copy = 0;
	static const tsk_size_t xmax_size = (3840 * 2160 * 3) >> 3; // >>3 instead of >>1 (not an error)
	static tsk_size_t start_code_prefix_size = sizeof(H264_START_CODE_PREFIX);
#if HAVE_FFMPEG
	int got_picture_ptr = 0;
#endif

	if(!h264 || !in_data || !in_size || !out_data
#if HAVE_FFMPEG
		|| !h264->decoder.context
#endif
		)
	{
		TSK_DEBUG_ERROR("Invalid parameter");
		return 0;
	}
	
	//TSK_DEBUG_INFO("SeqNo=%hu", rtp_hdr->seq_num);

	/* Packet lost? */
	if((h264->decoder.last_seq + 1) != rtp_hdr->seq_num && h264->decoder.last_seq){
		TSK_DEBUG_INFO("[H.264] Packet loss, seq_num=%d", (h264->decoder.last_seq + 1));
	}
	h264->decoder.last_seq = rtp_hdr->seq_num;


	/* 5.3. NAL Unit Octet Usage
	  +---------------+
      |0|1|2|3|4|5|6|7|
      +-+-+-+-+-+-+-+-+
      |F|NRI|  Type   |
      +---------------+
	*/
	if(*((uint8_t*)in_data) & 0x80){
		TSK_DEBUG_WARN("F=1");
		/* reset accumulator */
		h264->decoder.accumulator_pos = 0;
		return 0;
	}

	/* get payload */
	if((ret = tdav_codec_h264_get_pay(in_data, in_size, (const void**)&pay_ptr, &pay_size, &append_scp, &end_of_unit)) || !pay_ptr || !pay_size){
		TSK_DEBUG_ERROR("Depayloader failed to get H.264 content");
		return 0;
	}
	//append_scp = tsk_true;
	size_to_copy = pay_size + (append_scp ? start_code_prefix_size : 0);
	// whether it's SPS or PPS (append_scp is false for subsequent FUA chuncks)
	sps_or_pps = append_scp && pay_ptr && ((pay_ptr[0] & 0x1F) == 7 || (pay_ptr[0] & 0x1F) == 8);
	
	// start-accumulator
	if(!h264->decoder.accumulator){
		if(size_to_copy > xmax_size){
			TSK_DEBUG_ERROR("%u too big to contain valid encoded data. xmax_size=%u", size_to_copy, xmax_size);
			return 0;
		}
		if(!(h264->decoder.accumulator = tsk_calloc(size_to_copy, sizeof(uint8_t)))){
			TSK_DEBUG_ERROR("Failed to allocated new buffer");
			return 0;
		}
		h264->decoder.accumulator_size = size_to_copy;
	}
	if((h264->decoder.accumulator_pos + size_to_copy) >= xmax_size){
		TSK_DEBUG_ERROR("BufferOverflow");
		h264->decoder.accumulator_pos = 0;
		return 0;
	}
	if((h264->decoder.accumulator_pos + size_to_copy) > h264->decoder.accumulator_size){
		if(!(h264->decoder.accumulator = tsk_realloc(h264->decoder.accumulator, (h264->decoder.accumulator_pos + size_to_copy)))){
			TSK_DEBUG_ERROR("Failed to reallocated new buffer");
			h264->decoder.accumulator_pos = 0;
			h264->decoder.accumulator_size = 0;
			return 0;
		}
		h264->decoder.accumulator_size = (h264->decoder.accumulator_pos + size_to_copy);
	}

	if(append_scp){
		memcpy(&((uint8_t*)h264->decoder.accumulator)[h264->decoder.accumulator_pos], H264_START_CODE_PREFIX, start_code_prefix_size);
		h264->decoder.accumulator_pos += start_code_prefix_size;
	}
	memcpy(&((uint8_t*)h264->decoder.accumulator)[h264->decoder.accumulator_pos], pay_ptr, pay_size);
	h264->decoder.accumulator_pos += pay_size;
	// end-accumulator

	if(sps_or_pps){
		// http://libav-users.943685.n4.nabble.com/Decode-H264-streams-how-to-fill-AVCodecContext-from-SPS-PPS-td2484472.html
		// SPS and PPS should be bundled with IDR
		TSK_DEBUG_INFO("Receiving SPS or PPS ...to be tied to an IDR");
	}
	else if(rtp_hdr->marker){
		if(h264->decoder.passthrough){
			if(*out_max_size < h264->decoder.accumulator_pos){
				if((*out_data = tsk_realloc(*out_data, h264->decoder.accumulator_pos))){
					*out_max_size = h264->decoder.accumulator_pos;
				}
				else{
					*out_max_size = 0;
					return 0;
				}
			}
			memcpy(*out_data, h264->decoder.accumulator, h264->decoder.accumulator_pos);
			retsize = h264->decoder.accumulator_pos;
		}
		else { // !h264->decoder.passthrough
#if HAVE_FFMPEG
			AVPacket packet;

			/* decode the picture */
			av_init_packet(&packet);
			packet.dts = packet.pts = AV_NOPTS_VALUE;
			packet.size = (int)h264->decoder.accumulator_pos;
			packet.data = h264->decoder.accumulator;
			ret = avcodec_decode_video2(h264->decoder.context, h264->decoder.picture, &got_picture_ptr, &packet);

			if(ret <0){
				TSK_DEBUG_INFO("Failed to decode the buffer with error code =%d, size=%u, append=%s", ret, h264->decoder.accumulator_pos, append_scp ? "yes" : "no");
				if(TMEDIA_CODEC_VIDEO(self)->in.callback){
					TMEDIA_CODEC_VIDEO(self)->in.result.type = tmedia_video_decode_result_type_error;
					TMEDIA_CODEC_VIDEO(self)->in.result.proto_hdr = proto_hdr;
					TMEDIA_CODEC_VIDEO(self)->in.callback(&TMEDIA_CODEC_VIDEO(self)->in.result);
				}
			}
			else if(got_picture_ptr){
				tsk_size_t xsize;
			
				/* IDR ? */
				if(((pay_ptr[0] & 0x1F) == 0x05) && TMEDIA_CODEC_VIDEO(self)->in.callback){
					TSK_DEBUG_INFO("Decoded H.264 IDR");
					TMEDIA_CODEC_VIDEO(self)->in.result.type = tmedia_video_decode_result_type_idr;
					TMEDIA_CODEC_VIDEO(self)->in.result.proto_hdr = proto_hdr;
					TMEDIA_CODEC_VIDEO(self)->in.callback(&TMEDIA_CODEC_VIDEO(self)->in.result);
				}
				/* fill out */
				xsize = avpicture_get_size(h264->decoder.context->pix_fmt, h264->decoder.context->width, h264->decoder.context->height);
				if(*out_max_size<xsize){
					if((*out_data = tsk_realloc(*out_data, (xsize + FF_INPUT_BUFFER_PADDING_SIZE)))){
						*out_max_size = xsize;
					}
					else{
						*out_max_size = 0;
						return 0;
					}
				}
				retsize = xsize;
				TMEDIA_CODEC_VIDEO(h264)->in.width = h264->decoder.context->width;
				TMEDIA_CODEC_VIDEO(h264)->in.height = h264->decoder.context->height;
				avpicture_layout((AVPicture *)h264->decoder.picture, h264->decoder.context->pix_fmt, (int)h264->decoder.context->width, (int)h264->decoder.context->height,
						*out_data, (int)retsize);
			}
#endif /* HAVE_FFMPEG */
		} // else(h264->decoder.passthrough)

		h264->decoder.accumulator_pos = 0;
	} // else if(rtp_hdr->marker)

	return retsize;
}