Ticket #11435: git_diff.txt

File git_diff.txt, 21.2 KB (added by blm-ubunet@…, 11 years ago)

fresh git diff to master with non-video stream unblocked.

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..35def81 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,6 +792,9 @@ 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@@ -772,7 +807,9 @@ void H264Parser::decode_SPS(GetBitContext * gb)
214     get_bits(gb, 8);    // level_idc
215     get_ue_golomb(gb);  // sps_id
216 
217-    if (profile_idc >= 100)
218+    if (profile_idc == 100 || profile_idc == 110 || profile_idc == 122 ||
219+        profile_idc == 244 || profile_idc == 44  || profile_idc == 83  ||
220+        profile_idc == 86  || profile_idc == 118 || profile_idc == 128 )
221     { // high profile
222         if ((chroma_format_idc = get_ue_golomb(gb)) == 3) // chroma_format_idc
223             separate_colour_plane_flag = (get_bits1(gb) == 1);
224@@ -783,14 +820,19 @@ void H264Parser::decode_SPS(GetBitContext * gb)
225 
226         if (get_bits1(gb))     // seq_scaling_matrix_present_flag
227         {
228-            for (int idx = 0; idx < ((chroma_format_idc != 3) ? 8 : 12); ++idx)
229+            for (int idx = 0; idx < ((chroma_format_idc != 3) ? 8 : 12); idx++)
230             {
231-                if (get_bits1(gb)) // Scaling list presnent
232+                if (get_bits1(gb)) // Scaling list present
233                 {
234+                    lastScale = nextScale = 8;
235                     int sl_n = ((idx < 6) ? 16 : 64);
236                     for(int sl_i = 0; sl_i < sl_n; sl_i++)
237                     {
238-                        get_se_golomb(gb);
239+                        if (nextScale != 0)
240+                        {
241+                            deltaScale = get_se_golomb(gb);
242+                            nextScale = (lastScale + deltaScale + 256) % 256;
243+                        }
244                     }
245                 }
246             }
247@@ -809,6 +851,7 @@ void H264Parser::decode_SPS(GetBitContext * gb)
248     int  offset_for_non_ref_pic;
249     int  offset_for_top_to_bottom_field;
250     uint tmp;
251+    bool gaps_in_frame_num_allowed_flag;
252 
253     /*
254       pic_order_cnt_type specifies the method to decode picture order
255@@ -863,7 +906,7 @@ void H264Parser::decode_SPS(GetBitContext * gb)
256           shall be in the range of -231 to 231 - 1, inclusive.
257          */
258         tmp = get_ue_golomb(gb);
259-        for (uint idx = 0; idx < tmp; ++idx)
260+        for (uint idx = 0; idx < tmp; idx++)
261             get_se_golomb(gb);  // offset_for_ref_frame[i]
262     }
263     (void) offset_for_non_ref_pic; // suppress unused var warning
264@@ -886,8 +929,7 @@ void H264Parser::decode_SPS(GetBitContext * gb)
265       decoding process in case of an inferred gap between values of
266       frame_num as specified in subclause 8.2.5.2.
267      */
268-    //bool gaps_in_frame_num_allowed_flag = get_bits1(gb);
269-    get_bits1(gb); // Replaced above line
270+    gaps_in_frame_num_allowed_flag = get_bits1(gb);
271 
272     /*
273       pic_width_in_mbs_minus1 plus 1 specifies the width of each
274@@ -1040,20 +1082,28 @@ void H264Parser::decode_SEI(GetBitContext *gb)
275     bool  broken_link_flag = false;
276     int   changing_group_slice_idc = -1;
277 
278-    int type = 0, size = 0;
279+    int type = 0, size = 0, tmp_byte = 0;
280 
281     /* A message requires at least 2 bytes, and then
282      * there's the stop bit plus alignment, so there
283      * can be no message in less than 24 bits */
284     while (get_bits_left(gb) >= 24)
285     {
286-        do {
287-            type += show_bits(gb, 8);
288-        } while (get_bits(gb, 8) == 255);
289+        tmp_byte = get_bits(gb, 8);
290+        while (tmp_byte == 255)
291+        {
292+            type += 255;
293+            tmp_byte = get_bits(gb, 8);
294+        }
295+        type += get_bits(gb, 8);   //last_payload_type_byte
296 
297-        do {
298-            size += show_bits(gb, 8);
299-        } while (get_bits(gb, 8) == 255);
300+        tmp_byte = get_bits(gb, 8);
301+        while (tmp_byte == 255)
302+        {
303+            size += 255;
304+            tmp_byte = get_bits(gb, 8);
305+        }
306+        size += get_bits(gb, 8);   //last_payload_size_byte
307 
308         switch (type)
309         {
310@@ -1063,6 +1113,8 @@ void H264Parser::decode_SEI(GetBitContext *gb)
311                 broken_link_flag = get_bits1(gb);
312                 changing_group_slice_idc = get_bits(gb, 2);
313                 au_contains_keyframe_message = (recovery_frame_cnt == 0);
314+                if ((size - 12) > 0)
315+                    skip_bits(gb, (size - 12) * 8);
316                 return;
317 
318             default:
319diff --git a/mythtv/libs/libmythtv/mpeg/H264Parser.h b/mythtv/libs/libmythtv/mpeg/H264Parser.h
320index 9c984e0..7b750f2 100644
321--- a/mythtv/libs/libmythtv/mpeg/H264Parser.h
322+++ b/mythtv/libs/libmythtv/mpeg/H264Parser.h
323@@ -60,7 +60,7 @@ class H264Parser {
324     // ITU-T Rec. H.264 table 7-1
325     enum NAL_unit_type {
326         UNKNOWN         = 0,
327-        SLICE           = 1,
328+        SLICE           = 1,   // 1 - 5 are VCL NAL units
329         SLICE_DPA       = 2,
330         SLICE_DPB       = 3,
331         SLICE_DPC       = 4,
332@@ -73,11 +73,15 @@ class H264Parser {
333         END_STREAM      = 11,
334         FILLER_DATA     = 12,
335         SPS_EXT         = 13,
336-        AUXILIARY_SLICE = 19
337+        NALU_prefix     = 14,
338+        SPS_subset      = 15,
339+        AUXILIARY_SLICE = 19,
340+        SLICE_EXTENSION = 20
341     };
342 
343     enum SEI_type {
344         SEI_TYPE_PIC_TIMING             = 1,
345+        SEI_FILLER_PAYLOAD              = 3,
346         SEI_TYPE_USER_DATA_UNREGISTERED = 5,
347         SEI_TYPE_RECOVERY_POINT         = 6
348     };
349@@ -147,7 +151,9 @@ class H264Parser {
350 
351     uint64_t frameAUstreamOffset(void) const {return frame_start_offset;}
352     uint64_t keyframeAUstreamOffset(void) const {return keyframe_start_offset;}
353+    uint64_t SPSstreamOffset(void) const {return SPS_offset;}
354 
355+// == NAL_type AU_delimiter: primary_pic_type = 5
356     static int isKeySlice(uint slice_type)
357         {
358             return (slice_type == SLICE_I   ||
359@@ -164,6 +170,7 @@ class H264Parser {
360         }
361 
362     void use_I_forKeyframes(bool val) { I_is_keyframe = val; }
363+    bool using_I_forKeyframes(void) const { return I_is_keyframe; }
364 
365     uint32_t GetTimeScale(void) const { return timeScale; }
366 
367@@ -172,6 +179,10 @@ class H264Parser {
368     void parse_SPS(uint8_t *sps, uint32_t sps_size,
369                    bool& interlaced, int32_t& max_ref_frames);
370 
371+    bool seen_SPS(void) const { return seen_sps; }
372+
373+    bool found_AU(void) const { return AU_pending; }
374+
375   private:
376     enum constants {EXTENDED_SAR = 255};
377 
378@@ -247,6 +258,7 @@ class H264Parser {
379     bool       fixedRate;
380 
381     uint64_t   pkt_offset, AU_offset, frame_start_offset, keyframe_start_offset;
382+    uint64_t   SPS_offset;
383     bool       on_frame, on_key_frame;
384 };
385 
386diff --git a/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp b/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp
387index e25774d..b51b3a3 100644
388--- a/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp
389+++ b/mythtv/libs/libmythtv/recorders/dtvrecorder.cpp
390@@ -64,7 +64,7 @@ DTVRecorder::DTVRecorder(TVRec *rec) :
391     _pes_synced(false),
392     _seen_sps(false),
393     // settings
394-    _wait_for_keyframe_option(true),
395+    _wait_for_keyframe_option(true),   // is wait_for_SPS for H264
396     _has_written_other_keyframe(false),
397     // state
398     _error(),
399@@ -276,9 +276,8 @@ void DTVRecorder::BufferedWrite(const TSPacket &tspacket, bool insert)
400 {
401     if (!insert) // PAT/PMT may need inserted in front of any buffered data
402     {
403-        // delay until first GOP to avoid decoder crash on res change
404-        if (!_buffer_packets && _wait_for_keyframe_option &&
405-            _first_keyframe < 0)
406+        // delay until first SPS/GOP to avoid decoder crash on res change
407+        if (!_buffer_packets && _wait_for_keyframe_option && !_seen_sps)
408             return;
409 
410         if (curRecording && timeOfFirstDataIsSet.testAndSetRelaxed(0,1))
411@@ -552,6 +551,7 @@ bool DTVRecorder::FindMPEG2Keyframes(const TSPacket* tspacket)
412             .arg(_payload_buffer.size())
413             .arg(ringBuffer->GetWritePosition() + _payload_buffer.size()));
414 
415+        _seen_sps = true; // used by H264 to signal start rec to file
416         _last_keyframe_seen = _frames_seen_count;
417         HandleKeyframe(0);
418     }
419@@ -718,6 +718,7 @@ bool DTVRecorder::FindAudioKeyframes(const TSPacket*)
420             _audio_timer.start();
421 
422         _buffer_packets = false;
423+        _seen_sps = true;   // unblock BufferedWrite()
424         _frames_seen_count++;
425 
426         if (1 == (_frames_seen_count & 0x7))
427@@ -898,30 +899,38 @@ bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket)
428         uint32_t bytes_used = m_h264_parser.addBytes
429                               (tspacket->data() + i, TSPacket::kSize - i,
430                                ringBuffer->GetWritePosition());
431-        i += (bytes_used - 1);
432 
433-        if (m_h264_parser.stateChanged())
434+        if (!_seen_sps && m_h264_parser.seen_SPS())
435+            _seen_sps = true;
436+
437+        if (m_h264_parser.stateChanged() && _seen_sps)
438         {
439             if (m_h264_parser.onFrameStart() &&
440                 m_h264_parser.FieldType() != H264Parser::FIELD_BOTTOM)
441             {
442                 hasKeyFrame = m_h264_parser.onKeyFrameStart();
443                 hasFrame = true;
444-                _seen_sps |= hasKeyFrame;
445-
446+               
447                 width = m_h264_parser.pictureWidth();
448                 height = m_h264_parser.pictureHeight();
449                 aspectRatio = m_h264_parser.aspectRatio();
450                 m_h264_parser.getFrameRate(frameRate);
451             }
452         }
453+
454+        i += (bytes_used - 1);
455     } // for (; i < TSPacket::kSize; ++i)
456 
457     // _buffer_packets will only be true if a payload start has been seen
458-    if (hasKeyFrame && (_buffer_packets || _first_keyframe >= 0))
459+    if (_seen_sps)
460+        _buffer_packets = false;
461+    else
462+        _payload_buffer.clear();
463+
464+    if (hasKeyFrame)
465     {
466         LOG(VB_RECORD, LOG_DEBUG, LOC + QString
467-            ("Keyframe @ %1 + %2 = %3 AU %4")
468+            ("H264Keyframe @ %1 + %2 = %3 AU %4")
469             .arg(ringBuffer->GetWritePosition())
470             .arg(_payload_buffer.size())
471             .arg(ringBuffer->GetWritePosition() + _payload_buffer.size())
472@@ -934,22 +943,15 @@ bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket)
473     if (hasFrame)
474     {
475         LOG(VB_RECORD, LOG_DEBUG, LOC + QString
476-            ("Frame @ %1 + %2 = %3 AU %4")
477+            ("H264Frame @ %1 + %2 = %3 AU %4")
478             .arg(ringBuffer->GetWritePosition())
479             .arg(_payload_buffer.size())
480             .arg(ringBuffer->GetWritePosition() + _payload_buffer.size())
481-            .arg(m_h264_parser.keyframeAUstreamOffset()));
482+            .arg(m_h264_parser.frameAUstreamOffset()));
483 
484-        _buffer_packets = false;  // We now know if this is a keyframe
485         _frames_seen_count++;
486         if (!_wait_for_keyframe_option || _first_keyframe >= 0)
487             UpdateFramesWritten();
488-        else
489-        {
490-            /* Found a frame that is not a keyframe, and we want to
491-             * start on a keyframe */
492-            _payload_buffer.clear();
493-        }
494     }
495 
496     if ((aspectRatio > 0) && (aspectRatio != m_videoAspect))
497@@ -971,12 +973,12 @@ bool DTVRecorder::FindH264Keyframes(const TSPacket *tspacket)
498             QString("FindH264Keyframes: timescale: %1, tick: %2, framerate: %3")
499                       .arg( m_h264_parser.GetTimeScale() )
500                       .arg( m_h264_parser.GetUnitsInTick() )
501-                      .arg( frameRate.toDouble() * 1000 ) );
502+                      .arg( frameRate.toDouble() ) );
503         m_frameRate = frameRate;
504         FrameRateChange(frameRate.toDouble() * 1000, _frames_written_count);
505     }
506 
507-    return _seen_sps;
508+    return hasKeyFrame;
509 }
510 
511 /** \fn DTVRecorder::HandleH264Keyframe(void)
512@@ -991,15 +993,9 @@ void DTVRecorder::HandleH264Keyframe(void)
513     uint64_t startpos;
514     uint64_t frameNum = _frames_written_count;
515 
516-    if (_first_keyframe < 0)
517-    {
518-        _first_keyframe = frameNum;
519-        startpos = 0;
520-    }
521-    else
522-        startpos = m_h264_parser.keyframeAUstreamOffset();
523+    startpos = m_h264_parser.keyframeAUstreamOffset();
524 
525-    // Add key frame to position map
526+    // Add keyframe to position map
527     positionMapLock.lock();
528     if (!positionMap.contains(frameNum))
529     {
530@@ -1008,7 +1004,19 @@ void DTVRecorder::HandleH264Keyframe(void)
531         durationMap[frameNum]      = _total_duration + 0.5;
532         durationMapDelta[frameNum] = _total_duration + 0.5;
533     }
534+    if ((_first_keyframe < 0) && !positionMap.contains(0))
535+    {
536+        positionMapDelta[0] = 0;
537+        positionMap[0]      = 0;
538+        durationMap[0]      = 0.5;
539+        durationMapDelta[0] = 0.5;
540+    }
541     positionMapLock.unlock();
542+
543+    if (_first_keyframe < 0)
544+    {
545+        _first_keyframe = frameNum;
546+    }
547 }
548 
549 void DTVRecorder::FindPSKeyFrames(const uint8_t *buffer, uint len)
550@@ -1328,6 +1336,7 @@ bool DTVRecorder::ProcessTSPacket(const TSPacket &tspacket)
551     if (_input_pmt && _has_no_av)
552     {
553         FindOtherKeyframes(&tspacket);
554+        _seen_sps = true;   // unblock BufferedWrite()
555         _buffer_packets = false;
556     }
557     else
558@@ -1383,11 +1392,11 @@ bool DTVRecorder::ProcessAudioTSPacket(const TSPacket &tspacket)
559     return ProcessAVTSPacket(tspacket);
560 }
561 
562-/// Common code for processing either audio or video packets
563+/// Common code for processing either audio or video packets (mpeg2 or h264)
564 bool DTVRecorder::ProcessAVTSPacket(const TSPacket &tspacket)
565 {
566-    // Sync recording start to first keyframe
567-    if (_wait_for_keyframe_option && _first_keyframe < 0)
568+    // Sync recording start to first SPS / keyframe
569+    if (_wait_for_keyframe_option && !_seen_sps && _first_keyframe < 0)
570     {
571         if (_buffer_packets)
572             BufferedWrite(tspacket);