#include <regex.h>
#include "para.h"
+#include "error.h"
#include "portable_io.h"
#include "string.h"
#include "mp4.h"
*chunk_sample = 0;
*chunk = 1;
- if (f->track[track] == NULL) {
- return -1;
- }
total_entries = f->track[track]->stsc_entry_count;
return 0;
}
-static int32_t chunk_to_offset(const struct mp4 *f, int32_t track,
- int32_t chunk)
-{
- const struct mp4_track *p_track = f->track[track];
-
- if (p_track->stco_entry_count && (chunk > p_track->stco_entry_count)) {
- return p_track->stco_chunk_offset[p_track->stco_entry_count -
- 1];
- } else if (p_track->stco_entry_count) {
- return p_track->stco_chunk_offset[chunk - 1];
- } else {
- return 8;
- }
-
- return 0;
-}
-
-static int32_t sample_range_size(const struct mp4 *f, int32_t track,
- int32_t chunk_sample, int32_t sample)
-{
- int32_t i, total;
- const struct mp4_track *p_track = f->track[track];
-
- if (p_track->stsz_sample_size) {
- return (sample - chunk_sample) * p_track->stsz_sample_size;
- } else {
- if (sample >= p_track->stsz_sample_count)
- return 0; //error
-
- for (i = chunk_sample, total = 0; i < sample; i++) {
- total += p_track->stsz_table[i];
- }
- }
-
- return total;
-}
-
-static int32_t sample_to_offset(const struct mp4 *f, int32_t track,
- int32_t sample)
-{
- int32_t chunk, chunk_sample, chunk_offset1, chunk_offset2;
-
- chunk_of_sample(f, track, sample, &chunk_sample, &chunk);
-
- chunk_offset1 = chunk_to_offset(f, track, chunk);
- chunk_offset2 = chunk_offset1 + sample_range_size(f,
- track, chunk_sample, sample);
- return chunk_offset2;
-}
-
/**
* Return the number of milliseconds of the given track.
*
return f->track[track]->is_audio;
}
-void mp4_set_sample_position(struct mp4 *f, int32_t track, int32_t sample)
+int mp4_set_sample_position(struct mp4 *f, uint32_t track, int32_t sample)
{
- int32_t offset = sample_to_offset(f, track, sample);
- set_position(f, offset);
+ const struct mp4_track *t = f->track[track];
+ int32_t offset, chunk, chunk_sample;
+ uint32_t n, srs; /* sample range size */
+
+ if (sample >= t->stsz_sample_count || track >= f->total_tracks)
+ return -ERRNO_TO_PARA_ERROR(EINVAL);
+ chunk_of_sample(f, track, sample, &chunk_sample, &chunk);
+ if (t->stsz_sample_size > 0)
+ srs = (sample - chunk_sample) * t->stsz_sample_size;
+ else {
+ for (srs = 0, n = chunk_sample; n < sample; n++)
+ srs += t->stsz_table[n];
+ }
+ if (t->stco_entry_count > 0 && chunk > t->stco_entry_count)
+ offset = t->stco_chunk_offset[t->stco_entry_count - 1];
+ else if (t->stco_entry_count > 0)
+ offset = t->stco_chunk_offset[chunk - 1];
+ else
+ offset = 8;
+ set_position(f, offset + srs);
+ return 1;
}
int32_t mp4_get_sample_size(const struct mp4 *f, int track, int sample)