Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
15th October 2007, 17:35 | #762 | Link |
Registered Developer
Join Date: Sep 2006
Posts: 9,140
|
I'm sorry to say but there's another hang issue with "aften_encode_close" which is not properly handled by aften.c yet. Try this:
Code:
aften_encode_init(...); aften_encode_close(...); |
15th October 2007, 17:40 | #763 | Link |
HeadAC3he coder
Join Date: Oct 2001
Posts: 413
|
Right, this one is evil. And yes, this pattern should be allowed. I probably won't be able to fix it before the week-end, as I am busy with work. But thx for pointing this out.
Last edited by DarkAvenger; 15th October 2007 at 17:54. |
15th October 2007, 18:07 | #764 | Link |
Registered Developer
Join Date: Sep 2006
Posts: 9,140
|
The sample code in "API.txt" needs to be changed, too, I think. If "read_samples" returns 0, there'll be a hang.
You don't need to hurry about this. I know how to work around it. But my destructor is getting longer and longer. For giggles, here's my latest destructor code, which has now successfully passed all my tests: Code:
destructor TAftenEncoder.Destroy; var dummySamples : pointer; i1 : integer; begin if FValid then begin if (not FInitialized) and (FLastResult = -777) then begin // the encoder has not been fed any real samples yet // we need to do that, or else "aften_encode_close" will hang GetMem(dummySamples, FBytesPerFrame); FLastResult := aften_encode_frame(FContext, FBuf, dummySamples); FreeMem(dummySamples); end; if (not FInitialized) and (FLastResult = 0) then // encoder has not yet returned any valid AC3 frames // but it was already fed with real PCM samples // a call to "aften_encode_close" would hang in this situation // so we feed the encoder with samples until we receive a valid frame for i1 := 0 to 15 do begin FLastResult := aften_encode_frame(FContext, FBuf, nil); if FLastResult <> 0 then break; end; while FLastResult > 0 do // the last time the encoder was called we got a valid AC3 frame back // when encoding is aborted there may still be AC3 frames in the queue // a call to "aften_encode_close" would hang in this situation // so we fetch all AC3 frames from the queue until there's nothing left FLastResult := aften_encode_frame(FContext, FBuf, nil); // finally we can safely close the encoder down <sigh> aften_encode_close(FContext); VirtualFree(FBuf, 0, MEM_RELEASE); end; inherited; end; And there's another reason why I'm still not feeling well with all this destructor code: The whole destructing logic might be confused if "aften_encode_frame" keeps on returning error codes. What do I need to do in that case to properly shut aften down? Do I still need to feed the encoder until all threads are busy? Do I still need to empty the queue? If "aften_encode_frame" keeps on returning error codes, I might have to call "aften_encode_close" without ever having filled/freed the encoding queue. In that case I might again have a hang. Now I don't know in which situation exactly "aften_encode_frame" could return error codes. Maybe it will never happen (as long as there are no bugs in my code). But what do I know? Maybe if memory is short (so allocations fail) I'll have no other choice than to run into a hang because I simply can't empty the encoding queue? |
15th October 2007, 22:04 | #765 | Link |
HeadAC3he coder
Join Date: Oct 2001
Posts: 413
|
Well, I thought I had implemented it that way that the encoder will shut the threads down, if an error had happened.but looking again, I don't think it works that way... Man, you are cruel.
[Edit] Oh yes, it should work that way: On error in encoding routine, the encoder does shut down all threads, ie. if you get a negative value back from the encoder, you should be able to safely call the close function. You mustn't call the encode function after an error condition. Last edited by DarkAvenger; 15th October 2007 at 22:15. |
16th October 2007, 08:17 | #766 | Link | ||
Registered Developer
Join Date: Sep 2006
Posts: 9,140
|
Quote:
Quote:
|
||
16th October 2007, 17:53 | #767 | Link |
HeadAC3he coder
Join Date: Oct 2001
Posts: 413
|
I may have found an easy solution for the closing issue. Perhaps you can clean-up your dtor. Pleaser test. I haven't verified it thoroughly as I am quite tired. Furthmore error handling is missing (the close function should return, whether it was a clean close or not, ie if threads were running). And aften.c still doesn't clean up ressources thoroughly if it bails out early.
|
17th October 2007, 06:25 | #769 | Link | |
Registered User
Join Date: Nov 2006
Posts: 161
|
Quote:
https://sourceforge.net/project/show...ease_id=547576 |
|
19th October 2007, 19:02 | #771 | Link |
Registered Developer
Join Date: Sep 2006
Posts: 9,140
|
@wisodev, thanks for the new build!
@DarkAvenger, finally got around testing your changes. On a first check everything seemed to work beautifully. Unfortunately on the very last test I got a hang again. Then it was gone. Then it came back. Then I changed the test conditions and libAften crashed during aften_encode_close (it had worked in an earlier test). So it seems to me that the shutdown is not really stable yet. It often works. Then suddenly the same test which worked before hangs or crashes again. Wouldn't it be the safest solution to just move all the loops and checks that are currently in aften.c to aften_encode_close? Basically what you told me to do my in destructor - couldn't you do all of that in the beginning of aften_encode_close? Of course libAften would then internally need to keep track on whether aften_encode_frame was called often enough with real samples and with NULL and what the last aften_encode_frame had returned etc. But I guess that shouldn't be too hard? Adding the pad functionality to libAften sounds like a good idea to me. I welcome any change which simplifies the API. |
19th October 2007, 23:03 | #773 | Link | |
Registered Developer
Join Date: Sep 2006
Posts: 9,140
|
Quote:
(1) init (2) close Got a hang this time. Tried it 3 times. Got hangs 3 times. Recompiled. Tried again. Hang gone. Then I changed it to this: (1) init (2) one encode_frame(real samples) call (3) close Got a crash this time in libAften.dll. Tried it 3 times. Got 3 crashes. Recompiled. Still crash. All of this worked perfectly fine in my first test run. So I guess reproducing it might be tricky. It's probably a timing problem. (P.S: Might be that I confuse the 2 tests above. Maybe the first one had crashes and the 2nd hangs. Not sure...) Ehm... wisodev? |
|
20th October 2007, 13:59 | #776 | Link |
HeadAC3he coder
Join Date: Oct 2001
Posts: 413
|
It is C and svn. :P Anyway, you don't have look at the code...using cmake to just compile it doesn't require a lot of skills.
Anyway, I committed a hopefully now really fixed version. The big bug was quite embarassing and perfectly explains your findings: mdct buffers should be freed *after* flushing the encoder... |
21st October 2007, 12:45 | #778 | Link |
HeadAC3he coder
Join Date: Oct 2001
Posts: 413
|
So I moved the padding functionality into libaften (and also fixed aften.c to be able to encode files < 256 samples w/o padding. I didn't test this, though.) Just provide the first 256 samples in AftenContext's new member initial_samples and then no padding with zero samples happens.
|
22nd October 2007, 13:33 | #779 | Link | |
Registered User
Join Date: Nov 2006
Posts: 161
|
I have released version 0.8 of WAV to AC3 Encoder (sf.net shell service is offline so website was not updated).
Download Binary Package: Win32 Unicode | Win32 Ansi | Win64 Unicode | Win64 Ansi Installer Package: Win32 Unicode | Win32 Ansi | Win64 Unicode | Win64 Ansi Source Package: Visual C++ 2005 SP1 Changelog Quote:
Thanks, wisodev |
|
|
|