Example #1
0
/* read atom header, return atom size, atom size is with header included */
uint64_t mp4ff_atom_read_header(mp4ff_t *f, uint8_t *atom_type, uint8_t *header_size)
{
    uint64_t size;
    int32_t ret;
    int8_t atom_header[8];

    ret = mp4ff_read_data(f, atom_header, 8);
    if (ret != 8)
        return 0;

    size = mp4ff_atom_get_size(atom_header);
    *header_size = 8;

    /* check for 64 bit atom size */
    if (size == 1)
    {
        *header_size = 16;
        size = mp4ff_read_int64(f);
    }

    //printf("%c%c%c%c\n", atom_header[4], atom_header[5], atom_header[6], atom_header[7]);

    *atom_type = mp4ff_atom_name_to_type(atom_header[4], atom_header[5], atom_header[6], atom_header[7]);

    return size;
}
Example #2
0
int32_t mp4ff_read_sample(mp4ff_t *f, const int32_t track, const int32_t sample,
                          uint8_t **audio_buffer,  uint32_t *bytes)
{
    int32_t result = 0;

    *bytes = mp4ff_audio_frame_size(f, track, sample);

	if (*bytes==0) return 0;

    *audio_buffer = (uint8_t*)malloc(*bytes);
    if (!(*audio_buffer)) {
        //fprintf (stderr, "mp4ff_read_sample: malloc failure (tried to alloc %d bytes). possible mp4ff bug or memleak! please report a bug to deadbeef developers (i'm serious).\n", *bytes);
        return 0;
    }

    mp4ff_set_sample_position(f, track, sample);

    result = mp4ff_read_data(f, *audio_buffer, *bytes);

    if (!result)
	{
		free(*audio_buffer);
		*audio_buffer = 0;
        return 0;
	}

#ifdef ITUNES_DRM
    if (f->track[track]->p_drms != NULL)
    {
        drms_decrypt(f->track[track]->p_drms, (uint32_t*)*audio_buffer, *bytes);
    }
#endif

    return *bytes;
}
Example #3
0
int32_t mp4ff_read_sample(mp4ff_t *f, const int32_t track, const int32_t sample,
                          uint8_t **audio_buffer,  uint32_t *bytes)
{
    int32_t result = 0;

    *bytes = mp4ff_audio_frame_size(f, track, sample);

	if (*bytes==0) return 0;

    *audio_buffer = (uint8_t*)malloc(*bytes);

    mp4ff_set_sample_position(f, track, sample);

    result = mp4ff_read_data(f, *audio_buffer, *bytes);

    if (!result)
	{
		free(*audio_buffer);
		*audio_buffer = 0;
        return 0;
	}

#ifdef ITUNES_DRM
    if (f->track[track]->p_drms != NULL)
    {
        drms_decrypt(f->track[track]->p_drms, (uint32_t*)*audio_buffer, *bytes);
    }
#endif

    return *bytes;
}
Example #4
0
uint16_t mp4ff_read_int16(mp4ff_t *f)
{
    uint32_t result;
    uint32_t a, b;
    uint8_t data[2];
    
    mp4ff_read_data(f, data, 2);
    a = data[0];
    b = data[1];

    result = (a<<8) | b;
    return (uint16_t)result;
}
Example #5
0
uint32_t mp4ff_read_int24(mp4ff_t *f)
{
    uint32_t result;
    uint32_t a, b, c;
    uint8_t data[4];
    
    mp4ff_read_data(f, data, 3);
    a = data[0];
    b = data[1];
    c = data[2];

    result = (a<<16) | (b<<8) | c;
    return (uint32_t)result;
}
Example #6
0
uint64_t mp4ff_read_int64(mp4ff_t *f)
{
    uint8_t data[8];
    uint64_t result = 0;
    int i;

    mp4ff_read_data(f, data, 8);

    for (i = 0; i < 8; i++)
    {
        result |= ((uint64_t)data[i]) << ((7 - i) * 8);
    }

    return result;
}
Example #7
0
uint32_t mp4ff_read_int32(mp4ff_t *f)
{
    uint32_t result;
    uint32_t a, b, c, d;
    uint8_t data[4];
    
    mp4ff_read_data(f, data, 4);
    a = data[0];
    b = data[1];
    c = data[2];
    d = data[3];

    result = (a<<24) | (b<<16) | (c<<8) | d;
    return (uint32_t)result;
}
Example #8
0
static int32_t mp4ff_read_key(mp4ff_t *f, uint64_t size)
{
    uint8_t *data = malloc(size);
    mp4ff_read_data(f, data, size);

    if (f->track[f->total_tracks - 1]->p_drms != 0)
    {
        drms_init(f->track[f->total_tracks - 1]->p_drms,
            FOURCC_key, data, size );
    }

    if (data)
        free(data);

    return 0;
}
Example #9
0
int32_t mp4ff_read_sample_v2(mp4ff_t *f, const int track, const int sample,unsigned char *buffer)
{
    int32_t result = 0;
	int32_t size = mp4ff_audio_frame_size(f,track,sample);
	if (size<=0) return 0;
	mp4ff_set_sample_position(f, track, sample);
	result = mp4ff_read_data(f,buffer,size);

#ifdef ITUNES_DRM
    if (f->track[track]->p_drms != NULL)
    {
        drms_decrypt(f->track[track]->p_drms, (uint32_t*)buffer, size);
    }
#endif

    return result;
}
Example #10
0
char * mp4ff_read_string(mp4ff_t * f,uint32_t length)
{
	char * str = malloc(length + 1);
	if (str!=0)
	{
		if ((uint32_t)mp4ff_read_data(f,(uint8_t *)str,length)!=length)
		{
			free(str);
			str = 0;
		}
		else
		{
			str[length] = 0;
		}
	}
	return str;	
}
Example #11
0
static int32_t mp4ff_read_frma(mp4ff_t *f)
{
    uint8_t atom_type;
    int8_t type[4];

    mp4ff_read_data(f, type, 4);

    atom_type = mp4ff_atom_name_to_type(type[0], type[1], type[2], type[3]);

    if (atom_type == ATOM_MP4A)
    {
        f->track[f->total_tracks - 1]->type = TRACK_AUDIO;
    } else if (atom_type == ATOM_MP4V) {
        f->track[f->total_tracks - 1]->type = TRACK_VIDEO;
    } else if (atom_type == ATOM_MP4S) {
        f->track[f->total_tracks - 1]->type = TRACK_SYSTEM;
    } else {
        f->track[f->total_tracks - 1]->type = TRACK_UNKNOWN;
    }

    return 0;
}
Example #12
0
static int32_t mp4ff_read_esds(mp4ff_t *f)
{
    uint8_t tag;
    uint32_t temp;

    mp4ff_read_char(f); /* version */
    mp4ff_read_int24(f); /* flags */

    /* get and verify ES_DescrTag */
    tag = mp4ff_read_char(f);
    if (tag == 0x03)
    {
        /* read length */
        if (mp4ff_read_mp4_descr_length(f) < 5 + 15)
        {
            return 1;
        }
        /* skip 3 bytes */
        mp4ff_read_int24(f);
    } else {
        /* skip 2 bytes */
        mp4ff_read_int16(f);
    }

    /* get and verify DecoderConfigDescrTab */
    if (mp4ff_read_char(f) != 0x04)
    {
        return 1;
    }

    /* read length */
    temp = mp4ff_read_mp4_descr_length(f);
    if (temp < 13) return 1;

    f->track[f->total_tracks - 1]->audioType = mp4ff_read_char(f);
    mp4ff_read_int32(f);//0x15000414 ????
    f->track[f->total_tracks - 1]->maxBitrate = mp4ff_read_int32(f);
    f->track[f->total_tracks - 1]->avgBitrate = mp4ff_read_int32(f);

    /* get and verify DecSpecificInfoTag */
    if (mp4ff_read_char(f) != 0x05)
    {
        return 1;
    }

    /* read length */
    f->track[f->total_tracks - 1]->decoderConfigLen = mp4ff_read_mp4_descr_length(f);

    if (f->track[f->total_tracks - 1]->decoderConfig)
        free(f->track[f->total_tracks - 1]->decoderConfig);
    f->track[f->total_tracks - 1]->decoderConfig = malloc(f->track[f->total_tracks - 1]->decoderConfigLen);
    if (f->track[f->total_tracks - 1]->decoderConfig)
    {
        mp4ff_read_data(f, f->track[f->total_tracks - 1]->decoderConfig, f->track[f->total_tracks - 1]->decoderConfigLen);
    } else {
        f->track[f->total_tracks - 1]->decoderConfigLen = 0;
    }

    /* will skip the remainder of the atom */
    return 0;
}
Example #13
0
uint8_t mp4ff_read_char(mp4ff_t *f)
{
    uint8_t output;
    mp4ff_read_data(f, &output, 1);
    return output;
}
Example #14
0
int32_t mp4ff_parse_tag(mp4ff_t *f, const uint8_t parent_atom_type, const int32_t size)
{
    uint8_t atom_type;
    uint8_t header_size = 0;
    uint64_t subsize, sumsize = 0;
    char * name = NULL;
	char * data = NULL;
	uint32_t done = 0;


    while (sumsize < size)
    {
		uint64_t destpos;
        subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
		destpos = mp4ff_position(f)+subsize-header_size;
		if (!done)
		{
			if (atom_type == ATOM_DATA)
			{
				mp4ff_read_char(f); /* version */
				mp4ff_read_int24(f); /* flags */
				mp4ff_read_int32(f); /* reserved */

				/* some need special attention */
				if (parent_atom_type == ATOM_GENRE2 || parent_atom_type == ATOM_TEMPO)
				{
					if (subsize - header_size >= 8 + 2)
					{
						uint16_t val = mp4ff_read_int16(f);

						if (parent_atom_type == ATOM_TEMPO)
						{
							char temp[16];
							sprintf(temp, "%.5u BPM", val);
							mp4ff_tag_add_field(&(f->tags), "tempo", temp);
						}
						else
						{
							const char * temp = mp4ff_meta_index_to_genre(val);
							if (temp)
							{
								mp4ff_tag_add_field(&(f->tags), "genre", temp);
							}
						}
						done = 1;
					}
				} else if (parent_atom_type == ATOM_TRACK || parent_atom_type == ATOM_DISC) {
					/* if (!done && subsize - header_size >= 8 + 8) */
					/* modified by AJS */
					if ( !done && (subsize - header_size) >=
						(sizeof(char) + sizeof(uint8_t)*3 + sizeof(uint32_t) + /* version + flags + reserved */
						+ sizeof(uint16_t) /* leading uint16_t */
						+ sizeof(uint16_t) /* track / disc */
						+ sizeof(uint16_t)) /* totaltracks / totaldiscs */
						)
					{
						uint16_t index,total;
						char temp[32];
						mp4ff_read_int16(f);
						index = mp4ff_read_int16(f);
						total = mp4ff_read_int16(f);
  						/* modified by AJS */
						/* mp4ff_read_int16(f); */

						sprintf(temp,"%d",index);
						mp4ff_tag_add_field(&(f->tags), parent_atom_type == ATOM_TRACK ? "track" : "disc", temp);
						if (total>0)
						{
							sprintf(temp,"%d",total);
							mp4ff_tag_add_field(&(f->tags), parent_atom_type == ATOM_TRACK ? "totaltracks" : "totaldiscs", temp);
						}
						done = 1;
					}
				} else if (parent_atom_type == ATOM_COVER) {
					if (data)
					{
						free(data);
						data = NULL;
					}
					if (f->load_covers)
					{
						uint32_t datasize = (uint32_t)(subsize-(header_size+8));
						data = malloc(datasize);
						if (!data) {
							// allocation error
						}
						else if (datasize != mp4ff_read_data(f, data, datasize))
						{
							free (data);
							data = NULL;
						}
						else
						{
							mp4ff_cover_append_item (f, data, datasize);
							data = NULL;
						}
					}
				} else
				{
					if (data) {free(data);data = NULL;}
					data = mp4ff_read_string(f,(uint32_t)(subsize-(header_size+8)));
				}
			} else if (atom_type == ATOM_NAME) {
				if (!done)
				{
					mp4ff_read_char(f); /* version */
					mp4ff_read_int24(f); /* flags */
					if (name) free(name);
					name = mp4ff_read_string(f,(uint32_t)(subsize-(header_size+4)));
				}
			}
			mp4ff_set_position(f, destpos);
			sumsize += subsize;
		}
    }

	if (data)
	{
		if (!done)
		{
			if (name == NULL) mp4ff_set_metadata_name(f, parent_atom_type, &name);
			if (name) mp4ff_tag_add_field(&(f->tags), name, data);
		}

		free(data);
	}
	if (name) free(name);
    return 1;
}
Example #15
0
static int32_t mp4ff_read_chpl(mp4ff_t *f, const uint64_t size)
{
    int i;
    int i_read = size;

    mp4ff_read_char(f); /* version */
    mp4ff_read_int24(f); /* flags */

    mp4ff_chapterdata_t *p_chpl = &f->chapters;

    p_chpl->i_chapter = mp4ff_read_char (f);
    i_read -= 5;

    for( i = 0; i < p_chpl->i_chapter; i++ )
    {
        uint64_t i_start;
        uint8_t i_len;
        int i_copy;
        i_start = mp4ff_read_int64 (f);
        i_read -= 8;
        i_len = mp4ff_read_char (f);
        i_read -= 1;

        p_chpl->chapter[i].psz_name = malloc( i_len + 1 );
        if( !p_chpl->chapter[i].psz_name )
            goto error;

        i_copy = i_len < i_read ? i_len : i_read;
        if( i_copy > 0 )
            mp4ff_read_data (f, p_chpl->chapter[i].psz_name, i_copy);
        p_chpl->chapter[i].psz_name[i_copy] = '\0';
        p_chpl->chapter[i].i_start = i_start;

        i_read -= i_copy;
    }
    /* Bubble sort by increasing start date */
    do
    {
        for( i = 0; i < p_chpl->i_chapter - 1; i++ )
        {
            if( p_chpl->chapter[i].i_start > p_chpl->chapter[i+1].i_start )
            {
                char *psz = p_chpl->chapter[i+1].psz_name;
                int64_t i64 = p_chpl->chapter[i+1].i_start;

                p_chpl->chapter[i+1].psz_name = p_chpl->chapter[i].psz_name;
                p_chpl->chapter[i+1].i_start = p_chpl->chapter[i].i_start;

                p_chpl->chapter[i].psz_name = psz;
                p_chpl->chapter[i].i_start = i64;

                i = -1;
                break;
            }
        }
    } while( i == -1 );

    return 0;

error:
    return -1;
}