Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[what][draft][mov] 引入 mov_block_t 将部分内存管理控制权转给到调用方 #265

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 35 additions & 0 deletions libmov/include/mov-blocks.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
#ifndef _mov_blocks_h_
#define _mov_blocks_h_

#include <stdint.h>

struct mov_blocks_t
{
/// create a blocks
/// @param[in] param user-defined parameter
/// @param[in] id blocks identifier
/// @param[in] block_size single block size
/// @return 0-ok, <0-error
int (*create)(void* param, uint32_t id, uint32_t block_size);

/// destroy a blocks
/// @param[in] param user-defined parameter
/// @param[in] id blocks identifier
/// @return 0-ok, <0-error
int (*destroy)(void* param, uint32_t id);

/// set blocks capacity
/// @param[in] param user-defined parameter
/// @param[in] id blocks identifier
/// @param[in] capacity blocks capacity
int (*set_capacity)(void* param, uint32_t id, uint64_t capacity);

/// get block by index
/// @param[in] param user-defined parameter
/// @param[in] id blocks identifier
/// @param[in] index block index in blocks
/// @return memory pointer
void* (*at)(void* param, uint32_t id, uint64_t index);
};

#endif /*! _mov_blocks_h_ */
3 changes: 2 additions & 1 deletion libmov/include/mov-writer.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <stddef.h>
#include <stdint.h>
#include "mov-buffer.h"
#include "mov-blocks.h"

#ifdef __cplusplus
extern "C" {
Expand All @@ -12,7 +13,7 @@ extern "C" {
typedef struct mov_writer_t mov_writer_t;

/// @param[in] flags mov flags, such as: MOV_FLAG_FASTSTART, see more @mov-format.h
mov_writer_t* mov_writer_create(const struct mov_buffer_t* buffer, void* param, int flags);
mov_writer_t* mov_writer_create(const struct mov_buffer_t* buffer, const struct mov_blocks_t* blocks, void* buffer_param, void* blocks_param, int flags);
void mov_writer_destroy(mov_writer_t* mov);

/// @param[in] object MPEG-4 systems ObjectTypeIndication such as: MOV_OBJECT_H264, see more @mov-format.h
Expand Down
5 changes: 3 additions & 2 deletions libmov/source/fmp4-reader.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,14 @@ static int mov_fragment_seek_get_duration(struct mov_t* mov)
{
int i;
struct mov_track_t* track;
track = mov->track_count > 0 ? &mov->tracks[0] : NULL;
uint32_t track_id = 0;
track = mov->track_count > 0 ? &mov->tracks[track_id] : NULL;
if (track && track->frag_capacity < track->frag_count && track->mdhd.timescale)
{
mov_buffer_seek(&mov->io, track->frags[track->frag_count - 1].offset);
mov_reader_root(mov); // moof

track->mdhd.duration = track->samples[track->sample_count - 1].dts - track->samples[0].dts;
track->mdhd.duration = mov_sample_t_at(&mov->blocks, track_id, track->sample_count - 1)->dts - mov_sample_t_at(&mov->blocks, track_id, 0)->dts;
mov->mvhd.duration = track->mdhd.duration * mov->mvhd.timescale / track->mdhd.timescale;

// clear samples and seek to the first moof
Expand Down
38 changes: 23 additions & 15 deletions libmov/source/fmp4-writer.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,10 @@ static size_t fmp4_write_traf(struct mov_t* mov, uint32_t moof)
if (track->sample_count > 0)
{
track->tfhd.flags |= MOV_TFHD_FLAG_DEFAULT_DURATION | MOV_TFHD_FLAG_DEFAULT_SIZE;
track->tfhd.default_sample_duration = track->sample_count > 1 ? (uint32_t)(track->samples[1].dts - track->samples[0].dts) : (uint32_t)track->turn_last_duration;
track->tfhd.default_sample_size = track->samples[0].bytes;
track->tfhd.default_sample_duration = track->sample_count > 1 ?
(uint32_t)(mov_sample_t_at(&mov->blocks, track->track_id, 1)->dts - mov_sample_t_at(&mov->blocks, track->track_id, 0)->dts) :
(uint32_t)track->turn_last_duration;
track->tfhd.default_sample_size = mov_sample_t_at(&mov->blocks, track->track_id, 0)->bytes;
}
else
{
Expand All @@ -95,7 +97,8 @@ static size_t fmp4_write_traf(struct mov_t* mov, uint32_t moof)

for (start = 0, i = 1; i < track->sample_count; i++)
{
if (track->samples[i - 1].offset + track->samples[i - 1].bytes != track->samples[i].offset)
if (mov_sample_t_at(&mov->blocks, track->track_id, i - 1)->offset + mov_sample_t_at(&mov->blocks, track->track_id, i - 1)->bytes
!= mov_sample_t_at(&mov->blocks, track->track_id, i)->offset)
{
size += mov_write_trun(mov, start, i-start, moof);
start = i;
Expand Down Expand Up @@ -130,8 +133,8 @@ static size_t fmp4_write_moof(struct mov_t* mov, uint32_t fragment, uint32_t moo
// 2017/10/17 Dale Curtis SHA-1: a5fd8aa45b11c10613e6e576033a6b5a16b9cbb9 (libavformat/mov.c)
for (j = 0; j < mov->track->sample_count; j++)
{
mov->track->samples[j].offset = n;
n += mov->track->samples[j].bytes;
mov_sample_t_at(&mov->blocks, mov->track->track_id, j)->offset = n;
n += mov_sample_t_at(&mov->blocks, mov->track->track_id, j)->bytes;
}

if (mov->track->sample_count > 0)
Expand Down Expand Up @@ -272,7 +275,7 @@ static int fmp4_write_fragment(struct fmp4_writer_t* writer)
{
mov->track = mov->tracks + i;
if (mov->track->sample_count > 0 && 0 == (mov->flags & MOV_FLAG_SEGMENT))
fmp4_add_fragment_entry(mov->track, mov->track->samples[0].dts, mov->moof_offset);
fmp4_add_fragment_entry(mov->track, mov_sample_t_at(&mov->blocks, mov->track->track_id, 0)->dts, mov->moof_offset);

// hack: write sidx referenced_size
if (mov->flags & MOV_FLAG_SEGMENT)
Expand Down Expand Up @@ -301,11 +304,13 @@ static int fmp4_write_fragment(struct fmp4_writer_t* writer)
for (i = 0; i < mov->track_count; i++)
{
mov->track = mov->tracks + i;
while (mov->track->offset < mov->track->sample_count && n == mov->track->samples[mov->track->offset].offset)
while (mov->track->offset < mov->track->sample_count && n == mov_sample_t_at(&mov->blocks, mov->track->track_id, mov->track->offset)->offset)
{
mov_buffer_write(&mov->io, mov->track->samples[mov->track->offset].data, mov->track->samples[mov->track->offset].bytes);
free(mov->track->samples[mov->track->offset].data); // free av packet memory
n += mov->track->samples[mov->track->offset].bytes;

mov_buffer_write(&mov->io, mov_sample_t_at(&mov->blocks, mov->track->track_id, mov->track->offset)->data,
mov_sample_t_at(&mov->blocks, mov->track->track_id, mov->track->offset)->bytes);
free(mov_sample_t_at(&mov->blocks, mov->track->track_id, mov->track->offset)->data); // free av packet memory
n += mov_sample_t_at(&mov->blocks, mov->track->track_id, mov->track->offset)->bytes;
++mov->track->offset;
}
}
Expand Down Expand Up @@ -354,6 +359,8 @@ static int fmp4_writer_init(struct mov_t* mov)

struct fmp4_writer_t* fmp4_writer_create(const struct mov_buffer_t *buffer, void* param, int flags)
{
// todo : adaptor mov_blocks_t

struct mov_t* mov;
struct fmp4_writer_t* writer;
writer = (struct fmp4_writer_t*)calloc(1, sizeof(struct fmp4_writer_t));
Expand Down Expand Up @@ -385,7 +392,7 @@ void fmp4_writer_destroy(struct fmp4_writer_t* writer)
fmp4_writer_save_segment(writer);

for (i = 0; i < mov->track_count; i++)
mov_free_track(mov->tracks + i);
mov_free_track(mov, mov->tracks + i);
if (mov->tracks)
free(mov->tracks);
free(writer);
Expand Down Expand Up @@ -416,16 +423,17 @@ int fmp4_writer_write(struct fmp4_writer_t* writer, int idx, const void* data, s

if (track->sample_count + 1 >= track->sample_offset)
{
void* ptr = realloc(track->samples, sizeof(struct mov_sample_t) * (track->sample_offset + 1024));
if (NULL == ptr) return -ENOMEM;
track->samples = (struct mov_sample_t*)ptr;
if (mov_blocks_set_capacity(&writer->mov.blocks, idx, track->sample_offset + 1024) < 0)
{
return -ENOMEM;
}
track->sample_offset += 1024;
}

pts = pts * track->mdhd.timescale / 1000;
dts = dts * track->mdhd.timescale / 1000;

sample = &track->samples[track->sample_count];
sample = mov_sample_t_at(&writer->mov.blocks, idx, track->sample_count);
sample->sample_description_index = 1;
sample->bytes = (uint32_t)bytes;
sample->flags = flags;
Expand Down
39 changes: 39 additions & 0 deletions libmov/source/mov-blocks-util.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
#ifndef _mov_blocks_ulti_h_
#define _mov_ioutil_ulti_h_

#include "mov-blocks.h"

struct mov_sample_t;

struct mov_blocks_utli_t
{
struct mov_blocks_t blocks;
void* param;
};

static inline int mov_blocks_create(const struct mov_blocks_utli_t* blocks, uint32_t id, uint32_t block_size)
{
return blocks->blocks.create(blocks->param, id, block_size);
};

static inline int mov_blocks_destroy(const struct mov_blocks_utli_t* blocks, uint32_t id)
{
return blocks->blocks.destroy(blocks->param, id);
}

static inline int mov_blocks_set_capacity(const struct mov_blocks_utli_t* blocks, uint32_t id, uint64_t capacity)
{
return blocks->blocks.set_capacity(blocks->param, id, capacity);
}

static inline void* mov_blocks_at(const struct mov_blocks_utli_t* blocks, uint32_t id, uint64_t index)
{
return blocks->blocks.at(blocks->param, id, index);
}

static inline struct mov_sample_t* mov_sample_t_at(const struct mov_blocks_utli_t* blocks, uint32_t id, uint64_t index)
{
return (struct mov_sample_t*)mov_blocks_at(blocks, id, index);
}

#endif /* !_mov_ioutil_ulti_h_ */
18 changes: 9 additions & 9 deletions libmov/source/mov-elst.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,13 @@ size_t mov_write_elst(const struct mov_t* mov)
uint8_t version;
const struct mov_track_t* track = mov->track;

assert(track->start_dts == track->samples[0].dts);
assert(track->start_dts == mov_sample_t_at(&mov->blocks, track->track_id, 0)->dts);
version = track->tkhd.duration > UINT32_MAX ? 1 : 0;

// in media time scale units, in composition time
time = track->samples[0].pts - track->samples[0].dts;
time = mov_sample_t_at(&mov->blocks, track->track_id, 0)->pts - mov_sample_t_at(&mov->blocks, track->track_id, 0)->dts;
// in units of the timescale in the Movie Header Box
delay = track->samples[0].pts * mov->mvhd.timescale / track->mdhd.timescale;
delay = mov_sample_t_at(&mov->blocks, track->track_id, 0)->pts * mov->mvhd.timescale / track->mdhd.timescale;
if (delay > UINT32_MAX)
version = 1;

Expand Down Expand Up @@ -105,24 +105,24 @@ size_t mov_write_elst(const struct mov_t* mov)
return size;
}

void mov_apply_elst(struct mov_track_t *track)
void mov_apply_elst(const struct mov_t* mov, struct mov_track_t *track)
{
size_t i;

// edit list
track->samples[0].dts = 0;
track->samples[0].pts = 0;
mov_sample_t_at(&mov->blocks, track->track_id, 0)->dts = 0;
mov_sample_t_at(&mov->blocks, track->track_id, 0)->pts = 0;
for (i = 0; i < track->elst_count; i++)
{
if (-1 == track->elst[i].media_time)
{
track->samples[0].dts = track->elst[i].segment_duration;
track->samples[0].pts = track->samples[0].dts;
mov_sample_t_at(&mov->blocks, track->track_id, 0)->dts = track->elst[i].segment_duration;
mov_sample_t_at(&mov->blocks, track->track_id, 0)->pts = mov_sample_t_at(&mov->blocks, track->track_id, 0)->dts;
}
}
}

void mov_apply_elst_tfdt(struct mov_track_t *track)
void mov_apply_elst_tfdt(const struct mov_t* mov, struct mov_track_t *track)
{
size_t i;

Expand Down
30 changes: 17 additions & 13 deletions libmov/source/mov-internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
#include "mov-format.h"
#include "mov-buffer.h"
#include "mov-ioutil.h"
#include "mov-blocks-util.h"

#define MOV_APP "ireader/media-server"

Expand Down Expand Up @@ -163,6 +164,8 @@ struct mov_track_t
uint32_t handler_type; // MOV_VIDEO/MOV_AUDIO
const char* handler_descr; // VideoHandler/SoundHandler/SubtitleHandler

uint32_t track_id; // todo : correctly assign track id when track change

struct mov_tkhd_t tkhd;
struct mov_mdhd_t mdhd;
struct mov_stbl_t stbl;
Expand All @@ -178,7 +181,7 @@ struct mov_track_t
struct mov_elst_t* elst;
size_t elst_count;

struct mov_sample_t* samples;
struct mov_sample_t* samples; // todo : remove it use mov_blocks_utli_t instead
uint32_t sample_count;
size_t sample_offset; // sample_capacity

Expand All @@ -193,7 +196,8 @@ struct mov_track_t

struct mov_t
{
struct mov_ioutil_t io;
struct mov_ioutil_t io;
struct mov_blocks_utli_t blocks;

struct mov_ftyp_t ftyp;
struct mov_mvhd_t mvhd;
Expand Down Expand Up @@ -300,19 +304,19 @@ size_t mov_write_trak(const struct mov_t* mov);
size_t mov_write_dops(const struct mov_t* mov);
size_t mov_write_udta(const struct mov_t* mov);

uint32_t mov_build_stts(struct mov_track_t* track);
uint32_t mov_build_ctts(struct mov_track_t* track);
uint32_t mov_build_stco(struct mov_track_t* track);
void mov_apply_stco(struct mov_track_t* track);
void mov_apply_elst(struct mov_track_t *track);
void mov_apply_stts(struct mov_track_t* track);
void mov_apply_ctts(struct mov_track_t* track);
void mov_apply_stss(struct mov_track_t* track);
void mov_apply_elst_tfdt(struct mov_track_t *track);
uint32_t mov_build_stts(const struct mov_t* mov, struct mov_track_t* track);
uint32_t mov_build_ctts(const struct mov_t* mov, struct mov_track_t* track);
uint32_t mov_build_stco(const struct mov_t* mov, struct mov_track_t* track);
void mov_apply_stco(const struct mov_t* mov, struct mov_track_t* track);
void mov_apply_elst(const struct mov_t* mov, struct mov_track_t *track);
void mov_apply_stts(const struct mov_t* mov, struct mov_track_t* track);
void mov_apply_ctts(const struct mov_t* mov, struct mov_track_t* track);
void mov_apply_stss(const struct mov_t* mov, struct mov_track_t* track);
void mov_apply_elst_tfdt(const struct mov_t* mov, struct mov_track_t *track);

void mov_write_size(const struct mov_t* mov, uint64_t offset, size_t size);

size_t mov_stco_size(const struct mov_track_t* track, uint64_t offset);
size_t mov_stco_size(const struct mov_t* mov, const struct mov_track_t* track, uint64_t offset);

int mov_fragment_read_next_moof(struct mov_t* mov);
int mov_fragment_seek_read_mfra(struct mov_t* mov);
Expand All @@ -321,7 +325,7 @@ int mov_fragment_seek(struct mov_t* mov, int64_t* timestamp);
uint8_t mov_tag_to_object(uint32_t tag);
uint32_t mov_object_to_tag(uint8_t object);

void mov_free_track(struct mov_track_t* track);
void mov_free_track(const struct mov_t* mov, struct mov_track_t* track);
struct mov_track_t* mov_add_track(struct mov_t* mov);
struct mov_track_t* mov_find_track(const struct mov_t* mov, uint32_t track);
struct mov_track_t* mov_fetch_track(struct mov_t* mov, uint32_t track); // find and add
Expand Down
Loading