Esempio n. 1
0
def test_get_sample_location():
    trak = utils.make_meta_trak(0, 0, b"trak1\0", [12345, 67890], 23456)

    assert utils.get_sample_location(trak, 0) == (23456, 12345)
    assert utils.get_sample_location(trak, 1) == (35801, 67890)

    trak = utils.make_meta_trak(0, 0, b"trak1\0", [12345, 67890], [23456, 78901])

    assert utils.get_sample_location(trak, 0) == (23456, 12345)
    assert utils.get_sample_location(trak, 1) == (78901, 67890)
Esempio n. 2
0
def test_get_trak_sample_location():
    boxes = [bx_def.UnknownBox(hd_def.BoxHeader()),
             utils.make_meta_trak(0, 0, b"trak1\0", [12345, 67890], 23456)]

    boxes[0].header.type = b"0001"

    assert utils.get_trak_sample_location(boxes, b"trak1\0", 0) == (23456, 12345)
    assert utils.get_trak_sample_location(boxes, b"trak1\0", 1) == (35801, 67890)
Esempio n. 3
0
def test_find_traks():
    boxes = [utils.make_meta_trak(0, 0, b"trak1\0", [], 0),
             utils.make_meta_trak(0, 0, b"trak2\0", [], 0),
             utils.make_meta_trak(0, 0, b"trak3\0", [], 0),
             bx_def.UnknownBox(hd_def.BoxHeader()),
             utils.make_meta_trak(0, 0, b"trak2\0", [], 0)]

    boxes[3].header.type = b"0001"

    assert utils.get_name(next(utils.find_traks(boxes, b"trak1\0"))) == b"trak1\0"
    assert utils.get_name(next(utils.find_traks(boxes, b"trak2\0"))) == b"trak2\0"
    assert utils.get_name(next(utils.find_traks(boxes, b"trak3\0"))) == b"trak3\0"

    assert [utils.get_name(trak)
            for trak in utils.find_traks(boxes, b"trak2\0")] == [b"trak2\0", b"trak2\0"]
    assert [utils.get_name(trak)
            for trak in utils.find_traks(boxes, [b"trak1\0", b"trak3\0"])] == [b"trak1\0", b"trak3\0"]

    assert next(utils.find_boxes(boxes, b"0004"), None) is None
Esempio n. 4
0
def test_make_meta_trak():
    creation_time = utils.to_mp4_time(datetime(2019, 9, 15, 0, 0, 0))
    modification_time = utils.to_mp4_time(datetime(2019, 9, 16, 0, 0, 0))

    samples_sizes = [198297, 127477, 192476]
    samples_offset = 10
    trak = utils.make_meta_trak(creation_time, modification_time, b"bzna_inputs\0",
                                samples_sizes, samples_offset)

    # MOOV.TRAK.MDIA.HDLR
    hdlr = trak.boxes[-1].boxes[1]
    hdlr.refresh_box_size()

    assert hdlr.header.type == b"hdlr"
    assert hdlr.header.box_size == 44
    assert hdlr.handler_type == b"meta"
    # TODO: validate the use of the name
    assert hdlr.name == b"bzna_inputs\0"

    assert bytes(hdlr) == \
           pack("uintbe:32, bytes:4, uintbe:8, bits:24, "
                "uintbe:32, bytes:4, bits:32, bits:32, bits:32, "
                "bytes:12",
                44, b"hdlr", 0, b"\x00\x00\x00",
                0, b"meta", b"\x00" * 4, b"\x00" * 4, b"\x00" * 4,
                b"bzna_inputs\0")

    # MOOV.TRAK.MDIA.MINF.NMHD
    nmhd = trak.boxes[-1].boxes[-1].boxes[0]
    nmhd.refresh_box_size()

    assert nmhd.header.type == b"nmhd"
    assert nmhd.header.box_size == 12
    assert nmhd.header.version == 0
    assert nmhd.header.flags == b"\x00\x00\x00"

    assert bytes(nmhd) == pack("uintbe:32, bytes:4, uintbe:8, bits:24",
                               12, b"nmhd", 0, b"\x00\x00\x00")

    # MOOV.TRAK.MDIA.MINF.STBL.STSD
    stsd = trak.boxes[-1].boxes[-1].boxes[-1].boxes[0]

    assert stsd.header.type == b"stsd"
    assert len(stsd.boxes) == 1

    # MOOV.TRAK.MDIA.MINF.STBL.STSD.METT
    mett = stsd.boxes[0]
    mett.refresh_box_size()

    assert mett.header.type == b"mett"
    assert mett.header.box_size == 18
    assert mett.data_reference_index == 1
    assert mett.content_encoding == b'\0'
    assert mett.mime_format == b'\0'
    assert len(mett.boxes) == 0
Esempio n. 5
0
def test_get_sample_table():
    trak = utils.make_meta_trak(0, 0, b"trak1\0", [], 0)

    assert utils.get_sample_table(trak).header.type == b"stbl"
Esempio n. 6
0
def test_get_shape():
    trak = utils.make_meta_trak(0, 0, b"trak1\0", [], 0)

    assert utils.get_shape(trak) == (-1, -1)
Esempio n. 7
0
def test_get_name():
    trak = utils.make_meta_trak(0, 0, b"trak1\0", [], 0)

    assert utils.get_name(trak) == b"trak1\0"
Esempio n. 8
0
def test_mp4_dataset():
    creation_time = to_mp4_time(datetime(2019, 9, 15, 0, 0, 0))
    modification_time = to_mp4_time(datetime(2019, 9, 16, 0, 0, 0))

    # FTYP
    ftyp = bx_def.FTYP(BoxHeader())
    ftyp.header.type = b"ftyp"
    ftyp.major_brand = 1769172845           # b"isom"
    ftyp.minor_version = 0
    ftyp.compatible_brands = [1652190817,   # b"bzna"
                              1769172845]   # b"isom"

    ftyp.refresh_box_size()

    assert ftyp.header.type == b"ftyp"
    assert ftyp.header.box_size == 24
    assert ftyp.major_brand == 1769172845           # b"isom"
    assert ftyp.minor_version == 0
    assert ftyp.compatible_brands == [1652190817,   # b"bzna"
                                      1769172845]   # b"isom"
    assert bytes(ftyp) == pack("uintbe:32, bytes:4, bytes:4, uintbe:32, "
                               "bytes:8",
                               24, b"ftyp", b"isom", 0,
                               b"bznaisom")

    # MDAT
    mdat = bx_def.MDAT(BoxHeader())
    mdat.header.type = b"mdat"

    data = []

    with open("tests/data/small_vid_mdat_im0", "rb") as f:
        data.append(f.read())
    with open("tests/data/small_vid_mdat_im1", "rb") as f:
        data.append(f.read())
    with open("tests/data/small_vid_mdat_im2", "rb") as f:
        data.append(f.read())

    data.append(b"/path/image_1_name.JPEG")
    data.append(b"/path/image_2_name.JPEG")
    data.append(b"/path/image_3_name.JPEG")

    data.append((0).to_bytes(8, byteorder="little"))
    data.append((1).to_bytes(8, byteorder="little"))
    data.append((0).to_bytes(8, byteorder="little"))

    mdat.data = b''.join(data)

    mdat.refresh_box_size()

    assert mdat.header.type == b"mdat"
    assert mdat.header.box_size == 8 + sum(len(entry) for entry in data)

    # MOOV
    moov = bx_def.MOOV(BoxHeader())
    moov.header.type = b"moov"

    # MOOV.MVHD
    mvhd = make_mvhd(creation_time, modification_time, 3)
    # == total number of tracks
    mvhd.next_track_id = 5

    assert mvhd.next_track_id == 5

    moov.append(mvhd)

    # MOOV.TRAK
    offset = ftyp.header.box_size + mdat.header.header_size
    sizes = [198297, 127477, 192476]
    trak = make_vide_trak(creation_time, modification_time, b"VideoHandler\0",
                          sizes, offset)

    # MOOV.TRAK.TKHD
    tkhd = trak.boxes[0]

    # "\x00\x00\x01" trak is enabled
    # "\x00\x00\x02" trak is used in the presentation
    # "\x00\x00\x04" trak is used in the preview
    # "\x00\x00\x08" trak size in not in pixel but in aspect ratio
    tkhd.header.flags = b"\x00\x00\x03"

    tkhd.track_id = 1

    # TODO: make sure that this is the canvas size
    tkhd.width = [512, 0]
    tkhd.height = [512, 0]

    tkhd.refresh_box_size()

    assert tkhd.header.type == b"tkhd"
    assert tkhd.header.box_size == 104
    assert tkhd.header.flags == b"\x00\x00\x03"

    assert tkhd.track_id == 1

    assert tkhd.width == 512
    assert tkhd.height == 512

    assert bytes(tkhd) == \
           pack("uintbe:32, bytes:4, uintbe:8, bits:24, "
                "uintbe:64, uintbe:64, uintbe:32, "
                "bits:32, "
                "uintbe:64, "
                "bits:32, bits:32, "
                "uintbe:16, uintbe:16, uintbe:8, uintbe:8, "
                "bits:16, "
                "uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, "
                "uintbe:16, uintbe:16, uintbe:16, uintbe:16",
                104, b"tkhd", 1, b"\x00\x00\x03",
                creation_time, modification_time, 1,
                b"\x00" * 4,
                60,
                b"\x00" * 4, b"\x00" * 4,
                0, 0, 0, 0,
                b"\x00" * 2,
                65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824,
                512, 0, 512, 0)

    # MOOV.TRAK.MDIA.MINF.STBL.STSD.AVC1
    avc1 = trak.boxes[-1].boxes[-1].boxes[-1].boxes[0].boxes[0]
    avc1.width = 512
    avc1.height = 512

    assert avc1.header.type == b"avc1"
    assert avc1.width == 512
    assert avc1.height == 512

    moov.append(trak)

    # MOOV.TRAK
    trak = make_meta_trak(creation_time, modification_time, b"bzna_inputs\0",
                          sizes, offset)

    # MOOV.TRAK.TKHD
    tkhd = trak.boxes[0]

    # "\x00\x00\x01" trak is enabled
    # "\x00\x00\x02" trak is used in the presentation
    # "\x00\x00\x04" trak is used in the preview
    # "\x00\x00\x08" trak size in not in pixel but in aspect ratio
    tkhd.header.flags = b"\x00\x00\x00"

    tkhd.track_id = 2

    # TODO: make sure that this is the canvas size
    tkhd.width = [0, 0]
    tkhd.height = [0, 0]

    tkhd.refresh_box_size()

    assert tkhd.header.type == b"tkhd"
    assert tkhd.header.box_size == 104
    assert tkhd.header.flags == b"\x00\x00\x00"

    assert tkhd.track_id == 2

    assert tkhd.width == 0
    assert tkhd.height == 0

    assert bytes(tkhd) == \
           pack("uintbe:32, bytes:4, uintbe:8, bits:24, "
                "uintbe:64, uintbe:64, uintbe:32, "
                "bits:32, "
                "uintbe:64, "
                "bits:32, bits:32, "
                "uintbe:16, uintbe:16, uintbe:8, uintbe:8, "
                "bits:16, "
                "uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, "
                "uintbe:16, uintbe:16, uintbe:16, uintbe:16",
                104, b"tkhd", 1, b"\x00\x00\x00",
                creation_time, modification_time, 2,
                b"\x00" * 4,
                60,
                b"\x00" * 4, b"\x00" * 4,
                0, 0, 0, 0,
                b"\x00" * 2,
                65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824,
                0, 0, 0, 0)

    # MOOV.TRAK.MDIA.MDHD
    mdhd = trak.boxes[-1].boxes[0]
    mdhd.timescale = 20
    mdhd.duration = 60

    mdhd.refresh_box_size()

    assert mdhd.header.type == b"mdhd"
    assert mdhd.header.box_size == 44
    assert mdhd.timescale == 20
    assert mdhd.duration == 60

    assert bytes(mdhd) == \
           pack("uintbe:32, bytes:4, uintbe:8, bits:24, "
                "uintbe:64, uintbe:64, uintbe:32, uintbe:64, "
                "bits:1, uint:5, uint:5, uint:5, "
                "bits:16",
                44, b"mdhd", 1, b"\x00\x00\x00",
                creation_time, modification_time, 20, 60,
                0x1, 21, 14, 4,
                b"\x00" * 2)

    # MOOV.TRAK.MDIA.MINF.STBL.STSD.METT
    mett = trak.boxes[-1].boxes[-1].boxes[-1].boxes[0].boxes[0]
    mett.mime_format = b'video/h264\0'
    mett.refresh_box_size()

    assert mett.header.type == b"mett"
    assert mett.header.box_size == 28
    assert mett.mime_format == b'video/h264\0'

    moov.append(trak)

    # MOOV.TRAK
    offset += sum(sizes)
    sizes = [23, 23, 23]
    trak = make_text_trak(creation_time, modification_time, b"bzna_fnames\0",
                          sizes, offset)

    # MOOV.TRAK.TKHD
    tkhd = trak.boxes[0]

    # "\x00\x00\x01" trak is enabled
    # "\x00\x00\x02" trak is used in the presentation
    # "\x00\x00\x04" trak is used in the preview
    # "\x00\x00\x08" trak size in not in pixel but in aspect ratio
    tkhd.header.flags = b"\x00\x00\x00"

    tkhd.track_id = 3

    # TODO: make sure that this is the canvas size
    tkhd.width = [0, 0]
    tkhd.height = [0, 0]

    tkhd.refresh_box_size()

    assert tkhd.header.type == b"tkhd"
    assert tkhd.header.box_size == 104
    assert tkhd.header.flags == b"\x00\x00\x00"

    assert tkhd.track_id == 3

    assert tkhd.width == 0
    assert tkhd.height == 0

    assert bytes(tkhd) == \
           pack("uintbe:32, bytes:4, uintbe:8, bits:24, "
                "uintbe:64, uintbe:64, uintbe:32, "
                "bits:32, "
                "uintbe:64, "
                "bits:32, bits:32, "
                "uintbe:16, uintbe:16, uintbe:8, uintbe:8, "
                "bits:16, "
                "uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, "
                "uintbe:16, uintbe:16, uintbe:16, uintbe:16",
                104, b"tkhd", 1, b"\x00\x00\x00",
                creation_time, modification_time, 3,
                b"\x00" * 4,
                60,
                b"\x00" * 4, b"\x00" * 4,
                0, 0, 0, 0,
                b"\x00" * 2,
                65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824,
                0, 0, 0, 0)

    # MOOV.TRAK.MDIA.MDHD
    mdhd = trak.boxes[-1].boxes[0]
    mdhd.timescale = 20
    mdhd.duration = 60

    mdhd.refresh_box_size()

    assert mdhd.header.type == b"mdhd"
    assert mdhd.header.box_size == 44
    assert mdhd.timescale == 20
    assert mdhd.duration == 60

    assert bytes(mdhd) == \
           pack("uintbe:32, bytes:4, uintbe:8, bits:24, "
                "uintbe:64, uintbe:64, uintbe:32, uintbe:64, "
                "bits:1, uint:5, uint:5, uint:5, "
                "bits:16",
                44, b"mdhd", 1, b"\x00\x00\x00",
                creation_time, modification_time, 20, 60,
                0x1, 21, 14, 4,
                b"\x00" * 2)

    moov.append(trak)

    # MOOV.TRAK
    offset += sum(sizes)
    sizes = [8, 8, 8]
    trak = make_text_trak(creation_time, modification_time, b"bzna_targets\0",
                          sizes, offset)

    # MOOV.TRAK.TKHD
    tkhd = trak.boxes[0]

    # "\x00\x00\x01" trak is enabled
    # "\x00\x00\x02" trak is used in the presentation
    # "\x00\x00\x04" trak is used in the preview
    # "\x00\x00\x08" trak size in not in pixel but in aspect ratio
    tkhd.header.flags = b"\x00\x00\x00"

    tkhd.track_id = 4

    # TODO: make sure that this is the canvas size
    tkhd.width = [0, 0]
    tkhd.height = [0, 0]

    tkhd.refresh_box_size()

    assert tkhd.header.type == b"tkhd"
    assert tkhd.header.box_size == 104
    assert tkhd.header.flags == b"\x00\x00\x00"

    assert tkhd.track_id == 4

    assert tkhd.width == 0
    assert tkhd.height == 0

    assert bytes(tkhd) == \
           pack("uintbe:32, bytes:4, uintbe:8, bits:24, "
                "uintbe:64, uintbe:64, uintbe:32, "
                "bits:32, "
                "uintbe:64, "
                "bits:32, bits:32, "
                "uintbe:16, uintbe:16, uintbe:8, uintbe:8, "
                "bits:16, "
                "uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, uintbe:32, "
                "uintbe:16, uintbe:16, uintbe:16, uintbe:16",
                104, b"tkhd", 1, b"\x00\x00\x00",
                creation_time, modification_time, 4,
                b"\x00" * 4,
                60,
                b"\x00" * 4, b"\x00" * 4,
                0, 0, 0, 0,
                b"\x00" * 2,
                65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824,
                0, 0, 0, 0)

    # MOOV.TRAK.MDIA.MDHD
    mdhd = trak.boxes[-1].boxes[0]
    mdhd.timescale = 20
    mdhd.duration = 60

    mdhd.refresh_box_size()

    assert mdhd.header.type == b"mdhd"
    assert mdhd.header.box_size == 44
    assert mdhd.timescale == 20
    assert mdhd.duration == 60

    assert bytes(mdhd) == \
           pack("uintbe:32, bytes:4, uintbe:8, bits:24, "
                "uintbe:64, uintbe:64, uintbe:32, uintbe:64, "
                "bits:1, uint:5, uint:5, uint:5, "
                "bits:16",
                44, b"mdhd", 1, b"\x00\x00\x00",
                creation_time, modification_time, 20, 60,
                0x1, 21, 14, 4,
                b"\x00" * 2)

    moov.append(trak)

    moov.refresh_box_size()

    assert mvhd.next_track_id == len(moov.boxes)

    assert moov.header.type == b"moov"
    assert len(moov.boxes) == 5

    mp4_bytes = b''.join([bytes(ftyp), bytes(mdat), bytes(moov)])

    for box in moov.boxes:
        if isinstance(box, bx_def.TRAK):
            mdia = box.boxes[1]
        else:
            continue

        # trak.mdia.tkhd.name == b"bzna_inputs\0"
        if mdia.boxes[1].name == b"bzna_inputs\0":
            pass
        # trak.mdia.tkhd.name == b"bzna_names\0"
        elif mdia.boxes[1].name == b"bzna_fnames\0":
            # trak.mdia.minf.stbl.stsz
            stsz = mdia.boxes[2].boxes[2].boxes[2]
            # trak.mdia.minf.stbl.stco
            stco = mdia.boxes[2].boxes[2].boxes[4]
            for i, (sample, entry) in enumerate(zip(stsz.samples, stco.entries)):
                sample_end = entry.chunk_offset + sample.entry_size
                if i == 0:
                    assert mp4_bytes[entry.chunk_offset:sample_end] == \
                           b"/path/image_1_name.JPEG"
                elif i == 1:
                    assert mp4_bytes[entry.chunk_offset:sample_end] == \
                           b"/path/image_2_name.JPEG"
                elif i == 2:
                    assert mp4_bytes[entry.chunk_offset:sample_end] == \
                           b"/path/image_3_name.JPEG"
        # trak.mdia.tkhd.name == b"bzna_targets\0"
        elif mdia.boxes[1].name == b"bzna_targets\0":
            # trak.mdia.minf.stbl.stsz
            stsz = mdia.boxes[2].boxes[2].boxes[2]
            # trak.mdia.minf.stbl.stco
            stco = mdia.boxes[2].boxes[2].boxes[4]
            for i, (sample, entry) in enumerate(zip(stsz.samples, stco.entries)):
                sample_end = entry.chunk_offset + sample.entry_size
                if i == 0:
                    assert mp4_bytes[entry.chunk_offset:sample_end] == \
                           (0).to_bytes(8, byteorder="little")
                elif i == 1:
                    assert mp4_bytes[entry.chunk_offset:sample_end] == \
                           (1).to_bytes(8, byteorder="little")
                elif i == 2:
                    assert mp4_bytes[entry.chunk_offset:sample_end] == \
                           (0).to_bytes(8, byteorder="little")

    with open("tests/data/small_dataset.out.mp4", "rb") as f:
        assert mp4_bytes == f.read()