Re #1219:
- Initial version of H264 implementation (codec & packetization).
- Added vid_codec_util.h/c for video codec utilities (e.g: fmtp parser).
- Updated video RTP packetizations to be configurable and have internal state (to be more resilient to packet lost, etc).
- Fixed wrong SPF calculation in PJMEDIA_SPF2.
- Updated vid_codec_test.c to also have RTP packetization test.
- Updated sdp_neg.c to verify H.264 capability match.
git-svn-id: https://svn.pjsip.org/repos/pjproject/branches/projects/2.0-dev@3493 74dad513-b988-da41-8d7b-12977e46ad98
diff --git a/pjmedia/include/pjmedia-codec/h263_packetizer.h b/pjmedia/include/pjmedia-codec/h263_packetizer.h
index 930115a..b80faf8 100644
--- a/pjmedia/include/pjmedia-codec/h263_packetizer.h
+++ b/pjmedia/include/pjmedia-codec/h263_packetizer.h
@@ -22,121 +22,122 @@
/**
* @file h263_packetizer.h
- * @brief Packetizes H.263 bitstream into RTP payload.
+ * @brief Packetizes/unpacketizes H.263 bitstream into RTP payload.
*/
-#include <pj/errno.h>
+#include <pj/pool.h>
+#include <pj/types.h>
PJ_BEGIN_DECL
-/**
- * Find synchronization point (PSC, slice, GSBC, EOS, EOSBS) in H.263
- * bitstream, in reversed manner.
- */
-PJ_INLINE(pj_uint8_t*) pjmedia_h263_find_sync_point_rev(pj_uint8_t *data,
- pj_size_t data_len)
-{
- pj_uint8_t *p = data+data_len-1;
-
- while (p > data && *p && *(p+1))
- --p;
-
- if (p == data)
- return (data + data_len);
-
- return p;
-}
/**
- * Generate an RTP payload from H.263 frame bitstream, in-place processing.
+ * Opaque declaration for H.263 packetizer.
*/
-PJ_INLINE(pj_status_t) pjmedia_h263_packetize(pj_uint8_t *buf,
- pj_size_t buf_len,
- unsigned *pos,
- int max_payload_len,
- const pj_uint8_t **payload,
- pj_size_t *payload_len)
+typedef struct pjmedia_h263_packetizer pjmedia_h263_packetizer;
+
+
+/**
+ * Enumeration of H.263 packetization modes.
+ */
+typedef enum
{
- pj_uint8_t *p, *p_end;
-
- p = buf + *pos;
- p_end = buf + buf_len;
-
- /* Put two octets payload header */
- if ((p_end-p > 2) && *p==0 && *(p+1)==0) {
- /* The bitstream starts with synchronization point, just override
- * the two zero octets (sync point mark) for payload header.
- */
- *p = 0x04;
- } else {
- /* Not started in synchronization point, we will use two octets
- * preceeding the bitstream for payload header!
- */
-
- if (*pos < 2) {
- /* Invalid H263 bitstream, it's not started with PSC */
- return PJ_EINVAL;
- }
-
- p -= 2;
- *p = 0;
- }
- *(p+1) = 0;
-
- /* When bitstream truncation needed because of payload length/MTU
- * limitation, try to use sync point for the payload boundary.
+ /**
+ * H.263 RTP packetization using RFC 4629.
*/
- if (p_end-p > max_payload_len) {
- p_end = pjmedia_h263_find_sync_point_rev(p+2, max_payload_len-2);
- }
+ PJMEDIA_H263_PACKETIZER_MODE_RFC4629,
- *payload = p;
- *payload_len = p_end-p;
- *pos = p_end - buf;
+ /**
+ * H.263 RTP packetization using legacy RFC 2190.
+ * This is currently not supported.
+ */
+ PJMEDIA_H263_PACKETIZER_MODE_RFC2190,
- return PJ_SUCCESS;
-}
+} pjmedia_h263_packetizer_mode;
+
/**
- * Append RTP payload to a H.263 picture bitstream.
+ * H.263 packetizer configuration.
*/
-PJ_INLINE(pj_status_t) pjmedia_h263_unpacketize(const pj_uint8_t *payload,
- pj_size_t payload_len,
- pj_uint8_t *bits,
- pj_size_t *bits_len)
+typedef struct pjmedia_h263_packetizer_cfg
{
- pj_uint8_t P, V, PLEN;
- const pj_uint8_t *p=payload;
- pj_size_t max_len = *bits_len;
+ /**
+ * Maximum payload length.
+ * Default: PJMEDIA_MAX_MTU
+ */
+ int mtu;
- P = *p & 0x04;
- V = *p & 0x02;
- PLEN = ((*p & 0x01) << 5) + ((*(p+1) & 0xF8)>>3);
+ /**
+ * Packetization mode.
+ * Default: PJMEDIA_H263_PACKETIZER_MODE_RFC4629
+ */
+ pjmedia_h263_packetizer_mode mode;
- /* Get bitstream pointer */
- p += 2;
- if (V)
- p += 1; /* Skip VRC data */
- if (PLEN)
- p += PLEN; /* Skip extra picture header data */
+} pjmedia_h263_packetizer_cfg;
- /* Get bitstream length */
- payload_len -= (p-payload);
- *bits_len = payload_len + (P?2:0);
- PJ_ASSERT_RETURN(max_len >= *bits_len, PJ_ETOOSMALL);
+/**
+ * Create H.263 packetizer.
+ *
+ * @param pool The memory pool.
+ * @param cfg Packetizer settings, if NULL, default setting
+ * will be used.
+ * @param p_pktz Pointer to receive the packetizer.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_h263_packetizer_create(
+ pj_pool_t *pool,
+ const pjmedia_h263_packetizer_cfg *cfg,
+ pjmedia_h263_packetizer **p_pktz);
- /* Add two zero octets when payload flagged with sync point */
- if (P) {
- *bits++ = 0;
- *bits++ = 0;
- }
- /* Add the bitstream */
- pj_memcpy(bits, p, payload_len);
+/**
+ * Generate an RTP payload from a H.263 picture bitstream. Note that this
+ * function will apply in-place processing, so the bitstream may be modified
+ * during the packetization.
+ *
+ * @param pktz The packetizer.
+ * @param bits The picture bitstream to be packetized.
+ * @param bits_len The length of the bitstream.
+ * @param bits_pos The bitstream offset to be packetized.
+ * @param payload The output payload.
+ * @param payload_len The output payload length.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_h263_packetize(pjmedia_h263_packetizer *pktz,
+ pj_uint8_t *bits,
+ pj_size_t bits_len,
+ unsigned *bits_pos,
+ const pj_uint8_t **payload,
+ pj_size_t *payload_len);
- return PJ_SUCCESS;
-}
+
+/**
+ * Append an RTP payload to an H.263 picture bitstream. Note that in case of
+ * noticing packet lost, application should keep calling this function with
+ * payload pointer set to NULL, as the packetizer need to update its internal
+ * state.
+ *
+ * @param pktz The packetizer.
+ * @param payload The payload to be unpacketized.
+ * @param payload_len The payload length.
+ * @param bits The bitstream buffer.
+ * @param bits_size The bitstream buffer size.
+ * @param bits_pos The bitstream offset to put the unpacketized payload
+ * in the bitstream, upon return, this will be updated
+ * to the latest offset as a result of the unpacketized
+ * payload.
+ *
+ * @return PJ_SUCCESS on success.
+ */
+PJ_DECL(pj_status_t) pjmedia_h263_unpacketize(pjmedia_h263_packetizer *pktz,
+ const pj_uint8_t *payload,
+ pj_size_t payload_len,
+ pj_uint8_t *bits,
+ pj_size_t bits_size,
+ unsigned *bits_pos);
PJ_END_DECL