We handle the cases where the old codec private data size is larger, smaller or equal to the new one.
This commit is contained in:
69
removeads.py
69
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
|
# 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):
|
def changeEBMLElementSize(inputFile, position, addendum):
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@@ -350,6 +378,7 @@ def changeEBMLElementSize(inputFile, position, addendum):
|
|||||||
|
|
||||||
newSize = sizeOfData+addendum
|
newSize = sizeOfData+addendum
|
||||||
if newSize > maxSize:
|
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.')
|
logger.error('New size is too big to be encoded in actual size field.')
|
||||||
exit(-1)
|
exit(-1)
|
||||||
|
|
||||||
@@ -360,7 +389,8 @@ def changeEBMLElementSize(inputFile, position, addendum):
|
|||||||
lseek(infd, position, SEEK_SET)
|
lseek(infd, position, SEEK_SET)
|
||||||
write(infd, newSizeBuf)
|
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):
|
def changeCodecPrivateData(mkvinfo, inputFile, codecData):
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
@@ -408,24 +438,37 @@ def changeCodecPrivateData(mkvinfo, inputFile, codecData):
|
|||||||
write(infd, tail)
|
write(infd, tail)
|
||||||
lseek(infd, position, SEEK_SET)
|
lseek(infd, position, SEEK_SET)
|
||||||
write(infd, codecData)
|
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('.')
|
delta = futureLength-currentLength
|
||||||
logger.info(keys)
|
# 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):
|
for i in range(0, len(keys)-1):
|
||||||
keys.pop()
|
keys.pop()
|
||||||
key=".".join(map(str, keys))
|
key=".".join(map(str, keys))
|
||||||
pos, size = elements[key]
|
pos, size = elements[key]
|
||||||
logger.info('Trying to fix element with key: %s at position: %d with actual size: %d.' % (key, pos, size))
|
logger.info('Trying to fix element with key: %s at position: %d with actual size: %d.' % (key, pos, size))
|
||||||
changeEBMLElementSize(inputFile, pos, futureLength-currentLength)
|
# 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).
|
||||||
elif currentLength == futureLength:
|
# For now, the function always return 0.
|
||||||
logger.error("Not yet implemented")
|
delta+=changeEBMLElementSize(inputFile, pos, delta)
|
||||||
exit(-1)
|
|
||||||
else:
|
|
||||||
logger.error("Not yet implemented")
|
|
||||||
exit(-1)
|
|
||||||
|
|
||||||
|
|
||||||
def getFormat(ffprobe, inputFile):
|
def getFormat(ffprobe, inputFile):
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|||||||
Reference in New Issue
Block a user