Permalink
Browse files

added PES packet

  • Loading branch information...
1 parent c0fe49c commit 50c542966330d63644f110a94788f9019b7b5a3d @sile committed Sep 30, 2012
Showing with 175 additions and 6 deletions.
  1. +2 −0 package.lisp
  2. +96 −2 packet.lisp
  3. +77 −4 parser/parser.lisp
View
@@ -34,6 +34,8 @@
payload-unknown-data
make-payload-null
payload-null
+ payload-data
+ make-payload-data
;;; pat
payload-pat
View
@@ -167,6 +167,60 @@ CRC32 |
(eval-when (:compile-toplevel :load-toplevel :execute)
(defparameter *pes-document* (format nil "~
[PES: Packetized Elementary Stream]
+----------------------------------------------------------------------------------------------------
+Packet start code prefix | 0x000001
+----------------------------------------------------------------------------------------------------
+Stream id | Examples: Audio streams (0xC0-0xDF), Video streams (0xE0-0xEF)
+----------------------------------------------------------------------------------------------------
+PES Packet length | Can be zero. If the PES packet length is set to zero,
+ | the PES packet can be of any length.
+ | A value of zero for the PES packet length can be used only when
+ | the PES packet payload is a video elementary stream.
+----------------------------------------------------------------------------------------------------
+Optional PES header | not present in case of Padding stream & Private stream 2 (navigation data)
+----------------------------------------------------------------------------------------------------
+Stuffing bytes |
+----------------------------------------------------------------------------------------------------
+Data | See elementary stream. In the case of private streams the first byte of
+ | the payload is the sub-stream number.
+----------------------------------------------------------------------------------------------------
+
+==============
+[Optional PES header]
+----------------------------------------------------------------------------------------------------
+Marker bits | 10 binary or 0x2 hex
+----------------------------------------------------------------------------------------------------
+Scrambling control | 00 implies not scrambled
+----------------------------------------------------------------------------------------------------
+priority |
+----------------------------------------------------------------------------------------------------
+Data alignment indicator | 1 indicates that the PES packet header is immediately followed by
+ | the video start code or audio syncword
+----------------------------------------------------------------------------------------------------
+Copyright | 1 implies copyrighted
+----------------------------------------------------------------------------------------------------
+Original or Copy | 1 implies original
+----------------------------------------------------------------------------------------------------
+PTS DTS indicator | 11 = both present, 10 = only PTS
+----------------------------------------------------------------------------------------------------
+ESCR flag |
+----------------------------------------------------------------------------------------------------
+ES rate flag |
+----------------------------------------------------------------------------------------------------
+DSM trick mode flag |
+----------------------------------------------------------------------------------------------------
+Additional copy info flag|
+----------------------------------------------------------------------------------------------------
+CRC flag |
+----------------------------------------------------------------------------------------------------
+extension flag |
+----------------------------------------------------------------------------------------------------
+PES header length | gives the length of the remainder of the PES header
+----------------------------------------------------------------------------------------------------
+Optional fields | presence is determined by flag bits above
+----------------------------------------------------------------------------------------------------
+Stuffing Bytes | 0xFF
+----------------------------------------------------------------------------------------------------
")))
(defstruct payload)
@@ -210,20 +264,60 @@ CRC32 |
(crc32 0 :type (unsigned-byte 32)))
(defstruct (payload-pes (:include payload)) #.*pes-document*
+ (packet-start-prefix-code 0 :type (unsigned-byte 24))
+ (stream-id 0 :type (unsigned-byte 8))
+ (pes-packet-length 0 :type (unsigned-byte 16))
+
+ (marker-bits 0 :type (unsigned-byte 2))
+ (scrambling-control 0 :type (unsigned-byte 2))
+ (priority 0 :type (unsigned-byte 1))
+ (data-alignment-indicator 0 :type (unsigned-byte 1))
+ (copyright 0 :type (unsigned-byte 1))
+ (original-or-copy 0 :type (unsigned-byte 1))
+ (pts-dts-indicator 0 :type (unsigned-byte 2))
+ (escr-flag 0 :type (unsigned-byte 1))
+ (es-rate-flag 0 :type (unsigned-byte 1))
+ (dsm-trick-mode-flag 0 :type (unsigned-byte 1))
+ (additional-copy-into-flag 0 :type (unsigned-byte 1))
+ (crc-flag 0 :type (unsigned-byte 1))
+ (extension-flag 0 :type (unsigned-byte 1))
+ (pes-header-length 0 :type (unsigned-byte 8))
+
+ (pts 0 :type (or null (unsigned-byte 34)))
+ (dts 0 :type (or null (unsigned-byte 34)))
+ (escr 0 :type (or null (unsigned-byte 48)))
+ (es 0 :type (or null (unsigned-byte 24)))
+ (dsm-trick-mode 0 :type (or null (unsigned-byte 8)))
+ (additional-copy-info 0 :type (or null (unsigned-byte 8)))
+ (pes-crc 0 :type (or null (unsigned-byte 16)))
+
+ ;; pes-extension
+
+ (stuffing-bytes t :type list)
)
(defstruct (payload-unknown (:include payload))
(data t :type (array (unsigned-byte 8))))
(defstruct (payload-null (:include payload)))
+
+(defstruct (payload-data (:include payload))
+ (data t :type (array (unsigned-byte 8))))
+
+(defmethod print-object ((o payload-data) stream)
+ (print-unreadable-object (o stream :type t)
+ (format stream "~s ~a" :length (length (payload-data-data o)))))
-(defun get-packet-type (header &optional pmt-pids)
+(defun get-packet-type (header &optional pmt-pids pes-pids)
+ (if (= 0 (ts-header-payload-unit-start-indicator header))
+ :data
(case (ts-header-pid header)
(#x0000 :psi-pat) ; Program-specific information: program association table
(#x1FFF :null) ; Null packets
(otherwise
(cond ((member (ts-header-pid header) pmt-pids) :psi-pmt)
- (t :unknown)))))
+ ((member (ts-header-pid header) pes-pids) :pes)
+ (t :unknown))))))
(eval-when (:compile-toplevel :load-toplevel :execute)
(defparameter *adaptation-field-document* (format nil "~
View
@@ -114,8 +114,76 @@
)
(loop FOR i FROM count BELOW rest-count DO (read-byte stream))))))
+(defun parse-pes (stream rest-count)
+ (let ((header-start 0)
+ (header-length 0)
+ (count 0)
+ (byte 0)
+ (f1 0)
+ (f2 0)
+ (f3 0)
+ (f4 0)
+ (f5 0)
+ (f6 0)
+ (f7 0))
+ (labels ((next-byte () (incf count) (setf byte (read-byte stream)))
+ (read-dts/pts (dts?)
+ (declare (ignore dts?))
+ (let ((check-bits (ldb (byte 4 4) (next-byte)))
+ (data32-30 (ldb (byte 3 1) byte))
+ (marker1 (ldb (byte 1 0) byte))
+ (data29-15 (+ (ash (next-byte) 7)
+ (ldb (byte 7 1) (next-byte))))
+ (marker2 (ldb (byte 1 0) byte))
+ (data14-0 (+ (ash (next-byte) 7)
+ (ldb (byte 7 1) (next-byte))))
+ (marker3 (ldb (byte 1 0) byte)))
+ (declare (ignore check-bits marker1 marker2 marker3))
+ (+ (ash data32-30 30)
+ (ash data29-15 15)
+ data14-0))))
+
+ (prog1
+ (ts:make-payload-pes
+ :packet-start-prefix-code (+ (ash (next-byte) 16)
+ (ash (next-byte) 8)
+ (next-byte))
+ :stream-id (next-byte)
+ :pes-packet-length (+ (ash (next-byte) 8)
+ (next-byte))
+
+ :marker-bits (ldb (byte 2 6) (next-byte))
+ :scrambling-control (ldb (byte 2 4) byte)
+ :priority (ldb (byte 1 3) byte)
+ :data-alignment-indicator (ldb (byte 1 2) byte)
+ :copyright (ldb (byte 1 1) byte)
+ :original-or-copy (ldb (byte 1 0) byte)
+ :pts-dts-indicator (setf f1 (ldb (byte 2 6) (next-byte)))
+ :escr-flag (setf f2 (ldb (byte 1 5) byte))
+ :es-rate-flag (setf f3 (ldb (byte 1 4) byte))
+ :dsm-trick-mode-flag(setf f4 (ldb (byte 1 3) byte))
+ :additional-copy-into-flag (setf f5 (ldb (byte 1 2) byte))
+ :crc-flag (setf f6 (ldb (byte 1 1) byte))
+ :extension-flag (setf f7 (ldb (byte 1 0) byte))
+ :pes-header-length (prog1 (setf header-length (next-byte))
+ (setf header-start count))
+
+ :pts (when (ldb-test (byte 1 1) f1) (read-dts/pts nil))
+ :dts (when (ldb-test (byte 1 0) f1) (read-dts/pts t))
+ :escr (when (= f2 1) (loop FOR i FROM 5 DOWNTO 0 SUM (ash (next-byte) (* i 8))))
+ :es (when (= f3 1) (loop FOR i FROM 3 DOWNTO 0 SUM (ash (next-byte) (* i 8))))
+ :dsm-trick-mode (when (= f4 1) (next-byte))
+ :additional-copy-info (when (= f5 1) (next-byte))
+ :pes-crc (when (= f6 1) (loop FOR i FROM 2 DOWNTO 0 SUM (ash (next-byte) (* i 8))))
+
+ :stuffing-bytes (loop FOR i FROM (- count header-start) BELOW header-length
+ COLLECT (next-byte))
+ )
+ (loop FOR i FROM count BELOW rest-count DO (read-byte stream))))))
+
(defun parse-payload (header stream context rest-count)
- (ecase (ts:get-packet-type header (context-pmt-pids context))
+ (ecase (ts:get-packet-type header (context-pmt-pids context)
+ (context-pes-pids context))
(:psi-pat (let ((pat (parse-psi-pat header stream rest-count)))
(loop FOR (_ __ program-pid) IN (ts::payload-pat-pmt-map pat)
DO
@@ -126,9 +194,14 @@
DO
(pushnew pes-pid (context-pes-pids context)))
pmt))
+ (:pes (let ((pes (parse-pes stream rest-count)))
+ pes))
(:null
(dotimes (i rest-count) (read-byte stream))
(ts:make-payload-null))
+ (:data
+ (ts:make-payload-data :data (coerce (loop REPEAT rest-count COLLECT (read-byte stream))
+ '(simple-array (unsigned-byte 8) (*)))))
(:unknown
(dotimes (i rest-count)
(read-byte stream))
@@ -143,7 +216,7 @@
(f3 0)
(f4 0)
(f5 0))
- (flet ((next-byte () (incf count) (setf byte (read-byte stream))))
+ (labels ((next-byte () (incf count) (setf byte (read-byte stream))))
(values
(ts:make-adaptation-field
:length (setf length (next-byte))
@@ -155,8 +228,8 @@
:splicing-point-flag (setf f3 (ldb (byte 1 2) byte))
:transport-private-data-flag (setf f4 (ldb (byte 1 1) byte))
:adaptation-field-extension-flag (setf f5 (ldb (byte 1 0) byte))
- :pcr (when (plusp f1) (loop FOR i FROM 5 DOWNTO 0 SUM (ash (next-byte) (* i 8))))
- :opcr (when (plusp f2) (loop FOR i FROM 5 DOWNTO 0 SUM (ash (next-byte) (* i 8))))
+ :pcr (when (plusp f1) (ash (loop FOR i FROM 5 DOWNTO 0 SUM (ash (next-byte) (* i 8))) -15))
+ :opcr (when (plusp f2) (ash (loop FOR i FROM 5 DOWNTO 0 SUM (ash (next-byte) (* i 8))) -15))
:splice-countdown (when (plusp f3) (next-byte))
:stuffing-bytes (list (when (plusp f4)
(loop REPEAT (next-byte) COLLECT (next-byte)))

0 comments on commit 50c5429

Please sign in to comment.