Ticket #11435: git_diff3.txt

File git_diff3.txt, 23.8 KB (added by blm-ubunet@…, 13 years ago)

git diff to master ; added some mpeg2 video changes etc

Line 
1diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
2index 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 {
14diff --git a/mythtv/libs/libmythtv/mpeg/H264Parser.cpp b/mythtv/libs/libmythtv/mpeg/H264Parser.cpp
15index 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:
317diff --git a/mythtv/libs/libmythtv/mpeg/H264Parser.h b/mythtv/libs/libmythtv/mpeg/H264Parser.h
318index 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
384diff --git a/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp b/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp
385index 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);