| 4611 | |
| 4612 | |
| 4613 | static int hb_ts_stream_find_pids(hb_stream_t *stream) |
| 4614 | { |
| 4615 | // To be different from every other broadcaster in the world, New Zealand TV |
| 4616 | // changes PMTs (and thus video & audio PIDs) when 'programs' change. Since |
| 4617 | // we may have the tail of the previous program at the beginning of this |
| 4618 | // file, take our PMT from the middle of the file. |
| 4619 | fseeko(stream->file_handle, 0, SEEK_END); |
| 4620 | uint64_t fsize = ftello(stream->file_handle); |
| 4621 | fseeko(stream->file_handle, fsize >> 1, SEEK_SET); |
| 4622 | align_to_next_packet(stream); |
| 4623 | |
| 4624 | // Read the Transport Stream Packets (188 bytes each) looking at first for PID 0 (the PAT PID), then decode that |
| 4625 | // to find the program map PID and then decode that to get the list of audio and video PIDs |
| 4626 | |
| 4627 | for (;;) |
| 4628 | { |
| 4629 | const uint8_t *buf = next_packet( stream ); |
| 4630 | |
| 4631 | if ( buf == NULL ) |
| 4632 | { |
| 4633 | hb_log("hb_ts_stream_find_pids - end of file"); |
| 4634 | break; |
| 4635 | } |
| 4636 | |
| 4637 | // Get pid |
| 4638 | int pid = (((buf[1] & 0x1F) << 8) | buf[2]) & 0x1FFF; |
| 4639 | |
| 4640 | if ((pid == 0x0000) && (stream->ts_number_pat_entries == 0)) |
| 4641 | { |
| 4642 | decode_PAT(buf, stream); |
| 4643 | continue; |
| 4644 | } |
| 4645 | |
| 4646 | int pat_index = 0; |
| 4647 | for (pat_index = 0; pat_index < stream->ts_number_pat_entries; pat_index++) |
| 4648 | { |
| 4649 | // There are some streams where the PAT table has multiple |
| 4650 | // entries as if their are multiple programs in the same |
| 4651 | // transport stream, and yet there's actually only one |
| 4652 | // program really in the stream. This seems to be true for |
| 4653 | // transport streams that originate in the HDHomeRun but have |
| 4654 | // been output by EyeTV's export utility. What I think is |
| 4655 | // happening is that the HDHomeRun is sending the entire |
| 4656 | // transport stream as broadcast, but the EyeTV is only |
| 4657 | // recording a single (selected) program number and not |
| 4658 | // rewriting the PAT info on export to match what's actually |
| 4659 | // on the stream. Until we have a way of handling multiple |
| 4660 | // programs per transport stream elegantly we'll match on the |
| 4661 | // first pat entry for which we find a matching program map PID. |
| 4662 | // The ideal solution would be to build a title choice popup |
| 4663 | // from the PAT program number details and then select from |
| 4664 | // their - but right now the API's not capable of that. |
| 4665 | if (stream->pat_info[pat_index].program_number != 0 && |
| 4666 | pid == stream->pat_info[pat_index].program_map_PID) |
| 4667 | { |
| 4668 | if (build_program_map(buf, stream) > 0) |
| 4669 | { |
| 4670 | break; |
no test coverage detected