Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chained streams #667

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
Open

chained streams #667

wants to merge 10 commits into from

Conversation

philippe44
Copy link

@philippe44 philippe44 commented Jan 19, 2024

This is probably not yet an acceptable PR but getting closer and I wanted to know if this goes into the right direction for you.

Beyond the simple, dirty hack that is to reset serial number on page EoS which works but creates some sync issue for new metadata headers that are missed, this PR tries to properly handle chained stream.

I realized that the difference of data acquisition where flac pulls and ogg pushes creates a real challenge and I wanted to minimize modification to code. What happens is that when EoS is detected in the ogg decoder, we have no idea when that packet (audio frame) will be processed by the flac decoder. When it pulls 8kB of data, it could contain 2 remaining audio frames, then the streaminfo/vorbis/.. and audio frame for the next stream, alltogether. The ogg decoder has detected EoS but for the flac decoder, we are far from being there.

So it's easy to stop the ogg decoder when it has sent all packets of the EoS page but we still cannot instruct yet the flac decoder to self-reset because we don't know how many frames are in its internal buffer, although the read callback has sent everything. The only solution I found is to block ogg decoder once it has sent the last packet of the EoS page and fully "simulate" a FLAC_END_OF_STREAM to the flac decoder. Then we have to wait for flac to re-authorize ogg decoder to grab data once it has detected that end of stream. It's fully hidden to client, even when they decode frame-by-frame. They will not see a return from FLAC__stream_decoder_process_single until we have certainty. Once re-authorized to grab data, a "real" end of stream will be generated if we are really at the end of the stream. Otherwise, the decoder will reset, grab streaminfo and all other metadata headers and start decoding the new stream.

I've now added the boilerplate code to enabme/disable it as well as a --chaining option in flac application. When it is disabled, I don't think a single extra line of code is executed that was not before, so I'm hopeful there is no regression.

@philippe44
Copy link
Author

⬆️ ⬇️ ?

@ktmf01
Copy link
Collaborator

ktmf01 commented Jan 25, 2024

I am currently not able to review this and I probably won't for quite a while. I am not very familiar with the ogg code and as you say it is rather complicated.

@philippe44
Copy link
Author

Understood, no worries. What I'll do then is add the "boiler plate" code so that is complete while it's still fresh in my mind and you can review it at your leisure.

@philippe44 philippe44 mentioned this pull request Jan 27, 2024
@@ -1007,8 +1037,16 @@ FLAC_API FLAC__bool FLAC__stream_decoder_process_single(FLAC__StreamDecoder *dec
else
return true;
case FLAC__STREAM_DECODER_SEARCH_FOR_FRAME_SYNC:
if(!frame_sync_(decoder))
return true; /* above function sets the status for us */
if(!frame_sync_(decoder)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think there might be a way to replace this (and similar) bits of code with more code in ogg_decoder_aspect.c? The current approach 'catches' end of stream in the generic code, but I think it would be nice if the ogg_decoder_aspect code could handle that. More specifically, it would be great if as much handling as possible would be in the function FLAC__ogg_decoder_aspect_read_callback_wrapper

@ktmf01
Copy link
Collaborator

ktmf01 commented Apr 9, 2024

Hi @philippe44, sorry it took quite a while to review this. I think the code looks nice, but it would be even nicer if as much of it as possible would be in FLAC__ogg_decoder_aspect_read_callback_wrapper.

Also, can you explain to me what the last few commits' back-and-forth is supposed to do?

@philippe44
Copy link
Author

No worries, I understand what it is to be a maintainer and thank you for doing it, this is hard as the recent xz issue reminded us.

The latest back and forth was a miserable failure to try to deal with some backlash I had from people using project that required (optionally) my changes and that had to deal with existing libflac for static and dynamic linking. GCC and LLVC offer ways to deal with that at run time but not MSVC and not all versions of GCC. At the end I could not find a good solution so I just added a #define, parking to see what you'd think if/when you had time to review it.

I'll review the rest of your comments soon.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants