Skip to content

Commit

Permalink
added PES packet
Browse files Browse the repository at this point in the history
  • Loading branch information
sile committed Sep 30, 2012
1 parent c0fe49c commit 50c5429
Show file tree
Hide file tree
Showing 3 changed files with 175 additions and 6 deletions.
2 changes: 2 additions & 0 deletions package.lisp
Expand Up @@ -34,6 +34,8 @@
payload-unknown-data
make-payload-null
payload-null
payload-data
make-payload-data

;;; pat
payload-pat
Expand Down
98 changes: 96 additions & 2 deletions packet.lisp
Expand Up @@ -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)
Expand Down Expand Up @@ -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 "~
Expand Down
81 changes: 77 additions & 4 deletions parser/parser.lisp
Expand Up @@ -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
Expand All @@ -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))
Expand All @@ -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))
Expand All @@ -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)))
Expand Down

0 comments on commit 50c5429

Please sign in to comment.