]> git.tuebingen.mpg.de Git - paraslash.git/blobdiff - mp4.c
mp4: Implement error checking for the write path.
[paraslash.git] / mp4.c
diff --git a/mp4.c b/mp4.c
index 1ab200545180be77722b511afd6aaf1c86006faa..fc8c41b4af919358350812cae68033611c5d33c4 100644 (file)
--- a/mp4.c
+++ b/mp4.c
@@ -14,8 +14,9 @@
 #include "mp4.h"
 
 struct mp4_track {
-       uint16_t channelCount;
-       uint16_t sampleRate;
+       /* mp4a */
+       uint16_t channel_count;
+       uint16_t sample_rate;
 
        /* stsz */
        uint32_t stsz_sample_size;
@@ -35,7 +36,8 @@ struct mp4_track {
        uint32_t stco_entry_count;
        uint32_t *stco_chunk_offset;
 
-       uint32_t timeScale;
+       /* mdhd */
+       uint32_t time_scale;
        uint64_t duration;
 };
 
@@ -377,7 +379,7 @@ static int read_mp4a(struct mp4 *f)
        ret = read_int32(f, NULL); /* reserved */
        if (ret <= 0)
                return ret;
-       ret = read_int16(f, &t->channelCount);
+       ret = read_int16(f, &t->channel_count);
        if (ret <= 0)
                return ret;
        ret = read_int16(f, NULL);
@@ -389,7 +391,7 @@ static int read_mp4a(struct mp4 *f)
        ret = read_int16(f, NULL);
        if (ret <= 0)
                return ret;
-       return read_int16(f, &t->sampleRate);
+       return read_int16(f, &t->sample_rate);
 }
 
 static int read_stsd(struct mp4 *f)
@@ -516,7 +518,7 @@ static int read_mdhd(struct mp4 *f)
                ret = read_int64(f, NULL); /* modification-time */
                if (ret <= 0)
                        return ret;
-               ret = read_int32(f, &t->timeScale);
+               ret = read_int32(f, &t->time_scale);
                if (ret <= 0)
                        return ret;
                ret = read_int64(f, &t->duration);
@@ -531,7 +533,7 @@ static int read_mdhd(struct mp4 *f)
                ret = read_int32(f, NULL); /* modification-time */
                if (ret <= 0)
                        return ret;
-               ret = read_int32(f, &t->timeScale);
+               ret = read_int32(f, &t->time_scale);
                if (ret <= 0)
                        return ret;
                ret = read_int32(f, &temp);
@@ -778,9 +780,9 @@ uint64_t mp4_get_duration(const struct mp4 *f)
 {
        const struct mp4_track *t = f->audio_track;
 
-       if (t->timeScale == 0)
+       if (t->time_scale == 0)
                return 0;
-       return t->duration * 1000 / t->timeScale;
+       return t->duration * 1000 / t->time_scale;
 }
 
 int mp4_set_sample_position(struct mp4 *f, int32_t sample)
@@ -819,12 +821,12 @@ int32_t mp4_get_sample_size(const struct mp4 *f, int sample)
 
 uint32_t mp4_get_sample_rate(const struct mp4 *f)
 {
-       return f->audio_track->sampleRate;
+       return f->audio_track->sample_rate;
 }
 
 uint32_t mp4_get_channel_count(const struct mp4 *f)
 {
-       return f->audio_track->channelCount ;
+       return f->audio_track->channel_count;
 }
 
 int32_t mp4_num_samples(const struct mp4 *f)
@@ -901,11 +903,6 @@ static void create_ilst(const struct mp4_metadata *meta, uint8_t *out)
        }
 }
 
-static uint32_t fix_byte_order_32(uint32_t src)
-{
-       return read_u32_be(&src);
-}
-
 static void *modify_moov(struct mp4 *f, uint32_t *out_size)
 {
        int ret;
@@ -931,7 +928,7 @@ static void *modify_moov(struct mp4 *f, uint32_t *out_size)
        ret = read_int32(f, &tmp);
        if (ret <= 0)
                return NULL;
-       *(uint32_t *)p_out = fix_byte_order_32(tmp + size_delta);
+       write_u32_be(p_out, tmp + size_delta);
        p_out += 4;
        ret = read_data(f, p_out, 4);
        if (ret <= 0)
@@ -944,7 +941,7 @@ static void *modify_moov(struct mp4 *f, uint32_t *out_size)
        ret = read_int32(f, &tmp);
        if (ret <= 0)
                return NULL;
-       *(uint32_t *)p_out = fix_byte_order_32(tmp + size_delta);
+       write_u32_be(p_out, tmp + size_delta);
        p_out += 4;
        ret = read_data(f, p_out, 4);
        if (ret <= 0)
@@ -957,7 +954,7 @@ static void *modify_moov(struct mp4 *f, uint32_t *out_size)
        ret = read_int32(f, &tmp);
        if (ret <= 0)
                return NULL;
-       *(uint32_t *)p_out = fix_byte_order_32(tmp + size_delta);
+       write_u32_be(p_out, tmp + size_delta);
        p_out += 4;
        ret = read_data(f, p_out, 4);
        if (ret <= 0)
@@ -973,28 +970,27 @@ static void *modify_moov(struct mp4 *f, uint32_t *out_size)
        return out_buffer;
 }
 
-static int32_t write_data(struct mp4 *f, void *data, uint32_t size)
+static int write_data(struct mp4 *f, void *data, size_t size)
 {
-       int32_t result = 1;
-
-       result = f->cb->write(f->cb->user_data, data, size);
-
-       f->current_position += size;
-
-       return result;
-}
-
-static int32_t write_int32(struct mp4 *f, uint32_t data)
-{
-       int8_t temp[4];
-       write_u32_be(temp, data);
-       return write_data(f, temp, sizeof(temp));
+       while (size > 0) {
+               ssize_t ret = f->cb->write(f->cb->user_data, data, size);
+               if (ret < 0) {
+                       if (errno == EINTR)
+                               continue;
+                       return -ERRNO_TO_PARA_ERROR(errno);
+               }
+               f->current_position += ret;
+               size -= ret;
+       }
+       return 1;
 }
 
-int32_t mp4_meta_update(struct mp4 *f)
+int mp4_meta_update(struct mp4 *f)
 {
        void *new_moov_data;
        uint32_t new_moov_size;
+       uint8_t buf[8] = "----moov";
+       int ret;
 
        set_position(f, 0);
        new_moov_data = modify_moov(f, &new_moov_size);
@@ -1002,27 +998,26 @@ int32_t mp4_meta_update(struct mp4 *f)
                mp4_close(f);
                return 0;
        }
-       /* copy moov atom to end of the file */
        if (f->last_atom != ATOM_MOOV) {
-               char *free_data = "free";
-
-               /* rename old moov to free */
                set_position(f, f->moov_offset + 4);
-               write_data(f, free_data, 4);
-
-               set_position(f, f->file_size);
-               write_int32(f, new_moov_size + 8);
-               write_data(f, "moov", 4);
-               write_data(f, new_moov_data, new_moov_size);
-       } else {
+               ret = write_data(f, "free", 4); /* rename old moov to free */
+               if (ret < 0)
+                       goto free_moov;
+               set_position(f, f->file_size); /* write new moov atom at EOF */
+       } else /* overwrite old moov atom */
                set_position(f, f->moov_offset);
-               write_int32(f, new_moov_size + 8);
-               write_data(f, "moov", 4);
-               write_data(f, new_moov_data, new_moov_size);
-       }
-       free(new_moov_data);
+       write_u32_be(buf, new_moov_size + 8);
+       ret = write_data(f, buf, sizeof(buf));
+       if (ret < 0)
+               goto free_moov;
+       ret = write_data(f, new_moov_data, new_moov_size);
+       if (ret < 0)
+               goto free_moov;
        f->cb->truncate(f->cb->user_data);
-       return 1;
+       ret = 1;
+free_moov:
+       free(new_moov_data);
+       return ret;
 }
 
 static char *meta_find_by_name(const struct mp4 *f, const char *item)