Mercurial > libavcodec.hg
comparison h264enc.c @ 4291:0c090df061f8 libavcodec
Adding function which enables writing H.264 NAL units.
author | takis |
---|---|
date | Mon, 11 Dec 2006 01:00:50 +0000 |
parents | |
children | 01647ac078a7 |
comparison
equal
deleted
inserted
replaced
4290:e7dfc2743e26 | 4291:0c090df061f8 |
---|---|
1 /* | |
2 * H.264 encoder | |
3 * | |
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. | |
8 * | |
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. | |
13 * | |
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 | |
17 */ | |
18 | |
19 | |
20 #include "common.h" | |
21 #include "bitstream.h" | |
22 #include "mpegvideo.h" | |
23 #include "h264data.h" | |
24 | |
25 /** | |
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 occured | |
33 */ | |
34 static uint8_t *h264_write_nal_unit(int nal_ref_idc, int nal_unit_type, uint8_t *dest, int *destsize, | |
35 PutBitContext *b2) | |
36 { | |
37 PutBitContext b; | |
38 int i, destpos, rbsplen, escape_count; | |
39 uint8_t *rbsp; | |
40 | |
41 if (nal_unit_type != NAL_END_STREAM) | |
42 put_bits(b2,1,1); // rbsp_stop_bit | |
43 | |
44 // Align b2 on a byte boundary | |
45 align_put_bits(b2); | |
46 rbsplen = put_bits_count(b2)/8; | |
47 flush_put_bits(b2); | |
48 rbsp = b2->buf; | |
49 | |
50 init_put_bits(&b,dest,*destsize); | |
51 | |
52 put_bits(&b,16,0); | |
53 put_bits(&b,16,0x01); | |
54 | |
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 | |
58 | |
59 flush_put_bits(&b); | |
60 | |
61 destpos = 5; | |
62 escape_count= 0; | |
63 | |
64 for (i=0; i<rbsplen; i+=2) | |
65 { | |
66 if (rbsp[i]) continue; | |
67 if (i>0 && rbsp[i-1]==0) | |
68 i--; | |
69 if (i+2<rbsplen && rbsp[i+1]==0 && rbsp[i+2]<=3) | |
70 { | |
71 escape_count++; | |
72 i+=2; | |
73 } | |
74 } | |
75 | |
76 if(escape_count==0) | |
77 { | |
78 if(dest+destpos != rbsp) | |
79 { | |
80 memcpy(dest+destpos, rbsp, rbsplen); | |
81 *destsize -= (rbsplen+destpos); | |
82 } | |
83 return dest+rbsplen+destpos; | |
84 } | |
85 | |
86 if(rbsplen + escape_count + 1> *destsize) | |
87 { | |
88 av_log(NULL, AV_LOG_ERROR, "Destination buffer too small!\n"); | |
89 return NULL; | |
90 } | |
91 | |
92 // this should be damn rare (hopefully) | |
93 for (i = 0 ; i < rbsplen ; i++) | |
94 { | |
95 if (i + 2 < rbsplen && (rbsp[i] == 0 && rbsp[i+1] == 0 && rbsp[i+2] < 4)) | |
96 { | |
97 dest[destpos++] = rbsp[i++]; | |
98 dest[destpos++] = rbsp[i]; | |
99 dest[destpos++] = 0x03; // emulation prevention byte | |
100 } | |
101 else | |
102 dest[destpos++] = rbsp[i]; | |
103 } | |
104 *destsize -= destpos; | |
105 return dest+destpos; | |
106 } | |
107 |