kopia lustrzana https://github.com/F5OEO/tstools
Add (lazy) retrieval of PCR from TS packets.
--HG-- extra : convert_revision : svn%3Aeff31bef-be4a-0410-a8fe-e47997df2690/trunk%4071issue20
rodzic
e1598da9c0
commit
16f6e337c0
|
@ -349,6 +349,11 @@ needed:
|
||||||
>>> print p.adapt
|
>>> print p.adapt
|
||||||
None
|
None
|
||||||
|
|
||||||
|
Whether there is a PCR or not is also calculated lazily:
|
||||||
|
|
||||||
|
>>> print p.PCR
|
||||||
|
None
|
||||||
|
|
||||||
The payload itself won't print out nicely, as it's binary, but we can check
|
The payload itself won't print out nicely, as it's binary, but we can check
|
||||||
its length:
|
its length:
|
||||||
|
|
||||||
|
@ -436,6 +441,19 @@ Python 2.6 introduces the ``bytearray`` (an immutable array of bytes), which
|
||||||
is clearly what we'd prefer to be using to communicate with TS packets,
|
is clearly what we'd prefer to be using to communicate with TS packets,
|
||||||
instead of strings and ``array.array``.
|
instead of strings and ``array.array``.
|
||||||
|
|
||||||
|
The first packet with a PCR is at 100768:
|
||||||
|
|
||||||
|
>>> f = TSFile(test_ts_file)
|
||||||
|
>>> f.seek(100768)
|
||||||
|
>>> tspcr = f.read()
|
||||||
|
>>> tspcr.pusi
|
||||||
|
0
|
||||||
|
>>> len(tspcr.adapt)
|
||||||
|
183
|
||||||
|
>>> tspcr.PCR
|
||||||
|
16303619382L
|
||||||
|
>>> f.close()
|
||||||
|
|
||||||
Program data
|
Program data
|
||||||
------------
|
------------
|
||||||
A PAT is a wrapper around a lightly hidden dictionary of program number versus
|
A PAT is a wrapper around a lightly hidden dictionary of program number versus
|
||||||
|
|
|
@ -109,9 +109,14 @@ cdef FILE *convert_python_file(object file):
|
||||||
return stream
|
return stream
|
||||||
|
|
||||||
cdef extern from "stdint.h":
|
cdef extern from "stdint.h":
|
||||||
ctypedef int uint8_t # !!! *some* sort of int..
|
ctypedef unsigned char uint8_t
|
||||||
ctypedef int uint16_t # !!! *some* sort of int..
|
ctypedef unsigned uint16_t
|
||||||
ctypedef int uint32_t # !!! *some* sort of int..
|
ctypedef unsigned long uint32_t
|
||||||
|
ctypedef unsigned long long uint64_t
|
||||||
|
ctypedef signed char int8_t
|
||||||
|
ctypedef int int16_t
|
||||||
|
ctypedef long int32_t
|
||||||
|
ctypedef long long int64_t
|
||||||
|
|
||||||
# PIDs are too long for 16 bits, short enough to fit in 32
|
# PIDs are too long for 16 bits, short enough to fit in 32
|
||||||
ctypedef uint32_t PID
|
ctypedef uint32_t PID
|
||||||
|
@ -120,7 +125,7 @@ cdef extern from "compat.h":
|
||||||
# We don't need to define 'offset_t' exactly, just to let Pyrex
|
# We don't need to define 'offset_t' exactly, just to let Pyrex
|
||||||
# know it's vaguely int-like
|
# know it's vaguely int-like
|
||||||
ctypedef int offset_t
|
ctypedef int offset_t
|
||||||
ctypedef uint8_t byte
|
ctypedef uint8_t byte # but we already had our stdint byte daatype
|
||||||
|
|
||||||
cdef extern from 'es_defns.h':
|
cdef extern from 'es_defns.h':
|
||||||
# The reader for an ES file
|
# The reader for an ES file
|
||||||
|
@ -623,6 +628,8 @@ cdef extern from "ts_fns.h":
|
||||||
int split_TS_packet(byte *buf, PID *pid, int *payload_unit_start_indicator,
|
int split_TS_packet(byte *buf, PID *pid, int *payload_unit_start_indicator,
|
||||||
byte **adapt, int *adapt_len,
|
byte **adapt, int *adapt_len,
|
||||||
byte **payload, int *payload_len)
|
byte **payload, int *payload_len)
|
||||||
|
void get_PCR_from_adaptation_field(byte *adapt, int adapt_len, int*got_pcr,
|
||||||
|
uint64_t *pcr)
|
||||||
int find_pat(TS_reader_p tsreader, int max, int verbose, int quiet,
|
int find_pat(TS_reader_p tsreader, int max, int verbose, int quiet,
|
||||||
int *num_read, pidint_list_p *prog_list)
|
int *num_read, pidint_list_p *prog_list)
|
||||||
int find_next_pmt(TS_reader_p tsreader, uint32_t pmt_pid,
|
int find_next_pmt(TS_reader_p tsreader, uint32_t pmt_pid,
|
||||||
|
@ -630,6 +637,8 @@ cdef extern from "ts_fns.h":
|
||||||
int *num_read, pmt_p *pmt)
|
int *num_read, pmt_p *pmt)
|
||||||
int find_pmt(TS_reader_p tsreader, int max, int verbose, int quiet,
|
int find_pmt(TS_reader_p tsreader, int max, int verbose, int quiet,
|
||||||
int *num_read, pmt_p *pmt)
|
int *num_read, pmt_p *pmt)
|
||||||
|
int extract_prog_list_from_pat(int verbose, byte *data, int data_len,
|
||||||
|
pidint_list_p *prog_list)
|
||||||
|
|
||||||
|
|
||||||
DEF TS_PACKET_LEN = 188
|
DEF TS_PACKET_LEN = 188
|
||||||
|
@ -647,6 +656,10 @@ cdef class TSPacket:
|
||||||
cdef object _adapt
|
cdef object _adapt
|
||||||
cdef object _payload
|
cdef object _payload
|
||||||
|
|
||||||
|
# Ditto with looking for a PCR
|
||||||
|
cdef int _checked_for_pcr
|
||||||
|
cdef object _pcr # if we have one
|
||||||
|
|
||||||
def __cinit__(self,buffer,*args,**kwargs):
|
def __cinit__(self,buffer,*args,**kwargs):
|
||||||
"""The buffer *must* be 188 bytes long, by definition.
|
"""The buffer *must* be 188 bytes long, by definition.
|
||||||
"""
|
"""
|
||||||
|
@ -718,7 +731,6 @@ cdef class TSPacket:
|
||||||
cdef int adapt_len
|
cdef int adapt_len
|
||||||
cdef char *payload_buf
|
cdef char *payload_buf
|
||||||
cdef int payload_len
|
cdef int payload_len
|
||||||
if not self._already_split:
|
|
||||||
PyObject_AsReadBuffer(self.data, &buffer, &length)
|
PyObject_AsReadBuffer(self.data, &buffer, &length)
|
||||||
retval = split_TS_packet(<byte *>buffer,&pid,&self._pusi,
|
retval = split_TS_packet(<byte *>buffer,&pid,&self._pusi,
|
||||||
<byte **>&adapt_buf,&adapt_len,
|
<byte **>&adapt_buf,&adapt_len,
|
||||||
|
@ -735,7 +747,26 @@ cdef class TSPacket:
|
||||||
self._payload = PyString_FromStringAndSize(payload_buf,payload_len)
|
self._payload = PyString_FromStringAndSize(payload_buf,payload_len)
|
||||||
self._already_split = True
|
self._already_split = True
|
||||||
|
|
||||||
|
def _determine_PCR(self):
|
||||||
|
"""Determine our PCR, if we have one.
|
||||||
|
Assumes that self._split() has been called already.
|
||||||
|
"""
|
||||||
|
cdef void *adapt_buf
|
||||||
|
cdef Py_ssize_t adapt_len
|
||||||
|
cdef int got_pcr
|
||||||
|
cdef uint64_t pcr
|
||||||
|
if self._adapt:
|
||||||
|
PyObject_AsReadBuffer(self._adapt, &adapt_buf, &adapt_len)
|
||||||
|
get_PCR_from_adaptation_field(<byte *>adapt_buf, adapt_len,
|
||||||
|
&got_pcr, &pcr)
|
||||||
|
else:
|
||||||
|
got_pcr = 0
|
||||||
|
self._checked_for_pcr = True # regardless
|
||||||
|
if got_pcr:
|
||||||
|
self._pcr = pcr
|
||||||
|
|
||||||
def __getattr__(self,name):
|
def __getattr__(self,name):
|
||||||
|
if not self._already_split:
|
||||||
self._split()
|
self._split()
|
||||||
if name == 'pusi':
|
if name == 'pusi':
|
||||||
return self._pusi
|
return self._pusi
|
||||||
|
@ -743,6 +774,10 @@ cdef class TSPacket:
|
||||||
return self._adapt
|
return self._adapt
|
||||||
elif name == 'payload':
|
elif name == 'payload':
|
||||||
return self._payload
|
return self._payload
|
||||||
|
elif name == "PCR":
|
||||||
|
if not self._checked_for_pcr:
|
||||||
|
self._determine_PCR()
|
||||||
|
return self._pcr
|
||||||
else:
|
else:
|
||||||
raise AttributeError
|
raise AttributeError
|
||||||
|
|
||||||
|
|
Ładowanie…
Reference in New Issue