diff --git a/removeads.py b/removeads.py index 209a76d..6e9ae4f 100755 --- a/removeads.py +++ b/removeads.py @@ -294,6 +294,34 @@ def parseMKVTree(mkvinfo, inputFile): # 0000 0001 xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx xxxx - value 0 to 2^56-2 +def getEBMLLength(length): + if (0 <= length) and (length <= 2^7-2): + size = 1 + elif length <= 2^14-2: + size = 2 + elif length <= 2^21-2: + size = 3 + elif length <= 2^28-2: + size = 4 + elif length <= 2^35-2: + size = 5 + elif length <= 2^42-2: + size = 6 + elif length <= 2^49-2: + size = 7 + elif length <= 2^56-2: + size = 8 + elif length < 0: + logger.error('Impossible to encode a negative length with EBML.') + return None + else: + logger.error('Impossible to encode a length larger than 2^56-2 with EBML.') + return None + + encodedLength = length + ((128>>(size-1))<<((size-1)*8)) + res = (encodedLength).to_bytes(size, byteorder='big') + return res + def changeEBMLElementSize(inputFile, position, addendum): logger = logging.getLogger(__name__) @@ -350,6 +378,7 @@ def changeEBMLElementSize(inputFile, position, addendum): newSize = sizeOfData+addendum if newSize > maxSize: + # TODO: we can reencode the header with a larger length field ... logger.error('New size is too big to be encoded in actual size field.') exit(-1) @@ -360,7 +389,8 @@ def changeEBMLElementSize(inputFile, position, addendum): lseek(infd, position, SEEK_SET) write(infd, newSizeBuf) - + # TODO: we will return the increase of length of the modified element (if its new size does not fit the older one) + return 0 def changeCodecPrivateData(mkvinfo, inputFile, codecData): logger = logging.getLogger(__name__) @@ -408,24 +438,37 @@ def changeCodecPrivateData(mkvinfo, inputFile, codecData): write(infd, tail) lseek(infd, position, SEEK_SET) write(infd, codecData) + elif currentLength == futureLength: + # Almost nothing to do except overwriting old private codec data with new ones. + lseek(infd, position, SEEK_SET) + write(infd, codecData) + else: + lseek(infd, position+currentDataLength, SEEK_SET) + tail = read(infd, currentLength-(position+currentDataLength)) + lseek(infd, position+len(codecData), SEEK_SET) + write(infd, tail) + lseek(infd, position, SEEK_SET) + write(infd, codecData) + # We reduce the length of file. + ftruncate(infd, futureLength) + + # We have to modify the tree elements up to the root that contains the codec private data. + keys = key.split('.') + logger.info(keys) - keys = key.split('.') - logger.info(keys) - + delta = futureLength-currentLength + # if there is no modification of the private codec data, no need to change anything. + if delta != 0: for i in range(0, len(keys)-1): keys.pop() key=".".join(map(str, keys)) pos, size = elements[key] logger.info('Trying to fix element with key: %s at position: %d with actual size: %d.' % (key, pos, size)) - changeEBMLElementSize(inputFile, pos, futureLength-currentLength) - - elif currentLength == futureLength: - logger.error("Not yet implemented") - exit(-1) - else: - logger.error("Not yet implemented") - exit(-1) - + # Changing an element can increase its size (in very rare case). + # In that case, we update the new delta that will be larger (because the element has been resized). + # For now, the function always return 0. + delta+=changeEBMLElementSize(inputFile, pos, delta) + def getFormat(ffprobe, inputFile): logger = logging.getLogger(__name__)