Intel® Integrated Performance Primitives
Deliberate problems developing high-performance vision, signal, security, and storage applications.

IPP 7.0.4 H264 error

selea
Beginner
350 Views
I found that updating h264_dec from samples 7.0.3 to samples 7.0.4 can couse issue in multithreaded environment. I think the problem could be in the H264 Initialization table: in 7.0.3 the task was done by a static class. in 7.0.4 the code is moved in the Initialization of the decoder and this could cause the problem when multiple thread try to initialize the h264dec at the same time
0 Kudos
18 Replies
Chao_Y_Intel
Moderator
350 Views

Hello,

Thanks for your report. Do you have test stream that can show this problem? Also if you use IPP simplayer application, does the error happen for you.

Regards,
Chao

0 Kudos
selea
Beginner
350 Views
Hi, I did not try withsimplayer application just because had not enough time.
Anyway using h264_dec sample from 7.0.3 it's fine and using sample h264_dec from 7.0.4 make application crash: so I think that the problem is probably some changes in sample code.
Anyway I can produce a mkv h264 stream or an avi stream that make me crash the decoder.
Just let me record the stream, and I'll submit it
On more point of view about the problem: in my application I'm decoding about 10 (but I can have to decode a lot more) h264 streams at the same time. Do you think that the problem could be the initialization of the H264Decoder when I have multiple different histances of it?
I found that if I decode one stream at a time I can decode it, but if I try to decode more i got problem. The problem is not always on the same line. So I think it's some kind of corruption.
I don't think it depend from the stream but from how many stream. Could it be?
0 Kudos
selea
Beginner
350 Views
ok I think that the problem at 99% is on the decoder initializing when I have multiple stream that init at the same time.
Hi made this try:
1)decoding 1 h264 stream, no problem
2)if I decode one stream then I start decoding another stream while the first is running then a third stream...and so on till 10-15 streams I got no problem.
3) if I start my applicaztion and I run at the same time 10 threads that start decoding H264 stream I got the problem.
Could the problem is in the wayH264Bitstream::InitTables is called now?
0 Kudos
selea
Beginner
350 Views
Can you reproduce the problem?
0 Kudos
Chao_Y_Intel
Moderator
350 Views

Hi,

I will try to build a test code to reproduce your case. To confirm the problem: you are using difference H.264 decoder instances for different streams, and using non-threaded H.264 decoder (since you threaded at the high level). Right?

Thanks,
Chao

0 Kudos
selea
Beginner
350 Views
you are right. I'm using non-threaded static library. I have my high level threads that do the H264 decoding. Anyway remember that I'm using now library 7.0.4 with h264 decoder from samples 7.0.3 without problem. I got the problem only with the decoder from 7.0.4 samples. And I got the problem if I start decoding at the same time. If I run threads sequentially it works fine. For that I think it's something in decoder initialization.
0 Kudos
selea
Beginner
350 Views
AnywayI think that this code
static TableInitializer tableInitializer;
that is removed from 7.0.4 could fix the problem. I try it and I let you know
0 Kudos
selea
Beginner
350 Views
Ok, it's exactly wat I explained before. I have updated the h264_dec folder with samples from 7.0.4 BUT I leave this code:
class TableInitializer
{
public:
TableInitializer()
{
H264Bitstream::InitTables();
}
~TableInitializer()
{
H264Bitstream::ReleaseTables();
}
};
static TableInitializer tableInitializer;
in the umc_h264_dec_bitstream.cpp and the application works fine even in multithreaded.
probably the problem is the varibale m_bTablesInited that is not protected.
Is there a reason you cut away TableInitializer class?
0 Kudos
Chao_Y_Intel
Moderator
350 Views

Hi,

Thanks for the detail check. I will forward it to the engineer owner to have verify if it need a fix.

The workaround looks fine (use the static tableInitializer, and only call H264Bitstream::InitTables() once).

Regards,
Chao

0 Kudos
Pavel_V_Intel
Employee
350 Views
Good day.
There was a problem during memory deallocation under Mac OS, so we moved table initialization to main class initializer. You can use static member to count class instances and close tables only on last instance.
0 Kudos
selea
Beginner
350 Views
ok but I think that anyway, even if you put a static counter, you have to protect the counter against concurrency access from different thread, otherwise you could have the same problem.
I think I leave the static Initializer class until you fix it in next samples.
regards
0 Kudos
selea
Beginner
350 Views
Are you plan to modify the h264 sample to make it compatible again with multithreaded software?
0 Kudos
Chao_Y_Intel
Moderator
350 Views

Hello,

Surely we planed to add the fix in the future product release.Thanks for your report on this problem.

Thanks,
Chao

0 Kudos
j_miles
Beginner
350 Views
If you plan on going the static class initialization route instead of e.g. reverting completely back to having the tables as class members (which could be multithread-safe but use more memory), please beware of the C++ Gotcha #55: "Runtime Static Initialization Order" from the book "C++ Gotchas: Avoiding Common Problems in Coding and Design" by Stephen C. Dewhurst (or similar). The implementations in IPP/UMC 7.0.x are not properly aware of that. As the H.264 decoder may be implemented as a library and used arbitrarily, you cannot ensure that the tables have been initialized before a decoder is used in another static object. I know it might not be the usual case but if you work with libraries, end-users might do even the most abnormal things such as instantiating and start using (possibly indirectly) an H.264 decoder during construction of a static object. In that case, the tables might not have been initialized before going into decoding! There are thus good reasons to why static/global objects are often discouraged but they also do have their use. And in this case, I can appreciate the interest in saving the memory for the tables and the fact that they only need to be initialized a single time. But you need to ensure that it works even in the static usage case as outlined and in the multi-threaded case. Static object initialization occurs in a single thread before any threads are run, by the way.

Please, consider (correct) this when you are looking into the issue (and generally remember that Gotcha anywhere else).

Thanks.

Regards,

- Jay
0 Kudos
kwlee88
Beginner
350 Views
Dear selea,

Is that possible attach related codes in here.
For me, I just upgrade samples from IPP5 to IPP7.0.4

Best Regards,
KWLEE
0 Kudos
Chao_Y_Intel
Moderator
350 Views

KWLEE,

Selea noted before, he posted the following code at umc_h264_dec_bitstream.cpp file to resolve the problem.

class TableInitializer

{

public:

TableInitializer()

{

H264Bitstream::InitTables();

}

~TableInitializer()

{

H264Bitstream::ReleaseTables();

}

};

static TableInitializer tableInitializer;

thanks,
Chao

0 Kudos
kwlee88
Beginner
350 Views
Dear Chao,

To us,We just upgrade IPP from 5 to 7.0.4. I don't have otherreference code
in 7.0.3 or older. And since there are over 2000 line in umc_h264_dec_bitstream.cpp,
It's hard for me to guess where to insert that paragraph.

My first try is insert that codes after the function
void SetDefaultScalingLists(H264SeqParamSet * sps)
But the result is still same..crash!

It would be great if selea can post the whole modify umc_h264_dec_bitstream.cpp.

Best Regards,
KWLEE
0 Kudos
Chao_Y_Intel
Moderator
350 Views

Hello,

The fix is expected to included in the 7.0 update 5 release. The release is available for download in Intel registraction center.

Thanks,
Chao
0 Kudos
Reply