예제 #1
0
static int32_t mp4ff_read_meta(mp4ff_t *f, const uint64_t size)
{
    uint64_t subsize, sumsize = 0;
    uint8_t atom_type;
    uint8_t header_size = 0;

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

    while (sumsize < (size-(header_size+4)))
    {
        subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
        if (subsize <= header_size+4)
            return 1;
        if (atom_type == ATOM_ILST)
        {
            mp4ff_parse_metadata(f, (uint32_t)(subsize-(header_size+4)));
        } else {
            mp4ff_set_position(f, mp4ff_position(f)+subsize-header_size);
        }
        sumsize += subsize;
    }

    return 0;
}
예제 #2
0
static int32_t mp4ff_read_mp4a(mp4ff_t *f)
{
    uint64_t size;
    int32_t i;
    uint8_t atom_type = 0;
    uint8_t header_size = 0;

    for (i = 0; i < 6; i++)
    {
        mp4ff_read_char(f); /* reserved */
    }
    /* data_reference_index */ mp4ff_read_int16(f);

    mp4ff_read_int32(f); /* reserved */
    mp4ff_read_int32(f); /* reserved */

    f->track[f->total_tracks - 1]->channelCount = mp4ff_read_int16(f);
    f->track[f->total_tracks - 1]->sampleSize = mp4ff_read_int16(f);

    mp4ff_read_int16(f);
    mp4ff_read_int16(f);

    f->track[f->total_tracks - 1]->sampleRate = mp4ff_read_int16(f);

    mp4ff_read_int16(f);

    size = mp4ff_atom_read_header(f, &atom_type, &header_size);
    if (atom_type == ATOM_ESDS)
    {
        mp4ff_read_esds(f);
    }

    return 0;
}
예제 #3
0
static int32_t mp4ff_read_stsd(mp4ff_t *f)
{
    int32_t i;
    uint8_t header_size = 0;

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

    f->track[f->total_tracks - 1]->stsd_entry_count = mp4ff_read_int32(f);

    for (i = 0; i < f->track[f->total_tracks - 1]->stsd_entry_count; i++)
    {
        uint64_t skip = mp4ff_position(f);
        uint64_t size;
        uint8_t atom_type = 0;
        size = mp4ff_atom_read_header(f, &atom_type, &header_size);
        skip += size;

        if (atom_type == ATOM_MP4A)
        {
            f->track[f->total_tracks - 1]->type = TRACK_AUDIO;
            mp4ff_read_mp4a(f);
        } 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;
        }

        mp4ff_set_position(f, skip);
    }

    return 0;
}
예제 #4
0
static int32_t mp4ff_read_drms(mp4ff_t *f, uint64_t skip)
{
    uint64_t size;
    int32_t i;
    uint8_t atom_type = 0;
    uint8_t header_size = 0;

    f->track[f->total_tracks - 1]->p_drms = drms_alloc( GetHomeDir() );

    for (i = 0; i < 6; i++)
    {
        mp4ff_read_char(f); /* reserved */
    }
    /* data_reference_index */ mp4ff_read_int16(f);

    mp4ff_read_int32(f); /* reserved */
    mp4ff_read_int32(f); /* reserved */

    f->track[f->total_tracks - 1]->channelCount = mp4ff_read_int16(f);
    f->track[f->total_tracks - 1]->sampleSize = mp4ff_read_int16(f);

    mp4ff_read_int16(f);
    mp4ff_read_int16(f);

    f->track[f->total_tracks - 1]->sampleRate = mp4ff_read_int16(f);

    mp4ff_read_int16(f);

    size = mp4ff_atom_read_header(f, &atom_type, &header_size);
    if (atom_type == ATOM_ESDS)
    {
        mp4ff_read_esds(f);
    }
    mp4ff_set_position(f, skip+size+28);

    size = mp4ff_atom_read_header(f, &atom_type, &header_size);
    if (atom_type == ATOM_SINF)
    {
        parse_sub_atoms(f, size-header_size,0);
    }

    return 0;
}
예제 #5
0
/* parse root atoms */
static int32_t parse_atoms_int (mp4ff_t *f,int meta_only,int stop_on_mdat)
{
    uint64_t size;
    uint8_t atom_type = 0;
    uint8_t header_size = 0;
    int had_valid_atoms = 0;

    f->file_size = 0;

    while ((size = mp4ff_atom_read_header(f, &atom_type, &header_size)) != 0)
    {
        // FIXME: ATOM_UNKNOWN is returned both when a valid (but unknown) atom is encontered,
        // and for invalid data. They need to be handled separately.
        if (atom_type == ATOM_UNKNOWN && !had_valid_atoms && mp4ff_position(f)+size > 100) {
            return -1;
        }

        had_valid_atoms = 1;

        f->file_size += size;
        f->last_atom = atom_type;

        if (atom_type == ATOM_MDAT && f->moov_read)
        {
            /* moov atom is before mdat, we can stop reading when mdat is encountered */
            /* file position will stay at beginning of mdat data */
            if (!stop_on_mdat) {
                break;
            }
        }

        if (atom_type == ATOM_MOOV && size > header_size)
        {
            f->moov_read = 1;
            f->moov_offset = mp4ff_position(f)-header_size;
            f->moov_size = size;
        }

        /* parse subatoms */
		if (meta_only && !need_parse_when_meta_only(atom_type))
		{
			mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
		} else if (atom_type < SUBATOMIC)
        {
            parse_sub_atoms(f, size-header_size,meta_only);
        } else {
            /* skip this atom */
            mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
        }
    }

    return 0;
}
예제 #6
0
int32_t mp4ff_parse_metadata(mp4ff_t *f, const int32_t size)
{
    uint64_t subsize, sumsize = 0;
    uint8_t atom_type;
    uint8_t header_size = 0;

    while (sumsize < size)
    {
        subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
        mp4ff_parse_tag(f, atom_type, (uint32_t)(subsize-header_size));
        sumsize += subsize;
    }

    return 0;
}
예제 #7
0
/* parse atoms that are sub atoms of other atoms */
int32_t parse_sub_atoms(mp4ff_t *f, const uint64_t total_size,int meta_only)
{
    uint64_t size;
    uint8_t atom_type = 0;
    uint64_t counted_size = 0;
    uint8_t header_size = 0;

    while (counted_size < total_size)
    {
        size = mp4ff_atom_read_header(f, &atom_type, &header_size);
        counted_size += size;

        /* check for end of file */
        if (size == 0)
            break;

        /* we're starting to read a new track, update index,
         * so that all data and tables get written in the right place
         */
        if (atom_type == ATOM_TRAK)
        {
            mp4ff_track_add(f);
        }

        /* parse subatoms */
		if (meta_only && !need_parse_when_meta_only(atom_type))
		{
			mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
		} else if (atom_type < SUBATOMIC)
        {
            parse_sub_atoms(f, size-header_size,meta_only);
        } else {
            mp4ff_atom_read(f, (uint32_t)size, atom_type);
        }
#if 0
        if (atom_type == ATOM_TRAK)
        {
            trace ("mp4ff_track_create_chunks_index\n");
            mp4ff_track_create_chunks_index (f, f->track[f->total_tracks-1]);
            trace ("mp4ff_track_create_samples_index\n");
            mp4ff_track_create_samples_index (f, f->track[f->total_tracks-1]);
        }
#endif
    }

    return 0;
}
예제 #8
0
/* parse root atoms */
int32_t parse_atoms(mp4ff_t *f,int meta_only)
{
    uint64_t size;
    uint8_t atom_type = 0;
    uint8_t header_size = 0;

    f->file_size = 0;

    while ((size = mp4ff_atom_read_header(f, &atom_type, &header_size)) != 0)
    {
        f->file_size += size;
        f->last_atom = atom_type;

        if (atom_type == ATOM_MDAT && f->moov_read)
        {
            /* moov atom is before mdat, we can stop reading when mdat is encountered */
            /* file position will stay at beginning of mdat data */
//            break;
        }

        if (atom_type == ATOM_MOOV && size > header_size)
        {
            f->moov_read = 1;
            f->moov_offset = mp4ff_position(f)-header_size;
            f->moov_size = size;
        }

        /* parse subatoms */
		if (meta_only && !need_parse_when_meta_only(atom_type))
		{
			mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
		} else if (atom_type < SUBATOMIC)
        {
            parse_sub_atoms(f, size-header_size,meta_only);
        } else {
            /* skip this atom */
            mp4ff_set_position(f, mp4ff_position(f)+size-header_size);
        }
    }

    return 0;
}
예제 #9
0
int32_t mp4ff_parse_metadata(mp4ff_t *f, const int32_t size)
{
    uint64_t subsize, sumsize = 0;
    uint8_t atom_type;
    uint8_t header_size = 0;

    while (sumsize < size)
    {
        subsize = mp4ff_atom_read_header(f, &atom_type, &header_size);
        if (subsize == 0)
            break;
        if (atom_type == ATOM_UNKNOWN)
          mp4ff_set_position(f, mp4ff_position(f)+subsize-header_size);
        else
          mp4ff_parse_tag(f, atom_type, (uint32_t)(subsize-header_size));
        sumsize += subsize;
    }

    return 0;
}
예제 #10
0
파일: mp4meta.c 프로젝트: Bobbin007/xbmc
static 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)
					{
						uint16_t index,total;
						char temp[32];
						mp4ff_read_int16(f);
						index = mp4ff_read_int16(f);
						total = mp4ff_read_int16(f);
						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 (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;
}