Ticket #93: mpeg_duration.patch
| File mpeg_duration.patch, 5.2 kB (added by haypo, 2 years ago) |
|---|
-
hachoir-parser/hachoir_parser/video/mpeg_video.py
old new 12 12 """ 13 13 14 14 from hachoir_parser import Parser 15 from hachoir_core.field import (FieldSet, 15 from hachoir_core.field import (FieldSet, createOrphanField, 16 16 FieldError, ParserError, 17 17 Bit, Bits, Bytes, PaddingBits, NullBits, 18 18 UInt8, UInt16, … … 21 21 from hachoir_core.endian import BIG_ENDIAN 22 22 from hachoir_core.text_handler import hexadecimal 23 23 24 MAX_CHUNK_SIZE = 4096 # bytes 25 24 26 class Timestamp(FieldSet): 25 27 static_size = 36 26 28 … … 39 41 static_size = 35 40 42 41 43 def createFields(self): 42 yield Bits(self, " scr_a", 3)44 yield Bits(self, "a", 3) 43 45 yield Bit(self, "sync[]") # =True 44 yield Bits(self, " scr_b", 15)46 yield Bits(self, "b", 15) 45 47 yield Bit(self, "sync[]") # =True 46 yield Bits(self, " scr_c", 15)48 yield Bits(self, "c", 15) 47 49 50 def createValue(self): 51 return (((self["a"].value << 15) + self["b"].value) << 15) + self["c"].value 52 48 53 class ProgramStream(FieldSet): 49 54 def createFields(self): 50 55 if self.stream.readBits(self.absolute_address, 2, self.endian) == 1: … … 64 69 else: 65 70 # MPEG version 1 66 71 yield Bits(self, "sync[]", 4) 67 yield Bits(self, "scr_a", 3) 68 yield Bit(self, "sync[]") 69 yield Bits(self, "scr_b", 15) 70 yield Bit(self, "sync[]") 71 yield Bits(self, "scr_c", 15) 72 yield SCR(self, "scr") 72 73 yield Bits(self, "sync[]", 2) 73 74 yield Bits(self, "mux_rate", 22) 74 75 yield Bit(self, "sync[]") … … 87 88 elif (sync0.size == 4 and sync0.value == 2): 88 89 # MPEG1 89 90 if not self["sync[1]"].value \ 90 or not self["sync[2]"].value \ 91 or self["sync[3]"].value != 3 \ 92 or not self["sync[4]"].value: 91 or not self["sync[2]"].value: 93 92 return "Invalid synchronisation bits" 94 93 else: 95 94 return "Unknown version" … … 142 141 143 142 class Video(FieldSet): 144 143 def createFields(self): 144 yield Bytes(self, "xx", 48-36) 145 return 146 145 147 yield Bits(self, "sync[]", 2) # =2 146 148 if self["sync[0]"].value != 2: 147 149 raise ParserError("Unknown video elementary data") … … 194 196 yield Chunk(self, "chunk[]") 195 197 196 198 class Chunk(FieldSet): 197 ISO_END_CODE= 0xB9199 TAG_END = 0xB9 198 200 tag_info = { 199 201 # SLICE_START_CODE_MIN : 0x01 200 202 # SLICE_START_CODE_MAX : 0xAF … … 213 215 0xBB: ("system_start[]", None, "System start"), 214 216 0xBE: ("padding[]", Padding, "Padding"), 215 217 0xC0: ("audio[]", None, "Audio"), 218 # FIXME: ID 0xE0..0xEF ? (video id 0..15 ?) 216 219 0xE0: ("video[]", Video, "Video elementary"), 217 220 0xFF: ("directory[]", None, "Program Stream Directory"), 218 221 } … … 222 225 tag = self["tag"].value 223 226 if tag in self.tag_info: 224 227 self._name, self.parser, self._description = self.tag_info[tag] 225 if not self.parser :228 if not self.parser and (tag != self.TAG_END): 226 229 self.parser = defaultParser 227 230 else: 228 231 self.parser = defaultParser … … 284 287 else: 285 288 return "MPEG-1 video" 286 289 290 def createLastPackStart(self): 291 if not self._size: 292 return 293 start = self.size - MAX_CHUNK_SIZE*8 294 # FIXME: Use reverse search (end to the start) 295 # because MAX_CHUNK_SIZE bytes may contains two or more pack start! 296 offset = self.stream.searchBytes("\0\0\1\xBA", start) 297 if offset is None: 298 return None 299 return createOrphanField(self, offset, Chunk, "pack_start") 300 -
hachoir-metadata/hachoir_metadata/video.py
old new 1 1 from hachoir_core.field import MissingField 2 2 from hachoir_core.error import HachoirError 3 3 from hachoir_metadata.metadata import Metadata, MultipleMetadata, registerExtractor 4 from hachoir_parser.video import MovFile, AsfFile, FlvFile 4 from hachoir_parser.video import MovFile, AsfFile, FlvFile, MPEGVideoFile 5 5 from hachoir_parser.container import MkvFile 6 6 from hachoir_core.i18n import _ 7 7 from hachoir_core.tools import makePrintable … … 277 277 # meta.compression = text 278 278 return meta 279 279 280 class MpegVideoMetadata(Metadata): 281 def extract(self, mpeg): 282 self.compression = "MPEG" 283 pack = mpeg.createLastPackStart() 284 if pack \ 285 and "content/scr" in pack \ 286 and pack["content/scr"].hasValue(): 287 self.duration = pack["content/scr"].value // 90 288 280 289 registerExtractor(MovFile, MovMetadata) 281 290 registerExtractor(AsfFile, AsfMetadata) 282 291 registerExtractor(FlvFile, FlvMetadata) 283 292 registerExtractor(MkvFile, MkvMetadata) 293 registerExtractor(MPEGVideoFile, MpegVideoMetadata) 284 294