1 | diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp |
---|
2 | index 3eb42c7..41baca6 100644 |
---|
3 | --- a/mythtv/libs/libmythtv/avformatdecoder.cpp |
---|
4 | +++ b/mythtv/libs/libmythtv/avformatdecoder.cpp |
---|
5 | @@ -3108,7 +3108,7 @@ int AvFormatDecoder::H264PreProcessPkt(AVStream *stream, AVPacket *pkt) |
---|
6 | { |
---|
7 | buf += m_h264_parser->addBytes(buf, buf_end - buf, 0); |
---|
8 | |
---|
9 | - if (m_h264_parser->stateChanged()) |
---|
10 | + if (m_h264_parser->stateChanged() && m_h264_parser->seen_SPS()) |
---|
11 | { |
---|
12 | if (m_h264_parser->FieldType() != H264Parser::FIELD_BOTTOM) |
---|
13 | { |
---|
14 | diff --git a/mythtv/libs/libmythtv/mpeg/H264Parser.cpp b/mythtv/libs/libmythtv/mpeg/H264Parser.cpp |
---|
15 | index 3e45c60..e761138 100644 |
---|
16 | --- a/mythtv/libs/libmythtv/mpeg/H264Parser.cpp |
---|
17 | +++ b/mythtv/libs/libmythtv/mpeg/H264Parser.cpp |
---|
18 | @@ -98,7 +98,7 @@ H264Parser::H264Parser(void) |
---|
19 | rbsp_buffer_size = 0; |
---|
20 | |
---|
21 | Reset(); |
---|
22 | - I_is_keyframe = true; |
---|
23 | + I_is_keyframe = false; |
---|
24 | au_contains_keyframe_message = false; |
---|
25 | } |
---|
26 | |
---|
27 | @@ -116,14 +116,14 @@ void H264Parser::Reset(void) |
---|
28 | prev_pic_parameter_set_id = pic_parameter_set_id = -1; |
---|
29 | prev_field_pic_flag = field_pic_flag = -1; |
---|
30 | prev_bottom_field_flag = bottom_field_flag = -1; |
---|
31 | - prev_nal_ref_idc = nal_ref_idc = 0; |
---|
32 | + prev_nal_ref_idc = nal_ref_idc = 111; // != [0|1|2|3] |
---|
33 | prev_pic_order_cnt_type = pic_order_cnt_type = |
---|
34 | prev_pic_order_cnt_lsb = pic_order_cnt_lsb = 0; |
---|
35 | prev_delta_pic_order_cnt_bottom = delta_pic_order_cnt_bottom = 0; |
---|
36 | prev_delta_pic_order_cnt[0] = delta_pic_order_cnt[0] = 0; |
---|
37 | prev_delta_pic_order_cnt[1] = delta_pic_order_cnt[1] = 0; |
---|
38 | prev_nal_unit_type = nal_unit_type = UNKNOWN; |
---|
39 | - prev_idr_pic_id = idr_pic_id = 0; |
---|
40 | + prev_idr_pic_id = idr_pic_id = 111; // != [0|1|2|3] |
---|
41 | |
---|
42 | log2_max_frame_num = log2_max_pic_order_cnt_lsb = 0; |
---|
43 | seq_parameter_set_id = 0; |
---|
44 | @@ -401,6 +401,7 @@ uint32_t H264Parser::addBytes(const uint8_t *bytes, |
---|
45 | const uint8_t *startP = bytes; |
---|
46 | const uint8_t *endP; |
---|
47 | bool found_start_code; |
---|
48 | + bool good_nal_unit; |
---|
49 | |
---|
50 | state_changed = false; |
---|
51 | on_frame = false; |
---|
52 | @@ -474,23 +475,41 @@ uint32_t H264Parser::addBytes(const uint8_t *bytes, |
---|
53 | nal_unit_type = sync_accumulator & 0x1f; |
---|
54 | nal_ref_idc = (sync_accumulator >> 5) & 0x3; |
---|
55 | |
---|
56 | - if (nal_unit_type == SPS || nal_unit_type == PPS || |
---|
57 | - nal_unit_type == SEI || NALisSlice(nal_unit_type)) |
---|
58 | - { |
---|
59 | - /* This is a NAL we need to parse. We may have the body |
---|
60 | - * of it in the part of the stream past to us this call, |
---|
61 | - * or we may get the rest in subsequent calls to addBytes. |
---|
62 | - * Either way, we set have_unfinished_NAL, so that we |
---|
63 | - * start filling the rbsp buffer */ |
---|
64 | - have_unfinished_NAL = true; |
---|
65 | - } |
---|
66 | - else if (nal_unit_type == AU_DELIMITER || |
---|
67 | - (nal_unit_type > SPS_EXT && |
---|
68 | - nal_unit_type < AUXILIARY_SLICE)) |
---|
69 | +/* nal_ref_idc shall be equal to 0 for all NAL units having nal_unit_type equal to 6, 9, 10, 11, or 12. |
---|
70 | + */ |
---|
71 | + good_nal_unit = true; |
---|
72 | + if (nal_ref_idc && (nal_unit_type == SEI || (nal_unit_type >= AU_DELIMITER && |
---|
73 | + nal_unit_type <= FILLER_DATA)) ) |
---|
74 | + good_nal_unit = false; |
---|
75 | + |
---|
76 | +/* nal_ref_idc shall not be equal to 0 for NAL units with nal_unit_type equal to 5 |
---|
77 | + */ |
---|
78 | + if (!nal_ref_idc && (nal_unit_type == SLICE_IDR)) |
---|
79 | + good_nal_unit = false; |
---|
80 | + |
---|
81 | + if (good_nal_unit) |
---|
82 | { |
---|
83 | - set_AU_pending(); |
---|
84 | + if (nal_unit_type == SPS || nal_unit_type == PPS || |
---|
85 | + nal_unit_type == SEI || NALisSlice(nal_unit_type)) |
---|
86 | + { |
---|
87 | + /* This is a NAL we need to parse. We may have the body |
---|
88 | + * of it in the part of the stream past to us this call, |
---|
89 | + * or we may get the rest in subsequent calls to addBytes. |
---|
90 | + * Either way, we set have_unfinished_NAL, so that we |
---|
91 | + * start filling the rbsp buffer */ |
---|
92 | + have_unfinished_NAL = true; |
---|
93 | + } |
---|
94 | + else if (nal_unit_type == AU_DELIMITER || |
---|
95 | + (nal_unit_type > SPS_EXT && |
---|
96 | + nal_unit_type < AUXILIARY_SLICE)) |
---|
97 | + { |
---|
98 | + set_AU_pending(); |
---|
99 | + } |
---|
100 | } |
---|
101 | - } |
---|
102 | + else |
---|
103 | + LOG(VB_GENERAL, LOG_ERR, |
---|
104 | + "H264Parser::addbytes: malformed NAL units"); |
---|
105 | + } //found start code |
---|
106 | } |
---|
107 | |
---|
108 | return startP - bytes; |
---|
109 | @@ -523,6 +542,9 @@ void H264Parser::processRBSP(bool rbsp_complete) |
---|
110 | |
---|
111 | set_AU_pending(); |
---|
112 | |
---|
113 | + if (!seen_sps) |
---|
114 | + SPS_offset = pkt_offset; |
---|
115 | + |
---|
116 | decode_SPS(&gb); |
---|
117 | } |
---|
118 | else if (nal_unit_type == PPS) |
---|
119 | @@ -576,6 +598,8 @@ void H264Parser::processRBSP(bool rbsp_complete) |
---|
120 | */ |
---|
121 | bool H264Parser::decode_Header(GetBitContext *gb) |
---|
122 | { |
---|
123 | + uint first_mb_in_slice; |
---|
124 | + |
---|
125 | is_keyframe = false; |
---|
126 | |
---|
127 | if (log2_max_frame_num == 0 || pic_order_present_flag == -1) |
---|
128 | @@ -601,8 +625,7 @@ bool H264Parser::decode_Header(GetBitContext *gb) |
---|
129 | that precedes the current slice in decoding order and has the |
---|
130 | same value of colour_plane_id. |
---|
131 | */ |
---|
132 | - //uint first_mb_in_slice = get_ue_golomb(gb); |
---|
133 | - get_ue_golomb(gb); // Replaced above line |
---|
134 | + first_mb_in_slice = get_ue_golomb_long(gb); |
---|
135 | |
---|
136 | /* |
---|
137 | slice_type specifies the coding type of the slice according to |
---|
138 | @@ -611,8 +634,10 @@ bool H264Parser::decode_Header(GetBitContext *gb) |
---|
139 | When nal_unit_type is equal to 5 (IDR picture), slice_type shall |
---|
140 | be equal to 2, 4, 7, or 9 (I or SI) |
---|
141 | */ |
---|
142 | - slice_type = get_ue_golomb(gb); |
---|
143 | + slice_type = get_ue_golomb_31(gb); |
---|
144 | |
---|
145 | + /* s->pict_type = golomb_to_pict_type[slice_type % 5]; |
---|
146 | + */ |
---|
147 | /* |
---|
148 | pic_parameter_set_id specifies the picture parameter set in |
---|
149 | use. The value of pic_parameter_set_id shall be in the range of |
---|
150 | @@ -642,6 +667,8 @@ bool H264Parser::decode_Header(GetBitContext *gb) |
---|
151 | bitstream.... |
---|
152 | |
---|
153 | If the current picture is an IDR picture, frame_num shall be equal to 0. |
---|
154 | + |
---|
155 | + When max_num_ref_frames is equal to 0, slice_type shall be equal to 2, 4, 7, or 9. |
---|
156 | */ |
---|
157 | |
---|
158 | frame_num = get_bits(gb, log2_max_frame_num); |
---|
159 | @@ -683,9 +710,10 @@ bool H264Parser::decode_Header(GetBitContext *gb) |
---|
160 | { |
---|
161 | idr_pic_id = get_ue_golomb(gb); |
---|
162 | is_keyframe = true; |
---|
163 | + I_is_keyframe = true; |
---|
164 | } |
---|
165 | else |
---|
166 | - is_keyframe |= I_is_keyframe && isKeySlice(slice_type); |
---|
167 | + is_keyframe |= isKeySlice(slice_type); |
---|
168 | /* |
---|
169 | pic_order_cnt_lsb specifies the picture order count modulo |
---|
170 | MaxPicOrderCntLsb for the top field of a coded frame or for a coded |
---|
171 | @@ -702,7 +730,7 @@ bool H264Parser::decode_Header(GetBitContext *gb) |
---|
172 | { |
---|
173 | pic_order_cnt_lsb = get_bits(gb, log2_max_pic_order_cnt_lsb); |
---|
174 | |
---|
175 | - if (pic_order_present_flag && !field_pic_flag) |
---|
176 | + if ((pic_order_present_flag == 1) && !field_pic_flag) |
---|
177 | delta_pic_order_cnt_bottom = get_se_golomb(gb); |
---|
178 | else |
---|
179 | delta_pic_order_cnt_bottom = 0; |
---|
180 | @@ -731,13 +759,17 @@ bool H264Parser::decode_Header(GetBitContext *gb) |
---|
181 | { |
---|
182 | delta_pic_order_cnt[0] = get_se_golomb(gb); |
---|
183 | |
---|
184 | - if (pic_order_present_flag && !field_pic_flag) |
---|
185 | + if ((pic_order_present_flag == 1) && !field_pic_flag) |
---|
186 | delta_pic_order_cnt[1] = get_se_golomb(gb); |
---|
187 | - else |
---|
188 | + } |
---|
189 | + else |
---|
190 | + { |
---|
191 | + if (pic_order_cnt_type == 1) |
---|
192 | + { |
---|
193 | delta_pic_order_cnt[1] = 0; |
---|
194 | - } |
---|
195 | - else |
---|
196 | - delta_pic_order_cnt[0] = 0; |
---|
197 | + delta_pic_order_cnt[0] = 0; |
---|
198 | + } |
---|
199 | + } |
---|
200 | |
---|
201 | /* |
---|
202 | redundant_pic_cnt shall be equal to 0 for slices and slice data |
---|
203 | @@ -760,10 +792,13 @@ bool H264Parser::decode_Header(GetBitContext *gb) |
---|
204 | void H264Parser::decode_SPS(GetBitContext * gb) |
---|
205 | { |
---|
206 | int profile_idc; |
---|
207 | + int lastScale; |
---|
208 | + int nextScale; |
---|
209 | + int deltaScale; |
---|
210 | |
---|
211 | seen_sps = true; |
---|
212 | |
---|
213 | - profile_idc = get_bits(gb, 8); // profile_idc |
---|
214 | + profile_idc = get_bits(gb, 8); |
---|
215 | get_bits1(gb); // constraint_set0_flag |
---|
216 | get_bits1(gb); // constraint_set1_flag |
---|
217 | get_bits1(gb); // constraint_set2_flag |
---|
218 | @@ -772,9 +807,11 @@ void H264Parser::decode_SPS(GetBitContext * gb) |
---|
219 | get_bits(gb, 8); // level_idc |
---|
220 | get_ue_golomb(gb); // sps_id |
---|
221 | |
---|
222 | - if (profile_idc >= 100) |
---|
223 | + if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 || |
---|
224 | + profile_idc == 244 || profile_idc == 44 || profile_idc == 83 || |
---|
225 | + profile_idc == 86 || profile_idc == 118 || profile_idc == 128 ) |
---|
226 | { // high profile |
---|
227 | - if ((chroma_format_idc = get_ue_golomb(gb)) == 3) // chroma_format_idc |
---|
228 | + if ((chroma_format_idc = get_ue_golomb(gb)) == 3) |
---|
229 | separate_colour_plane_flag = (get_bits1(gb) == 1); |
---|
230 | |
---|
231 | get_ue_golomb(gb); // bit_depth_luma_minus8 |
---|
232 | @@ -785,12 +822,18 @@ void H264Parser::decode_SPS(GetBitContext * gb) |
---|
233 | { |
---|
234 | for (int idx = 0; idx < ((chroma_format_idc != 3) ? 8 : 12); ++idx) |
---|
235 | { |
---|
236 | - if (get_bits1(gb)) // Scaling list presnent |
---|
237 | + if (get_bits1(gb)) // Scaling list present |
---|
238 | { |
---|
239 | + lastScale = nextScale = 8; |
---|
240 | int sl_n = ((idx < 6) ? 16 : 64); |
---|
241 | - for(int sl_i = 0; sl_i < sl_n; sl_i++) |
---|
242 | + for(int sl_i = 0; sl_i < sl_n; ++sl_i) |
---|
243 | { |
---|
244 | - get_se_golomb(gb); |
---|
245 | + if (nextScale != 0) |
---|
246 | + { |
---|
247 | + deltaScale = get_se_golomb(gb); |
---|
248 | + nextScale = (lastScale + deltaScale + 256) % 256; |
---|
249 | + } |
---|
250 | + lastScale = (nextScale == 0) ? lastScale : nextScale; |
---|
251 | } |
---|
252 | } |
---|
253 | } |
---|
254 | @@ -809,6 +852,7 @@ void H264Parser::decode_SPS(GetBitContext * gb) |
---|
255 | int offset_for_non_ref_pic; |
---|
256 | int offset_for_top_to_bottom_field; |
---|
257 | uint tmp; |
---|
258 | + bool gaps_in_frame_num_allowed_flag; |
---|
259 | |
---|
260 | /* |
---|
261 | pic_order_cnt_type specifies the method to decode picture order |
---|
262 | @@ -886,8 +930,7 @@ void H264Parser::decode_SPS(GetBitContext * gb) |
---|
263 | decoding process in case of an inferred gap between values of |
---|
264 | frame_num as specified in subclause 8.2.5.2. |
---|
265 | */ |
---|
266 | - //bool gaps_in_frame_num_allowed_flag = get_bits1(gb); |
---|
267 | - get_bits1(gb); // Replaced above line |
---|
268 | + gaps_in_frame_num_allowed_flag = get_bits1(gb); |
---|
269 | |
---|
270 | /* |
---|
271 | pic_width_in_mbs_minus1 plus 1 specifies the width of each |
---|
272 | @@ -1040,20 +1083,28 @@ void H264Parser::decode_SEI(GetBitContext *gb) |
---|
273 | bool broken_link_flag = false; |
---|
274 | int changing_group_slice_idc = -1; |
---|
275 | |
---|
276 | - int type = 0, size = 0; |
---|
277 | + int type = 0, size = 0, tmp_byte = 0; |
---|
278 | |
---|
279 | /* A message requires at least 2 bytes, and then |
---|
280 | * there's the stop bit plus alignment, so there |
---|
281 | * can be no message in less than 24 bits */ |
---|
282 | while (get_bits_left(gb) >= 24) |
---|
283 | { |
---|
284 | - do { |
---|
285 | - type += show_bits(gb, 8); |
---|
286 | - } while (get_bits(gb, 8) == 255); |
---|
287 | + tmp_byte = get_bits(gb, 8); |
---|
288 | + while (tmp_byte == 255) |
---|
289 | + { |
---|
290 | + type += 255; |
---|
291 | + tmp_byte = get_bits(gb, 8); |
---|
292 | + } |
---|
293 | + type += get_bits(gb, 8); //last_payload_type_byte |
---|
294 | |
---|
295 | - do { |
---|
296 | - size += show_bits(gb, 8); |
---|
297 | - } while (get_bits(gb, 8) == 255); |
---|
298 | + tmp_byte = get_bits(gb, 8); |
---|
299 | + while (tmp_byte == 255) |
---|
300 | + { |
---|
301 | + size += 255; |
---|
302 | + tmp_byte = get_bits(gb, 8); |
---|
303 | + } |
---|
304 | + size += get_bits(gb, 8); //last_payload_size_byte |
---|
305 | |
---|
306 | switch (type) |
---|
307 | { |
---|
308 | @@ -1063,6 +1114,8 @@ void H264Parser::decode_SEI(GetBitContext *gb) |
---|
309 | broken_link_flag = get_bits1(gb); |
---|
310 | changing_group_slice_idc = get_bits(gb, 2); |
---|
311 | au_contains_keyframe_message = (recovery_frame_cnt == 0); |
---|
312 | + if ((size - 12) > 0) |
---|
313 | + skip_bits(gb, (size - 12) * 8); |
---|
314 | return; |
---|
315 | |
---|
316 | default: |
---|
317 | diff --git a/mythtv/libs/libmythtv/mpeg/H264Parser.h b/mythtv/libs/libmythtv/mpeg/H264Parser.h |
---|
318 | index 9c984e0..7b750f2 100644 |
---|
319 | --- a/mythtv/libs/libmythtv/mpeg/H264Parser.h |
---|
320 | +++ b/mythtv/libs/libmythtv/mpeg/H264Parser.h |
---|
321 | @@ -60,7 +60,7 @@ class H264Parser { |
---|
322 | // ITU-T Rec. H.264 table 7-1 |
---|
323 | enum NAL_unit_type { |
---|
324 | UNKNOWN = 0, |
---|
325 | - SLICE = 1, |
---|
326 | + SLICE = 1, // 1 - 5 are VCL NAL units |
---|
327 | SLICE_DPA = 2, |
---|
328 | SLICE_DPB = 3, |
---|
329 | SLICE_DPC = 4, |
---|
330 | @@ -73,11 +73,15 @@ class H264Parser { |
---|
331 | END_STREAM = 11, |
---|
332 | FILLER_DATA = 12, |
---|
333 | SPS_EXT = 13, |
---|
334 | - AUXILIARY_SLICE = 19 |
---|
335 | + NALU_prefix = 14, |
---|
336 | + SPS_subset = 15, |
---|
337 | + AUXILIARY_SLICE = 19, |
---|
338 | + SLICE_EXTENSION = 20 |
---|
339 | }; |
---|
340 | |
---|
341 | enum SEI_type { |
---|
342 | SEI_TYPE_PIC_TIMING = 1, |
---|
343 | + SEI_FILLER_PAYLOAD = 3, |
---|
344 | SEI_TYPE_USER_DATA_UNREGISTERED = 5, |
---|
345 | SEI_TYPE_RECOVERY_POINT = 6 |
---|
346 | }; |
---|
347 | @@ -147,7 +151,9 @@ class H264Parser { |
---|
348 | |
---|
349 | uint64_t frameAUstreamOffset(void) const {return frame_start_offset;} |
---|
350 | uint64_t keyframeAUstreamOffset(void) const {return keyframe_start_offset;} |
---|
351 | + uint64_t SPSstreamOffset(void) const {return SPS_offset;} |
---|
352 | |
---|
353 | +// == NAL_type AU_delimiter: primary_pic_type = 5 |
---|
354 | static int isKeySlice(uint slice_type) |
---|
355 | { |
---|
356 | return (slice_type == SLICE_I || |
---|
357 | @@ -164,6 +170,7 @@ class H264Parser { |
---|
358 | } |
---|
359 | |
---|
360 | void use_I_forKeyframes(bool val) { I_is_keyframe = val; } |
---|
361 | + bool using_I_forKeyframes(void) const { return I_is_keyframe; } |
---|
362 | |
---|
363 | uint32_t GetTimeScale(void) const { return timeScale; } |
---|
364 | |
---|
365 | @@ -172,6 +179,10 @@ class H264Parser { |
---|
366 | void parse_SPS(uint8_t *sps, uint32_t sps_size, |
---|
367 | bool& interlaced, int32_t& max_ref_frames); |
---|
368 | |
---|
369 | + bool seen_SPS(void) const { return seen_sps; } |
---|
370 | + |
---|
371 | + bool found_AU(void) const { return AU_pending; } |
---|
372 | + |
---|
373 | private: |
---|
374 | enum constants {EXTENDED_SAR = 255}; |
---|
375 | |
---|
376 | @@ -247,6 +258,7 @@ class H264Parser { |
---|
377 | bool fixedRate; |
---|
378 | |
---|
379 | uint64_t pkt_offset, AU_offset, frame_start_offset, keyframe_start_offset; |
---|
380 | + uint64_t SPS_offset; |
---|
381 | bool on_frame, on_key_frame; |
---|
382 | }; |
---|
383 | |
---|
384 | diff --git a/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp b/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp |
---|
385 | index e25774d..21707ce 100644 |
---|
386 | --- a/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp |
---|
387 | +++ b/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp |
---|
388 | @@ -64,7 +64,7 @@ DTVRecorder::DTVRecorder(TVRec *rec) : |
---|
389 | _pes_synced(false), |
---|
390 | _seen_sps(false), |
---|
391 | // settings |
---|
392 | - _wait_for_keyframe_option(true), |
---|
393 | + _wait_for_keyframe_option(true), // is wait_for_SPS for H264 |
---|
394 | _has_written_other_keyframe(false), |
---|
395 | // state |
---|
396 | _error(), |
---|
397 | @@ -195,7 +195,7 @@ void DTVRecorder::ResetForNewFile(void) |
---|
398 | _repeat_pict = 0; |
---|
399 | |
---|
400 | //_pes_synced |
---|
401 | - //_seen_sps |
---|
402 | + _seen_sps = false; |
---|
403 | positionMap.clear(); |
---|
404 | positionMapDelta.clear(); |
---|
405 | durationMap.clear(); |
---|
406 | @@ -276,9 +276,8 @@ void DTVRecorder::BufferedWrite(const TSPacket &tspacket, bool insert) |
---|
407 | { |
---|
408 | if (!insert) // PAT/PMT may need inserted in front of any buffered data |
---|
409 | { |
---|
410 | - // delay until first GOP to avoid decoder crash on res change |
---|
411 | - if (!_buffer_packets && _wait_for_keyframe_option && |
---|
412 | - _first_keyframe < 0) |
---|
413 | + // delay until first SPS/GOP to avoid decoder crash on res change |
---|
414 | + if (!_buffer_packets && _wait_for_keyframe_option && !_seen_sps) |
---|
415 | return; |
---|
416 | |
---|
417 | if (curRecording && timeOfFirstDataIsSet.testAndSetRelaxed(0,1)) |
---|
418 | @@ -461,6 +460,7 @@ bool DTVRecorder::FindMPEG2Keyframes(const TSPacket* tspacket) |
---|
419 | } |
---|
420 | else if (PESStreamID::SequenceStartCode == stream_id) |
---|
421 | { |
---|
422 | + _seen_sps = true; // for mpeg2vid ==SeqStartHeader |
---|
423 | _last_seq_seen = _frames_seen_count; |
---|
424 | hasKeyFrame |= (_last_gop_seen + maxKFD)<_frames_seen_count; |
---|
425 | |
---|
426 | @@ -532,6 +532,12 @@ bool DTVRecorder::FindMPEG2Keyframes(const TSPacket* tspacket) |
---|
427 | } |
---|
428 | } |
---|
429 | |
---|
430 | + // _buffer_packets will only be true if a payload start has been seen |
---|
431 | + if (_seen_sps || !_wait_for_keyframe_option) |
---|
432 | + _buffer_packets = false; |
---|
433 | + else |
---|
434 | + _payload_buffer.clear(); |
---|
435 | + |
---|
436 | if (hasFrame && !hasKeyFrame) |
---|
437 | { |
---|
438 | // If we have seen kMaxKeyFrameDistance frames since the |
---|
439 | @@ -543,8 +549,7 @@ bool DTVRecorder::FindMPEG2Keyframes(const TSPacket* tspacket) |
---|
440 | hasKeyFrame &= (_last_seq_seen + maxKFD) < _frames_seen_count; |
---|
441 | } |
---|
442 | |
---|
443 | - // _buffer_packets will only be true if a payload start has been seen |
---|
444 | - if (hasKeyFrame && (_buffer_packets || _first_keyframe >= 0)) |
---|
445 | + if (hasKeyFrame) |
---|
446 | { |
---|
447 | LOG(VB_RECORD, LOG_DEBUG, LOC + QString |
---|
448 | ("Keyframe @ %1 + %2 = %3") |
---|
449 | @@ -553,7 +558,7 @@ bool DTVRecorder::FindMPEG2Keyframes(const TSPacket* tspacket) |
---|
450 | .arg(ringBuffer->GetWritePosition() + _payload_buffer.size())); |
---|
451 | |
---|
452 | _last_keyframe_seen = _frames_seen_count; |
---|
453 | - HandleKeyframe(0); |
---|
454 | + HandleKeyframe(_payload_buffer.size()); |
---|
455 | } |
---|
456 | |
---|
457 | if (hasFrame) |
---|
458 | @@ -564,16 +569,9 @@ bool DTVRecorder::FindMPEG2Keyframes(const TSPacket* tspacket) |
---|
459 | .arg(_payload_buffer.size()) |
---|
460 | .arg(ringBuffer->GetWritePosition() + _payload_buffer.size())); |
---|
461 | |
---|
462 | - _buffer_packets = false; // We now know if it is a keyframe, or not |
---|
463 | _frames_seen_count++; |
---|
464 | - if (!_wait_for_keyframe_option || _first_keyframe >= 0) |
---|
465 | + if (_first_keyframe >= 0) |
---|
466 | UpdateFramesWritten(); |
---|
467 | - else |
---|
468 | - { |
---|
469 | - /* Found a frame that is not a keyframe, and we want to |
---|
470 | - * start on a keyframe */ |
---|
471 | - _payload_buffer.clear(); |
---|
472 | - } |
---|
473 | } |
---|
474 | |
---|
475 | if ((aspectRatio > 0) && (aspectRatio != m_videoAspect)) |
---|
476 | @@ -718,6 +716,7 @@ bool DTVRecorder::FindAudioKeyframes(const TSPacket*) |
---|
477 | _audio_timer.start(); |
---|
478 | |
---|
479 | _buffer_packets = false; |
---|
480 | + _seen_sps = true; // unblock BufferedWrite() |
---|
481 | _frames_seen_count++; |
---|
482 | |
---|
483 | if (1 == (_frames_seen_count & 0x7)) |
---|
484 | @@ -898,30 +897,38 @@ bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket) |
---|
485 | uint32_t bytes_used = m_h264_parser.addBytes |
---|
486 | (tspacket->data() + i, TSPacket::kSize - i, |
---|
487 | ringBuffer->GetWritePosition()); |
---|
488 | - i += (bytes_used - 1); |
---|
489 | |
---|
490 | - if (m_h264_parser.stateChanged()) |
---|
491 | + if (!_seen_sps && m_h264_parser.seen_SPS()) |
---|
492 | + _seen_sps = true; |
---|
493 | + |
---|
494 | + if (m_h264_parser.stateChanged() && _seen_sps) |
---|
495 | { |
---|
496 | if (m_h264_parser.onFrameStart() && |
---|
497 | m_h264_parser.FieldType() != H264Parser::FIELD_BOTTOM) |
---|
498 | { |
---|
499 | hasKeyFrame = m_h264_parser.onKeyFrameStart(); |
---|
500 | hasFrame = true; |
---|
501 | - _seen_sps |= hasKeyFrame; |
---|
502 | - |
---|
503 | + |
---|
504 | width = m_h264_parser.pictureWidth(); |
---|
505 | height = m_h264_parser.pictureHeight(); |
---|
506 | aspectRatio = m_h264_parser.aspectRatio(); |
---|
507 | m_h264_parser.getFrameRate(frameRate); |
---|
508 | } |
---|
509 | } |
---|
510 | + |
---|
511 | + i += (bytes_used - 1); |
---|
512 | } // for (; i < TSPacket::kSize; ++i) |
---|
513 | |
---|
514 | // _buffer_packets will only be true if a payload start has been seen |
---|
515 | - if (hasKeyFrame && (_buffer_packets || _first_keyframe >= 0)) |
---|
516 | + if (_seen_sps || !_wait_for_keyframe_option) |
---|
517 | + _buffer_packets = false; |
---|
518 | + else |
---|
519 | + _payload_buffer.clear(); |
---|
520 | + |
---|
521 | + if (hasKeyFrame) |
---|
522 | { |
---|
523 | LOG(VB_RECORD, LOG_DEBUG, LOC + QString |
---|
524 | - ("Keyframe @ %1 + %2 = %3 AU %4") |
---|
525 | + ("H264Keyframe @ %1 + %2 = %3 AU %4") |
---|
526 | .arg(ringBuffer->GetWritePosition()) |
---|
527 | .arg(_payload_buffer.size()) |
---|
528 | .arg(ringBuffer->GetWritePosition() + _payload_buffer.size()) |
---|
529 | @@ -934,22 +941,15 @@ bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket) |
---|
530 | if (hasFrame) |
---|
531 | { |
---|
532 | LOG(VB_RECORD, LOG_DEBUG, LOC + QString |
---|
533 | - ("Frame @ %1 + %2 = %3 AU %4") |
---|
534 | + ("H264Frame @ %1 + %2 = %3 AU %4") |
---|
535 | .arg(ringBuffer->GetWritePosition()) |
---|
536 | .arg(_payload_buffer.size()) |
---|
537 | .arg(ringBuffer->GetWritePosition() + _payload_buffer.size()) |
---|
538 | - .arg(m_h264_parser.keyframeAUstreamOffset())); |
---|
539 | + .arg(m_h264_parser.frameAUstreamOffset())); |
---|
540 | |
---|
541 | - _buffer_packets = false; // We now know if this is a keyframe |
---|
542 | _frames_seen_count++; |
---|
543 | - if (!_wait_for_keyframe_option || _first_keyframe >= 0) |
---|
544 | + if (_first_keyframe >= 0) |
---|
545 | UpdateFramesWritten(); |
---|
546 | - else |
---|
547 | - { |
---|
548 | - /* Found a frame that is not a keyframe, and we want to |
---|
549 | - * start on a keyframe */ |
---|
550 | - _payload_buffer.clear(); |
---|
551 | - } |
---|
552 | } |
---|
553 | |
---|
554 | if ((aspectRatio > 0) && (aspectRatio != m_videoAspect)) |
---|
555 | @@ -971,12 +971,12 @@ bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket) |
---|
556 | QString("FindH264Keyframes: timescale: %1, tick: %2, framerate: %3") |
---|
557 | .arg( m_h264_parser.GetTimeScale() ) |
---|
558 | .arg( m_h264_parser.GetUnitsInTick() ) |
---|
559 | - .arg( frameRate.toDouble() * 1000 ) ); |
---|
560 | + .arg( frameRate.toDouble() ) ); |
---|
561 | m_frameRate = frameRate; |
---|
562 | FrameRateChange(frameRate.toDouble() * 1000, _frames_written_count); |
---|
563 | } |
---|
564 | |
---|
565 | - return _seen_sps; |
---|
566 | + return hasKeyFrame; |
---|
567 | } |
---|
568 | |
---|
569 | /** \fn DTVRecorder::HandleH264Keyframe(void) |
---|
570 | @@ -991,15 +991,9 @@ void DTVRecorder::HandleH264Keyframe(void) |
---|
571 | uint64_t startpos; |
---|
572 | uint64_t frameNum = _frames_written_count; |
---|
573 | |
---|
574 | - if (_first_keyframe < 0) |
---|
575 | - { |
---|
576 | - _first_keyframe = frameNum; |
---|
577 | - startpos = 0; |
---|
578 | - } |
---|
579 | - else |
---|
580 | - startpos = m_h264_parser.keyframeAUstreamOffset(); |
---|
581 | + startpos = m_h264_parser.keyframeAUstreamOffset(); |
---|
582 | |
---|
583 | - // Add key frame to position map |
---|
584 | + // Add keyframe to position map |
---|
585 | positionMapLock.lock(); |
---|
586 | if (!positionMap.contains(frameNum)) |
---|
587 | { |
---|
588 | @@ -1008,7 +1002,19 @@ void DTVRecorder::HandleH264Keyframe(void) |
---|
589 | durationMap[frameNum] = _total_duration + 0.5; |
---|
590 | durationMapDelta[frameNum] = _total_duration + 0.5; |
---|
591 | } |
---|
592 | + if ((_first_keyframe < 0) && !positionMap.contains(0)) |
---|
593 | + { |
---|
594 | + positionMapDelta[0] = 0; |
---|
595 | + positionMap[0] = 0; |
---|
596 | + durationMap[0] = 0.5; |
---|
597 | + durationMapDelta[0] = 0.5; |
---|
598 | + } |
---|
599 | positionMapLock.unlock(); |
---|
600 | + |
---|
601 | + if (_first_keyframe < 0) |
---|
602 | + { |
---|
603 | + _first_keyframe = frameNum; |
---|
604 | + } |
---|
605 | } |
---|
606 | |
---|
607 | void DTVRecorder::FindPSKeyFrames(const uint8_t *buffer, uint len) |
---|
608 | @@ -1074,6 +1080,7 @@ void DTVRecorder::FindPSKeyFrames(const uint8_t *buffer, uint len) |
---|
609 | else if (PESStreamID::SequenceStartCode == stream_id) |
---|
610 | { // pes_packet_length is meaningless |
---|
611 | pes_packet_length = -1; |
---|
612 | + _seen_sps = true; // for mpeg2vid ==SeqStartHeader |
---|
613 | _last_seq_seen = _frames_seen_count; |
---|
614 | hasKeyFrame |= (_last_gop_seen + maxKFD)<_frames_seen_count; |
---|
615 | |
---|
616 | @@ -1328,6 +1335,7 @@ bool DTVRecorder::ProcessTSPacket(const TSPacket &tspacket) |
---|
617 | if (_input_pmt && _has_no_av) |
---|
618 | { |
---|
619 | FindOtherKeyframes(&tspacket); |
---|
620 | + _seen_sps = true; // unblock BufferedWrite() |
---|
621 | _buffer_packets = false; |
---|
622 | } |
---|
623 | else |
---|
624 | @@ -1383,11 +1391,11 @@ bool DTVRecorder::ProcessAudioTSPacket(const TSPacket &tspacket) |
---|
625 | return ProcessAVTSPacket(tspacket); |
---|
626 | } |
---|
627 | |
---|
628 | -/// Common code for processing either audio or video packets |
---|
629 | +/// Common code for processing either audio or video packets (mpeg2 or h264) |
---|
630 | bool DTVRecorder::ProcessAVTSPacket(const TSPacket &tspacket) |
---|
631 | { |
---|
632 | - // Sync recording start to first keyframe |
---|
633 | - if (_wait_for_keyframe_option && _first_keyframe < 0) |
---|
634 | + // Sync recording start to first SPS / keyframe |
---|
635 | + if (_wait_for_keyframe_option && !_seen_sps && _first_keyframe < 0) |
---|
636 | { |
---|
637 | if (_buffer_packets) |
---|
638 | BufferedWrite(tspacket); |
---|