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

fragmentation mode + slices doesn't work #15

Open
rhwu opened this issue Feb 22, 2020 · 2 comments
Open

fragmentation mode + slices doesn't work #15

rhwu opened this issue Feb 22, 2020 · 2 comments

Comments

@rhwu
Copy link

rhwu commented Feb 22, 2020

./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

@lieff
Copy link
Owner

lieff commented Feb 22, 2020

This is sliced h264 stream. As already mentioned here #16 fragmentation+slices mode currently not supported by mp4_h26x_write_nal helper. Will do it at some point too.

@lieff lieff changed the title sequential mode doesn't work on certain bitstream fragmentation mode doesn't work on certain bitstream Feb 22, 2020
@lieff lieff changed the title fragmentation mode doesn't work on certain bitstream fragmentation mode + slices doesn't work Feb 22, 2020
@autoexpect
Copy link

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
    }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants