Commit 968b0ea0 authored by Christophe Massiot's avatar Christophe Massiot

* Initial import.

parents
# Contributors to biTStream
# $Id$
#
# The format of this file was inspired by the Linux kernel CREDITS file.
# Authors are listed alphabetically.
#
# The fields are: name (N), email (E), web-address (W), CVS account login (C),
# PGP key ID and fingerprint (P), description (D), and snail-mail address (S).
N: Christophe Massiot
E: massiot AT via DOT ecp DOT fr
C: massiot
D: All of the code
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
Version 2, December 2004
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
Everyone is permitted to copy and distribute verbatim or modified
copies of this license document, and changing it is allowed as long
as the name is changed.
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. You just DO WHAT THE FUCK YOU WANT TO.
$Id$
Installing biTStream
====================
No Makefile yet... Just create a /usr/include/bitstream or
/usr/local/include/bitstream directory, and copy all top-level directories
there.
$Id$
1.0 (?? Aug 2010)
=================
- Initial public release
$Id$
Welcome to biTStream!
=====================
biTStream is a set of C headers allowing a simpler access to binary
structures such as specified by MPEG, DVB, IETF, etc.
biTStream vs. libdvbpsi
=======================
libdvbpsi converts binary structures to C structures. Lists are implemented
with chained lists of C structures.
biTStream is lower level, and more efficient: fewer memory allocations,
fewer memory copies. It also features a better separation between layers
and specifications.
Extending biTStream
===================
A lot of MPEG and DVB tables and descriptors are not implemented yet, or
are incomplete. Patches are very welcome.
Though biTStream is originally targeted at video applications in general
and MPEG-2 transport stream in particular, the same principle can be
followed with other binary data types, and patches are welcome here too.
Just try to follow a coherent directory naming.
My coding style is Linux kernel + Hungarian conventions. Really, I do not
care about the coding style of new files; do (WTF) you want. However, for
existing files, please try to follow the original conventions.
biTStream is released under the WTF public license because since it is a
direct application of standards, there is no added value. The WTF license
doesn't require you to contribute back your changes, and you can use
biTStream in proprietary applications. However, if you add new structures,
or fix bugs in current structures, you'd be very nice to contribute them
(again, there is no point in concealing this). Thanks.
/*****************************************************************************
* ci.h: ETSI EN 50 221 Common Interface Specification
*****************************************************************************
* Copyright (C) 2010 VideoLAN
* $Id$
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*****************************************************************************/
/*
* Normative references:
* - ETSI EN 50 221 (1997) (Common Interface Specification)
*/
#ifndef __BITSTREAM_DVB_CI_H__
#define __BITSTREAM_DVB_CI_H__
#include <bitstream/mpeg/psi.h>
#ifdef __cplusplus
extern "C"
{
#endif
/*****************************************************************************
* Conditional Access Program Map Table
*****************************************************************************
* Implementation note: the first field here is ca_pmt_list_management,
* since the previous length field is variable size and is generally put
* afterwards.
*****************************************************************************/
#define CAPMT_HEADER_SIZE 6
#define CAPMT_ES_SIZE 5
#define CAPMTI_HEADER_SIZE 3
/* Max theoritical size is PSI_MAX_SIZE + ~100 */
#define CAPMT_DECLARE PSI_PRIVATE_DECLARE
#define capmt_allocate psi_private_allocate
static inline void capmt_init(uint8_t *p_capmt)
{
p_capmt[3] = 0xc1;
p_capmt[4] = 0xf0;
}
static inline void capmt_set_listmanagement(uint8_t *p_capmt, uint8_t i_mgt)
{
p_capmt[0] = i_mgt;
}
static inline void capmt_set_program(uint8_t *p_capmt, uint16_t i_program)
{
p_capmt[1] = i_program >> 8;
p_capmt[2] = i_program & 0xff;
}
static inline void capmt_set_version(uint8_t *p_capmt, uint8_t i_version)
{
p_capmt[3] &= ~0x3e;
p_capmt[3] |= i_version << 1;
}
static inline uint8_t *capmt_get_infos(uint8_t *p_capmt)
{
return &p_capmt[4];
}
static inline uint16_t capmt_get_infoslength(const uint8_t *p_capmt)
{
return ((p_capmt[4] & 0xf) << 8) | p_capmt[5];
}
static inline void capmtn_init(uint8_t *p_capmt_n)
{
p_capmt_n[1] = 0xe0;
}
static inline void capmtn_set_streamtype(uint8_t *p_capmt_n,
uint8_t i_stream_type)
{
p_capmt_n[0] = i_stream_type;
}
static inline void capmtn_set_pid(uint8_t *p_capmt_n, uint16_t i_pid)
{
p_capmt_n[1] &= ~0x1f;
p_capmt_n[1] |= i_pid >> 8;
p_capmt_n[2] = i_pid & 0xff;
}
static inline uint16_t capmtn_get_infoslength(const uint8_t *p_capmt_n)
{
return ((p_capmt_n[3] & 0xf) << 8) | p_capmt_n[4];
}
static inline uint8_t *capmtn_get_infos(uint8_t *p_capmt_n)
{
return &p_capmt_n[3];
}
static inline uint8_t *capmt_get_es(uint8_t *p_capmt, uint8_t n)
{
uint8_t *p_capmt_n = p_capmt + CAPMT_HEADER_SIZE
+ capmt_get_infoslength(p_capmt);
while (n) {
p_capmt_n += CAPMT_ES_SIZE + capmtn_get_infoslength(p_capmt_n);
n--;
}
return p_capmt_n;
}
static inline void capmti_init(uint8_t *p_infos)
{
p_infos[0] = 0xf0;
}
static inline void capmti_set_length(uint8_t *p_infos, uint16_t i_length)
{
p_infos[0] &= ~0xf;
p_infos[0] |= i_length >> 8;
p_infos[1] = i_length & 0xff;
}
static inline uint16_t capmti_get_length(const uint8_t *p_infos)
{
return ((p_infos[0] & 0xf) << 8) | p_infos[1];
}
static inline void capmti_set_cmd(uint8_t *p_infos, uint8_t i_cmd)
{
p_infos[2] = i_cmd;
}
static inline uint8_t *capmti_get_info(uint8_t *p_infos, uint16_t n)
{
uint8_t *p_info = p_infos + CAPMTI_HEADER_SIZE;
uint16_t i_infos_size = capmti_get_length(p_infos) + DESCS_HEADER_SIZE;
while (n) {
if (p_info + DESC_HEADER_SIZE - p_infos > i_infos_size) return NULL;
p_info += DESC_HEADER_SIZE + desc_get_length(p_info);
n--;
}
if (p_info - p_infos >= i_infos_size) return NULL;
return p_info;
}
#ifdef __cplusplus
}
#endif
#endif
This diff is collapsed.
/*****************************************************************************
* rtp.h: Real-Time Protocol
*****************************************************************************
* Copyright (C) 2009 VideoLAN
* $Id$
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*****************************************************************************/
/*
* Normative references:
* - IETF RFC 3550 Real-Time Protocol (July 2003)
*/
#ifndef __BITSTREAM_IETF_RTP_H__
#define __BITSTREAM_IETF_RTP_H__
#ifdef __cplusplus
extern "C"
{
#endif
#define RTP_HEADER_SIZE 12
#define RTP_TYPE_TS 33
/*
* Reminder : RTP header
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|V=2|P|X| CC |M| PT | sequence number |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| timestamp |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| synchronization source (SSRC) identifier |
+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
| contributing source (CSRC) identifiers |
| .... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
*/
static inline void rtp_set_hdr(uint8_t *p_rtp)
{
p_rtp[0] = 0x80;
}
static inline bool rtp_check_hdr(const uint8_t *p_rtp)
{
return (p_rtp[0] & 0xc0) == 0x80;
}
static inline void rtp_set_type(uint8_t *p_rtp, uint8_t i_type)
{
p_rtp[1] = i_type;
}
static inline uint8_t rtp_get_type(const uint8_t *p_rtp)
{
return p_rtp[1] & 0x7f;
}
static inline void rtp_set_cc(uint8_t *p_rtp, uint16_t i_rtp_cc)
{
p_rtp[2] = i_rtp_cc >> 8;
p_rtp[3] = i_rtp_cc & 0xff;
}
static inline uint16_t rtp_get_cc(uint8_t *p_rtp)
{
return (p_rtp[2] << 8) | p_rtp[3];
}
static inline void rtp_set_timestamp(uint8_t *p_rtp, uint32_t i_timestamp)
{
p_rtp[4] = (i_timestamp >> 24) & 0xff;
p_rtp[5] = (i_timestamp >> 16) & 0xff;
p_rtp[6] = (i_timestamp >> 8) & 0xff;
p_rtp[7] = i_timestamp & 0xff;
}
static inline uint32_t rtp_get_timestamp(uint8_t *p_rtp)
{
return (p_rtp[4] << 24) | (p_rtp[5] << 16) | (p_rtp[6] << 8) | p_rtp[7];
}
static inline void rtp_set_ssrc(uint8_t *p_rtp, const uint8_t pi_ssrc[4])
{
p_rtp[8] = pi_ssrc[0];
p_rtp[9] = pi_ssrc[1];
p_rtp[10] = pi_ssrc[2];
p_rtp[11] = pi_ssrc[3];
}
static inline void rtp_get_ssrc(uint8_t *p_rtp, uint8_t pi_ssrc[4])
{
pi_ssrc[0] = p_rtp[8];
pi_ssrc[1] = p_rtp[9];
pi_ssrc[2] = p_rtp[10];
pi_ssrc[3] = p_rtp[11];
}
static inline uint8_t *rtp_payload(uint8_t *p_rtp)
{
unsigned int i_size = RTP_HEADER_SIZE;
i_size += 4 * (p_rtp[0] & 0xf);
if (p_rtp[0] & 0x10) /* header extension */
i_size += 4 + (p_rtp[i_size + 2] << 8) + p_rtp[i_size + 3];
return p_rtp + i_size;
}
#ifdef __cplusplus
}
#endif
#endif
/*****************************************************************************
* aac.h: ISO/IEC 14496-3 Advanced Audio Coding
*****************************************************************************
* Copyright (C) 2010 VideoLAN
* $Id$
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*****************************************************************************/
/*
* Normative references:
* - ISO/IEC 14496-3 Subpart 4:1998(E)
* (Advanced Audio Coding, Time/Frequency Coding)
*/
#ifndef __BITSTREAM_MPEG_AAC_H__
#define __BITSTREAM_MPEG_AAC_H__
#ifdef __cplusplus
extern "C"
{
#endif
/*****************************************************************************
* ADTS header
*****************************************************************************/
#define ADTS_HEADER_SIZE 7
/* fixed header */
static inline void adts_set_sync(uint8_t *p_adts)
{
p_adts[0] = 0xff;
p_adts[1] = 0xf9; /* protection absent */
p_adts[2] = 0x0;
p_adts[3] = 0x0;
p_adts[4] = 0x0;
p_adts[5] = 0x0;
p_adts[6] = 0x0;
}
static inline void adts_set_profile(uint8_t *p_adts, uint8_t i_profile)
{
p_adts[2] &= ~0xc0;
p_adts[2] |= i_profile << 6;
}
static inline void adts_set_index(uint8_t *p_adts, uint8_t i_index)
{
p_adts[2] &= ~0x3c;
p_adts[2] |= (i_index & 0xf) << 2;
}
static inline void adts_set_channels(uint8_t *p_adts, uint8_t i_channels)
{
p_adts[2] &= ~0x03; /* also clear out the private bit */
p_adts[2] |= (i_channels & 0x7) >> 2;
p_adts[3] &= ~0xc0;
p_adts[3] |= (i_channels & 0x7) << 6;
}
static inline void adts_set_copy(uint8_t *p_adts, bool b_copy)
{
if (!b_copy)
p_adts[3] &= ~0x20;
else
p_adts[3] |= 0x20;
}
static inline void adts_set_home(uint8_t *p_adts, bool b_home)
{
if (!b_home)
p_adts[3] &= ~0x10;
else
p_adts[3] |= 0x10;
}
/* variable header */
static inline void adts_set_cp_id(uint8_t *p_adts, bool b_bit, bool b_start)
{
p_adts[3] &= ~0x0c;
if (b_bit)
p_adts[3] |= 0x08;
if (b_start)
p_adts[3] |= 0x04;
}
static inline void adts_set_length(uint8_t *p_adts, uint16_t i_length)
{
p_adts[3] &= ~0x03;
p_adts[3] |= (i_length >> 11) & 0x03;
p_adts[4] = i_length >> 3;
p_adts[5] &= ~0xe0;
p_adts[5] |= (i_length << 5) & 0xe0;
}
static inline void adts_set_fullness(uint8_t *p_adts, uint16_t i_fullness)
{
p_adts[5] &= ~0x1f;
p_adts[5] |= (i_fullness >> 6) & 0x1f;
p_adts[6] &= ~0xfc;
p_adts[6] |= (i_fullness << 2) & 0xfc;
}
/* i_blocks == number of blocks - 1 */
static inline void adts_set_num_blocks(uint8_t *p_adts, uint8_t i_blocks)
{
p_adts[6] &= ~0x03;
p_adts[6] |= i_blocks & 0x03;
}
#ifdef __cplusplus
}
#endif
#endif
/*****************************************************************************
* pes.h: ISO/IEC 13818-1 Packetized Elementary Stream
*****************************************************************************
* Copyright (C) 2010 VideoLAN
* $Id$
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*****************************************************************************/
/*
* Normative references:
* - ISO/IEC 13818-1:2007(E) (MPEG-2 systems)
*/
#ifndef __BITSTREAM_MPEG_PES_H__
#define __BITSTREAM_MPEG_PES_H__
#ifdef __cplusplus
extern "C"
{
#endif
/*****************************************************************************
* PES header
*****************************************************************************/
#define PES_HEADER_SIZE 6
#define PES_HEADER_SIZE_NOPTS 9
#define PES_HEADER_SIZE_PTS 14
#define PES_HEADER_SIZE_PTSDTS 19
#define PES_STREAM_ID_MIN 0xbc
#define PES_STREAM_ID_PRIVATE_1 0xbd
#define PES_STREAM_ID_PRIVATE_2 0xbf
#define PES_STREAM_ID_AUDIO_MPEG 0xc0
#define PES_STREAM_ID_VIDEO_MPEG 0xe0
static inline void pes_init(uint8_t *p_pes)
{
p_pes[0] = 0x0;
p_pes[1] = 0x0;
p_pes[2] = 0x1;
p_pes[6] = 0x80;
p_pes[7] = 0x0;
p_pes[8] = 0x0;
}
static inline void pes_set_streamid(uint8_t *p_pes, uint8_t i_stream_id)
{
p_pes[3] = i_stream_id;
}
static inline void pes_set_length(uint8_t *p_pes, uint16_t i_length)
{
p_pes[4] = i_length >> 8;
p_pes[5] = i_length & 0xff;
}
static inline void pes_set_headerlength(uint8_t *p_pes, uint8_t i_length)
{
p_pes[6] = 0x80;
p_pes[7] = 0x0;
p_pes[8] = i_length;
if ( i_length > 0 )
memset( &p_pes[9], 0xff, i_length ); /* stuffing */
}
static inline uint8_t pes_get_headerlength(const uint8_t *p_pes)
{
return p_pes[8];
}
static inline void pes_set_dataalignment(uint8_t *p_pes)
{
p_pes[6] |= 0x4;
}
static inline void pes_set_pts(uint8_t *p_pes, uint64_t i_pts)
{
p_pes[7] |= 0x80;
if (p_pes[8] < 5)
p_pes[8] = 5;
p_pes[9] = 0x21 | ((i_pts >> 29) & 0xe);
p_pes[10] = (i_pts >> 22) & 0xff;
p_pes[11] = 0x1 | ((i_pts >> 14) & 0xfe);
p_pes[12] = (i_pts >> 7) & 0xff;
p_pes[13] = 0x1 | ((i_pts << 1) & 0xfe);
}
static inline void pes_set_dts(uint8_t *p_pes, uint64_t i_dts)
{
p_pes[7] |= 0x40;
if (p_pes[8] < 10)
p_pes[8] = 10;
p_pes[14] = 0x11 | ((i_dts >> 29) & 0xe);
p_pes[15] = (i_dts >> 22) & 0xff;
p_pes[16] = 0x1 | ((i_dts >> 14) & 0xfe);
p_pes[17] = (i_dts >> 7) & 0xff;
p_pes[18] = 0x1 | ((i_dts << 1) & 0xfe);
}
static inline bool pes_validate(const uint8_t *p_pes)
{
return (p_pes[0] == 0x0 && p_pes[1] == 0x0 && p_pes[2] == 0x1
&& p_pes[3] >= PES_STREAM_ID_MIN);
}
/*****************************************************************************
* PES payload
*****************************************************************************/
static inline uint8_t *pes_payload(uint8_t *p_pes)
{
return p_pes + PES_HEADER_SIZE + pes_get_headerlength(p_pes);
}
#ifdef __cplusplus
}
#endif
#endif
This diff is collapsed.
/*****************************************************************************
* ts.h: ISO/IEC 13818-1 Transport Stream
*****************************************************************************
* Copyright (C) 2009-2010 VideoLAN
* $Id$
*
* Authors: Christophe Massiot <massiot@via.ecp.fr>
*
* This program is free software. It comes without any warranty, to
* the extent permitted by applicable law. You can redistribute it
* and/or modify it under the terms of the Do What The Fuck You Want
* To Public License, Version 2, as published by Sam Hocevar. See
* http://sam.zoy.org/wtfpl/COPYING for more details.
*****************************************************************************/
/*
* Normative references:
* - ISO/IEC 13818-1:2007(E) (MPEG-2 systems)
*/
#ifndef __BITSTREAM_MPEG_TS_H__
#define __BITSTREAM_MPEG_TS_H__
#ifdef __cplusplus
extern "C"
{
#endif
/*****************************************************************************
* TS header
*****************************************************************************/
#define TS_SIZE 188
#define TS_HEADER_SIZE 4
#define TS_HEADER_SIZE_AF 6
#define TS_HEADER_SIZE_PCR 12
#define TS_DECLARE(p_ts) \
uint8_t p_ts[TS_SIZE]
static inline uint8_t *ts_allocate(void)
{
return malloc(TS_SIZE * sizeof(uint8_t));
}
static inline void ts_init(uint8_t *p_ts)
{
p_ts[0] = 0x47;
p_ts[1] = 0x0;
p_ts[2] = 0x0;
p_ts[3] = 0x0;
}
static inline bool ts_get_transporterror(const uint8_t *p_ts)
{
return p_ts[1] & 0x80;
}
static inline void ts_set_unitstart(uint8_t *p_ts)
{
p_ts[1] |= 0x40;
}
static inline bool ts_get_unitstart(const uint8_t *p_ts)
{
return p_ts[1] & 0x40;
}
static inline void ts_set_transportpriority(uint8_t *p_ts)
{
p_ts[1] |= 0x20;
}
static inline bool ts_get_transportpriority(const uint8_t *p_ts)
{
return p_ts[1] & 0x20;
}
static inline void ts_set_pid(uint8_t *p_ts, uint16_t i_pid)
{
p_ts[1] &= ~0x1f;
p_ts[1] |= (i_pid >> 8) & 0x1f;
p_ts[2] = i_pid & 0xff;
}
static inline uint16_t ts_get_pid(const uint8_t *p_ts)
{
return ((p_ts[1] & 0x1f) << 8) | p_ts[2];
}
static inline void ts_set_cc(uint8_t *p_ts, uint8_t i_cc)
{
p_ts[3] &= ~0xf;
p_ts[3] |= (i_cc & 0xf);
}
static inline uint8_t ts_get_cc(const uint8_t *p_ts)
{
return p_ts[3] & 0xf;
}
static inline void ts_set_payload(uint8_t *p_ts)
{
p_ts[3] |= 0x10;
}
static inline bool ts_has_payload(const uint8_t *p_ts)
{
return p_ts[3] & 0x10;
}
static inline void ts_set_adaptation(uint8_t *p_ts, uint8_t i_length)
{
p_ts[3] |= 0x20;
p_ts[4] = i_length;
if (i_length)
p_ts[5] = 0x0;
if (i_length > 1)
memset(&p_ts[6], 0xff, i_length - 1); /* stuffing */
}
static inline bool ts_has_adaptation(const uint8_t *p_ts)
{
return (p_ts[3] & 0x20);
}
static inline uint8_t ts_get_adaptation(const uint8_t *p_ts)
{
return p_ts[4];
}
static inline void ts_set_scrambling(uint8_t *p_ts, uint8_t i_scrambling)
{
p_ts[3] &= ~0xc0;
p_ts[3] |= i_scrambling << 6;
}
static inline uint8_t ts_get_scrambling(const uint8_t *p_ts)
{
return (p_ts[3] & 0xc0) >> 6;
}
static inline bool ts_validate(const uint8_t *p_ts)
{
return p_ts[0] == 0x47;
}
/*****************************************************************************
* TS payload
*****************************************************************************/
static inline void ts_pad(uint8_t *p_ts)
{
ts_init(p_ts);
ts_set_pid(p_ts, 0x1fff);
ts_set_cc(p_ts, 0);
ts_set_payload(p_ts);
memset(p_ts + 4, 0xff, TS_SIZE - 4);
}
static inline uint8_t *ts_payload(uint8_t *p_ts)
{
if (!ts_has_payload(p_ts))
return p_ts + TS_SIZE;
if (!ts_has_adaptation(p_ts))
return p_ts + TS_HEADER_SIZE;
return p_ts + TS_HEADER_SIZE + 1 + ts_get_adaptation(p_ts);
}
static inline uint8_t *ts_section(uint8_t *p_ts)
{
uint8_t *p_payload;
if (!ts_get_unitstart(p_ts))
return p_ts + TS_SIZE;
p_payload = ts_payload(p_ts);
if (p_payload >= p_ts + TS_SIZE)
return p_ts + TS_SIZE;
return p_payload + *p_payload + 1; /* pointer_field */
}
/*****************************************************************************
* Adaptation field
*****************************************************************************/
static inline void tsaf_set_discontinuity(uint8_t *p_ts)
{
p_ts[5] |= 0x80;
}
static inline void tsaf_set_randomaccess(uint8_t *p_ts)
{
p_ts[5] |= 0x40;
}
static inline bool tsaf_has_randomaccess(const uint8_t *p_ts)
{
return p_ts[5] & 0x40;
}
static inline void tsaf_set_streampriority(uint8_t *p_ts)
{
p_ts[5] |= 0x20;
}
static inline void tsaf_set_pcr(uint8_t *p_ts, uint64_t i_pcr)
{
p_ts[5] |= 0x10;
p_ts[6] = (i_pcr >> 25) & 0xff;
p_ts[7] = (i_pcr >> 17) & 0xff;
p_ts[8] = (i_pcr >> 9) & 0xff;
p_ts[9] = (i_pcr >> 1) & 0xff;
p_ts[10] = 0x7e | ((i_pcr << 7) & 0x80);
p_ts[11] = 0;
}
static inline void tsaf_set_pcrext(uint8_t *p_ts, uint16_t i_pcr_ext)
{
p_ts[10] |= (i_pcr_ext >> 8) & 0x1;
p_ts[11] = i_pcr_ext & 0xff;
}
static inline bool tsaf_has_pcr(uint8_t *p_ts)
{
return p_ts[5] & 0x10;
}
static inline uint64_t tsaf_get_pcr(const uint8_t *p_ts)
{
return (p_ts[6] << 25) | (p_ts[7] << 17) | (p_ts[8] << 9) | (p_ts[9] << 1) |
(p_ts[10] >> 7);
}
static inline uint64_t tsaf_get_pcrext(const uint8_t *p_ts)
{
return ((p_ts[10] & 1) << 8) | p_ts[11];
}
/*****************************************************************************
* TS payload gathering
*****************************************************************************/
static inline bool ts_check_duplicate(uint8_t i_cc, uint8_t i_last_cc)
{
return i_last_cc == i_cc;
}
static inline bool ts_check_discontinuity(uint8_t i_cc, uint8_t i_last_cc)
{
return (i_last_cc + 17 - i_cc) % 16;
}
#ifdef __cplusplus
}
#endif
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment