Mercurial > libavcodec.hg
comparison h264_sei.c @ 10858:31645cf81fcb libavcodec
Split SEI code off h264.c.
author | michael |
---|---|
date | Tue, 12 Jan 2010 18:54:40 +0000 |
parents | h264.c@b20434143fd5 |
children | 75a2c166f11a |
comparison
equal
deleted
inserted
replaced
10857:b20434143fd5 | 10858:31645cf81fcb |
---|---|
1 /* | |
2 * H.26L/H.264/AVC/JVT/14496-10/... sei decoding | |
3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> | |
4 * | |
5 * This file is part of FFmpeg. | |
6 * | |
7 * FFmpeg is free software; you can redistribute it and/or | |
8 * modify it under the terms of the GNU Lesser General Public | |
9 * License as published by the Free Software Foundation; either | |
10 * version 2.1 of the License, or (at your option) any later version. | |
11 * | |
12 * FFmpeg is distributed in the hope that it will be useful, | |
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Lesser General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Lesser General Public | |
18 * License along with FFmpeg; if not, write to the Free Software | |
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 */ | |
21 | |
22 /** | |
23 * @file libavcodec/h264-sei.c | |
24 * H.264 / AVC / MPEG4 part10 sei decoding. | |
25 * @author Michael Niedermayer <michaelni@gmx.at> | |
26 */ | |
27 | |
28 #include "internal.h" | |
29 #include "avcodec.h" | |
30 #include "h264.h" | |
31 #include "golomb.h" | |
32 | |
33 //#undef NDEBUG | |
34 #include <assert.h> | |
35 | |
36 static const uint8_t sei_num_clock_ts_table[9]={ | |
37 1, 1, 1, 2, 2, 3, 3, 2, 3 | |
38 }; | |
39 | |
40 void ff_h264_reset_sei(H264Context *h) { | |
41 h->sei_recovery_frame_cnt = -1; | |
42 h->sei_dpb_output_delay = 0; | |
43 h->sei_cpb_removal_delay = -1; | |
44 h->sei_buffering_period_present = 0; | |
45 } | |
46 | |
47 static int decode_picture_timing(H264Context *h){ | |
48 MpegEncContext * const s = &h->s; | |
49 if(h->sps.nal_hrd_parameters_present_flag || h->sps.vcl_hrd_parameters_present_flag){ | |
50 h->sei_cpb_removal_delay = get_bits(&s->gb, h->sps.cpb_removal_delay_length); | |
51 h->sei_dpb_output_delay = get_bits(&s->gb, h->sps.dpb_output_delay_length); | |
52 } | |
53 if(h->sps.pic_struct_present_flag){ | |
54 unsigned int i, num_clock_ts; | |
55 h->sei_pic_struct = get_bits(&s->gb, 4); | |
56 h->sei_ct_type = 0; | |
57 | |
58 if (h->sei_pic_struct > SEI_PIC_STRUCT_FRAME_TRIPLING) | |
59 return -1; | |
60 | |
61 num_clock_ts = sei_num_clock_ts_table[h->sei_pic_struct]; | |
62 | |
63 for (i = 0 ; i < num_clock_ts ; i++){ | |
64 if(get_bits(&s->gb, 1)){ /* clock_timestamp_flag */ | |
65 unsigned int full_timestamp_flag; | |
66 h->sei_ct_type |= 1<<get_bits(&s->gb, 2); | |
67 skip_bits(&s->gb, 1); /* nuit_field_based_flag */ | |
68 skip_bits(&s->gb, 5); /* counting_type */ | |
69 full_timestamp_flag = get_bits(&s->gb, 1); | |
70 skip_bits(&s->gb, 1); /* discontinuity_flag */ | |
71 skip_bits(&s->gb, 1); /* cnt_dropped_flag */ | |
72 skip_bits(&s->gb, 8); /* n_frames */ | |
73 if(full_timestamp_flag){ | |
74 skip_bits(&s->gb, 6); /* seconds_value 0..59 */ | |
75 skip_bits(&s->gb, 6); /* minutes_value 0..59 */ | |
76 skip_bits(&s->gb, 5); /* hours_value 0..23 */ | |
77 }else{ | |
78 if(get_bits(&s->gb, 1)){ /* seconds_flag */ | |
79 skip_bits(&s->gb, 6); /* seconds_value range 0..59 */ | |
80 if(get_bits(&s->gb, 1)){ /* minutes_flag */ | |
81 skip_bits(&s->gb, 6); /* minutes_value 0..59 */ | |
82 if(get_bits(&s->gb, 1)) /* hours_flag */ | |
83 skip_bits(&s->gb, 5); /* hours_value 0..23 */ | |
84 } | |
85 } | |
86 } | |
87 if(h->sps.time_offset_length > 0) | |
88 skip_bits(&s->gb, h->sps.time_offset_length); /* time_offset */ | |
89 } | |
90 } | |
91 | |
92 if(s->avctx->debug & FF_DEBUG_PICT_INFO) | |
93 av_log(s->avctx, AV_LOG_DEBUG, "ct_type:%X pic_struct:%d\n", h->sei_ct_type, h->sei_pic_struct); | |
94 } | |
95 return 0; | |
96 } | |
97 | |
98 static int decode_unregistered_user_data(H264Context *h, int size){ | |
99 MpegEncContext * const s = &h->s; | |
100 uint8_t user_data[16+256]; | |
101 int e, build, i; | |
102 | |
103 if(size<16) | |
104 return -1; | |
105 | |
106 for(i=0; i<sizeof(user_data)-1 && i<size; i++){ | |
107 user_data[i]= get_bits(&s->gb, 8); | |
108 } | |
109 | |
110 user_data[i]= 0; | |
111 e= sscanf(user_data+16, "x264 - core %d"/*%s - H.264/MPEG-4 AVC codec - Copyleft 2005 - http://www.videolan.org/x264.html*/, &build); | |
112 if(e==1 && build>=0) | |
113 h->x264_build= build; | |
114 | |
115 if(s->avctx->debug & FF_DEBUG_BUGS) | |
116 av_log(s->avctx, AV_LOG_DEBUG, "user data:\"%s\"\n", user_data+16); | |
117 | |
118 for(; i<size; i++) | |
119 skip_bits(&s->gb, 8); | |
120 | |
121 return 0; | |
122 } | |
123 | |
124 static int decode_recovery_point(H264Context *h){ | |
125 MpegEncContext * const s = &h->s; | |
126 | |
127 h->sei_recovery_frame_cnt = get_ue_golomb(&s->gb); | |
128 skip_bits(&s->gb, 4); /* 1b exact_match_flag, 1b broken_link_flag, 2b changing_slice_group_idc */ | |
129 | |
130 return 0; | |
131 } | |
132 | |
133 static int decode_buffering_period(H264Context *h){ | |
134 MpegEncContext * const s = &h->s; | |
135 unsigned int sps_id; | |
136 int sched_sel_idx; | |
137 SPS *sps; | |
138 | |
139 sps_id = get_ue_golomb_31(&s->gb); | |
140 if(sps_id > 31 || !h->sps_buffers[sps_id]) { | |
141 av_log(h->s.avctx, AV_LOG_ERROR, "non-existing SPS %d referenced in buffering period\n", sps_id); | |
142 return -1; | |
143 } | |
144 sps = h->sps_buffers[sps_id]; | |
145 | |
146 // NOTE: This is really so duplicated in the standard... See H.264, D.1.1 | |
147 if (sps->nal_hrd_parameters_present_flag) { | |
148 for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) { | |
149 h->initial_cpb_removal_delay[sched_sel_idx] = get_bits(&s->gb, sps->initial_cpb_removal_delay_length); | |
150 skip_bits(&s->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset | |
151 } | |
152 } | |
153 if (sps->vcl_hrd_parameters_present_flag) { | |
154 for (sched_sel_idx = 0; sched_sel_idx < sps->cpb_cnt; sched_sel_idx++) { | |
155 h->initial_cpb_removal_delay[sched_sel_idx] = get_bits(&s->gb, sps->initial_cpb_removal_delay_length); | |
156 skip_bits(&s->gb, sps->initial_cpb_removal_delay_length); // initial_cpb_removal_delay_offset | |
157 } | |
158 } | |
159 | |
160 h->sei_buffering_period_present = 1; | |
161 return 0; | |
162 } | |
163 | |
164 int ff_h264_decode_sei(H264Context *h){ | |
165 MpegEncContext * const s = &h->s; | |
166 | |
167 while(get_bits_count(&s->gb) + 16 < s->gb.size_in_bits){ | |
168 int size, type; | |
169 | |
170 type=0; | |
171 do{ | |
172 type+= show_bits(&s->gb, 8); | |
173 }while(get_bits(&s->gb, 8) == 255); | |
174 | |
175 size=0; | |
176 do{ | |
177 size+= show_bits(&s->gb, 8); | |
178 }while(get_bits(&s->gb, 8) == 255); | |
179 | |
180 switch(type){ | |
181 case SEI_TYPE_PIC_TIMING: // Picture timing SEI | |
182 if(decode_picture_timing(h) < 0) | |
183 return -1; | |
184 break; | |
185 case SEI_TYPE_USER_DATA_UNREGISTERED: | |
186 if(decode_unregistered_user_data(h, size) < 0) | |
187 return -1; | |
188 break; | |
189 case SEI_TYPE_RECOVERY_POINT: | |
190 if(decode_recovery_point(h) < 0) | |
191 return -1; | |
192 break; | |
193 case SEI_BUFFERING_PERIOD: | |
194 if(decode_buffering_period(h) < 0) | |
195 return -1; | |
196 break; | |
197 default: | |
198 skip_bits(&s->gb, 8*size); | |
199 } | |
200 | |
201 //FIXME check bits here | |
202 align_get_bits(&s->gb); | |
203 } | |
204 | |
205 return 0; | |
206 } |