4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "libavutil/common.h"
23 #include "bitstream.h"
24 #include "mpegvideo.h"
28 * Write out the provided data into a NAL unit.
29 * @param nal_ref_idc NAL reference IDC
30 * @param nal_unit_type NAL unit payload type
31 * @param dest the target buffer, dst+1 == src is allowed as a special case
32 * @param destsize the length of the dst array
33 * @param b2 the data which should be escaped
34 * @returns pointer to current position in the output buffer or NULL if an error occurred
36 static uint8_t *h264_write_nal_unit(int nal_ref_idc
, int nal_unit_type
, uint8_t *dest
, int *destsize
,
40 int i
, destpos
, rbsplen
, escape_count
;
43 if (nal_unit_type
!= NAL_END_STREAM
)
44 put_bits(b2
,1,1); // rbsp_stop_bit
46 // Align b2 on a byte boundary
48 rbsplen
= put_bits_count(b2
)/8;
52 init_put_bits(&b
,dest
,*destsize
);
57 put_bits(&b
,1,0); // forbidden zero bit
58 put_bits(&b
,2,nal_ref_idc
); // nal_ref_idc
59 put_bits(&b
,5,nal_unit_type
); // nal_unit_type
66 for (i
=0; i
<rbsplen
; i
+=2)
68 if (rbsp
[i
]) continue;
69 if (i
>0 && rbsp
[i
-1]==0)
71 if (i
+2<rbsplen
&& rbsp
[i
+1]==0 && rbsp
[i
+2]<=3)
80 if(dest
+destpos
!= rbsp
)
82 memcpy(dest
+destpos
, rbsp
, rbsplen
);
83 *destsize
-= (rbsplen
+destpos
);
85 return dest
+rbsplen
+destpos
;
88 if(rbsplen
+ escape_count
+ 1> *destsize
)
90 av_log(NULL
, AV_LOG_ERROR
, "Destination buffer too small!\n");
94 // this should be damn rare (hopefully)
95 for (i
= 0 ; i
< rbsplen
; i
++)
97 if (i
+ 2 < rbsplen
&& (rbsp
[i
] == 0 && rbsp
[i
+1] == 0 && rbsp
[i
+2] < 4))
99 dest
[destpos
++] = rbsp
[i
++];
100 dest
[destpos
++] = rbsp
[i
];
101 dest
[destpos
++] = 0x03; // emulation prevention byte
104 dest
[destpos
++] = rbsp
[i
];
106 *destsize
-= destpos
;