Commit 24e89b7b authored by Rafaël Carré's avatar Rafaël Carré

mp4 mux: simplify

parent e7042bde
...@@ -164,6 +164,8 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux); ...@@ -164,6 +164,8 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux);
static block_t *ConvertSUBT(block_t *); static block_t *ConvertSUBT(block_t *);
static block_t *ConvertAVC1(block_t *); static block_t *ConvertAVC1(block_t *);
static const char avc1_start_code[4] = { 0, 0, 0, 1 };
/***************************************************************************** /*****************************************************************************
* Open: * Open:
*****************************************************************************/ *****************************************************************************/
...@@ -236,15 +238,11 @@ static void Close(vlc_object_t *p_this) ...@@ -236,15 +238,11 @@ static void Close(vlc_object_t *p_this)
{ {
sout_mux_t *p_mux = (sout_mux_t*)p_this; sout_mux_t *p_mux = (sout_mux_t*)p_this;
sout_mux_sys_t *p_sys = p_mux->p_sys; sout_mux_sys_t *p_sys = p_mux->p_sys;
block_t *p_hdr;
bo_t bo, *moov;
vlc_value_t val;
uint64_t i_moov_pos;
msg_Dbg(p_mux, "Close"); msg_Dbg(p_mux, "Close");
/* Update mdat size */ /* Update mdat size */
bo_t bo;
bo_init(&bo); bo_init(&bo);
if (p_sys->i_pos - p_sys->i_mdat_pos >= (((uint64_t)1)<<32)) { if (p_sys->i_pos - p_sys->i_mdat_pos >= (((uint64_t)1)<<32)) {
/* Extended size */ /* Extended size */
...@@ -257,29 +255,26 @@ static void Close(vlc_object_t *p_this) ...@@ -257,29 +255,26 @@ static void Close(vlc_object_t *p_this)
bo_add_32be (&bo, p_sys->i_pos - p_sys->i_mdat_pos - 8); bo_add_32be (&bo, p_sys->i_pos - p_sys->i_mdat_pos - 8);
bo_add_fourcc(&bo, "mdat"); bo_add_fourcc(&bo, "mdat");
} }
p_hdr = bo.b;
p_hdr->i_buffer = bo.len;
bo.b->i_buffer = bo.len;
sout_AccessOutSeek(p_mux->p_access, p_sys->i_mdat_pos); sout_AccessOutSeek(p_mux->p_access, p_sys->i_mdat_pos);
sout_AccessOutWrite(p_mux->p_access, p_hdr); sout_AccessOutWrite(p_mux->p_access, bo.b);
/* Create MOOV header */ /* Create MOOV header */
i_moov_pos = p_sys->i_pos; uint64_t i_moov_pos = p_sys->i_pos;
moov = GetMoovBox(p_mux); bo_t *moov = GetMoovBox(p_mux);
/* Check we need to create "fast start" files */ /* Check we need to create "fast start" files */
var_Get(p_this, SOUT_CFG_PREFIX "faststart", &val); p_sys->b_fast_start = var_GetBool(p_this, SOUT_CFG_PREFIX "faststart");
p_sys->b_fast_start = val.b_bool;
while (p_sys->b_fast_start) { while (p_sys->b_fast_start) {
/* Move data to the end of the file so we can fit the moov header /* Move data to the end of the file so we can fit the moov header
* at the start */ * at the start */
block_t *p_buf; int64_t i_size = p_sys->i_pos - p_sys->i_mdat_pos;
int64_t i_chunk, i_size = p_sys->i_pos - p_sys->i_mdat_pos;
int i_moov_size = moov->len; int i_moov_size = moov->len;
while (i_size > 0) { while (i_size > 0) {
i_chunk = __MIN(32768, i_size); int64_t i_chunk = __MIN(32768, i_size);
p_buf = block_Alloc(i_chunk); block_t *p_buf = block_Alloc(i_chunk);
sout_AccessOutSeek(p_mux->p_access, sout_AccessOutSeek(p_mux->p_access,
p_sys->i_mdat_pos + i_size - i_chunk); p_sys->i_mdat_pos + i_size - i_chunk);
if (sout_AccessOutRead(p_mux->p_access, p_buf) < i_chunk) { if (sout_AccessOutRead(p_mux->p_access, p_buf) < i_chunk) {
...@@ -304,21 +299,18 @@ static void Close(vlc_object_t *p_this) ...@@ -304,21 +299,18 @@ static void Close(vlc_object_t *p_this)
moov->len = p_stream->i_stco_pos; moov->len = p_stream->i_stco_pos;
for (unsigned i = 0; i < p_stream->i_entry_count; ) { for (unsigned i = 0; i < p_stream->i_entry_count; ) {
mp4_entry_t *entry = p_stream->entry;
if (p_stream->b_stco64) if (p_stream->b_stco64)
bo_add_64be(moov, p_stream->entry[i].i_pos + i_moov_size); bo_add_64be(moov, entry[i].i_pos + i_moov_size);
else else
bo_add_32be(moov, p_stream->entry[i].i_pos + i_moov_size); bo_add_32be(moov, entry[i].i_pos + i_moov_size);
while (i < p_stream->i_entry_count) { for (; i < p_stream->i_entry_count; i++)
if (i + 1 < p_stream->i_entry_count && if (i >= p_stream->i_entry_count - 1 ||
p_stream->entry[i].i_pos + p_stream->entry[i].i_size entry[i].i_pos + entry[i].i_size != entry[i+1].i_pos) {
!= p_stream->entry[i + 1].i_pos) {
i++; i++;
break; break;
} }
i++;
}
} }
} }
...@@ -443,32 +435,27 @@ static int Mux(sout_mux_t *p_mux) ...@@ -443,32 +435,27 @@ static int Mux(sout_mux_t *p_mux)
sout_mux_sys_t *p_sys = p_mux->p_sys; sout_mux_sys_t *p_sys = p_mux->p_sys;
for (;;) { for (;;) {
sout_input_t *p_input; int i_stream = sout_MuxGetStream(p_mux, 2, NULL);
mp4_stream_t *p_stream;
block_t *p_data;
mtime_t i_dts;
int i_stream = sout_MuxGetStream(p_mux, 2, &i_dts);
if (i_stream < 0) if (i_stream < 0)
return(VLC_SUCCESS); return(VLC_SUCCESS);
p_input = p_mux->pp_inputs[i_stream]; sout_input_t *p_input = p_mux->pp_inputs[i_stream];
p_stream = (mp4_stream_t*)p_input->p_sys; mp4_stream_t *p_stream = (mp4_stream_t*)p_input->p_sys;
again: block_t *p_data;
p_data = block_FifoGet(p_input->p_fifo); do {
if (p_stream->fmt.i_codec == VLC_CODEC_H264) p_data = block_FifoGet(p_input->p_fifo);
p_data = ConvertAVC1(p_data); if (p_stream->fmt.i_codec == VLC_CODEC_H264)
else if (p_stream->fmt.i_codec == VLC_CODEC_SUBT) p_data = ConvertAVC1(p_data);
p_data = ConvertSUBT(p_data); else if (p_stream->fmt.i_codec == VLC_CODEC_SUBT)
if (p_data == NULL) p_data = ConvertSUBT(p_data);
goto again; } while (!p_data);
if (p_stream->fmt.i_cat != SPU_ES) { if (p_stream->fmt.i_cat != SPU_ES) {
/* Fix length of the sample */ /* Fix length of the sample */
if (block_FifoCount(p_input->p_fifo) > 0) { if (block_FifoCount(p_input->p_fifo) > 0) {
block_t *p_next = block_FifoShow(p_input->p_fifo); block_t *p_next = block_FifoShow(p_input->p_fifo);
int64_t i_diff = p_next->i_dts - p_data->i_dts; int64_t i_diff = p_next->i_dts - p_data->i_dts;
if (i_diff < INT64_C(1000000)) /* protection */ if (i_diff < INT64_C(1000000)) /* protection */
p_data->i_length = i_diff; p_data->i_length = i_diff;
...@@ -505,14 +492,15 @@ again: ...@@ -505,14 +492,15 @@ again:
p_stream->entry[p_stream->i_entry_count-1].i_length = i_length; p_stream->entry[p_stream->i_entry_count-1].i_length = i_length;
} }
/* add index entry */ /* add index entry */
p_stream->entry[p_stream->i_entry_count].i_pos = p_sys->i_pos; mp4_entry_t *e = &p_stream->entry[p_stream->i_entry_count];
p_stream->entry[p_stream->i_entry_count].i_size = p_data->i_buffer; e->i_pos = p_sys->i_pos;
p_stream->entry[p_stream->i_entry_count].i_pts_dts= e->i_size = p_data->i_buffer;
__MAX(p_data->i_pts - p_data->i_dts, 0); e->i_pts_dts = p_data->i_pts - p_data->i_dts;
p_stream->entry[p_stream->i_entry_count].i_length = p_data->i_length; if (e->i_pts_dts < 0)
p_stream->entry[p_stream->i_entry_count].i_flags = p_data->i_flags; e->i_pts_dts = 0;
e->i_length = p_data->i_length;
e->i_flags = p_data->i_flags;
p_stream->i_entry_count++; p_stream->i_entry_count++;
/* XXX: -1 to always have 2 entry for easy adding of empty SPU */ /* XXX: -1 to always have 2 entry for easy adding of empty SPU */
...@@ -540,11 +528,12 @@ again: ...@@ -540,11 +528,12 @@ again:
msg_Dbg(p_mux, "writing an empty sub") ; msg_Dbg(p_mux, "writing an empty sub") ;
/* Append a idx entry */ /* Append a idx entry */
p_stream->entry[p_stream->i_entry_count].i_pos = p_sys->i_pos; mp4_entry_t *e = &p_stream->entry[p_stream->i_entry_count];
p_stream->entry[p_stream->i_entry_count].i_size = 3; e->i_pos = p_sys->i_pos;
p_stream->entry[p_stream->i_entry_count].i_pts_dts= 0; e->i_size = 3;
p_stream->entry[p_stream->i_entry_count].i_length = 0; e->i_pts_dts= 0;
p_stream->entry[p_stream->i_entry_count].i_flags = 0; e->i_length = 0;
e->i_flags = 0;
/* XXX: No need to grow the entry here */ /* XXX: No need to grow the entry here */
p_stream->i_entry_count++; p_stream->i_entry_count++;
...@@ -598,10 +587,8 @@ static block_t *ConvertAVC1(block_t *p_block) ...@@ -598,10 +587,8 @@ static block_t *ConvertAVC1(block_t *p_block)
/* Replace the 4 bytes start code with 4 bytes size, /* Replace the 4 bytes start code with 4 bytes size,
* FIXME are all startcodes 4 bytes ? (I don't think :(*/ * FIXME are all startcodes 4 bytes ? (I don't think :(*/
while (dat < end) { while (dat < end) {
int i_size;
while (dat < end - 4) { while (dat < end - 4) {
if (dat[0] == 0x00 && dat[1] == 0x00 && dat[2] == 0x00 && dat[3] == 0x01) if (!memcmp(dat, avc1_start_code, 4))
break; break;
dat++; dat++;
} }
...@@ -609,7 +596,7 @@ static block_t *ConvertAVC1(block_t *p_block) ...@@ -609,7 +596,7 @@ static block_t *ConvertAVC1(block_t *p_block)
dat = end; dat = end;
/* Fix size */ /* Fix size */
i_size = dat - &last[4]; int i_size = dat - &last[4];
last[0] = (i_size >> 24)&0xff; last[0] = (i_size >> 24)&0xff;
last[1] = (i_size >> 16)&0xff; last[1] = (i_size >> 16)&0xff;
last[2] = (i_size >> 8)&0xff; last[2] = (i_size >> 8)&0xff;
...@@ -627,9 +614,6 @@ static block_t *ConvertAVC1(block_t *p_block) ...@@ -627,9 +614,6 @@ static block_t *ConvertAVC1(block_t *p_block)
static bo_t *GetESDS(mp4_stream_t *p_stream) static bo_t *GetESDS(mp4_stream_t *p_stream)
{ {
bo_t *esds; bo_t *esds;
int i_stream_type;
int i_object_type_indication;
int i_decoder_specific_info_size;
int64_t i_bitrate_avg = 0; int64_t i_bitrate_avg = 0;
int64_t i_bitrate_max = 0; int64_t i_bitrate_max = 0;
...@@ -651,7 +635,7 @@ static bo_t *GetESDS(mp4_stream_t *p_stream) ...@@ -651,7 +635,7 @@ static bo_t *GetESDS(mp4_stream_t *p_stream)
i_bitrate_max = 0x7fffffff; i_bitrate_max = 0x7fffffff;
/* */ /* */
i_decoder_specific_info_size = (p_stream->fmt.i_extra > 0) ? 5 + p_stream->fmt.i_extra : 0; int i_decoder_specific_info_size = (p_stream->fmt.i_extra > 0) ? 5 + p_stream->fmt.i_extra : 0;
esds = box_full_new("esds", 0, 0); esds = box_full_new("esds", 0, 0);
...@@ -663,6 +647,7 @@ static bo_t *GetESDS(mp4_stream_t *p_stream) ...@@ -663,6 +647,7 @@ static bo_t *GetESDS(mp4_stream_t *p_stream)
/* DecoderConfigDescr */ /* DecoderConfigDescr */
bo_add_descr(esds, 0x04, 13 + i_decoder_specific_info_size); bo_add_descr(esds, 0x04, 13 + i_decoder_specific_info_size);
int i_object_type_indication;
switch(p_stream->fmt.i_codec) switch(p_stream->fmt.i_codec)
{ {
case VLC_CODEC_MP4V: case VLC_CODEC_MP4V:
...@@ -684,7 +669,7 @@ static bo_t *GetESDS(mp4_stream_t *p_stream) ...@@ -684,7 +669,7 @@ static bo_t *GetESDS(mp4_stream_t *p_stream)
i_object_type_indication = 0x00; i_object_type_indication = 0x00;
break; break;
} }
i_stream_type = p_stream->fmt.i_cat == VIDEO_ES ? 0x04 : 0x05; int i_stream_type = p_stream->fmt.i_cat == VIDEO_ES ? 0x04 : 0x05;
bo_add_8 (esds, i_object_type_indication); bo_add_8 (esds, i_object_type_indication);
bo_add_8 (esds, (i_stream_type << 2) | 1); bo_add_8 (esds, (i_stream_type << 2) | 1);
...@@ -793,27 +778,23 @@ static bo_t *GetAvcCTag(mp4_stream_t *p_stream) ...@@ -793,27 +778,23 @@ static bo_t *GetAvcCTag(mp4_stream_t *p_stream)
int i_buffer = p_stream->fmt.i_extra; int i_buffer = p_stream->fmt.i_extra;
while (i_buffer > 3) { while (i_buffer > 3) {
/* seek startcode */ while (memcmp(p_buffer, &avc1_start_code[1], 3)) {
while (p_buffer[0] != 0 || p_buffer[1] != 0 || p_buffer[2] != 1) {
i_buffer--; i_buffer--;
p_buffer++; p_buffer++;
} }
const int i_nal_type = p_buffer[3]&0x1f; const int i_nal_type = p_buffer[3]&0x1f;
int i_size = 0;
int i_startcode = 0; int i_startcode = 0;
for (int i_offset = 1; i_offset+2 < i_buffer ; i_offset++)
for (int i_offset = 1; i_offset+2 < i_buffer ; i_offset++) { if (!memcmp(&p_buffer[i_offset], &avc1_start_code[1], 3)) {
if (p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 &&
p_buffer[i_offset+2] == 1) {
/* we found another startcode */ /* we found another startcode */
i_startcode = i_offset; i_startcode = i_offset;
while (p_buffer[i_startcode-1] == 0 && i_startcode > 0) while (p_buffer[i_startcode-1] == 0 && i_startcode > 0)
i_startcode--; i_startcode--;
break; break;
} }
}
i_size = i_startcode ? i_startcode : i_buffer; int i_size = i_startcode ? i_startcode : i_buffer;
if (i_nal_type == 7) { if (i_nal_type == 7) {
p_sps = &p_buffer[3]; p_sps = &p_buffer[3];
...@@ -891,9 +872,9 @@ static bo_t *GetUdtaTag(sout_mux_t *p_mux) ...@@ -891,9 +872,9 @@ static bo_t *GetUdtaTag(sout_mux_t *p_mux)
/* Requirements */ /* Requirements */
for (int i_track = 0; i_track < p_sys->i_nb_streams; i_track++) { for (int i_track = 0; i_track < p_sys->i_nb_streams; i_track++) {
mp4_stream_t *p_stream = p_sys->pp_streams[i_track]; mp4_stream_t *p_stream = p_sys->pp_streams[i_track];
vlc_fourcc_t codec = p_stream->fmt.i_codec;
if (p_stream->fmt.i_codec == VLC_CODEC_MP4V || if (codec == VLC_CODEC_MP4V || codec == VLC_CODEC_MP4A) {
p_stream->fmt.i_codec == VLC_CODEC_MP4A) {
bo_t *box = box_new("\251req"); bo_t *box = box_new("\251req");
/* String length */ /* String length */
bo_add_16be(box, sizeof("QuickTime 6.0 or greater") - 1); bo_add_16be(box, sizeof("QuickTime 6.0 or greater") - 1);
...@@ -951,44 +932,26 @@ static bo_t *GetUdtaTag(sout_mux_t *p_mux) ...@@ -951,44 +932,26 @@ static bo_t *GetUdtaTag(sout_mux_t *p_mux)
static bo_t *GetSounBox(sout_mux_t *p_mux, mp4_stream_t *p_stream) static bo_t *GetSounBox(sout_mux_t *p_mux, mp4_stream_t *p_stream)
{ {
sout_mux_sys_t *p_sys = p_mux->p_sys; sout_mux_sys_t *p_sys = p_mux->p_sys;
bool b_descr = false; bool b_descr = true;
bo_t *soun; vlc_fourcc_t codec = p_stream->fmt.i_codec;
char fcc[4] = " "; char fcc[4];
vlc_fourcc_to_char(codec, fcc);
switch(p_stream->fmt.i_codec)
{ if (codec == VLC_CODEC_MPGA) {
case VLC_CODEC_MP4A: if (p_sys->b_mov) {
memcpy(fcc, "mp4a", 4); b_descr = false;
b_descr = true;
break;
case VLC_CODEC_AMR_NB:
case VLC_CODEC_AMR_WB:
memcpy(fcc, (char*)&p_stream->fmt.i_codec, 4);
b_descr = true;
break;
case VLC_CODEC_MPGA:
if (p_sys->b_mov)
memcpy(fcc, ".mp3", 4); memcpy(fcc, ".mp3", 4);
else { } else
memcpy(fcc, "mp4a", 4); memcpy(fcc, "mp4a", 4);
b_descr = true;
}
break;
default:
memcpy(fcc, (char*)&p_stream->fmt.i_codec, 4);
break;
} }
soun = box_new(fcc); bo_t *soun = box_new(fcc);
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
bo_add_8(soun, 0); // reserved; bo_add_8(soun, 0); // reserved;
bo_add_16be(soun, 1); // data-reference-index bo_add_16be(soun, 1); // data-reference-index
/* SoundDescription */ /* SoundDescription */
if (p_sys->b_mov && p_stream->fmt.i_codec == VLC_CODEC_MP4A) if (p_sys->b_mov && codec == VLC_CODEC_MP4A)
bo_add_16be(soun, 1); // version 1; bo_add_16be(soun, 1); // version 1;
else else
bo_add_16be(soun, 0); // version 0; bo_add_16be(soun, 0); // version 0;
...@@ -1018,9 +981,9 @@ static bo_t *GetSounBox(sout_mux_t *p_mux, mp4_stream_t *p_stream) ...@@ -1018,9 +981,9 @@ static bo_t *GetSounBox(sout_mux_t *p_mux, mp4_stream_t *p_stream)
if (b_descr) { if (b_descr) {
bo_t *box; bo_t *box;
if (p_sys->b_mov && p_stream->fmt.i_codec == VLC_CODEC_MP4A) if (p_sys->b_mov && codec == VLC_CODEC_MP4A)
box = GetWaveTag(p_stream); box = GetWaveTag(p_stream);
else if (p_stream->fmt.i_codec == VLC_CODEC_AMR_NB) else if (codec == VLC_CODEC_AMR_NB)
box = GetDamrTag(p_stream); box = GetDamrTag(p_stream);
else else
box = GetESDS(p_stream); box = GetESDS(p_stream);
...@@ -1035,50 +998,25 @@ static bo_t *GetSounBox(sout_mux_t *p_mux, mp4_stream_t *p_stream) ...@@ -1035,50 +998,25 @@ static bo_t *GetSounBox(sout_mux_t *p_mux, mp4_stream_t *p_stream)
static bo_t *GetVideBox(mp4_stream_t *p_stream) static bo_t *GetVideBox(mp4_stream_t *p_stream)
{ {
bo_t *vide; char fcc[4];
char fcc[4] = " ";
switch(p_stream->fmt.i_codec) switch(p_stream->fmt.i_codec)
{ {
case VLC_CODEC_MP4V: case VLC_CODEC_MP4V:
case VLC_CODEC_MPGV: case VLC_CODEC_MPGV: memcpy(fcc, "mp4v", 4); break;
memcpy(fcc, "mp4v", 4); case VLC_CODEC_MJPG: memcpy(fcc, "mjpa", 4); break;
break; case VLC_CODEC_SVQ1: memcpy(fcc, "SVQ1", 4); break;
case VLC_CODEC_SVQ3: memcpy(fcc, "SVQ3", 4); break;
case VLC_CODEC_MJPG: case VLC_CODEC_H263: memcpy(fcc, "s263", 4); break;
memcpy(fcc, "mjpa", 4); case VLC_CODEC_H264: memcpy(fcc, "avc1", 4); break;
break; case VLC_CODEC_YV12: memcpy(fcc, "yv12", 4); break;
case VLC_CODEC_YUYV: memcpy(fcc, "yuy2", 4); break;
case VLC_CODEC_SVQ1:
memcpy(fcc, "SVQ1", 4);
break;
case VLC_CODEC_SVQ3:
memcpy(fcc, "SVQ3", 4);
break;
case VLC_CODEC_H263:
memcpy(fcc, "s263", 4);
break;
case VLC_CODEC_H264:
memcpy(fcc, "avc1", 4);
break;
case VLC_CODEC_YV12:
memcpy(fcc, "yv12", 4);
break;
case VLC_CODEC_YUYV:
memcpy(fcc, "yuy2", 4);
break;
default: default:
memcpy(fcc, (char*)&p_stream->fmt.i_codec, 4); vlc_fourcc_to_char(p_stream->fmt.i_codec, fcc);
break; break;
} }
vide = box_new(fcc); bo_t *vide = box_new(fcc);
for (int i = 0; i < 6; i++) for (int i = 0; i < 6; i++)
bo_add_8(vide, 0); // reserved; bo_add_8(vide, 0); // reserved;
bo_add_16be(vide, 1); // data-reference-index bo_add_16be(vide, 1); // data-reference-index
...@@ -1138,9 +1076,6 @@ static bo_t *GetVideBox(mp4_stream_t *p_stream) ...@@ -1138,9 +1076,6 @@ static bo_t *GetVideBox(mp4_stream_t *p_stream)
case VLC_CODEC_H264: case VLC_CODEC_H264:
box_gather(vide, GetAvcCTag(p_stream)); box_gather(vide, GetAvcCTag(p_stream));
break; break;
default:
break;
} }
box_fix(vide); box_fix(vide);
...@@ -1181,25 +1116,19 @@ static bo_t *GetTextBox(void) ...@@ -1181,25 +1116,19 @@ static bo_t *GetTextBox(void)
static bo_t *GetStblBox(sout_mux_t *p_mux, mp4_stream_t *p_stream) static bo_t *GetStblBox(sout_mux_t *p_mux, mp4_stream_t *p_stream)
{ {
sout_mux_sys_t *p_sys = p_mux->p_sys; sout_mux_sys_t *p_sys = p_mux->p_sys;
unsigned int i_chunk, i_stsc_last_val, i_stsc_entries, i, i_index;
bo_t *stbl, *stsd, *stts, *stco, *stsc, *stsz, *stss; bo_t *stbl, *stsd, *stts, *stco, *stsc, *stsz, *stss;
uint32_t i_timescale;
int64_t i_dts, i_dts_q;
stbl = box_new("stbl"); stbl = box_new("stbl");
/* sample description */ /* sample description */
stsd = box_full_new("stsd", 0, 0); stsd = box_full_new("stsd", 0, 0);
bo_add_32be(stsd, 1); bo_add_32be(stsd, 1);
if (p_stream->fmt.i_cat == AUDIO_ES) { if (p_stream->fmt.i_cat == AUDIO_ES)
bo_t *soun = GetSounBox(p_mux, p_stream); box_gather(stsd, GetSounBox(p_mux, p_stream));
box_gather(stsd, soun); else if (p_stream->fmt.i_cat == VIDEO_ES)
} else if (p_stream->fmt.i_cat == VIDEO_ES) { box_gather(stsd, GetVideBox(p_stream));
bo_t *vide = GetVideBox(p_stream); else if (p_stream->fmt.i_cat == SPU_ES)
box_gather(stsd, vide);
} else if (p_stream->fmt.i_cat == SPU_ES) {
box_gather(stsd, GetTextBox()); box_gather(stsd, GetTextBox());
}
box_fix(stsd); box_fix(stsd);
/* chunk offset table */ /* chunk offset table */
...@@ -1218,26 +1147,24 @@ static bo_t *GetStblBox(sout_mux_t *p_mux, mp4_stream_t *p_stream) ...@@ -1218,26 +1147,24 @@ static bo_t *GetStblBox(sout_mux_t *p_mux, mp4_stream_t *p_stream)
stsc = box_full_new("stsc", 0, 0); stsc = box_full_new("stsc", 0, 0);
bo_add_32be(stsc, 0); // entry-count (fixed latter) bo_add_32be(stsc, 0); // entry-count (fixed latter)
for (i_chunk = 0, i_stsc_last_val = 0, i_stsc_entries = 0, i = 0; unsigned i_chunk = 0;
i < p_stream->i_entry_count; i_chunk++) { unsigned i_stsc_last_val = 0, i_stsc_entries = 0;
for (unsigned i = 0; i < p_stream->i_entry_count; i_chunk++) {
mp4_entry_t *entry = p_stream->entry;
int i_first = i; int i_first = i;
if (p_stream->b_stco64) if (p_stream->b_stco64)
bo_add_64be(stco, p_stream->entry[i].i_pos); bo_add_64be(stco, entry[i].i_pos);
else else
bo_add_32be(stco, p_stream->entry[i].i_pos); bo_add_32be(stco, entry[i].i_pos);
while (i < p_stream->i_entry_count) { for (; i < p_stream->i_entry_count; i++)
if (i + 1 < p_stream->i_entry_count && if (i >= p_stream->i_entry_count - 1 ||
p_stream->entry[i].i_pos + p_stream->entry[i].i_size entry[i].i_pos + entry[i].i_size != entry[i+1].i_pos) {
!= p_stream->entry[i + 1].i_pos) {
i++; i++;
break; break;
} }
i++;
}
/* Add entry to the stsc table */ /* Add entry to the stsc table */
if (i_stsc_last_val != i - i_first) { if (i_stsc_last_val != i - i_first) {
bo_add_32be(stsc, 1 + i_chunk); // first-chunk bo_add_32be(stsc, 1 + i_chunk); // first-chunk
...@@ -1261,13 +1188,15 @@ static bo_t *GetStblBox(sout_mux_t *p_mux, mp4_stream_t *p_stream) ...@@ -1261,13 +1188,15 @@ static bo_t *GetStblBox(sout_mux_t *p_mux, mp4_stream_t *p_stream)
stts = box_full_new("stts", 0, 0); stts = box_full_new("stts", 0, 0);
bo_add_32be(stts, 0); // entry-count (fixed latter) bo_add_32be(stts, 0); // entry-count (fixed latter)
uint32_t i_timescale;
if (p_stream->fmt.i_cat == AUDIO_ES) if (p_stream->fmt.i_cat == AUDIO_ES)
i_timescale = p_stream->fmt.audio.i_rate; i_timescale = p_stream->fmt.audio.i_rate;
else else
i_timescale = 1001; i_timescale = 1001;
/* first, create quantified length */ /* first, create quantified length */
for (i = 0, i_dts = 0, i_dts_q = 0; i < p_stream->i_entry_count; i++) { int64_t i_dts = 0, i_dts_q = 0;
for (unsigned i = 0 ; i < p_stream->i_entry_count; i++) {
int64_t i_dts_deq = i_dts_q * INT64_C(1000000) / (int64_t)i_timescale; int64_t i_dts_deq = i_dts_q * INT64_C(1000000) / (int64_t)i_timescale;
int64_t i_delta = p_stream->entry[i].i_length + i_dts - i_dts_deq; int64_t i_delta = p_stream->entry[i].i_length + i_dts - i_dts_deq;
...@@ -1279,15 +1208,14 @@ static bo_t *GetStblBox(sout_mux_t *p_mux, mp4_stream_t *p_stream) ...@@ -1279,15 +1208,14 @@ static bo_t *GetStblBox(sout_mux_t *p_mux, mp4_stream_t *p_stream)
i_dts_q += p_stream->entry[i].i_length; i_dts_q += p_stream->entry[i].i_length;
} }
/* then write encoded table */ /* then write encoded table */
for (i = 0, i_index = 0; i < p_stream->i_entry_count; i_index++) { unsigned i_index = 0;
for (unsigned i = 0; i < p_stream->i_entry_count; i_index++) {
int i_first = i; int i_first = i;
int64_t i_delta = p_stream->entry[i].i_length; int64_t i_delta = p_stream->entry[i].i_length;
while (i < p_stream->i_entry_count) { for (; i < p_stream->i_entry_count; ++i)
i++; if (i == p_stream->i_entry_count || p_stream->entry[i].i_length != i_delta)
if (i >= p_stream->i_entry_count || p_stream->entry[i].i_length != i_delta)
break; break;
}
bo_add_32be(stts, i - i_first); // sample-count bo_add_32be(stts, i - i_first); // sample-count
bo_add_32be(stts, i_delta); // sample-delta bo_add_32be(stts, i_delta); // sample-delta
...@@ -1306,7 +1234,8 @@ static bo_t *GetStblBox(sout_mux_t *p_mux, mp4_stream_t *p_stream) ...@@ -1306,7 +1234,8 @@ static bo_t *GetStblBox(sout_mux_t *p_mux, mp4_stream_t *p_stream)
/* create stss table */ /* create stss table */
stss = NULL; stss = NULL;
for (i = 0, i_index = 0; i < p_stream->i_entry_count; i++) i_index = 0;
for (unsigned i = 0; i < p_stream->i_entry_count; i++)
if (p_stream->entry[i].i_flags & BLOCK_FLAG_TYPE_I) { if (p_stream->entry[i].i_flags & BLOCK_FLAG_TYPE_I) {
if (stss == NULL) { if (stss == NULL) {
stss = box_full_new("stss", 0, 0); stss = box_full_new("stss", 0, 0);
...@@ -1395,23 +1324,19 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux) ...@@ -1395,23 +1324,19 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux)
box_gather(moov, mvhd); box_gather(moov, mvhd);
for (int i_trak = 0; i_trak < p_sys->i_nb_streams; i_trak++) { for (int i_trak = 0; i_trak < p_sys->i_nb_streams; i_trak++) {
mp4_stream_t *p_stream; mp4_stream_t *p_stream = p_sys->pp_streams[i_trak];
uint32_t i_timescale;
bo_t *trak, *tkhd, *edts, *elst, *mdia, *mdhd, *hdlr;
bo_t *minf, *dinf, *dref, *url, *stbl;
p_stream = p_sys->pp_streams[i_trak];
uint32_t i_timescale;
if (p_stream->fmt.i_cat == AUDIO_ES) if (p_stream->fmt.i_cat == AUDIO_ES)
i_timescale = p_stream->fmt.audio.i_rate; i_timescale = p_stream->fmt.audio.i_rate;
else else
i_timescale = 1001; i_timescale = 1001;
/* *** add /moov/trak *** */ /* *** add /moov/trak *** */
trak = box_new("trak"); bo_t *trak = box_new("trak");
/* *** add /moov/trak/tkhd *** */ /* *** add /moov/trak/tkhd *** */
bo_t *tkhd;
if (!p_sys->b_64_ext) { if (!p_sys->b_64_ext) {
if (p_sys->b_mov) if (p_sys->b_mov)
tkhd = box_full_new("tkhd", 0, 0x0f); tkhd = box_full_new("tkhd", 0, 0x0f);
...@@ -1488,8 +1413,8 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux) ...@@ -1488,8 +1413,8 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux)
box_gather(trak, tkhd); box_gather(trak, tkhd);
/* *** add /moov/trak/edts and elst */ /* *** add /moov/trak/edts and elst */
edts = box_new("edts"); bo_t *edts = box_new("edts");
elst = box_full_new("elst", p_sys->b_64_ext ? 1 : 0, 0); bo_t *elst = box_full_new("elst", p_sys->b_64_ext ? 1 : 0, 0);
if (p_stream->i_dts_start > p_sys->i_dts_start) { if (p_stream->i_dts_start > p_sys->i_dts_start) {
bo_add_32be(elst, 2); bo_add_32be(elst, 2);
...@@ -1525,9 +1450,10 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux) ...@@ -1525,9 +1450,10 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux)
box_gather(trak, edts); box_gather(trak, edts);
/* *** add /moov/trak/mdia *** */ /* *** add /moov/trak/mdia *** */
mdia = box_new("mdia"); bo_t *mdia = box_new("mdia");
/* media header */ /* media header */
bo_t *mdhd;
if (!p_sys->b_64_ext) { if (!p_sys->b_64_ext) {
mdhd = box_full_new("mdhd", 0, 0); mdhd = box_full_new("mdhd", 0, 0);
bo_add_32be(mdhd, i_timestamp); // creation time bo_add_32be(mdhd, i_timestamp); // creation time
...@@ -1569,7 +1495,7 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux) ...@@ -1569,7 +1495,7 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux)
box_gather(mdia, mdhd); box_gather(mdia, mdhd);
/* handler reference */ /* handler reference */
hdlr = box_full_new("hdlr", 0, 0); bo_t *hdlr = box_full_new("hdlr", 0, 0);
if (p_sys->b_mov) if (p_sys->b_mov)
bo_add_fourcc(hdlr, "mhlr"); // media handler bo_add_fourcc(hdlr, "mhlr"); // media handler
...@@ -1604,7 +1530,7 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux) ...@@ -1604,7 +1530,7 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux)
box_gather(mdia, hdlr); box_gather(mdia, hdlr);
/* minf*/ /* minf*/
minf = box_new("minf"); bo_t *minf = box_new("minf");
/* add smhd|vmhd */ /* add smhd|vmhd */
if (p_stream->fmt.i_cat == AUDIO_ES) { if (p_stream->fmt.i_cat == AUDIO_ES) {
...@@ -1644,10 +1570,10 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux) ...@@ -1644,10 +1570,10 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux)
} }
/* dinf */ /* dinf */
dinf = box_new("dinf"); bo_t *dinf = box_new("dinf");
dref = box_full_new("dref", 0, 0); bo_t *dref = box_full_new("dref", 0, 0);
bo_add_32be(dref, 1); bo_add_32be(dref, 1);
url = box_full_new("url ", 0, 0x01); bo_t *url = box_full_new("url ", 0, 0x01);
box_fix(url); box_fix(url);
box_gather(dref, url); box_gather(dref, url);
box_fix(dref); box_fix(dref);
...@@ -1658,7 +1584,7 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux) ...@@ -1658,7 +1584,7 @@ static bo_t *GetMoovBox(sout_mux_t *p_mux)
box_gather(minf, dinf); box_gather(minf, dinf);
/* add stbl */ /* add stbl */
stbl = GetStblBox(p_mux, p_stream); bo_t *stbl = GetStblBox(p_mux, p_stream);
/* append stbl to minf */ /* append stbl to minf */
p_stream->i_stco_pos += minf->len; p_stream->i_stco_pos += minf->len;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment