Ejemplo n.º 1
0
/**
 * Takes an initialized asf_file_t structure file as a parameter. Allocates
 * a new asf_object_data_t in file->data and uses the file->iostream to
 * read all its compulsory fields into it. Notice that the actual data is
 * not read in any way, because we need to be able to work with non-seekable
 * streams as well.
 */
int
asf_parse_data(asf_file_t *file)
{
	asf_object_data_t *data;
	asf_iostream_t *iostream;
	uint8_t ddata[50];
	int tmp;

	file->data = NULL;
	iostream = &file->iostream;

	/* object minimum is 24 bytes and data object needs to have
	 * 26 additional bytes for its internal fields */
	tmp = asf_byteio_read(iostream, ddata, 50);
	if (tmp < 0) {
		return tmp;
	}

	file->data = malloc(sizeof(asf_object_data_t));
	data = file->data;
	if (!data) {
		return ASF_ERROR_OUTOFMEM;
	}

	/* read the object and check its size value */
	asf_parse_read_object((asfint_object_t *) data, ddata);
	if (data->size < 50) {
		/* invalid size for data object */
		return ASF_ERROR_INVALID_OBJECT_SIZE;
	}

	/* read data object specific compulsory fields */
	GetGUID(ddata + 24, &data->file_id);
	data->total_data_packets = GetQWLE(ddata + 40);
	data->reserved = GetWLE(ddata + 48);
	data->packets_position = file->position + 50;

	/* If the file_id GUID in data object doesn't match the
	 * file_id GUID in headers, the file is corrupted */
	if (!asf_guid_equals(&data->file_id, &file->file_id)) {
		return ASF_ERROR_INVALID_VALUE;
	}

	/* if data->total_data_packets is non-zero (not a stream) and
	   the data packets count doesn't match, return error */
	if (data->total_data_packets &&
	    data->total_data_packets != file->data_packets_count) {
		return ASF_ERROR_INVALID_VALUE;
	}

	return 50;
}
static void F64IDecode( void *outp, const uint8_t *in, unsigned samples )
{
    double *out = outp;

    for( size_t i = 0; i < samples; i++ )
    {
        union { double d; uint64_t u; } s;

#ifdef WORDS_BIGENDIAN
        s.u = GetQWLE( in );
#else
        s.u = GetQWBE( in );
#endif
        *(out++) = s.d;
        in += 8;
    }
}
Ejemplo n.º 3
0
/**
 * Read next object from buffer pointed by data. Notice that
 * no buffer overflow checks are done! This function always
 * expects to have 24 bytes available, which is the size of
 * the object header (GUID + data size)
 */
static void
asf_parse_read_object(asfint_object_t *obj, uint8_t *data)
{
	GetGUID(data, &obj->guid);
	obj->type = asf_guid_get_type(&obj->guid);
	obj->size = GetQWLE(data + 16);
	obj->full_data = data;
	obj->datalen = 0;
	obj->data = NULL;
	obj->next = NULL;

	if (obj->type == GUID_UNKNOWN) {
		debug_printf("unknown object: %x-%x-%x-%02x%02x%02x%02x%02x%02x%02x%02x, %ld bytes",
		             obj->guid.v1, obj->guid.v2, obj->guid.v3, obj->guid.v4[0],
		             obj->guid.v4[1], obj->guid.v4[2], obj->guid.v4[3], obj->guid.v4[4],
		             obj->guid.v4[5], obj->guid.v4[6], obj->guid.v4[7], (long) obj->size);
	}
}
Ejemplo n.º 4
0
/*****************************************************************************
 * Lookup frame offset in index file
 *****************************************************************************/
static bool ReadIndexRecord( FILE *p_file, bool b_ts, int64_t i_frame,
                            uint64_t *pi_offset, uint16_t *pi_file_num )
{
    uint8_t index_record[8];
    if( fseek( p_file, sizeof(index_record) * i_frame, SEEK_SET ) != 0 )
        return false;
    if( fread( &index_record, sizeof(index_record), 1, p_file ) < 1 )
        return false;

    /* VDR usually (only?) runs on little endian machines, but VLC has a
     * broader audience. See recording.* in VDR source for data layout. */
    if( b_ts )
    {
        uint64_t i_index_entry = GetQWLE( &index_record );
        *pi_offset = i_index_entry & UINT64_C(0xFFFFFFFFFF);
        *pi_file_num = i_index_entry >> 48;
    }
    else
    {
Ejemplo n.º 5
0
/**
 * Takes an initialized asf_file_t structure file as a parameter. Allocates
 * a new asf_object_index_t in file->index and uses the file->iostream to
 * read all its compulsory fields into it. Notice that the actual data is
 * not read in any way, because we need to be able to work with non-seekable
 * streams as well.
 */
int
asf_parse_index(asf_file_t *file)
{
	asf_object_index_t *index;
	asf_iostream_t *iostream;
	uint8_t idata[56];
	uint64_t entry_data_size;
	uint8_t *entry_data = NULL;
	int tmp, i;

	file->index = NULL;
	iostream = &file->iostream;

	/* read the raw data of an index header */
	tmp = asf_byteio_read(iostream, idata, 56);
	if (tmp < 0) {
		printf("Could not read index header\n");
		return tmp;
	}

	/* allocate the index object */
	index = malloc(sizeof(asf_object_index_t));
	if (!index) {
		return ASF_ERROR_OUTOFMEM;
	}

	asf_parse_read_object((asfint_object_t *) index, idata);
	if (index->type != GUID_INDEX) {
		tmp = index->size;
		free(index);

		/* The guid type was wrong, just return the bytes to skip */
		return tmp;
	}

	if (index->size < 56) {
		/* invalid size for index object */
		free(index);
		return ASF_ERROR_INVALID_OBJECT_SIZE;
	}

	GetGUID(idata + 24, &index->file_id);
	index->entry_time_interval = GetQWLE(idata + 40);
	index->max_packet_count = GetDWLE(idata + 48);
	index->entry_count = GetDWLE(idata + 52);

	printf("INDEX\n");
	printf("Total Index Entries %d\n",index->entry_count);
	printf("Index Size in bytes %Ld\n",index->size);
	printf("Index Max Packet Count %d\n",index->max_packet_count);
	printf("Index Entry Time Interval %Ld\n",index->entry_time_interval);
	
	if (index->entry_count == 0) {
		printf("Index has no entries\n");
		file->index = index;
		return index->size;
	}

	if (index->entry_count * 6 + 56 > index->size) {
		free(index);
		return ASF_ERROR_INVALID_LENGTH;
	}

	entry_data_size = index->entry_count * 6;
	entry_data = malloc(entry_data_size * sizeof(uint8_t));
	if (!entry_data) {
		free(index);
		return ASF_ERROR_OUTOFMEM;
	}
	tmp = asf_byteio_read(iostream, entry_data, entry_data_size);
	if (tmp < 0) {
		printf("Could not read entry data\n");
		free(index);
		free(entry_data);
		return tmp;
	}

	index->entries = malloc(index->entry_count * sizeof(asf_index_entry_t));
	if (!index->entries) {
		free(index);
		free(entry_data);
		return ASF_ERROR_OUTOFMEM;
	}

	for (i=0; i<index->entry_count; i++) {
		index->entries[i].packet_index = GetDWLE(entry_data + i*6);
		index->entries[i].packet_count = GetWLE(entry_data + i*6 + 4);
	}

	free(entry_data);
	file->index = index;

	return index->size;
}
Ejemplo n.º 6
0
/*****************************************************************************
 * ProcessHeader: process OggSpots header.
 *****************************************************************************/
static int ProcessHeader(decoder_t* p_dec)
{
    decoder_sys_t* p_sys = p_dec->p_sys;
    const uint8_t* p_extra;
    int i_major;
    int i_minor;
    uint64_t i_granulerate_numerator;
    uint64_t i_granulerate_denominator;

    /* The OggSpots header is always 52 bytes */
    if (p_dec->fmt_in.i_extra != 52) {
        return VLC_EGENERIC;
    }
    p_extra = p_dec->fmt_in.p_extra;

    /* Identification string */
    if ( memcmp(p_extra, "SPOTS\0\0", 8) ) {
        return VLC_EGENERIC;
    }

    /* Version number */
    i_major = GetWLE(&p_extra[ 8]); /* major version num */
    i_minor = GetWLE(&p_extra[10]); /* minor version num */
    if (i_major != 0 || i_minor != 1) {
        return VLC_EGENERIC;
    }

    /* Granule rate */
    i_granulerate_numerator   = GetQWLE(&p_extra[12]);
    i_granulerate_denominator = GetQWLE(&p_extra[20]);
    if (i_granulerate_numerator == 0 || i_granulerate_denominator == 0) {
        return VLC_EGENERIC;
    }

    /* The OggSpots spec contained an error and there are implementations out
     * there that used the wrong value. So we detect that case and switch
     * numerator and denominator in that case */
    if (i_granulerate_numerator == 1 && i_granulerate_denominator == 30) {
        i_granulerate_numerator   = 30;
        i_granulerate_denominator = 1;
    }

    /* Normalize granulerate */
    vlc_ureduce(&p_dec->fmt_in.video.i_frame_rate,
                &p_dec->fmt_in.video.i_frame_rate_base,
                i_granulerate_numerator, i_granulerate_denominator, 0);

    /* Image format */
    if (!p_sys->b_packetizer) {
        if ( memcmp(&p_extra[32], "PNG", 3) && memcmp(&p_extra[32], "JPEG", 4) ) {
            char psz_image_type[8+1];
            strncpy(psz_image_type, (char*)&p_extra[32], 8);
            psz_image_type[sizeof(psz_image_type)-1] = '\0';

            msg_Warn(p_dec, "Unsupported image format: %s", psz_image_type);
        }
    }

    /* Dimensions */
    p_dec->fmt_out.video.i_width  = p_dec->fmt_out.video.i_visible_width  =
            GetWLE(&p_extra[40]);
    p_dec->fmt_out.video.i_height = p_dec->fmt_out.video.i_visible_height =
            GetWLE(&p_extra[42]);

    /* We assume square pixels */
    p_dec->fmt_out.video.i_sar_num = 1;
    p_dec->fmt_out.video.i_sar_den = 1;

    /* We don't implement background color, alignment and options at the
     * moment because the former doesn't seem necessary right now and the
     * latter are underspecified. */

    if (p_sys->b_packetizer) {
        void* p_new_extra = realloc(p_dec->fmt_out.p_extra,
                                p_dec->fmt_in.i_extra);
        if (unlikely(p_new_extra == NULL)) {
            return VLC_ENOMEM;
        }
        p_dec->fmt_out.p_extra = p_new_extra;
        p_dec->fmt_out.i_extra = p_dec->fmt_in.i_extra;
        memcpy(p_dec->fmt_out.p_extra,
               p_dec->fmt_in.p_extra, p_dec->fmt_out.i_extra);
    }

    return VLC_SUCCESS;
}