justdan96 / tsMuxer

tsMuxer is a transport stream muxer for remuxing/muxing elementary streams, EVO/VOB/MPG, MKV/MKA, MP4/MOV, TS, M2TS to TS to M2TS. Supported video codecs H.264/AVC, H.265/HEVC, VC-1, MPEG2. Supported audio codecs AAC, AC3 / E-AC3(DD+), DTS/ DTS-HD.
Apache License 2.0
863 stars 144 forks source link

EAC3 muxing is not working correctly in newer versions #682

Closed DreckSoft closed 1 year ago

DreckSoft commented 1 year ago

This will be a longer issue. I try to include all the information needed.

Short version: BD-Discs containing (only) EAC3 audio created with tsMuxeR 1.10.6 work, those with the current nightly do not.

Long version: Prequel: I'm trying to find a way, to create UHD BD with free tools. The idea was to create a BD in MultiAVCHD and then replace the streams with the 4k ones and fix everything in BDEdit. It kinda works but I do not get any audio on my hardware player (works in PowerDVD). So to do one step at a time I did go back to the 1080p files and create a properly working BD first.

I did the BD version in MultiAVCHD. The disc plays with sound in my player. However, I had issues with seeking (fast forward / jump to chapter). I don't know why as it worked with other files before using the same method. The I remuxed all the files with a recent version of tsMuxeR (MultiAVCHD uses 1.10.6). Now seeking works but there is no audio at all. The audio tracks are 640kbit EAC3 files without AC3 core. Yes, I know that is not standard compliant but as you can see it works with an old version of tsMuxeR (if I mux the files manually and replace them also without seeking issues). I did several tests and created various discs with just tsMuxeR, so just one title, no menus. H264 video stream 1920x1080 2 EAC3 640kbit audio tracks 2 subtitle tracks

  1. Muxing with 1.10.6 as BD and burn on BD => works
  2. Muxing with Nightly as BD and burn on BD => no audio
  3. Muxing with Nightly as BD and burn on DVD => does not play at all
  4. Muxing with Nightly as AVCHD and burn on BD => no audio
  5. Muxing with Nightly as AVCHD and burn on DVD => works (this is strange)

I have no clue why (5) works.

Seems I have a very picky player (Panasonic DP-UB824) but I don't have anything else to test. In PowerDVD it works.

2nd test 1st audio track is now AC3

  1. Muxing with Nightly as BD and burn on BD => AC3 plays, no audio after switching to EAC3 and the player takes ages to react to any key presses after that
  2. Muxing with 1.10.6 as BD and burn on BD => works (all tracks)
jcdr428 commented 1 year ago

@DreckSoft Is 2.6.12 working ? Is any release of tsMuxer open source working ?

DreckSoft commented 1 year ago

2.6.12 completely messes up EAC3:

Network Optix tsMuxeR. Version 2.6.12. www.networkoptix.com Decoding H264 stream (track 1): Profile: High@4.0 Resolution: 1920:1080p Frame rate: 24 H.264 muxing fps is not set. Get fps from stream. Value: 24 B-pyramid level 1 detected. Shift DTS to 2 frames 0.0% complete H264 bitstream changed: insert nal unit delimiters H264 bitstream changed: insert pict timing and buffering period SEI units Decoding E-AC3 (DD+) stream (track 2): Bitrate: 640Kbps (core 0Kbps) Sample Rate: 48KHz Channels: 0 Decoding E-AC3 (DD+) stream (track 3): Bitrate: 1817211Kbps (core 1817199Kbps) Sample Rate: 0KHz Channels: 116.1 Decoding PGS stream (track 4): Resolution: 1920:1080 Frame rate: 24 Decoding PGS stream (track 5): Resolution: 1920:1080 Frame rate: 24 H264 bitstream changed: insert SPS/PPS units 91.1% complete Processed 75199 video frames 100.0% complete Flushing write buffer Creating Blu-ray stream info and seek index Creating Blu-ray playlist Mux successful complete Muxing time: 40 sec

BDEdit

DreckSoft commented 1 year ago

The first release here (2019-12-16) does also not work. But at least the entries in Clipinf are correct (again)

DreckSoft commented 1 year ago

The difference must be in the M2TS, not the MPLS or CLPI. I edited the two files in BDEdit changing the audio to DD, save and change it back to DD+. The old mux (1.10.6) still works, the newer still won't.

I then copied the M2TS from the old version into the directory of the newer version, having all files except the M2TS from the newer version and it still works. It breaks seeking cause the CLPI won't match the M2TS but the audio is there.

So the old version must use a different descriptor, stream id or something similar than the newer version. The file size of the M2TS also differs by about 40MB using a 100% identical input.

DreckSoft commented 1 year ago

I've uploaded two advanced outputs from MediaInfo. There are quite some differences in the M2TS. Hopefully that helps.

Old.txt New.txt

Seems the old version is muxing EAC3 as AC3. Edit: No, the codec ID is correct, just the descriptor says AC3.

DreckSoft commented 1 year ago

I just compiled a patched version which sets the format_identifier to AC-3. This does not work either. However, I have issues compiling an unmodified version of tsMuxeR in Windows.

I need to add #include <cstring> to lpcmStreamReader.cpp but that seems to lead to some strange issue that some descriptors are not set correctly. See: https://github.com/justdan96/tsMuxer/issues/675

MediaInfo with patched version: Patch.txt

DreckSoft commented 1 year ago

The main difference between the two versions seems to be the first ID. It is 1 (0x1) in the old version and 0 (0x0) in the new version. Does anyone know where this ID is set? I couldn't find it with a quick search.

See Old.txt / New.txt from two comments above.

jcdr428 commented 1 year ago

The ID is set in tsMuxer.cpp lines 230-242 and 264. The ID for pure EAC3 might need to be different for each AVCHD, TS, M2TS, Bluray V2 and Bluray V3.

DreckSoft commented 1 year ago

Thanks but I did not mean the codec ID, I found those.

General Count : 333 Count of stream of this kind : 1 Kind of stream : General Kind of stream : General Stream identifier : 0 Inform : BDAV: 2.87 GiB, 52 min 13 s ID : 0 ID : 0 (0x0)

That's from MediaInfo. I want to change the ID 0 (0x0) to 1 (0x1) like the old tsMuxeR. This is likely not compliant but I just want to get it working (again) even if it is not up to specs.

jcdr428 commented 1 year ago

Ok, so it might be the PAT transport_stream_id, set to 0 at line 1141 of tsMuxer.cpp H.222 2.4.4.6 says "Its value is defined by the user". Bluray specs say "This field has no meaning in the HDMV TS and may take any value". Its value is set to 0 in all Blu-rays I've checked. But as you say, a Blu-ray with pure EAC3 does not exist...

DreckSoft commented 1 year ago

Thanks. First test was also unsuccessful though. Now I'll try to combine the patches to make the TS look as much as possible like 1.10.6. But I fear that the newer versions have some fundamental changes to the TS structure.

DreckSoft commented 1 year ago

I now patched everything to look as close to 1.10.6 as possible but still no luck. I'm out of ideas.

jcdr428 commented 1 year ago

@DreckSoft what is the difference you are seeking, is it EAC3 AVCHD mux 1.10.6 vs latest ?

DreckSoft commented 1 year ago

Yes. It works in my player when I mux with 1.10.6 but won't with any open source version. As I'm also trying to create 4k discs I need a newer version that works.

jcdr428 commented 1 year ago

@DreckSoft you probably just need to trick the player by changing the EAC3 descriptor back to an AC-3 descriptor. Try commenting out line 71 of ac3StreamReader.cpp (// if (isAC3())

Edit: I don't know whether other bluray players recognize the ATSC EAC3 descriptor: I would need more users to report before changing the descriptor to AC-3 for bluray mode.

Edit2: on second thought, I have pushed the change: please try tomorrow's release.

DreckSoft commented 1 year ago

Thanks but I already tried that too. It does not make a difference (just re-tested).

I saw several subtypes defined in AC3StreamReader::writePESExtension. I'm not sure if those are correct. First 0x72 should be E-AC3, then the same magic number is TrueHD. But I don't have any clue what exactly is set there.

Would it help if I provide two example BD structures from old and new tsMuxeR?

jcdr428 commented 1 year ago

Yes please provide, i'll have a look.

DreckSoft commented 1 year ago

Here it is: https://anonfiles.com/acZ4R2c4z1/multiAVCHD_Out_7z

DreckSoft commented 1 year ago

I just tried remuxing the 00000.m2ts using tsRemux: https://github.com/antiochus/tsremux After that, EAC3 playback works (again). I also did adjust the packet size in the clpi with BDEdit.

Settings: Keep all streams Output Format: M2TS Bypass Audio Alignment: Off Use async I/O: On

I would really like get rid of the two extra steps. And it will not work with UHD/HEVC video cause tsRemux won't recognize those.

DreckSoft commented 1 year ago

tsRemux seems to do it differently from old tsMuxeR versions. It sets E-AC3 codec ID to 129 instead of 131. However, changing this in recent tsMuxeR versions won't help either.

jcdr428 commented 1 year ago

Here it is: https://anonfiles.com/acZ4R2c4z1/multiAVCHD_Out_7z

You did not use the latest release to output the Example_TSMuxerNightly. As advised four days ago, I pushed a change to keep the AC-3 descriptor instead of the EAC3 one in Bluray/AVCHD mode.

DreckSoft commented 1 year ago

I can do a new mux with the latest version but the behavior in my player is exactly the same. I tried it with your change. It has to do something the structure. I tried a ton of things and nothing works except the old tsMuxer and tsRemux - both can't handle 4k which is what I'll need in the second step.

DreckSoft commented 1 year ago

Here's a new mux: https://anonfiles.com/l31dL2d8z2/multiAVCHD_Out_7z

This time I also included the mux from MultiAVCHD including the META file it uses.

DreckSoft commented 1 year ago

And here with a remux of the Nightly tsMuxeR with tsRemux: https://anonfiles.com/k6B8L1d1z1/multiAVCHD_Out_7z

jcdr428 commented 1 year ago

@DreckSoft the difference seems to be that tsRemux puts the 0x81 stream_type descriptor for EAC3, whereas tsMuxer puts 0x84. Bluray specs are clear: image AVCHD specs might be different, as AVCHD is supposed to know AC-3 only. Please try changing StreamType::AUDIO_EAC3 with StreamType::AUDIO_AC3 on line 343 of tsMuxer.cpp (last release) to see whether this solves your issue. If it does, I'll find a way to change the stream_type for AVCHD only.

DreckSoft commented 1 year ago

That does also not make any difference.

Regarding to tsRemux: I don't think it is the descriptors. I also patched tsMuxeR to handle everything like AC3, so the muxing was AC3, the descriptors were AC3, the codec ID was AC3 - did not work. It has be something deeper inside how the stream is created. Maybe a different interleaving, maybe some meta-data MediaInfo does not display. Maybe something in the support tables (PAT,PMT,PCR, ...)

DreckSoft commented 1 year ago

Please ignore the tsRemux file for now. I seem to have issues with that two. I'll need to recheck and maybe create a new file.

DreckSoft commented 1 year ago

Here's a new set including AVCHD mux from the new version: https://anonfiles.com/waO0Z5d5zd/multiAVCHD_Out_7z

Currently I'm unable to reproduce the working result(s) from tsRemux. So please ingore all tsRemux files from the previous uploads. I'm not 100% sure I copied the correct file.

I'll check out DVBInspector and see what I can find.

DreckSoft commented 1 year ago

Here's a set from tsRemux that is playing: https://anonfiles.com/j6P2a5efz6/multiAVCHD_Out_tsRemux_7z

Note that this uses a different source file as tsRemux seems to only produce a usable output if there is at least one PGS stream present. Also the only working version is 0.0.21.2. Newer versions (including the one I pointed to earlier) do NOT work.

DreckSoft commented 1 year ago

tsRemux 0.21.2 NOT tsMuxeR. I just wanted to provide a second set of working files.

DreckSoft commented 1 year ago

Why shouldn't it? AC3 inside EAC3 was just a fallback for the very beginning. If the equipment was EAC3 capable the AC3 part was never used. And most newer players also offer USB or network playing and those files usually have EAC3 ONLY.

DreckSoft commented 1 year ago

No, it's not a separate track but interleaved in EAC3 or TrueHD. However, the AC3 part is not used for decoding EAC3 and I also think not for TrueHD. That was DTS-HD that uses the core for decoding the HD part.

The old tsMuxeR did tag it as 0x84. Only the format identifier was AC-3 instead of EAC3. tsRemux even sets the format identifier correctly and it works.

Hellboy00000 commented 1 year ago

Blu-ray with pure EAC3 does not exist

First "Dolby Digital Plus" is EAC3 right?

I don't know much about this but "Puss in Boots: The Last Wish" Blu-ray have EAC3 https://www.blu-ray.com/movies/Puss-in-Boots-The-Last-Wish-Blu-ray/329494/

jcdr428 commented 1 year ago

@DreckSoft the problem might come from the transport_priority flag: it must be set to 1 for independent substreams.

Edit:

Many Blu-rays have EAC3. They all do not have strmtyp: 0 though as used in pure EAC3.

Drecksoft seems to confirm that his Panasonic player reads the DD+ with a strmtyp 0. Would be interesting to know whether this is the case with all DD+ compatible players.

DreckSoft commented 1 year ago

Has this changed between 1.10.6 and open source versions? Can you tell me where it's set? The I'll do a local patch and test.

jcdr428 commented 1 year ago

So of course it is logical it must support all types of EAC3

What I mean is: will the player play the bluray disk if replacing the ac3 legacy independant substream with an eac3 independant substream (strmtyp 2) ?

DreckSoft commented 1 year ago

Old LG players won't even play BD-R. They removed it on purpose with a firmware update. Newer ones could read them again and I think at least the UP970 could play EAC3 type 2.

DreckSoft commented 1 year ago

I re-tried the latest version with the fix: Always write PAT PMT PCR in the beginning of the stream (#688) But still the same.

Is there an easy way to change the stream type? I mean muxing EAC3 as AC3 didn't help either and that should have resulted in an independent stream but maybe there's something else?

jcdr428 commented 1 year ago

@DreckSoft as stated above, problem most likely comes from the transport_priority flag.

DreckSoft commented 1 year ago

That does not seem to be easy to patch. I tried returning always true for AC3StreamReader::isPriorityData but that didn't work.

jcdr428 commented 1 year ago

@DreckSoft I had a quick look as well, and yes it seems complicated to patch.

Edit: please try replacement of line 14 of ac3StreamReader.cpp as follows (in the latest release), and report: return (packet->size >= 2 && packet->data[0] == 0x0B && packet->data[1] == 0x77 && m_strmtyp != 1);

strmtyp 0 = independant eac3 frame strmtyp 1 = dependant eac3 frame strmtyp 2 = independant ac3 frame transport_priority must be 1 for independant eac3 or ac3 frames.

DreckSoft commented 1 year ago

The line already looked like that. I then removed "&& m_strmtyp != 1" and now it plays. I will do more tests to ensure I didn't mix up files or something like that.

jcdr428 commented 1 year ago

I then removed "&& m_strmtyp != 1" and now it plays.

Bizarre... Dependent substreams are not supposed to have transport_priority enabled.

DreckSoft commented 1 year ago

Maybe the stream is incorrectly recognized?

Btw: I just muxed an UHD BD with working EAC3 so this works but removing the constraint could cause other issues.

jcdr428 commented 1 year ago

Excerpt from Blu-Ray spec: image

But then as you say, this is for AC3+EAC3. So with full EAC3 this is 'undefined behavior': we would need to know how the Sony and LG players behave to implement the change.

DreckSoft commented 1 year ago

That actually makes sense. The player looks for the priority frame first. If there is no priority frame, then there is no playback at all. So for pure EAC3 I think this MUST be set to 1.

jcdr428 commented 1 year ago

@DreckSoft the only purpose of transport_priority = 1 is to show priority over other packets with the same PID having transport_priority = 0. So for me it does not really make sense to have all packets =1. image I'll try to find some samples of TS with EAC3 from reputable sources.

DreckSoft commented 1 year ago

Maybe but I assume for audio decoding the player (or at least Panasonic) look for transport_priority = 1 audio frames first and then subsequently looking for the "non priority" frames. If there is none with transport_priority = 1 (as it is the case with pure EAC3) there will be no decoding. With AC3 also all frames would be transport_priority = 1. So that is consistent.

DreckSoft commented 1 year ago

Not with EAC3 where the EAC3 stream is dependent on the AC3 stream. First it need the AC3 part to decode and then "add" the EAC3 part. So there will always be a part of the audio stream with transport_priority = 1. transport_priority = 0 are just "add-on packets".

I assume with DTS-HD the core has transport_priority = 1 and the HD part has transport_priority = 0?

DreckSoft commented 1 year ago

Even if the specs say something different, shouldn't we adapt to the real world scenarios? Like Linux emulating Windows Bugs (!) with ACPI tables so systems "just work"?