diff --git a/mythtv/libs/libmythtv/avformatdecoder.cpp b/mythtv/libs/libmythtv/avformatdecoder.cpp
index 3a42b40..f61a8fa 100644
a
|
b
|
AvFormatDecoder::AvFormatDecoder(MythPlayer *parent, |
427 | 427 | |
428 | 428 | cc608_build_parity_table(cc608_parity_table); |
429 | 429 | |
430 | | SetIdrOnlyKeyframes(true); |
| 430 | SetIdrOnlyKeyframes(false); |
431 | 431 | |
432 | 432 | LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString("PlayerFlags: 0x%1") |
433 | 433 | .arg(playerFlags, 0, 16)); |
… |
… |
int AvFormatDecoder::H264PreProcessPkt(AVStream *stream, AVPacket *pkt) |
3354 | 3354 | if (m_h264_parser->onFrameStart()) |
3355 | 3355 | ++num_frames; |
3356 | 3356 | |
3357 | | if (!m_h264_parser->onKeyFrameStart()) |
| 3357 | if (!m_h264_parser->onKeyFrameStart() || !m_h264_parser->seen_SPS()) |
3358 | 3358 | continue; |
3359 | 3359 | } |
3360 | 3360 | else |
diff --git a/mythtv/libs/libmythtv/mpeg/H264Parser.cpp b/mythtv/libs/libmythtv/mpeg/H264Parser.cpp
index d0eebde..db79855 100644
a
|
b
|
void H264Parser::Reset(void) |
115 | 115 | slice_type = SLICE_UNDEF; |
116 | 116 | prev_pic_parameter_set_id = pic_parameter_set_id = -1; |
117 | 117 | prev_field_pic_flag = field_pic_flag = -1; |
118 | | prev_bottom_field_flag = bottom_field_flag = -1; |
119 | | prev_nal_ref_idc = nal_ref_idc = 111; // != [0|1|2|3] |
120 | | prev_pic_order_cnt_type = pic_order_cnt_type = |
| 118 | prev_bottom_field_flag = bottom_field_flag = 0; |
| 119 | prev_nal_ref_idc = nal_ref_idc = 0; |
| 120 | prev_pic_order_cnt_type = pic_order_cnt_type = 0; |
121 | 121 | prev_pic_order_cnt_lsb = pic_order_cnt_lsb = 0; |
122 | 122 | prev_delta_pic_order_cnt_bottom = delta_pic_order_cnt_bottom = 0; |
123 | 123 | prev_delta_pic_order_cnt[0] = delta_pic_order_cnt[0] = 0; |
… |
… |
void H264Parser::Reset(void) |
125 | 125 | prev_nal_unit_type = nal_unit_type = UNKNOWN; |
126 | 126 | |
127 | 127 | // The value of idr_pic_id shall be in the range of 0 to 65535, inclusive. |
128 | | prev_idr_pic_id = idr_pic_id = 65536; |
| 128 | prev_idr_pic_id = idr_pic_id = -1; |
129 | 129 | |
130 | 130 | log2_max_frame_num = log2_max_pic_order_cnt_lsb = 0; |
131 | 131 | seq_parameter_set_id = 0; |
… |
… |
void H264Parser::Reset(void) |
146 | 146 | frame_crop_top_offset = frame_crop_bottom_offset = 0; |
147 | 147 | aspect_ratio_idc = 0; |
148 | 148 | sar_width = sar_height = 0; |
149 | | unitsInTick = 0; |
| 149 | prev_unitsInTick = 1; unitsInTick = 0; |
150 | 150 | timeScale = 0; |
151 | 151 | fixedRate = 0; |
| 152 | stream_changed = false; |
152 | 153 | |
153 | 154 | pkt_offset = AU_offset = frame_start_offset = keyframe_start_offset = 0; |
154 | 155 | on_frame = on_key_frame = false; |
… |
… |
bool H264Parser::new_AU(void) |
260 | 261 | |
261 | 262 | */ |
262 | 263 | |
263 | | bool result = false; |
| 264 | bool result = false; |
264 | 265 | |
265 | 266 | if (prev_frame_num != -1) |
266 | 267 | { |
… |
… |
bool H264Parser::new_AU(void) |
273 | 274 | result = true; |
274 | 275 | else if (field_pic_flag != prev_field_pic_flag) |
275 | 276 | result = true; |
276 | | else if ((bottom_field_flag != -1 && prev_bottom_field_flag != -1) && |
| 277 | else if ((bottom_field_flag != 0 && prev_bottom_field_flag != 0) && |
277 | 278 | bottom_field_flag != prev_bottom_field_flag) |
278 | 279 | result = true; |
279 | 280 | else if ((nal_ref_idc == 0 || prev_nal_ref_idc == 0) && |
… |
… |
bool H264Parser::new_AU(void) |
297 | 298 | idr_pic_id != prev_idr_pic_id) |
298 | 299 | result = true; |
299 | 300 | } |
| 301 | result |= au_contains_keyframe_message; |
300 | 302 | |
301 | 303 | prev_frame_num = frame_num; |
302 | 304 | prev_pic_parameter_set_id = pic_parameter_set_id; |
… |
… |
bool H264Parser::decode_Header(GetBitContext *gb) |
639 | 641 | that precedes the current slice in decoding order and has the |
640 | 642 | same value of colour_plane_id. |
641 | 643 | */ |
642 | | /* uint first_mb_in_slice = */ get_ue_golomb(gb); |
| 644 | /* uint first_mb_in_slice = */ get_ue_golomb_long(gb); |
643 | 645 | |
644 | 646 | /* |
645 | 647 | slice_type specifies the coding type of the slice according to |
… |
… |
bool H264Parser::decode_Header(GetBitContext *gb) |
718 | 720 | such IDR access unit shall differ from the idr_pic_id in the |
719 | 721 | second such IDR access unit. The value of idr_pic_id shall be in |
720 | 722 | the range of 0 to 65535, inclusive. |
| 723 | |
| 724 | 7.4.3 |
| 725 | If the current picture is an IDR picture, PrevRefFrameNum is set equal to 0 |
| 726 | but 7.4.1.2.4 says prev_frame_num raw header value is used for AU detection |
| 727 | prev_frame_num = 0; // but only for decoding process |
721 | 728 | */ |
| 729 | |
722 | 730 | if (nal_unit_type == SLICE_IDR) |
723 | 731 | { |
724 | 732 | idr_pic_id = get_ue_golomb(gb); |
725 | 733 | is_keyframe = true; |
726 | 734 | } |
727 | | else |
| 735 | else // option all I frames as keyframes. |
728 | 736 | is_keyframe = (I_is_keyframe && isKeySlice(slice_type)); |
729 | 737 | |
730 | 738 | /* |
… |
… |
void H264Parser::vui_parameters(GetBitContext * gb) |
1261 | 1269 | sar_height = get_bits(gb, 16); |
1262 | 1270 | break; |
1263 | 1271 | } |
| 1272 | if (aspect_ratio_idc != prev_aspect_ratio_idc) |
| 1273 | { |
| 1274 | stream_changed = true; |
| 1275 | prev_aspect_ratio_idc = aspect_ratio_idc; |
| 1276 | } |
1264 | 1277 | } |
1265 | 1278 | else |
1266 | 1279 | sar_width = sar_height = 0; |
… |
… |
void H264Parser::vui_parameters(GetBitContext * gb) |
1291 | 1304 | unitsInTick = get_bits_long(gb, 32); //num_units_in_tick |
1292 | 1305 | timeScale = get_bits_long(gb, 32); //time_scale |
1293 | 1306 | fixedRate = get_bits1(gb); |
| 1307 | if (unitsInTick != prev_unitsInTick) |
| 1308 | { |
| 1309 | stream_changed = true; |
| 1310 | prev_unitsInTick = unitsInTick; |
| 1311 | } |
1294 | 1312 | } |
1295 | 1313 | } |
1296 | 1314 | |
diff --git a/mythtv/libs/libmythtv/mpeg/H264Parser.h b/mythtv/libs/libmythtv/mpeg/H264Parser.h
index ad78946..5874c45 100644
a
|
b
|
class H264Parser { |
94 | 94 | slice_type â 5. |
95 | 95 | */ |
96 | 96 | enum SLICE_type { |
97 | | SLICE_P = 0, |
98 | | SLICE_B = 1, |
99 | | SLICE_I = 2, |
100 | | SLICE_SP = 3, |
101 | | SLICE_SI = 4, |
102 | | SLICE_P_a = 5, |
103 | | SLICE_B_a = 6, |
104 | | SLICE_I_a = 7, |
105 | | SLICE_SP_a = 8, |
106 | | SLICE_SI_a = 9, |
| 97 | SLICE_P = 0, |
| 98 | SLICE_B = 1, |
| 99 | SLICE_I = 2, |
| 100 | SLICE_SP = 3, |
| 101 | SLICE_SI = 4, |
| 102 | SLICE_P_a = 5, |
| 103 | SLICE_B_a = 6, |
| 104 | SLICE_I_a = 7, |
| 105 | SLICE_SP_a = 8, |
| 106 | SLICE_SI_a = 9, |
107 | 107 | SLICE_UNDEF = 10 |
108 | 108 | }; |
109 | 109 | |
110 | 110 | enum frame_type { |
111 | | FRAME = 'F', |
112 | | FIELD_TOP = 'T', |
| 111 | FRAME = 'F', |
| 112 | FIELD_TOP = 'T', |
113 | 113 | FIELD_BOTTOM = 'B' |
114 | 114 | }; |
115 | 115 | |
… |
… |
class H264Parser { |
214 | 214 | bool au_contains_keyframe_message; |
215 | 215 | bool is_keyframe; |
216 | 216 | bool I_is_keyframe; |
| 217 | bool stream_changed; |
217 | 218 | |
218 | 219 | uint32_t sync_accumulator; |
219 | 220 | uint8_t *rbsp_buffer; |
… |
… |
class H264Parser { |
253 | 254 | uint frame_crop_right_offset; |
254 | 255 | uint frame_crop_top_offset; |
255 | 256 | uint frame_crop_bottom_offset; |
256 | | uint8_t aspect_ratio_idc; |
| 257 | uint8_t aspect_ratio_idc, prev_aspect_ratio_idc; |
257 | 258 | uint sar_width, sar_height; |
258 | | uint32_t unitsInTick, timeScale; |
| 259 | uint32_t unitsInTick, prev_unitsInTick, timeScale; |
259 | 260 | bool fixedRate; |
260 | 261 | |
261 | 262 | uint64_t pkt_offset, AU_offset, frame_start_offset, keyframe_start_offset; |
diff --git a/mythtv/libs/libmythtv/mythcommflagplayer.cpp b/mythtv/libs/libmythtv/mythcommflagplayer.cpp
index b521e01..361c051 100644
a
|
b
|
bool MythCommFlagPlayer::RebuildSeekTable( |
106 | 106 | cout << "\r \r" << flush; |
107 | 107 | |
108 | 108 | int prevperc = -1; |
109 | | bool usingIframes = false; |
| 109 | bool usingIframes = true; |
110 | 110 | while (GetEof() == kEofStateNone) |
111 | 111 | { |
112 | 112 | if (inuse_timer.elapsed() > 2534) |
… |
… |
bool MythCommFlagPlayer::RebuildSeekTable( |
182 | 182 | if (DecoderGetFrame(kDecodeNothing,true)) |
183 | 183 | myFramesPlayed = decoder->GetFramesRead(); |
184 | 184 | |
185 | | // H.264 recordings from an HD-PVR contain IDR keyframes, |
186 | | // which are the only valid cut points for lossless cuts. |
187 | | // However, DVB-S h.264 recordings may lack IDR keyframes, in |
188 | | // which case we need to allow non-IDR I-frames. If we get |
189 | | // far enough into the rebuild without having created any |
190 | | // seektable entries, we can assume it is because of the IDR |
191 | | // keyframe setting, and so we rewind and allow h.264 non-IDR |
192 | | // I-frames to be treated as keyframes. |
| 185 | // H.264 recordings from an HD-PVR contain IDR keyframes |
| 186 | // and are the only valid cut points for lossless cuts. |
| 187 | // DVB-S(2)/T(2) H.264 recordings typically do not use |
| 188 | // IDR keyframes & do not use I frames as keyframes. |
| 189 | // If we get far enough into the rebuild without having created any |
| 190 | // seektable entries, we assume it is because of the IDR |
| 191 | // keyframe setting, and so we rewind and allow H.264 IDR |
| 192 | // (HD-PVR type) detection. |
193 | 193 | uint64_t frames = decoder->GetFramesRead(); |
194 | | if (!usingIframes && |
195 | | (GetEof() != kEofStateNone || (frames > 1000 && frames < 1100)) && |
| 194 | if (usingIframes && |
| 195 | (GetEof() != kEofStateNone || (frames > 1000 && frames < 1100)) && |
196 | 196 | !decoder->HasPositionMap()) |
197 | 197 | { |
198 | | cout << "No I-frames found, rewinding..." << endl; |
| 198 | cout << "No non-IDR keyframes found, rewinding..." << endl; |
199 | 199 | decoder->DoRewind(0); |
200 | 200 | decoder->Reset(true, true, true); |
201 | 201 | pmap_first = pmap_last = myFramesPlayed = 0; |
202 | | decoder->SetIdrOnlyKeyframes(false); |
203 | | usingIframes = true; |
| 202 | decoder->SetIdrOnlyKeyframes(true); |
| 203 | usingIframes = false; |
204 | 204 | } |
205 | 205 | } |
206 | 206 | |