blob: 4208fc0e2311cf58ce692fe83bd4454712331b52 [file] [log] [blame]
Benny Prijonoc45d9512010-12-10 11:04:30 +00001/* $Id$ */
2/*
3 * Copyright (C) 2008-2009 Teluu Inc. (http://www.teluu.com)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19#ifndef __PJMEDIA_H263_PACKETIZER_H__
20#define __PJMEDIA_H263_PACKETIZER_H__
21
22
23/**
24 * @file h263_packetizer.h
25 * @brief Packetizes H.263 bitstream into RTP payload.
26 */
27
28#include <pj/errno.h>
29
30PJ_BEGIN_DECL
31
32/**
33 * Find synchronization point (PSC, slice, GSBC, EOS, EOSBS) in H.263
34 * bitstream, in reversed manner.
35 */
36PJ_INLINE(pj_uint8_t*) pjmedia_h263_find_sync_point_rev(pj_uint8_t *data,
37 pj_size_t data_len)
38{
39 pj_uint8_t *p = data+data_len-1;
40
41 while (p > data && *p && *(p+1))
42 --p;
43
44 if (p == data)
45 return (data + data_len);
46
47 return p;
48}
49
50/**
51 * Generate an RTP payload from H.263 frame bitstream, in-place processing.
52 */
53PJ_INLINE(pj_status_t) pjmedia_h263_packetize(pj_uint8_t *buf,
54 pj_size_t buf_len,
55 unsigned *pos,
56 int max_payload_len,
57 const pj_uint8_t **payload,
58 pj_size_t *payload_len)
59{
60 pj_uint8_t *p, *p_end;
61
62 p = buf + *pos;
63 p_end = buf + buf_len;
64
65 /* Put two octets payload header */
66 if ((p_end-p > 2) && *p==0 && *(p+1)==0) {
67 /* The bitstream starts with synchronization point, just override
68 * the two zero octets (sync point mark) for payload header.
69 */
70 *p = 0x04;
71 } else {
72 /* Not started in synchronization point, we will use two octets
73 * preceeding the bitstream for payload header!
74 */
75 pj_assert(*pos>=2);
76 p -= 2;
77 *p = 0;
78 }
79 *(p+1) = 0;
80
81 /* When bitstream truncation needed because of payload length/MTU
82 * limitation, try to use sync point for the payload boundary.
83 */
84 if (p_end-p > max_payload_len) {
85 p_end = pjmedia_h263_find_sync_point_rev(p+2, max_payload_len-2);
86 }
87
88 *payload = p;
89 *payload_len = p_end-p;
90 *pos = p_end - buf;
91
92 return PJ_SUCCESS;
93}
94
95/**
96 * Append RTP payload to a H.263 picture bitstream.
97 */
98PJ_INLINE(pj_status_t) pjmedia_h263_unpacketize(const pj_uint8_t *payload,
99 pj_size_t payload_len,
100 pj_uint8_t *bits,
101 pj_size_t *bits_len)
102{
103 pj_uint8_t P, V, PLEN;
104 const pj_uint8_t *p=payload;
105 pj_size_t max_len = *bits_len;
106
107 P = *p & 0x04;
108 V = *p & 0x02;
109 PLEN = ((*p & 0x01) << 5) + ((*(p+1) & 0xF8)>>3);
110
111 /* Get bitstream pointer */
112 p += 2;
113 if (V)
114 p += 1; /* Skip VRC data */
115 if (PLEN)
116 p += PLEN; /* Skip extra picture header data */
117
118 /* Get bitstream length */
119 payload_len -= (p-payload);
120
121 *bits_len = payload_len + (P?2:0);
122 PJ_ASSERT_RETURN(max_len >= *bits_len, PJ_ETOOSMALL);
123
124 /* Add two zero octets when payload flagged with sync point */
125 if (P) {
126 *bits++ = 0;
127 *bits++ = 0;
128 }
129
130 /* Add the bitstream */
131 pj_memcpy(bits, p, payload_len);
132
133 return PJ_SUCCESS;
134}
135
136
137PJ_END_DECL
138
139
140#endif /* __PJMEDIA_H263_PACKETIZER_H__ */