Open rhwu opened 4 years ago
This is sliced h264 stream. As already mentioned here https://github.com/lieff/minimp4/issues/16 fragmentation+slices mode currently not supported by mp4_h26x_write_nal helper. Will do it at some point too.
I tried to modify this function,
static int mp4_h265_write_nal(mp4_h26x_writer_t *h, const unsigned char *nal, int sizeof_nal, unsigned timeStamp90kHz_next)
{
int payload_type = (nal[0] >> 1) & 0x3f;
int slice_type;
int is_intra = payload_type >= HEVC_NAL_BLA_W_LP && payload_type <= HEVC_NAL_CRA_NUT;
int err = MP4E_STATUS_OK;
//printf("payload_type=%d, intra=%d\n", payload_type, is_intra);
if (is_intra && !h->need_sps && !h->need_pps && !h->need_vps)
h->need_idr = 0;
switch (payload_type)
{
case HEVC_NAL_VPS:
MP4E_set_vps(h->mux, h->mux_track_id, nal, sizeof_nal);
h->need_vps = 0;
break;
case HEVC_NAL_SPS:
MP4E_set_sps(h->mux, h->mux_track_id, nal, sizeof_nal);
h->need_sps = 0;
break;
case HEVC_NAL_PPS:
MP4E_set_pps(h->mux, h->mux_track_id, nal, sizeof_nal);
h->need_pps = 0;
break;
default:
if (h->need_vps || h->need_sps || h->need_pps || h->need_idr)
return MP4E_STATUS_BAD_ARGUMENTS;
{
unsigned char *tmp = (unsigned char *)malloc(4 + sizeof_nal);
if (!tmp)
return MP4E_STATUS_NO_MEMORY;
int sample_kind = MP4E_SAMPLE_DEFAULT;
tmp[0] = (unsigned char)(sizeof_nal >> 24);
tmp[1] = (unsigned char)(sizeof_nal >> 16);
tmp[2] = (unsigned char)(sizeof_nal >> 8);
tmp[3] = (unsigned char)(sizeof_nal);
memcpy(tmp + 4, nal, sizeof_nal);
if (is_intra) {
slice_type = (nal[2] >> 2) & 0x07;
if (slice_type != 3) {
sample_kind = MP4E_SAMPLE_CONTINUATION;
} else {
sample_kind = MP4E_SAMPLE_RANDOM_ACCESS;
}
} else {
slice_type = (nal[2] >> 3) & 0x07;
if (slice_type != 2) {
sample_kind = MP4E_SAMPLE_CONTINUATION;
} else {
sample_kind = MP4E_SAMPLE_DEFAULT;
}
}
err = MP4E_put_sample(h->mux, h->mux_track_id, tmp, 4 + sizeof_nal, timeStamp90kHz_next, sample_kind);
free(tmp);
}
break;
}
return err;
}
maybe i need to fix the mp4e_write_fragment_header function too...
else if (kind == MP4E_SAMPLE_CONTINUATION)
{
flags = 0;
flags |= 0x001; // data-offset-present
flags |= 0x004; // first-sample-flags-present
flags |= 0x100; // sample-duration-present
flags |= 0x200; // sample-size-present
ATOM_FULL(BOX_trun, flags)
WRITE_4(1); // sample_count
pdata_offset = p;
p += 4; // save ptr to data_offset
WRITE_4(0x2000000); // first_sample_flags
WRITE_4(duration); // sample_duration
WRITE_4(data_bytes); // sample_size
END_ATOM
}
./minimp4_x86 -f test.264 test-f.mp4 ./minimp4_x86 -s test.264 test-s.mp4 ./minimp4_x86 test.264 test.mp4
test-s.mp4 and test.mp4 looks fine. But test-f.mp4 is broken. test-f.mp4 and test.264 (1920x1080) attached. test.zip