/* * This file is part of libbdplus * Copyright (C) 2013 VideoLAN * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library. If not, see * . */ #include #include #include #include // endian safe fetch #define FETCH4(X) (uint32_t)(((X)[0]<<24)|(X)[1]<<16|(X)[2]<<8|(X)[3]) #define FETCHU2(X) (uint32_t)((uint16_t)(((X)[0]<<8)|(X)[1])) // raw table #define MAX_TAB_SIZE 64*1024*1024 uint8_t tab[MAX_TAB_SIZE]; uint32_t index[0xffff]; static size_t _read_tab(const char *file) { FILE *fp = fopen(file, "rb"); size_t len; if (!fp) { perror("fopen(): "); return 0; } memset(tab, 0, MAX_TAB_SIZE); len = fread(tab, 1, MAX_TAB_SIZE, fp); if (len < 1) { perror("fread(): "); } fclose(fp); printf("Read %zd bytes from %s\n", len, file); return len; } int main(int argc, char **argv) { uint32_t numTables, table; uint32_t ptr = 0; uint32_t offset = 0; if (argc < 2) { fprintf(stderr, "%s /path/to/conv_tab.bin\n", argv[0]); exit(1); } if (_read_tab(argv[1]) < 1) { fprintf(stderr, "Error reading %s\n", argv[0]); exit(1); } numTables = FETCHU2(&tab[ptr]); ptr += 2; printf("%d tables:\n", numTables); for (table = 0; table < numTables; table++) { uint32_t tableID, numSegments, segment; tableID = FETCH4(&tab[ptr]); ptr += 4; numSegments = FETCHU2(&tab[ptr]); ptr += 2; printf("Table %d: %05d.m2ts (%d segments)\n", table, tableID, numSegments); for (segment = 0; segment < numSegments; segment++) { uint32_t numEntries, entry; offset = FETCH4(&tab[ptr + (segment * 4) ]); numEntries = FETCH4(&tab[offset]); offset += 4; printf(" Segment %d: %d entries\n", segment, numEntries); // read index table for (entry = 0; entry < numEntries; entry++) { index[entry] = FETCH4(&tab[offset]); offset += 4; } // read data for (entry = 0; entry < numEntries; entry++) { uint8_t flags = tab[ offset ]; offset += 1; uint32_t tmp = FETCH4(&tab[offset]); // only fetch 3bytes, 24 bits. offset += 3; tmp &= 0xFFFFFF00; uint32_t patch0_address_adjust = (tmp & 0xFFF00000) >> 20; uint32_t patch1_address_adjust = (tmp & 0x000FFF00) >> 8; uint32_t patch0_buffer_offset = tab[offset++]; uint32_t patch1_buffer_offset = tab[offset++]; uint8_t patch0[5], patch1[5]; memcpy(patch0, &tab[ offset ], sizeof(patch0)); offset += 5; memcpy(patch1, &tab[ offset ], sizeof(patch1)); offset += 5; uint64_t off0 = (( (uint64_t)index[entry] + (uint64_t)patch0_address_adjust) * (uint64_t)0xC0 + (uint64_t)patch0_buffer_offset); uint64_t off1 = (( (uint64_t)index[entry] + (uint64_t)patch0_address_adjust + (uint64_t)patch1_address_adjust) * (uint64_t)0xC0 + (uint64_t)patch1_buffer_offset); printf(" Entry %d: flags 0x%x (%d)\n", entry, flags, flags>>6); printf(" %08X %08X: %02X %02X %02X %02X %02X\n", (uint32_t)(off0 >> 32), (uint32_t)(off0 & 0xffffffff), patch0[0], patch0[1], patch0[2], patch0[3], patch0[4]); printf(" %08X %08X: %02X %02X %02X %02X %02X\n", (uint32_t)(off1 >> 32), (uint32_t)(off1 & 0xffffffff), patch1[0], patch1[1], patch1[2], patch1[3], patch1[4]); } // for entry } // for segment ptr = offset; } // for table return 0; }