1import bento4.core as bt4
2import os.path as path
3import unittest
4from struct import pack
5
6BENTO4_TEST_DATA_DIR = path.join(path.dirname(__file__), '..', 'Data')
7
8class CoreTester(unittest.TestCase):
9
10    def setUp(self):
11        self.file = bt4.File(path.join(BENTO4_TEST_DATA_DIR, 'test-001.mp4'))
12
13    def test_moov_position(self):
14        self.assertTrue(self.file.moov_is_before_mdat)
15
16    def test_atom_type_name(self):
17        self.assertEquals('caca', bt4.atom_name(bt4.atom_type('caca')))
18        self.assertNotEquals('zobi', bt4.atom_name(bt4.atom_type('fouf')))
19
20    def test_filetype(self):
21        major_brand, minor_version, compat_brands = self.file.type
22        self.assertEquals(major_brand, bt4.File.FILE_BRAND_MP42)
23        self.assertEquals(minor_version, 1)
24        self.assertEquals(len(compat_brands), 2)
25        self.assertEquals(compat_brands[0], bt4.File.FILE_BRAND_MP42)
26        self.assertEquals(bt4.atom_name(compat_brands[1]), 'avc1')
27
28    def test_movie(self):
29        self.failIfEqual(self.file.movie, None, "no movie in file")
30
31    def test_tracks(self):
32        tracks = self.file.movie.tracks
33        known_values = {
34            1: {'type': bt4.Track.TYPE_AUDIO,
35                'handler_type': bt4.Track.HANDLER_TYPE_SOUN,
36                'sample_count': 78,
37                'durationms': 3600,
38                'media_timescale': 22050,
39                'sample_descriptions': [
40                    {'type': bt4.SampleDescription.TYPE_MPEG},
41                ]},
42            2: {'type': bt4.Track.TYPE_VIDEO,
43                'handler_type': bt4.Track.HANDLER_TYPE_VIDE,
44                'sample_count': 54,
45                'durationms': 3600,
46                'media_timescale': 30000,
47                'sample_descriptions': [
48                    {'type': bt4.SampleDescription.TYPE_AVC}
49                ]},
50            3: {'type': bt4.Track.TYPE_HINT,
51                'handler_type': bt4.Track.HANDLER_TYPE_HINT,
52                'sample_count': 54,
53                'durationms': 3600,
54                'media_timescale': 90000},
55            4: {'type': bt4.Track.TYPE_HINT,
56                'handler_type': bt4.Track.HANDLER_TYPE_HINT,
57                'sample_count': 39,
58                'durationms': 3600,
59                'media_timescale': 22050}
60        }
61        for id in known_values:
62            self.assertEquals(tracks[id].id, id)
63            self.assertEquals(tracks[id].type, known_values[id]['type'])
64            self.assertEquals(tracks[id].handler_type,
65                              known_values[id]['handler_type'])
66            self.assertEquals(tracks[id].media_duration[1],
67                              known_values[id]['media_timescale'])
68            self.assertEquals(tracks[id].sample_count,
69                              known_values[id]['sample_count'])
70            duration, timescale = tracks[id].duration
71            self.assertEquals(duration*1000/timescale,
72                              known_values[id]['durationms'])
73            if 'sample_descriptions' in known_values:
74                known_sample_descs = known_values['sample_descriptions']
75                for i in xrange(len(sample_descs)):
76                    self.assertEquals(sample_descs['type'],
77                                      tracks[id].sample_description(i).type)
78
79    def test_avc_track(self):
80        tracks = self.file.movie.tracks
81        avc_track = tracks[2]
82        test_filename = path.join(BENTO4_TEST_DATA_DIR, 'test-001.mp4.2')
83        try:
84            test_file = open(test_filename, 'rb')
85            avc_data = ''
86            for s in avc_track.sample_iterator():
87                self.assertEquals(len(s.data), s.size)
88                self.assertEquals(s.description_index, 0)
89                avc_data += pack('>I', s.size)
90                avc_data += s.data
91
92            # test the sample data
93            test_data = test_file.read()
94            self.assertEquals(len(avc_data), len(test_data))
95            self.assertEquals(avc_data, test_data,
96                              'avc data mismatch')
97
98            # test the sample description
99            avc_desc = avc_track.sample_description(0)
100            self.assertEquals(avc_desc.type, bt4.SampleDescription.TYPE_AVC)
101            self.assertEquals(bt4.avc_profile_name(avc_desc.profile), "Main")
102            self.assertEquals(avc_desc.profile_compatibility, 0x40)
103            self.assertEquals(avc_desc.nalu_length_size, 4)
104            self.assertEquals(avc_desc.width, 160)
105            self.assertEquals(avc_desc.height, 120)
106            self.assertEquals(avc_desc.depth, 24)
107
108        finally:
109            test_file.close()
110
111
112if __name__ == '__main__':
113    unittest.main()
114
115