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