~ubuntu-branches/ubuntu/trusty/sflphone/trusty

« back to all changes in this revision

Viewing changes to daemon/libs/pjproject-2.0.1/pjmedia/src/pjmedia-codec/h264_packetizer.c

  • Committer: Package Import Robot
  • Author(s): Mark Purcell
  • Date: 2014-01-28 18:23:36 UTC
  • mfrom: (4.3.4 sid)
  • Revision ID: package-import@ubuntu.com-20140128182336-jrsv0k9u6cawc068
Tags: 1.3.0-1
* New upstream release 
  - Fixes "New Upstream Release" (Closes: #735846)
  - Fixes "Ringtone does not stop" (Closes: #727164)
  - Fixes "[sflphone-kde] crash on startup" (Closes: #718178)
  - Fixes "sflphone GUI crashes when call is hung up" (Closes: #736583)
* Build-Depends: ensure GnuTLS 2.6
  - libucommon-dev (>= 6.0.7-1.1), libccrtp-dev (>= 2.0.6-3)
  - Fixes "FTBFS Build-Depends libgnutls{26,28}-dev" (Closes: #722040)
* Fix "boost 1.49 is going away" unversioned Build-Depends: (Closes: #736746)
* Add Build-Depends: libsndfile-dev, nepomuk-core-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* $Id: h264_packetizer.c 4006 2012-04-02 08:40:54Z nanang $ */
2
 
/*
3
 
 * Copyright (C) 2011 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
 
#include <pjmedia-codec/h264_packetizer.h>
20
 
#include <pjmedia/types.h>
21
 
#include <pj/assert.h>
22
 
#include <pj/errno.h>
23
 
#include <pj/log.h>
24
 
#include <pj/pool.h>
25
 
#include <pj/string.h>
26
 
 
27
 
 
28
 
#if defined(PJMEDIA_HAS_VIDEO) && (PJMEDIA_HAS_VIDEO != 0)
29
 
 
30
 
 
31
 
#define THIS_FILE               "h264_packetizer.c"
32
 
 
33
 
#define DBG_PACKETIZE           0
34
 
#define DBG_UNPACKETIZE         0
35
 
 
36
 
 
37
 
/* H.264 packetizer definition */
38
 
struct pjmedia_h264_packetizer
39
 
{
40
 
    /* Current settings */
41
 
    pjmedia_h264_packetizer_cfg cfg;
42
 
 
43
 
    /* Unpacketizer state */
44
 
    unsigned        unpack_last_sync_pos;
45
 
    pj_bool_t       unpack_prev_lost;
46
 
};
47
 
 
48
 
 
49
 
/* Enumeration of H.264 NAL unit types */
50
 
enum
51
 
{
52
 
    NAL_TYPE_SINGLE_NAL_MIN     = 1,
53
 
    NAL_TYPE_SINGLE_NAL_MAX     = 23,
54
 
    NAL_TYPE_STAP_A             = 24,
55
 
    NAL_TYPE_FU_A               = 28,
56
 
};
57
 
 
58
 
 
59
 
/*
60
 
 * Find next NAL unit from the specified H.264 bitstream data.
61
 
 */
62
 
static pj_uint8_t* find_next_nal_unit(pj_uint8_t *start,
63
 
                                      pj_uint8_t *end)
64
 
{
65
 
    pj_uint8_t *p = start;
66
 
 
67
 
    /* Simply lookup "0x000001" pattern */
68
 
    while (p <= end-3 && (p[0] || p[1] || p[2]!=1))
69
 
        ++p;
70
 
 
71
 
    if (p > end-3)
72
 
        /* No more NAL unit in this bitstream */
73
 
        return NULL;
74
 
 
75
 
    /* Include 8 bits leading zero */
76
 
    if (p>start && *(p-1)==0)
77
 
        return (p-1);
78
 
 
79
 
    return p;
80
 
}
81
 
 
82
 
 
83
 
/*
84
 
 * Create H264 packetizer.
85
 
 */
86
 
PJ_DEF(pj_status_t) pjmedia_h264_packetizer_create(
87
 
                                pj_pool_t *pool,
88
 
                                const pjmedia_h264_packetizer_cfg *cfg,
89
 
                                pjmedia_h264_packetizer **p)
90
 
{
91
 
    pjmedia_h264_packetizer *p_;
92
 
 
93
 
    PJ_ASSERT_RETURN(pool && p, PJ_EINVAL);
94
 
 
95
 
    if (cfg &&
96
 
        cfg->mode != PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED &&
97
 
        cfg->mode != PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL)
98
 
    {
99
 
        return PJ_ENOTSUP;
100
 
    }
101
 
 
102
 
    p_ = PJ_POOL_ZALLOC_T(pool, pjmedia_h264_packetizer);
103
 
    if (cfg) {
104
 
        pj_memcpy(&p_->cfg, cfg, sizeof(*cfg));
105
 
    } else {
106
 
        p_->cfg.mode = PJMEDIA_H264_PACKETIZER_MODE_NON_INTERLEAVED;
107
 
        p_->cfg.mtu = PJMEDIA_MAX_VID_PAYLOAD_SIZE;
108
 
    }
109
 
 
110
 
    *p = p_;
111
 
 
112
 
    return PJ_SUCCESS;
113
 
}
114
 
 
115
 
 
116
 
 
117
 
/*
118
 
 * Generate an RTP payload from H.264 frame bitstream, in-place processing.
119
 
 */
120
 
PJ_DEF(pj_status_t) pjmedia_h264_packetize(pjmedia_h264_packetizer *pktz,
121
 
                                           pj_uint8_t *buf,
122
 
                                           pj_size_t buf_len,
123
 
                                           unsigned *pos,
124
 
                                           const pj_uint8_t **payload,
125
 
                                           pj_size_t *payload_len)
126
 
{
127
 
    pj_uint8_t *nal_start = NULL, *nal_end = NULL, *nal_octet = NULL;
128
 
    pj_uint8_t *p, *end;
129
 
    enum {
130
 
        HEADER_SIZE_FU_A             = 2,
131
 
        HEADER_SIZE_STAP_A           = 3,
132
 
    };
133
 
    enum { MAX_NALS_IN_AGGR = 32 };
134
 
 
135
 
#if DBG_PACKETIZE
136
 
    if (*pos == 0 && buf_len) {
137
 
        PJ_LOG(3, ("h264pack", "<< Start packing new frame >>"));
138
 
    }
139
 
#endif
140
 
 
141
 
    p = buf + *pos;
142
 
    end = buf + buf_len;
143
 
 
144
 
    /* Find NAL unit startcode */
145
 
    if (end-p >= 4)
146
 
        nal_start = find_next_nal_unit(p, p+4);
147
 
    if (nal_start) {
148
 
        /* Get NAL unit octet pointer */
149
 
        while (*nal_start++ == 0);
150
 
        nal_octet = nal_start;
151
 
    } else {
152
 
        /* This NAL unit is being fragmented */
153
 
        nal_start = p;
154
 
    }
155
 
 
156
 
    /* Get end of NAL unit */
157
 
    p = nal_start+pktz->cfg.mtu+1;
158
 
    if (p > end || pktz->cfg.mode==PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL)
159
 
        p = end;
160
 
    nal_end = find_next_nal_unit(nal_start, p);
161
 
    if (!nal_end)
162
 
        nal_end = p;
163
 
 
164
 
    /* Validate MTU vs NAL length on single NAL unit packetization */
165
 
    if ((pktz->cfg.mode==PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL) &&
166
 
        nal_end - nal_start > pktz->cfg.mtu)
167
 
    {
168
 
        //pj_assert(!"MTU too small for H.264 single NAL packetization mode");
169
 
        PJ_LOG(2,("h264_packetizer.c",
170
 
                  "MTU too small for H.264 (required=%u, MTU=%u)",
171
 
                  nal_end - nal_start, pktz->cfg.mtu));
172
 
        return PJ_ETOOSMALL;
173
 
    }
174
 
 
175
 
    /* Evaluate the proper payload format structure */
176
 
 
177
 
    /* Fragmentation (FU-A) packet */
178
 
    if ((pktz->cfg.mode != PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL) &&
179
 
        (!nal_octet || nal_end-nal_start > pktz->cfg.mtu))
180
 
    {
181
 
        pj_uint8_t NRI, TYPE;
182
 
 
183
 
        if (nal_octet) {
184
 
            /* We have NAL unit octet, so this is the first fragment */
185
 
            NRI = (*nal_octet & 0x60) >> 5;
186
 
            TYPE = *nal_octet & 0x1F;
187
 
 
188
 
            /* Skip nal_octet in nal_start to be overriden by FU header */
189
 
            ++nal_start;
190
 
        } else {
191
 
            /* Not the first fragment, get NRI and NAL unit type
192
 
             * from the previous fragment.
193
 
             */
194
 
            p = nal_start - pktz->cfg.mtu;
195
 
            NRI = (*p & 0x60) >> 5;
196
 
            TYPE = *(p+1) & 0x1F;
197
 
        }
198
 
 
199
 
        /* Init FU indicator (one octet: F+NRI+TYPE) */
200
 
        p = nal_start - HEADER_SIZE_FU_A;
201
 
        *p = (NRI << 5) | NAL_TYPE_FU_A;
202
 
        ++p;
203
 
 
204
 
        /* Init FU header (one octed: S+E+R+TYPE) */
205
 
        *p = TYPE;
206
 
        if (nal_octet)
207
 
            *p |= (1 << 7); /* S bit flag = start of fragmentation */
208
 
        if (nal_end-nal_start+HEADER_SIZE_FU_A <= pktz->cfg.mtu)
209
 
            *p |= (1 << 6); /* E bit flag = end of fragmentation */
210
 
 
211
 
        /* Set payload, payload length */
212
 
        *payload = nal_start - HEADER_SIZE_FU_A;
213
 
        if (nal_end-nal_start+HEADER_SIZE_FU_A > pktz->cfg.mtu)
214
 
            *payload_len = pktz->cfg.mtu;
215
 
        else
216
 
            *payload_len = nal_end - nal_start + HEADER_SIZE_FU_A;
217
 
        *pos = *payload + *payload_len - buf;
218
 
 
219
 
#if DBG_PACKETIZE
220
 
        PJ_LOG(3, ("h264pack", "Packetized fragmented H264 NAL unit "
221
 
                   "(pos=%d, type=%d, NRI=%d, S=%d, E=%d, len=%d/%d)",
222
 
                   *payload-buf, TYPE, NRI, *p>>7, (*p>>6)&1, *payload_len,
223
 
                   buf_len));
224
 
#endif
225
 
 
226
 
        return PJ_SUCCESS;
227
 
    }
228
 
 
229
 
    /* Aggregation (STAP-A) packet */
230
 
    if ((pktz->cfg.mode != PJMEDIA_H264_PACKETIZER_MODE_SINGLE_NAL) &&
231
 
        (nal_end != end) &&
232
 
        (nal_end - nal_start + HEADER_SIZE_STAP_A) < pktz->cfg.mtu)
233
 
    {
234
 
        int total_size;
235
 
        unsigned nal_cnt = 1;
236
 
        pj_uint8_t *nal[MAX_NALS_IN_AGGR];
237
 
        pj_size_t nal_size[MAX_NALS_IN_AGGR];
238
 
        pj_uint8_t NRI;
239
 
 
240
 
        pj_assert(nal_octet);
241
 
 
242
 
        /* Init the first NAL unit in the packet */
243
 
        nal[0] = nal_start;
244
 
        nal_size[0] = nal_end - nal_start;
245
 
        total_size = nal_size[0] + HEADER_SIZE_STAP_A;
246
 
        NRI = (*nal_octet & 0x60) >> 5;
247
 
 
248
 
        /* Populate next NAL units */
249
 
        while (nal_cnt < MAX_NALS_IN_AGGR) {
250
 
            pj_uint8_t *tmp_end;
251
 
 
252
 
            /* Find start address of the next NAL unit */
253
 
            p = nal[nal_cnt-1] + nal_size[nal_cnt-1];
254
 
            while (*p++ == 0);
255
 
            nal[nal_cnt] = p;
256
 
 
257
 
            /* Find end address of the next NAL unit */
258
 
            tmp_end = p + (pktz->cfg.mtu - total_size);
259
 
            if (tmp_end > end)
260
 
                tmp_end = end;
261
 
            p = find_next_nal_unit(p+1, tmp_end);
262
 
            if (p) {
263
 
                nal_size[nal_cnt] = p - nal[nal_cnt];
264
 
            } else {
265
 
                break;
266
 
            }
267
 
 
268
 
            /* Update total payload size (2 octet NAL size + NAL) */
269
 
            total_size += (2 + nal_size[nal_cnt]);
270
 
            if (total_size <= pktz->cfg.mtu) {
271
 
                pj_uint8_t tmp_nri;
272
 
 
273
 
                /* Get maximum NRI of the aggregated NAL units */
274
 
                tmp_nri = (*(nal[nal_cnt]-1) & 0x60) >> 5;
275
 
                if (tmp_nri > NRI)
276
 
                    NRI = tmp_nri;
277
 
            } else {
278
 
                break;
279
 
            }
280
 
 
281
 
            ++nal_cnt;
282
 
        }
283
 
 
284
 
        /* Only use STAP-A when we found more than one NAL units */
285
 
        if (nal_cnt > 1) {
286
 
            unsigned i;
287
 
 
288
 
            /* Init STAP-A NAL header (F+NRI+TYPE) */
289
 
            p = nal[0] - HEADER_SIZE_STAP_A;
290
 
            *p++ = (NRI << 5) | NAL_TYPE_STAP_A;
291
 
 
292
 
            /* Append all populated NAL units into payload (SIZE+NAL) */
293
 
            for (i = 0; i < nal_cnt; ++i) {
294
 
                /* Put size (2 octets in network order) */
295
 
                pj_assert(nal_size[i] <= 0xFFFF);
296
 
                *p++ = (pj_uint8_t)(nal_size[i] >> 8);
297
 
                *p++ = (pj_uint8_t)(nal_size[i] & 0xFF);
298
 
 
299
 
                /* Append NAL unit, watchout memmove()-ing bitstream! */
300
 
                if (p != nal[i])
301
 
                    pj_memmove(p, nal[i], nal_size[i]);
302
 
                p += nal_size[i];
303
 
            }
304
 
 
305
 
            /* Set payload, payload length, and pos */
306
 
            *payload = nal[0] - HEADER_SIZE_STAP_A;
307
 
            pj_assert(*payload >= buf+*pos);
308
 
            *payload_len = p - *payload;
309
 
            *pos = nal[nal_cnt-1] + nal_size[nal_cnt-1] - buf;
310
 
 
311
 
#if DBG_PACKETIZE
312
 
            PJ_LOG(3, ("h264pack", "Packetized aggregation of "
313
 
                       "%d H264 NAL units (pos=%d, NRI=%d len=%d/%d)",
314
 
                       nal_cnt, *payload-buf, NRI, *payload_len, buf_len));
315
 
#endif
316
 
 
317
 
            return PJ_SUCCESS;
318
 
        }
319
 
    }
320
 
 
321
 
    /* Single NAL unit packet */
322
 
    *payload = nal_start;
323
 
    *payload_len = nal_end - nal_start;
324
 
    *pos = nal_end - buf;
325
 
 
326
 
#if DBG_PACKETIZE
327
 
    PJ_LOG(3, ("h264pack", "Packetized single H264 NAL unit "
328
 
               "(pos=%d, type=%d, NRI=%d, len=%d/%d)",
329
 
               nal_start-buf, *nal_octet&0x1F, (*nal_octet&0x60)>>5,
330
 
               *payload_len, buf_len));
331
 
#endif
332
 
 
333
 
    return PJ_SUCCESS;
334
 
}
335
 
 
336
 
 
337
 
/*
338
 
 * Append RTP payload to a H.264 picture bitstream. Note that the only
339
 
 * payload format that cares about packet lost is the NAL unit
340
 
 * fragmentation format (FU-A/B), so we will only manage the "prev_lost"
341
 
 * state for the FU-A/B packets.
342
 
 */
343
 
PJ_DEF(pj_status_t) pjmedia_h264_unpacketize(pjmedia_h264_packetizer *pktz,
344
 
                                             const pj_uint8_t *payload,
345
 
                                             pj_size_t   payload_len,
346
 
                                             pj_uint8_t *bits,
347
 
                                             pj_size_t   bits_len,
348
 
                                             unsigned   *bits_pos)
349
 
{
350
 
    const pj_uint8_t nal_start_code[3] = {0, 0, 1};
351
 
    enum { MIN_PAYLOAD_SIZE = 2 };
352
 
    pj_uint8_t nal_type;
353
 
 
354
 
    PJ_UNUSED_ARG(pktz);
355
 
 
356
 
#if DBG_UNPACKETIZE
357
 
    if (*bits_pos == 0 && payload_len) {
358
 
        PJ_LOG(3, ("h264unpack", ">> Start unpacking new frame <<"));
359
 
    }
360
 
#endif
361
 
 
362
 
    /* Check if this is a missing/lost packet */
363
 
    if (payload == NULL) {
364
 
        pktz->unpack_prev_lost = PJ_TRUE;
365
 
        return PJ_SUCCESS;
366
 
    }
367
 
 
368
 
    /* H264 payload size */
369
 
    if (payload_len < MIN_PAYLOAD_SIZE) {
370
 
        /* Invalid bitstream, discard this payload */
371
 
        pktz->unpack_prev_lost = PJ_TRUE;
372
 
        return PJ_EINVAL;
373
 
    }
374
 
 
375
 
    /* Reset last sync point for every new picture bitstream */
376
 
    if (*bits_pos == 0)
377
 
        pktz->unpack_last_sync_pos = 0;
378
 
 
379
 
    nal_type = *payload & 0x1F;
380
 
    if (nal_type >= NAL_TYPE_SINGLE_NAL_MIN &&
381
 
        nal_type <= NAL_TYPE_SINGLE_NAL_MAX)
382
 
    {
383
 
        /* Single NAL unit packet */
384
 
        pj_uint8_t *p = bits + *bits_pos;
385
 
 
386
 
        /* Validate bitstream length */
387
 
        if (bits_len-*bits_pos < payload_len+PJ_ARRAY_SIZE(nal_start_code)) {
388
 
            /* Insufficient bistream buffer, discard this payload */
389
 
            pj_assert(!"Insufficient H.263 bitstream buffer");
390
 
            return PJ_ETOOSMALL;
391
 
        }
392
 
 
393
 
        /* Write NAL unit start code */
394
 
        pj_memcpy(p, &nal_start_code, PJ_ARRAY_SIZE(nal_start_code));
395
 
        p += PJ_ARRAY_SIZE(nal_start_code);
396
 
 
397
 
        /* Write NAL unit */
398
 
        pj_memcpy(p, payload, payload_len);
399
 
        p += payload_len;
400
 
 
401
 
        /* Update the bitstream writing offset */
402
 
        *bits_pos = p - bits;
403
 
        pktz->unpack_last_sync_pos = *bits_pos;
404
 
 
405
 
#if DBG_UNPACKETIZE
406
 
        PJ_LOG(3, ("h264unpack", "Unpacked single H264 NAL unit "
407
 
                   "(type=%d, NRI=%d, len=%d)",
408
 
                   nal_type, (*payload&0x60)>>5, payload_len));
409
 
#endif
410
 
 
411
 
    }
412
 
    else if (nal_type == NAL_TYPE_STAP_A)
413
 
    {
414
 
        /* Aggregation packet */
415
 
        pj_uint8_t *p, *p_end;
416
 
        const pj_uint8_t *q, *q_end;
417
 
        unsigned cnt = 0;
418
 
 
419
 
        /* Validate bitstream length */
420
 
        if (bits_len - *bits_pos < payload_len + 32) {
421
 
            /* Insufficient bistream buffer, discard this payload */
422
 
            pj_assert(!"Insufficient H.263 bitstream buffer");
423
 
            return PJ_ETOOSMALL;
424
 
        }
425
 
 
426
 
        /* Fill bitstream */
427
 
        p = bits + *bits_pos;
428
 
        p_end = bits + bits_len;
429
 
        q = payload + 1;
430
 
        q_end = payload + payload_len;
431
 
        while (q < q_end && p < p_end) {
432
 
            pj_uint16_t tmp_nal_size;
433
 
 
434
 
            /* Write NAL unit start code */
435
 
            pj_memcpy(p, &nal_start_code, PJ_ARRAY_SIZE(nal_start_code));
436
 
            p += PJ_ARRAY_SIZE(nal_start_code);
437
 
 
438
 
            /* Get NAL unit size */
439
 
            tmp_nal_size = (*q << 8) | *(q+1);
440
 
            q += 2;
441
 
            if (q + tmp_nal_size > q_end) {
442
 
                /* Invalid bitstream, discard the rest of the payload */
443
 
                return PJ_EINVAL;
444
 
            }
445
 
 
446
 
            /* Write NAL unit */
447
 
            pj_memcpy(p, q, tmp_nal_size);
448
 
            p += tmp_nal_size;
449
 
            q += tmp_nal_size;
450
 
            ++cnt;
451
 
 
452
 
            /* Update the bitstream writing offset */
453
 
            *bits_pos = p - bits;
454
 
            pktz->unpack_last_sync_pos = *bits_pos;
455
 
        }
456
 
 
457
 
#if DBG_UNPACKETIZE
458
 
        PJ_LOG(3, ("h264unpack", "Unpacked %d H264 NAL units (len=%d)",
459
 
                   cnt, payload_len));
460
 
#endif
461
 
 
462
 
    }
463
 
    else if (nal_type == NAL_TYPE_FU_A)
464
 
    {
465
 
        /* Fragmentation packet */
466
 
        pj_uint8_t *p;
467
 
        const pj_uint8_t *q = payload;
468
 
        pj_uint8_t NRI, TYPE, S, E;
469
 
 
470
 
        p = bits + *bits_pos;
471
 
 
472
 
        /* Validate bitstream length */
473
 
        if (bits_len-*bits_pos < payload_len+PJ_ARRAY_SIZE(nal_start_code)) {
474
 
            /* Insufficient bistream buffer, drop this packet */
475
 
            pj_assert(!"Insufficient H.263 bitstream buffer");
476
 
            pktz->unpack_prev_lost = PJ_TRUE;
477
 
            return PJ_ETOOSMALL;
478
 
        }
479
 
 
480
 
        /* Get info */
481
 
        S = *(q+1) & 0x80;    /* Start bit flag */
482
 
        E = *(q+1) & 0x40;    /* End bit flag   */
483
 
        TYPE = *(q+1) & 0x1f;
484
 
        NRI = (*q & 0x60) >> 5;
485
 
 
486
 
        /* Fill bitstream */
487
 
        if (S) {
488
 
            /* This is the first part, write NAL unit start code */
489
 
            pj_memcpy(p, &nal_start_code, PJ_ARRAY_SIZE(nal_start_code));
490
 
            p += PJ_ARRAY_SIZE(nal_start_code);
491
 
 
492
 
            /* Write NAL unit octet */
493
 
            *p++ = (NRI << 5) | TYPE;
494
 
        } else if (pktz->unpack_prev_lost) {
495
 
            /* If prev packet was lost, revert the bitstream pointer to
496
 
             * the last sync point.
497
 
             */
498
 
            pj_assert(pktz->unpack_last_sync_pos <= *bits_pos);
499
 
            *bits_pos = pktz->unpack_last_sync_pos;
500
 
            /* And discard this payload (and the following fragmentation
501
 
             * payloads carrying this same NAL unit.
502
 
             */
503
 
            return PJ_EIGNORED;
504
 
        }
505
 
        q += 2;
506
 
 
507
 
        /* Write NAL unit */
508
 
        pj_memcpy(p, q, payload_len - 2);
509
 
        p += (payload_len - 2);
510
 
 
511
 
        /* Update the bitstream writing offset */
512
 
        *bits_pos = p - bits;
513
 
        if (E) {
514
 
            /* Update the sync pos only if the end bit flag is set */
515
 
            pktz->unpack_last_sync_pos = *bits_pos;
516
 
        }
517
 
 
518
 
#if DBG_UNPACKETIZE
519
 
        PJ_LOG(3, ("h264unpack", "Unpacked fragmented H264 NAL unit "
520
 
                   "(type=%d, NRI=%d, len=%d)",
521
 
                   TYPE, NRI, payload_len));
522
 
#endif
523
 
 
524
 
    } else {
525
 
        *bits_pos = 0;
526
 
        return PJ_ENOTSUP;
527
 
    }
528
 
 
529
 
    pktz->unpack_prev_lost = PJ_FALSE;
530
 
 
531
 
    return PJ_SUCCESS;
532
 
}
533
 
 
534
 
 
535
 
#endif /* PJMEDIA_HAS_VIDEO */