Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

added adaptation-field

  • Loading branch information...
commit c0fe49ce740a3e885df9d23e192d1feb899babee 1 parent d41c594
authored September 30, 2012
8  package.lisp
@@ -42,6 +42,14 @@
42 42
            ;;; pmt
43 43
            payload-pmt
44 44
            make-payload-pmt
  45
+
  46
+           ;;; pes
  47
+           payload-pes
  48
+           make-payload-pes
  49
+
  50
+           ;; adaptation-field
  51
+           adaptation-field
  52
+           make-adaptation-field
45 53
            
46 54
            ;;; packet
47 55
            packet
64  packet.lisp
@@ -3,6 +3,7 @@
3 3
 (defconstant +SYNC_BYTE+ #x47)
4 4
 
5 5
 (defconstant +PID_PAT+ 0)
  6
+(defconstant +PID_CAT+ 1) ; TODO: Conditional Access Table
6 7
 (defconstant +PID_NULL+ #x1FFF)
7 8
 
8 9
 (eval-when (:compile-toplevel :load-toplevel :execute)
@@ -163,6 +164,10 @@ CRC32                    |
163 164
 ----------------------------------------------------------------------------------------------------
164 165
 ")))
165 166
 
  167
+(eval-when (:compile-toplevel :load-toplevel :execute)
  168
+  (defparameter *pes-document* (format nil "~
  169
+[PES: Packetized Elementary Stream]
  170
+")))
166 171
 
167 172
 (defstruct payload)
168 173
 
@@ -204,6 +209,9 @@ CRC32                    |
204 209
                                           ;             es-info-length es-descriptors))
205 210
   (crc32                    0 :type (unsigned-byte 32)))
206 211
 
  212
+(defstruct (payload-pes (:include payload)) #.*pes-document*
  213
+  )
  214
+
207 215
 (defstruct (payload-unknown (:include payload))
208 216
   (data t :type (array (unsigned-byte 8))))
209 217
 
@@ -217,7 +225,59 @@ CRC32                    |
217 225
      (cond ((member (ts-header-pid header) pmt-pids) :psi-pmt)
218 226
            (t :unknown)))))
219 227
 
  228
+(eval-when (:compile-toplevel :load-toplevel :execute)
  229
+  (defparameter *adaptation-field-document* (format nil "~
  230
+[Adaptation Field]
  231
+----------------------------------------------------------------------------------------------------
  232
+Adaptation Field Length              | Number of bytes in the adaptation field immediately following this byte.
  233
+----------------------------------------------------------------------------------------------------
  234
+Discontinuity indicator              | Set to 1 if current TS packet is in a discontinuity state with respect 
  235
+                                     | to either the continuity counter or the program clock reference.
  236
+----------------------------------------------------------------------------------------------------
  237
+Random Access indicator              | Set to 1 if the PES packet in this TS packet starts a video/audio sequence
  238
+----------------------------------------------------------------------------------------------------
  239
+Elementary stream priority indicator | 1 = higher priority
  240
+----------------------------------------------------------------------------------------------------
  241
+PCR flag                             | 1 means adaptation field does contain a PCR field
  242
+----------------------------------------------------------------------------------------------------
  243
+OPCR flag                            | 1 means adaptation field does contain an OPCR field
  244
+----------------------------------------------------------------------------------------------------
  245
+Splicing point flag                  | 1 means presence of splice countdown field in adaptation field
  246
+----------------------------------------------------------------------------------------------------
  247
+Transport private data flag          | 1 means presence of private data bytes in adaptation field
  248
+----------------------------------------------------------------------------------------------------
  249
+Adaptation field extension flag      | 1 means presence of adaptation field extension
  250
+----------------------------------------------------------------------------------------------------
  251
+# Below fields are optional          | Depends on flags
  252
+----------------------------------------------------------------------------------------------------
  253
+PCR                                  | Program clock reference, stored in 6 octets in big-endian as 33 bits base, 
  254
+                                     | 6 bits padding, 9 bits extension.
  255
+----------------------------------------------------------------------------------------------------
  256
+OPCR                                 | Original Program clock reference. Helps when one TS is copied into another
  257
+----------------------------------------------------------------------------------------------------
  258
+Splice countdown                     | Indicates how many TS packets from this one a splicing point occurs 
  259
+                                     | (may be negative)
  260
+----------------------------------------------------------------------------------------------------
  261
+stuffing bytes                       |
  262
+----------------------------------------------------------------------------------------------------
  263
+")))
  264
+
  265
+(defstruct adaptation-field 
  266
+  (length                          0 :type (unsigned-byte 8))
  267
+  (discontinuity-indicator         0 :type (unsigned-byte 1))
  268
+  (random-access-indicator         0 :type (unsigned-byte 1))
  269
+  (es-priority-indicator           0 :type (unsigned-byte 1))
  270
+  (pcr-flag                        0 :type (unsigned-byte 1))
  271
+  (opcr-flag                       0 :type (unsigned-byte 1))
  272
+  (splicing-point-flag             0 :type (unsigned-byte 1))
  273
+  (transport-private-data-flag     0 :type (unsigned-byte 1))
  274
+  (adaptation-field-extension-flag 0 :type (unsigned-byte 1))
  275
+  (pcr                             0 :type (or null (unsigned-byte 48)))
  276
+  (opcr                            0 :type (or null (unsigned-byte 48)))
  277
+  (splice-countdown                0 :type (or null (unsigned-byte 8)))
  278
+  (stuffing-bytes                  0 :type (or null list)))
  279
+
220 280
 (defstruct packet 
221 281
   (ts-header        t :type ts-header)
222  
-  adaptation-field
223  
-  (payload          t :type payload))
  282
+  (adaptation-field t :type (or null adaptation-field))
  283
+  (payload          t :type (or null payload)))
69  parser/parser.lisp
... ...
@@ -1,7 +1,8 @@
1 1
 (in-package :ts.parser)
2 2
 
3 3
 (defstruct context
4  
-  pmt-pids)
  4
+  pmt-pids
  5
+  pes-pids)
5 6
 
6 7
 (defun init-context () (make-context))
7 8
 
@@ -26,7 +27,7 @@
26 27
      :adaptation-field-exist       (ldb (byte 2 4) byte3)
27 28
      :continuity-counter           (ldb (byte 4 0) byte3))))
28 29
 
29  
-(defun parse-psi-pat (header stream &aux (count 0) (byte 0) (section-length 0))
  30
+(defun parse-psi-pat (header stream rest-count &aux (count 0) (byte 0) (section-length 0))
30 31
   (flet ((next-byte () (incf count) (setf byte (read-byte stream))))
31 32
     (prog1
32 33
     (ts:make-payload-pat
@@ -58,9 +59,9 @@
58 59
                  (ash (next-byte)  8)
59 60
                  (next-byte)))
60 61
 
61  
-    (loop FOR i FROM count BELOW 184 DO (read-byte stream))))) ; XXX:
  62
+    (loop FOR i FROM count BELOW rest-count DO (read-byte stream))))) ; XXX:
62 63
 
63  
-(defun parse-psi-pmt (header stream)
  64
+(defun parse-psi-pmt (header stream rest-count)
64 65
   (let ((count 0)
65 66
         (byte 0)
66 67
         (section-length 0)
@@ -111,30 +112,70 @@
111 112
                       (next-byte))
112 113
           
113 114
           )
114  
-        (loop FOR i FROM count BELOW 184 DO (read-byte stream))))))
  115
+        (loop FOR i FROM count BELOW rest-count DO (read-byte stream))))))
115 116
 
116  
-(defun parse-payload (header stream context)
  117
+(defun parse-payload (header stream context rest-count)
117 118
   (ecase (ts:get-packet-type header (context-pmt-pids context))
118  
-    (:psi-pat (let ((pat (parse-psi-pat header stream)))
  119
+    (:psi-pat (let ((pat (parse-psi-pat header stream rest-count)))
119 120
                 (loop FOR (_ __ program-pid) IN (ts::payload-pat-pmt-map pat)
120 121
                       DO
121 122
                       (pushnew program-pid (context-pmt-pids context)))
122 123
                 pat))
123  
-    (:psi-pmt (let ((pmt (parse-psi-pmt header stream)))
  124
+    (:psi-pmt (let ((pmt (parse-psi-pmt header stream rest-count)))
  125
+                (loop FOR (_1 _2 pes-pid _3 _4 _5 _6) IN (ts::payload-pmt-stream-infos pmt)
  126
+                      DO
  127
+                      (pushnew pes-pid (context-pes-pids context)))
124 128
                 pmt))
125 129
     (:null 
126  
-     (dotimes (i 184) (read-byte stream))
  130
+     (dotimes (i rest-count) (read-byte stream))
127 131
      (ts:make-payload-null))
128 132
     (:unknown 
129  
-     (dotimes (i 184)
  133
+     (dotimes (i rest-count)
130 134
        (read-byte stream))
131 135
      (ts:make-payload-unknown :data (sb-ext:string-to-octets "")))))
132 136
 
  137
+(defun parse-adaptation-field (stream)
  138
+  (let ((length 0)
  139
+        (count 0)
  140
+        (byte 0)
  141
+        (f1 0)
  142
+        (f2 0)
  143
+        (f3 0)
  144
+        (f4 0)
  145
+        (f5 0))
  146
+    (flet ((next-byte () (incf count) (setf byte (read-byte stream))))
  147
+      (values
  148
+        (ts:make-adaptation-field 
  149
+         :length                  (setf length (next-byte))
  150
+         :discontinuity-indicator (ldb (byte 1 7) (next-byte))
  151
+         :random-access-indicator (ldb (byte 1 6) byte)
  152
+         :es-priority-indicator   (ldb (byte 1 5) byte)
  153
+         :pcr-flag                (setf f1 (ldb (byte 1 4) byte))
  154
+         :opcr-flag               (setf f2 (ldb (byte 1 3) byte))
  155
+         :splicing-point-flag     (setf f3 (ldb (byte 1 2) byte))
  156
+         :transport-private-data-flag     (setf f4 (ldb (byte 1 1) byte))
  157
+         :adaptation-field-extension-flag (setf f5 (ldb (byte 1 0) byte))
  158
+         :pcr              (when (plusp f1) (loop FOR i FROM 5 DOWNTO 0 SUM (ash (next-byte) (* i 8))))
  159
+         :opcr             (when (plusp f2) (loop FOR i FROM 5 DOWNTO 0 SUM (ash (next-byte) (* i 8))))
  160
+         :splice-countdown (when (plusp f3) (next-byte))
  161
+         :stuffing-bytes (list (when (plusp f4)
  162
+                                 (loop REPEAT (next-byte) COLLECT (next-byte)))
  163
+                               (when (plusp f5)
  164
+                                 (loop REPEAT (next-byte) COLLECT (next-byte)))
  165
+                               (loop FOR i FROM count TO length COLLECT (next-byte))))
  166
+        count))))
  167
+
133 168
 (defun parse-one (stream context)
134  
-  (let* ((header (parse-ts-header stream))
135  
-         (payload (parse-payload header stream context)))
136  
-    (ts:make-packet :ts-header header
137  
-                    :payload payload)))
  169
+  (let ((header (parse-ts-header stream)))
  170
+    (multiple-value-bind (adaptation-field read-count)
  171
+                         (if (ldb-test (byte 1 1) (ts:ts-header-adaptation-field-exist header))
  172
+                             (parse-adaptation-field stream)
  173
+                           (values nil 0))
  174
+      (let ((payload (when (ldb-test (byte 1 0) (ts:ts-header-adaptation-field-exist header))
  175
+                       (parse-payload header stream context (- 188 4 read-count)))))
  176
+        (ts:make-packet :ts-header header
  177
+                        :adaptation-field adaptation-field
  178
+                        :payload payload)))))
138 179
 
139 180
 (defun parse (stream &key (context (init-context)))
140 181
   (values

0 notes on commit c0fe49c

Please sign in to comment.
Something went wrong with that request. Please try again.