int MP4_moov_uuid_parse(uint8_t *uuid_data, uint32_t data_len, char *title)
{
	uint8_t *data = uuid_data;
	
	uint32_t uuid_len = read_be32(data);
	data += sizeof(uint32_t);
	if ( uuid_len != data_len ) {
		return 0;
	}
	//printf("uuid len = %08lx\n", uuid_len);
	
	// "MTDT" tag expected
	uint32_t tag = read_be32(data);
	if ( tag != 0x4d544454 ) {
		return 0;
	}
	data += sizeof(uint32_t);
	//printf("tag = %08lx\n", tag);
	if ( read_be16(data) != 0x0001 ) {
		return 0;
	}
	data += sizeof(uint16_t);
	uint16_t title_len = (read_be16(data) - 10) / 2;
	data += sizeof(uint16_t);

	if ( read_be32(data) != 0x00000001 ) {
		return 0;
	}
	data += sizeof(uint32_t);
	
	uint16_t lang_code = read_be16(data);
	data += sizeof(uint16_t);
	
	if ( read_be16(data) != 0x0001 ) {
		return 0;
	}
	data += sizeof(uint16_t);

	//printf("title len = %04lx (%d) \n", title_len, title_len);
	if ( title_len > (data_len - (data - uuid_data)) ) {
		title_len = data_len - (data - uuid_data) - 1;
	}

	for(uint16_t i = 0; i < title_len; i++) {
		uint16_t wc = read_be16(data);
		//printf("\twc=%04x\n", wc);
		data += sizeof(uint16_t);
		title[i] = (char)(wc & 0xff);
	}
	title[title_len] = 0;

	return 1;
}
Beispiel #2
0
    aiffStream(std::istream *_fstream)
        : alureStream(_fstream), format(0), dataStart(0)
    {
        ALubyte buffer[25];
        int length;

        if(!fstream->read(reinterpret_cast<char*>(buffer), 12) ||
                memcmp(buffer, "FORM", 4) != 0 || memcmp(buffer+8, "AIFF", 4) != 0)
            return;

        while(!dataStart || format == AL_NONE)
        {
            char tag[4];
            if(!fstream->read(tag, 4))
                break;

            /* read chunk length */
            length = read_be32(fstream);

            if(memcmp(tag, "COMM", 4) == 0 && length >= 18)
            {
                /* mono or stereo data */
                channels = read_be16(fstream);

                /* number of sample frames */
                fstream->ignore(4);

                /* bits per sample */
                sampleSize = read_be16(fstream) / 8;

                /* sample frequency */
                samplerate = read_be80extended(fstream);

                /* block alignment */
                blockAlign = channels * sampleSize;

                format = GetSampleFormat(channels, sampleSize*8, false);

                length -= 18;
            }
            else if(memcmp(tag, "SSND", 4) == 0)
            {
                dataStart = fstream->tellg();
                dataStart += 8;
                dataLen = remLen = length - 8;
            }

            fstream->seekg(length, std::ios_base::cur);
        }

        if(dataStart > 0 && format != AL_NONE)
            fstream->seekg(dataStart);
    }
static vod_status_t
mp4_decrypt_start_frame(void* ctx, input_frame_t* frame)
{
	mp4_decrypt_state_t* state = ctx;
	vod_status_t rc;

	rc = state->frames_source->start_frame(state->frames_source_context, frame);
	if (rc != VOD_OK)
	{
		return rc;
	}

	// get the iv
	if (state->auxiliary_info_pos + MP4_AES_CTR_IV_SIZE > state->auxiliary_info_end)
	{
		vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
			"mp4_decrypt_start_frame: failed to get iv from auxiliary info");
		return VOD_BAD_DATA;
	}

	mp4_aes_ctr_set_iv(&state->cipher, state->auxiliary_info_pos);
	state->auxiliary_info_pos += MP4_AES_CTR_IV_SIZE;

	if (!state->use_subsamples)
	{
		state->encrypted_bytes = UINT_MAX;
		return VOD_OK;
	}

	// get the subsample info
	if (state->auxiliary_info_pos + sizeof(uint16_t) + sizeof(cenc_sample_auxiliary_data_subsample_t) > state->auxiliary_info_end)
	{
		vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
			"mp4_decrypt_start_frame: failed to get subsample info from auxiliary info");
		return VOD_BAD_DATA;
	}

	read_be16(state->auxiliary_info_pos, state->subsample_count);
	if (state->subsample_count <= 0)
	{
		vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
			"mp4_decrypt_start_frame: invalid subsample count");
		return VOD_BAD_DATA;
	}

	read_be16(state->auxiliary_info_pos, state->clear_bytes);
	read_be32(state->auxiliary_info_pos, state->encrypted_bytes);

	state->subsample_count--;

	return VOD_OK;
}
Beispiel #4
0
int mb_pa_resp_writen(mb_msg *buf, uint16_t *addr, size_t *awords)
{
	int e;
	if(!buf) return(MB_ENOBUF);
	uint8_t fn;
	if((e=mb_pa_resp_fn(buf, &fn))) return(e);
	if(fn!=MB_FN_WRITEN) return(MB_EBADBUF); // not a writen message
	if((e=mb_respbuflen(buf, 8))) return(e);
	if((e=mb_pa_resp_checkcrc(buf))) return(e);
	if(addr) *addr=read_be16(buf->data+2);
	if(awords) *awords=read_be16(buf->data+4);
	return(MB_EOK);
}
    fluidStream(std::istream *_fstream)
      : alureStream(_fstream), Divisions(100),
        format(AL_NONE), sampleRate(48000), samplesPerTick(1.),
        fluidSettings(NULL), fluidSynth(NULL), fontID(FLUID_FAILED),
        doFontLoad(true)
    {
        if(!fsynth_handle) return;

        ALCdevice *device = alcGetContextsDevice(alcGetCurrentContext());
        if(device) alcGetIntegerv(device, ALC_FREQUENCY, 1, &sampleRate);

        char hdr[4];
        if(!fstream->read(hdr, 4))
            return;

        if(memcmp(hdr, "MThd", 4) == 0)
        {
            ALuint len = read_be32(fstream);
            if(len != 6)
                return;

            int type = read_be16(fstream);
            if(type != 0 && type != 1)
                return;

            ALuint numtracks = read_be16(fstream);

            Divisions = read_be16(fstream);
            UpdateTempo(500000);

            Tracks.resize(numtracks);
            for(std::vector<MidiTrack>::iterator i = Tracks.begin(), end = Tracks.end();i != end;i++)
            {
                if(!fstream->read(hdr, 4) || memcmp(hdr, "MTrk", 4) != 0)
                    return;

                ALint len = read_be32(fstream);
                i->data.resize(len);
                if(!fstream->read(reinterpret_cast<char*>(&i->data[0]), len) ||
                   fstream->gcount() != len)
                    return;

                unsigned long val = i->ReadVarLen();
                i->SamplesLeft += val * samplesPerTick;
            }
            SetupSynth();
        }
    }
Beispiel #6
0
// Response parsers (mb_pa_resp_*) interrogate a response datagram
//  First arg is always const mb_msg *buf, the datagram to decode
int mb_pa_resp_checkcrc(const mb_msg *buf)
{
	if(!buf) return(MB_ENOBUF);
	if(buf->len<2) return(MB_EMSHORT);
	int e;
	uint16_t crc;
	if((e=mb_crc16(buf, &crc))) return(e);
	uint16_t read_crc=read_be16(buf->data+buf->len-2);
	if(crc!=read_crc) return(MB_EBADBUF);
	return(MB_EOK);
}
Beispiel #7
0
int mb_pa_resp_readn(mb_msg *buf, size_t words, size_t *awords, uint16_t *vals)
{
	int e;
	if(!buf) return(MB_ENOBUF);
	uint8_t fn;
	if((e=mb_pa_resp_fn(buf, &fn))) return(e);
	if(!mb_is_fn_readn(fn)) return(MB_EBADBUF); // not a readn message
	if(buf->len<3) return(MB_EMSHORT);
	size_t nbytes=buf->data[2];
	if((e=mb_respbuflen(buf, nbytes+5))) return(e);
	if((e=mb_pa_resp_checkcrc(buf))) return(e);
	if(nbytes&1) return(MB_EBADBUF); // nbytes should always be even
	size_t rwords=nbytes/2;
	if(awords) *awords=rwords;
	for(size_t i=0;(i<words)&&(i<rwords);i++)
	{
		if(vals) vals[i]=read_be16(buf->data+3+(i<<1));
	}
	if(words<rwords) return(MB_EDLONG);
	return(MB_EOK);
}
Beispiel #8
0
vod_status_t 
codec_config_avcc_get_nal_units(
	request_context_t* request_context,
	const u_char* extra_data,
	uint32_t extra_data_size,
	bool_t size_only,
	uint32_t* nal_packet_size_length,
	u_char** result,
	uint32_t* result_size)
{
	const u_char* extra_data_end = extra_data + extra_data_size;
	const u_char* cur_pos;
	u_char* p;
	size_t actual_size;
	uint16_t unit_size;
	int unit_count;
	int i;

	if (extra_data_size < sizeof(avcc_config_t))
	{
		vod_log_error(VOD_LOG_ERR, request_context->log, 0,
			"codec_config_avcc_get_nal_units: extra data size %uD too small", extra_data_size);
		return VOD_BAD_DATA;
	}

	*nal_packet_size_length = (((avcc_config_t*)extra_data)->nula_length_size & 0x3) + 1;

	// calculate total size and validate
	*result_size = 0;
	cur_pos = extra_data + sizeof(avcc_config_t);
	for (i = 0; i < 2; i++)		// once for SPS, once for PPS
	{
		if (cur_pos >= extra_data_end)
		{
			vod_log_error(VOD_LOG_ERR, request_context->log, 0,
				"codec_config_avcc_get_nal_units: extra data overflow while reading unit count");
			return VOD_BAD_DATA;
		}

		for (unit_count = (*cur_pos++ & 0x1f); unit_count; unit_count--)
		{
			if (cur_pos + sizeof(uint16_t) > extra_data_end)
			{
				vod_log_error(VOD_LOG_ERR, request_context->log, 0,
					"codec_config_avcc_get_nal_units: extra data overflow while reading unit size");
				return VOD_BAD_DATA;
			}

			read_be16(cur_pos, unit_size);
			if (cur_pos + unit_size > extra_data_end)
			{
				vod_log_error(VOD_LOG_ERR, request_context->log, 0,
					"codec_config_avcc_get_nal_units: unit size %uD overflows the extra data buffer", (uint32_t)unit_size);
				return VOD_BAD_DATA;
			}

			cur_pos += unit_size;
			*result_size += sizeof(uint32_t) + unit_size;
		}
	}

	if (size_only)
	{
		*result = NULL;
		return VOD_OK;
	}

	// allocate buffer
	p = vod_alloc(request_context->pool, *result_size);
	if (p == NULL)
	{
		vod_log_debug0(VOD_LOG_DEBUG_LEVEL, request_context->log, 0,
			"codec_config_avcc_get_nal_units: vod_alloc failed");
		return VOD_ALLOC_FAILED;
	}
	*result = p;

	// copy data
	cur_pos = extra_data + sizeof(avcc_config_t);
	for (i = 0; i < 2; i++)		// once for SPS, once for PPS
	{
		for (unit_count = *cur_pos++ & 0x1f; unit_count; unit_count--)
		{
			unit_size = parse_be16(cur_pos);
			cur_pos += sizeof(uint16_t);

			*((uint32_t*)p) = 0x01000000;
			p += sizeof(uint32_t);

			vod_memcpy(p, cur_pos, unit_size);
			cur_pos += unit_size;
			p += unit_size;
		}
	}

	actual_size = p - *result;
	if (actual_size != *result_size)
	{
		vod_log_error(VOD_LOG_ERR, request_context->log, 0,
			"codec_config_avcc_get_nal_units: actual extra data size %uz is different than calculated size %uD",
			actual_size, *result_size);
		return VOD_UNEXPECTED;
	}

	vod_log_buffer(VOD_LOG_DEBUG_LEVEL, request_context->log, 0, "codec_config_avcc_get_nal_units: parsed extra data ", *result, *result_size);
	return VOD_OK;
}
Beispiel #9
0
vod_status_t
codec_config_hevc_get_nal_units(
	request_context_t* request_context,
	const u_char* extra_data,
	uint32_t extra_data_size,
	bool_t size_only,
	uint32_t* nal_packet_size_length,
	u_char** result,
	uint32_t* result_size)
{
	hevc_config_t cfg;
	vod_status_t rc;
	const u_char* start_pos;
	const u_char* cur_pos;
	const u_char* end_pos;
	size_t actual_size;
	uint16_t unit_size;
	uint16_t count;
	uint8_t type_count;
	u_char* p;

	rc = codec_config_hevc_config_parse(request_context, extra_data, extra_data_size, &cfg, &start_pos);
	if (rc != VOD_OK)
	{
		return rc;
	}

	*nal_packet_size_length = cfg.nal_unit_size;

	end_pos = extra_data + extra_data_size;

	// calculate total size and validate
	*result_size = 0;
	cur_pos = start_pos;
	if (cur_pos >= end_pos)
	{
		vod_log_error(VOD_LOG_ERR, request_context->log, 0,
			"codec_config_hevc_get_nal_units: extra data overflow while reading type count");
		return VOD_BAD_DATA;
	}

	for (type_count = *cur_pos++; type_count > 0; type_count--)
	{
		if (cur_pos + 3 > end_pos)
		{
			vod_log_error(VOD_LOG_ERR, request_context->log, 0,
				"codec_config_hevc_get_nal_units: extra data overflow while reading type header");
			return VOD_BAD_DATA;
		}

		cur_pos++;
		read_be16(cur_pos, count);

		for (; count > 0; count--)
		{
			if (cur_pos + sizeof(uint16_t) > end_pos)
			{
				vod_log_error(VOD_LOG_ERR, request_context->log, 0,
					"codec_config_hevc_get_nal_units: extra data overflow while reading unit size");
				return VOD_BAD_DATA;
			}

			read_be16(cur_pos, unit_size);

			cur_pos += unit_size;

			if (cur_pos > end_pos)
			{
				vod_log_error(VOD_LOG_ERR, request_context->log, 0,
					"codec_config_hevc_get_nal_units: extra data overflow while reading unit data");
				return VOD_BAD_DATA;
			}

			*result_size += sizeof(uint32_t) + unit_size;
		}
	}

	if (size_only)
	{
		*result = NULL;
		return VOD_OK;
	}

	// allocate buffer
	p = vod_alloc(request_context->pool, *result_size);
	if (p == NULL)
	{
		vod_log_debug0(VOD_LOG_DEBUG_LEVEL, request_context->log, 0,
			"codec_config_hevc_get_nal_units: vod_alloc failed");
		return VOD_ALLOC_FAILED;
	}
	*result = p;

	// copy data
	cur_pos = start_pos;
	for (type_count = *cur_pos++; type_count > 0; type_count--)
	{
		cur_pos++;		// unit type
		read_be16(cur_pos, count);

		for (; count > 0; count--)
		{
			read_be16(cur_pos, unit_size);

			*((uint32_t*)p) = 0x01000000;
			p += sizeof(uint32_t);

			vod_memcpy(p, cur_pos, unit_size);
			p += unit_size;

			cur_pos += unit_size;
		}
	}

	// verify size
	actual_size = p - *result;
	if (actual_size != *result_size)
	{
		vod_log_error(VOD_LOG_ERR, request_context->log, 0,
			"codec_config_hevc_get_nal_units: actual extra data size %uz is different than calculated size %uD",
			actual_size, *result_size);
		return VOD_UNEXPECTED;
	}

	vod_log_buffer(VOD_LOG_DEBUG_LEVEL, request_context->log, 0, "codec_config_hevc_get_nal_units: parsed extra data ", *result, *result_size);
	return VOD_OK;
}
Beispiel #10
0
static vod_status_t
mp4_decrypt_process(
	mp4_decrypt_state_t* state, 
	size_t size)
{
	u_char* dest = state->output_pos;
	u_char* src = state->input_pos;
	vod_status_t rc;
	size_t cur_size;

	while (size > 0)
	{
		if (state->clear_bytes <= 0 && state->encrypted_bytes <= 0)
		{
			// finished a subsample, read the next one
			if (state->subsample_count <= 0)
			{
				vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
					"mp4_decrypt_process: exhausted subsample bytes");
				return VOD_BAD_DATA;
			}

			if (state->auxiliary_info_pos + sizeof(cenc_sample_auxiliary_data_subsample_t) > state->auxiliary_info_end)
			{
				vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
					"mp4_decrypt_process: failed to get subsample info from auxiliary info");
				return VOD_BAD_DATA;
			}

			read_be16(state->auxiliary_info_pos, state->clear_bytes);
			read_be32(state->auxiliary_info_pos, state->encrypted_bytes);

			state->subsample_count--;
		}

		if (state->clear_bytes > 0)
		{
			// copy clear bytes
			cur_size = vod_min(state->clear_bytes, size);
			dest = vod_copy(dest, src, cur_size);
			src += cur_size;
			size -= cur_size;
			state->clear_bytes -= cur_size;
		}

		// decrypt encrypted bytes
		cur_size = vod_min(state->encrypted_bytes, size);
		rc = mp4_aes_ctr_process(&state->cipher, dest, src, cur_size);
		if (rc != VOD_OK)
		{
			return rc;
		}

		dest += cur_size;
		src += cur_size;
		size -= cur_size;
		state->encrypted_bytes -= cur_size;
	}

	state->output_pos = dest;
	state->input_pos = src;

	return VOD_OK;
}