Discussion:
[PATCH 0/2] h264: Threadsafe Initialization
(too old to reply)
Derek Buitenhuis
2015-10-07 16:32:59 UTC
Permalink
Towards a glorious non-locking future.

Anton Khirnov (1):
cabac: Make CABAC states hardcoded.

Derek Buitenhuis (1):
h264: Run VLC init under pthread_once

libavcodec/cabac.c | 225 ++++++++++++++++++++++++-------------------
libavcodec/cabac.h | 3 +-
libavcodec/cabac_functions.h | 8 +-
libavcodec/h264.c | 11 ++-
libavcodec/h264.h | 1 +
libavcodec/hevc.c | 2 -
6 files changed, 138 insertions(+), 112 deletions(-)
--
1.8.3.1
Derek Buitenhuis
2015-10-07 16:33:01 UTC
Permalink
This makes the h.264 decoder threadsafe to initialize.

Signed-off-by: Derek Buitenhuis <***@gmail.com>
---
libavcodec/h264.c | 9 ++++++++-
libavcodec/h264.h | 1 +
2 files changed, 9 insertions(+), 1 deletion(-)

diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 4c1e135..0a0db9a 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -606,6 +606,8 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h)
return 0;
}

+static pthread_once_t ff_h264_vlc_init = PTHREAD_ONCE_INIT;
+
av_cold int ff_h264_decode_init(AVCodecContext *avctx)
{
H264Context *h = avctx->priv_data;
@@ -619,7 +621,11 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
if (!avctx->has_b_frames)
h->low_delay = 1;

- ff_h264_decode_init_vlc();
+ ret = pthread_once(&ff_h264_vlc_init, &ff_h264_decode_init_vlc);
+ if (ret != 0) {
+ av_log(avctx, AV_LOG_ERROR, "pthread_once has failed.");
+ return AVERROR_UNKNOWN;
+ }

if (avctx->codec_id == AV_CODEC_ID_H264) {
if (avctx->ticks_per_frame == 1)
@@ -1801,6 +1807,7 @@ AVCodec ff_h264_decoder = {
.capabilities = /*AV_CODEC_CAP_DRAW_HORIZ_BAND |*/ AV_CODEC_CAP_DR1 |
AV_CODEC_CAP_DELAY | AV_CODEC_CAP_SLICE_THREADS |
AV_CODEC_CAP_FRAME_THREADS,
+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
.flush = flush_dpb,
.init_thread_copy = ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
.update_thread_context = ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context),
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index bf8b07e..e9fd9cc 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -29,6 +29,7 @@
#define AVCODEC_H264_H

#include "libavutil/intreadwrite.h"
+#include "libavutil/thread.h"
#include "cabac.h"
#include "error_resilience.h"
#include "get_bits.h"
--
1.8.3.1
Luca Barbato
2015-10-07 16:44:10 UTC
Permalink
Post by Derek Buitenhuis
This makes the h.264 decoder threadsafe to initialize.
---
libavcodec/h264.c | 9 ++++++++-
libavcodec/h264.h | 1 +
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 4c1e135..0a0db9a 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -606,6 +606,8 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h)
return 0;
}
+static pthread_once_t ff_h264_vlc_init = PTHREAD_ONCE_INIT;
Do you plan to use it outside somehow? The rest seems fine.

lu
Derek Buitenhuis
2015-10-07 17:08:52 UTC
Permalink
Post by Luca Barbato
Do you plan to use it outside somehow? The rest seems fine.
No.

- Derek
Rémi Denis-Courmont
2015-10-08 08:08:23 UTC
Permalink
Post by Derek Buitenhuis
This makes the h.264 decoder threadsafe to initialize.
---
libavcodec/h264.c | 9 ++++++++-
libavcodec/h264.h | 1 +
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index 4c1e135..0a0db9a 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -606,6 +606,8 @@ static int h264_init_context(AVCodecContext *avctx, H264Context *h)
return 0;
}
+static pthread_once_t ff_h264_vlc_init = PTHREAD_ONCE_INIT;
+
av_cold int ff_h264_decode_init(AVCodecContext *avctx)
{
H264Context *h = avctx->priv_data;
@@ -619,7 +621,11 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)
if (!avctx->has_b_frames)
h->low_delay = 1;
- ff_h264_decode_init_vlc();
+ ret = pthread_once(&ff_h264_vlc_init, &ff_h264_decode_init_vlc);
+ if (ret != 0) {
I would assert and abort here. The most likely problems here are
deadlocks (i.e. recursive initialization) and memory corruption (once
ff_h264_vlc_init is garbage)...
Post by Derek Buitenhuis
+ av_log(avctx, AV_LOG_ERROR, "pthread_once has failed.");
+ return AVERROR_UNKNOWN;
+ }
if (avctx->codec_id == AV_CODEC_ID_H264) {
if (avctx->ticks_per_frame == 1)
@@ -1801,6 +1807,7 @@ AVCodec ff_h264_decoder = {
.capabilities = /*AV_CODEC_CAP_DRAW_HORIZ_BAND |*/ AV_CODEC_CAP_DR1 |
AV_CODEC_CAP_DELAY |
AV_CODEC_CAP_SLICE_THREADS |
AV_CODEC_CAP_FRAME_THREADS,
+ .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE,
.flush = flush_dpb,
.init_thread_copy =
ONLY_IF_THREADS_ENABLED(decode_init_thread_copy),
.update_thread_context =
ONLY_IF_THREADS_ENABLED(ff_h264_update_thread_context),
diff --git a/libavcodec/h264.h b/libavcodec/h264.h
index bf8b07e..e9fd9cc 100644
--- a/libavcodec/h264.h
+++ b/libavcodec/h264.h
@@ -29,6 +29,7 @@
#define AVCODEC_H264_H
#include "libavutil/intreadwrite.h"
+#include "libavutil/thread.h"
#include "cabac.h"
#include "error_resilience.h"
#include "get_bits.h"
--
Rémi Denis-Courmont
http://www.remlab.net/
Derek Buitenhuis
2015-10-08 13:27:16 UTC
Permalink
Post by Rémi Denis-Courmont
I would assert and abort here. The most likely problems here are
deadlocks (i.e. recursive initialization) and memory corruption (once
ff_h264_vlc_init is garbage)...
I initially had this since Hendrik's patch could fail, but that is no
longer the case.

I have no strong opinion on what to do in the error case - you're screwed
regardless.

- Derek
Hendrik Leppkes
2015-10-08 13:55:45 UTC
Permalink
Post by Derek Buitenhuis
Post by Rémi Denis-Courmont
I would assert and abort here. The most likely problems here are
deadlocks (i.e. recursive initialization) and memory corruption (once
ff_h264_vlc_init is garbage)...
I initially had this since Hendrik's patch could fail, but that is no
longer the case.
I have no strong opinion on what to do in the error case - you're screwed
regardless.
I would just not check the error, it should never be able to fail and
reduces code noise.
Ganesh Ajjanagadde
2015-10-08 14:05:34 UTC
Permalink
Post by Hendrik Leppkes
Post by Derek Buitenhuis
Post by Rémi Denis-Courmont
I would assert and abort here. The most likely problems here are
deadlocks (i.e. recursive initialization) and memory corruption (once
ff_h264_vlc_init is garbage)...
+1
Post by Hendrik Leppkes
Post by Derek Buitenhuis
I initially had this since Hendrik's patch could fail, but that is no
longer the case.
I have no strong opinion on what to do in the error case - you're screwed
regardless.
I would just not check the error, it should never be able to fail and
reduces code noise.
IMHO this should be checked - errors should almost always be handled.
A few exceptions include possibly signal handlers since they can do
very little anyway and are going to exit. Any function in regular code
that can fail will fail under certain circumstances - that is all that
is guaranteed by the API: http://linux.die.net/man/3/pthread_once. If
said function is guaranteed not to fail, the designers would not have
returned the int and would have made it void.

As for return checks being code noise, I disagree here - they serve a
concrete purpose in the code.
Post by Hendrik Leppkes
_______________________________________________
libav-devel mailing list
https://lists.libav.org/mailman/listinfo/libav-devel
Hendrik Leppkes
2015-10-08 14:21:31 UTC
Permalink
Post by Ganesh Ajjanagadde
Post by Hendrik Leppkes
Post by Derek Buitenhuis
Post by Rémi Denis-Courmont
I would assert and abort here. The most likely problems here are
deadlocks (i.e. recursive initialization) and memory corruption (once
ff_h264_vlc_init is garbage)...
+1
Post by Hendrik Leppkes
Post by Derek Buitenhuis
I initially had this since Hendrik's patch could fail, but that is no
longer the case.
I have no strong opinion on what to do in the error case - you're screwed
regardless.
I would just not check the error, it should never be able to fail and
reduces code noise.
IMHO this should be checked - errors should almost always be handled.
A few exceptions include possibly signal handlers since they can do
very little anyway and are going to exit. Any function in regular code
that can fail will fail under certain circumstances - that is all that
is guaranteed by the API: http://linux.die.net/man/3/pthread_once. If
said function is guaranteed not to fail, the designers would not have
returned the int and would have made it void.
pthread is a bit of a exception. All its functions can return errors,
but the only time they would is if you pass in an invalid argument.
No-one checks return values of pthread_mutex_lock, for example. Only
functions worthy of checking are the related init functions.

- Hendrik
Rémi Denis-Courmont
2015-10-08 14:29:01 UTC
Permalink
Post by Hendrik Leppkes
pthread is a bit of a exception. All its functions can return errors,
but the only time they would is if you pass in an invalid argument.
No-one checks return values of pthread_mutex_lock, for example.
That is not true. Plenty of projects check for errors there for
debugging.
Post by Hendrik Leppkes
Only functions worthy of checking are the related init functions.
I have to disagree pretty much totally here.

POSIX thread errors on use (lock, unlock, signal, wait, etc) and
destroy functions should be checked via assertions. I found quite a few
bugs in other projects thanks to that. In debug builds, error detection
can be further improved with the error-checking mutex type instead of
the default.

On the other hand, checking init functions is useless. Any sane POSIX
thread implementation will just initialize memory and always return 0
(glibc does that, probably musl too). Errors are only specified to allow
naive POSIX implementations to allocate resources; reasonable
implementations allocate all needed resources when creating processes
and threads.

Except for the ETIMEDOUT error, the only really possible failure case
is pthread_create().
--
Rémi Denis-Courmont
http://www.remlab.net/
Ganesh Ajjanagadde
2015-10-08 14:35:44 UTC
Permalink
Post by Hendrik Leppkes
pthread is a bit of a exception. All its functions can return errors,
but the only time they would is if you pass in an invalid argument.
No-one checks return values of pthread_mutex_lock, for example.
That is not true. Plenty of projects check for errors there for debugging.
Indeed, see for instance
http://www.libsdl.org/tmp/SDL/src/thread/pthread/SDL_sysmutex.c (SDL
mutexes) used by avplay. SDL mutex creation and destruction forwards
the error to avplay, where it is (currently) not being checked.
Post by Hendrik Leppkes
Only functions worthy of checking are the related init functions.
I have to disagree pretty much totally here.
POSIX thread errors on use (lock, unlock, signal, wait, etc) and destroy
functions should be checked via assertions. I found quite a few bugs in
other projects thanks to that. In debug builds, error detection can be
further improved with the error-checking mutex type instead of the default.
On the other hand, checking init functions is useless. Any sane POSIX thread
implementation will just initialize memory and always return 0 (glibc does
that, probably musl too). Errors are only specified to allow naive POSIX
implementations to allocate resources; reasonable implementations allocate
all needed resources when creating processes and threads.
Except for the ETIMEDOUT error, the only really possible failure case is
pthread_create().
--
Rémi Denis-Courmont
http://www.remlab.net/
_______________________________________________
libav-devel mailing list
https://lists.libav.org/mailman/listinfo/libav-devel
Hendrik Leppkes
2015-10-08 14:47:51 UTC
Permalink
Post by Ganesh Ajjanagadde
Post by Hendrik Leppkes
pthread is a bit of a exception. All its functions can return errors,
but the only time they would is if you pass in an invalid argument.
No-one checks return values of pthread_mutex_lock, for example.
That is not true. Plenty of projects check for errors there for debugging.
Indeed, see for instance
http://www.libsdl.org/tmp/SDL/src/thread/pthread/SDL_sysmutex.c (SDL
mutexes) used by avplay. SDL mutex creation and destruction forwards
the error to avplay, where it is (currently) not being checked.
The real point of course is that pthread_once just cannot fail. The
spec doesn't define any error codes, and the win32 implementation
doesn't ever fail, the glibc impl never does, the musl impl never
does, and at that point I gave up trying to figure out which
implementations I should look for.
If you want to litter the codebase with dead code, well, just go ahead.

- Hendrik
wm4
2015-10-08 14:53:43 UTC
Permalink
On Thu, 8 Oct 2015 16:47:51 +0200
Post by Hendrik Leppkes
Post by Ganesh Ajjanagadde
Post by Hendrik Leppkes
pthread is a bit of a exception. All its functions can return errors,
but the only time they would is if you pass in an invalid argument.
No-one checks return values of pthread_mutex_lock, for example.
That is not true. Plenty of projects check for errors there for debugging.
Indeed, see for instance
http://www.libsdl.org/tmp/SDL/src/thread/pthread/SDL_sysmutex.c (SDL
mutexes) used by avplay. SDL mutex creation and destruction forwards
the error to avplay, where it is (currently) not being checked.
The real point of course is that pthread_once just cannot fail. The
spec doesn't define any error codes, and the win32 implementation
doesn't ever fail, the glibc impl never does, the musl impl never
does, and at that point I gave up trying to figure out which
implementations I should look for.
If you want to litter the codebase with dead code, well, just go ahead.
Amen. (+1)
Ganesh Ajjanagadde
2015-10-08 14:56:16 UTC
Permalink
Post by Hendrik Leppkes
Post by Ganesh Ajjanagadde
Post by Hendrik Leppkes
pthread is a bit of a exception. All its functions can return errors,
but the only time they would is if you pass in an invalid argument.
No-one checks return values of pthread_mutex_lock, for example.
That is not true. Plenty of projects check for errors there for debugging.
Indeed, see for instance
http://www.libsdl.org/tmp/SDL/src/thread/pthread/SDL_sysmutex.c (SDL
mutexes) used by avplay. SDL mutex creation and destruction forwards
the error to avplay, where it is (currently) not being checked.
The real point of course is that pthread_once just cannot fail. The
spec doesn't define any error codes, and the win32 implementation
doesn't ever fail, the glibc impl never does, the musl impl never
does, and at that point I gave up trying to figure out which
implementations I should look for.
If you want to litter the codebase with dead code, well, just go ahead.
Maybe so currently, but there is no guarantee. In fact, it seems like
internally, glibc itself checks the return code:
https://patchwork.ozlabs.org/patch/482350/
Post by Hendrik Leppkes
- Hendrik
_______________________________________________
libav-devel mailing list
https://lists.libav.org/mailman/listinfo/libav-devel
wm4
2015-10-08 15:02:49 UTC
Permalink
On Thu, 8 Oct 2015 10:56:16 -0400
Post by Ganesh Ajjanagadde
Post by Hendrik Leppkes
Post by Ganesh Ajjanagadde
Post by Hendrik Leppkes
pthread is a bit of a exception. All its functions can return errors,
but the only time they would is if you pass in an invalid argument.
No-one checks return values of pthread_mutex_lock, for example.
That is not true. Plenty of projects check for errors there for debugging.
Indeed, see for instance
http://www.libsdl.org/tmp/SDL/src/thread/pthread/SDL_sysmutex.c (SDL
mutexes) used by avplay. SDL mutex creation and destruction forwards
the error to avplay, where it is (currently) not being checked.
The real point of course is that pthread_once just cannot fail. The
spec doesn't define any error codes, and the win32 implementation
doesn't ever fail, the glibc impl never does, the musl impl never
does, and at that point I gave up trying to figure out which
implementations I should look for.
If you want to litter the codebase with dead code, well, just go ahead.
Maybe so currently, but there is no guarantee. In fact, it seems like
https://patchwork.ozlabs.org/patch/482350/
That's a lot of text for something that doesn't matter, so I didn't
read it. But they seem to be talking about C++ and UNIX signals, which
don't matter at all in our case (or anyone who's sufficiently
non-insane).
Ganesh Ajjanagadde
2015-10-08 15:14:15 UTC
Permalink
Post by wm4
On Thu, 8 Oct 2015 10:56:16 -0400
Post by Ganesh Ajjanagadde
Post by Hendrik Leppkes
Post by Ganesh Ajjanagadde
Post by Hendrik Leppkes
pthread is a bit of a exception. All its functions can return errors,
but the only time they would is if you pass in an invalid argument.
No-one checks return values of pthread_mutex_lock, for example.
That is not true. Plenty of projects check for errors there for debugging.
Indeed, see for instance
http://www.libsdl.org/tmp/SDL/src/thread/pthread/SDL_sysmutex.c (SDL
mutexes) used by avplay. SDL mutex creation and destruction forwards
the error to avplay, where it is (currently) not being checked.
The real point of course is that pthread_once just cannot fail. The
spec doesn't define any error codes, and the win32 implementation
doesn't ever fail, the glibc impl never does, the musl impl never
does, and at that point I gave up trying to figure out which
implementations I should look for.
If you want to litter the codebase with dead code, well, just go ahead.
Maybe so currently, but there is no guarantee. In fact, it seems like
https://patchwork.ozlabs.org/patch/482350/
That's a lot of text for something that doesn't matter, so I didn't
read it. But they seem to be talking about C++ and UNIX signals, which
don't matter at all in our case (or anyone who's sufficiently
non-insane).
I did not expect you to read it (and neither have I). I just wanted to
point out the actual patch (which is at the very bottom). There,
pthread_once is indeed checked.

Regardless, I do not have a strong enough preference on this to oppose
the patch. If you, Hendrik, and perhaps some others don't want to
check the return value, then by all means go ahead.
Post by wm4
_______________________________________________
libav-devel mailing list
https://lists.libav.org/mailman/listinfo/libav-devel
wm4
2015-10-08 15:50:04 UTC
Permalink
On Thu, 8 Oct 2015 11:14:15 -0400
Post by Ganesh Ajjanagadde
Post by wm4
On Thu, 8 Oct 2015 10:56:16 -0400
Post by Ganesh Ajjanagadde
Post by Hendrik Leppkes
Post by Ganesh Ajjanagadde
Post by Hendrik Leppkes
pthread is a bit of a exception. All its functions can return errors,
but the only time they would is if you pass in an invalid argument.
No-one checks return values of pthread_mutex_lock, for example.
That is not true. Plenty of projects check for errors there for debugging.
Indeed, see for instance
http://www.libsdl.org/tmp/SDL/src/thread/pthread/SDL_sysmutex.c (SDL
mutexes) used by avplay. SDL mutex creation and destruction forwards
the error to avplay, where it is (currently) not being checked.
The real point of course is that pthread_once just cannot fail. The
spec doesn't define any error codes, and the win32 implementation
doesn't ever fail, the glibc impl never does, the musl impl never
does, and at that point I gave up trying to figure out which
implementations I should look for.
If you want to litter the codebase with dead code, well, just go ahead.
Maybe so currently, but there is no guarantee. In fact, it seems like
https://patchwork.ozlabs.org/patch/482350/
That's a lot of text for something that doesn't matter, so I didn't
read it. But they seem to be talking about C++ and UNIX signals, which
don't matter at all in our case (or anyone who's sufficiently
non-insane).
I did not expect you to read it (and neither have I). I just wanted to
point out the actual patch (which is at the very bottom). There,
pthread_once is indeed checked.
Regardless, I do not have a strong enough preference on this to oppose
the patch. If you, Hendrik, and perhaps some others don't want to
check the return value, then by all means go ahead.
That patch adds an automated regression test. It's not real code.
Rémi Denis-Courmont
2015-10-08 15:29:15 UTC
Permalink
Post by Hendrik Leppkes
The real point of course is that pthread_once just cannot fail. The
spec doesn't define any error codes,
A reasonable implementation cannot fail. The specification certainly
allows for it to fail. The only forbidden error code is EINTR, meaning a
signal will not interrupt the call.

It would definitely make sense for a libc to return EINVAL if it
detects that the once is not in either of the valid two states. A lame
implementation could return ENOMEM.

I don't really care about pthread_once(). But I think libav should
check mutex and CV operations. Namely, abort if init fails, and assert
for all other functions for self debugging.
--
Rémi Denis-Courmont
http://www.remlab.net/
Ganesh Ajjanagadde
2015-10-08 17:50:08 UTC
Permalink
Post by Hendrik Leppkes
Post by Ganesh Ajjanagadde
Post by Hendrik Leppkes
pthread is a bit of a exception. All its functions can return errors,
but the only time they would is if you pass in an invalid argument.
No-one checks return values of pthread_mutex_lock, for example.
That is not true. Plenty of projects check for errors there for debugging.
Indeed, see for instance
http://www.libsdl.org/tmp/SDL/src/thread/pthread/SDL_sysmutex.c (SDL
mutexes) used by avplay. SDL mutex creation and destruction forwards
the error to avplay, where it is (currently) not being checked.
The real point of course is that pthread_once just cannot fail. The
spec doesn't define any error codes, and the win32 implementation
doesn't ever fail, the glibc impl never does, the musl impl never
does, and at that point I gave up trying to figure out which
implementations I should look for.
If you want to litter the codebase with dead code, well, just go ahead.
I am sorry, but I am not convinced by your claim. Unless this code has
changed recently, see e.g
https://github.com/VFR-maniac/pthreads-win32/blob/master/pthread_once.c

there is a nonzero return value.
Here EINVAL can be returned.

I want to lay out all this stuff here; feel free to do whatever you want.
Post by Hendrik Leppkes
- Hendrik
_______________________________________________
libav-devel mailing list
https://lists.libav.org/mailman/listinfo/libav-devel
wm4
2015-10-08 18:05:56 UTC
Permalink
On Thu, 8 Oct 2015 13:50:08 -0400
Post by Ganesh Ajjanagadde
Post by Hendrik Leppkes
Post by Ganesh Ajjanagadde
Post by Hendrik Leppkes
pthread is a bit of a exception. All its functions can return errors,
but the only time they would is if you pass in an invalid argument.
No-one checks return values of pthread_mutex_lock, for example.
That is not true. Plenty of projects check for errors there for debugging.
Indeed, see for instance
http://www.libsdl.org/tmp/SDL/src/thread/pthread/SDL_sysmutex.c (SDL
mutexes) used by avplay. SDL mutex creation and destruction forwards
the error to avplay, where it is (currently) not being checked.
The real point of course is that pthread_once just cannot fail. The
spec doesn't define any error codes, and the win32 implementation
doesn't ever fail, the glibc impl never does, the musl impl never
does, and at that point I gave up trying to figure out which
implementations I should look for.
If you want to litter the codebase with dead code, well, just go ahead.
I am sorry, but I am not convinced by your claim. Unless this code has
changed recently, see e.g
https://github.com/VFR-maniac/pthreads-win32/blob/master/pthread_once.c
there is a nonzero return value.
Here EINVAL can be returned.
I want to lay out all this stuff here; feel free to do whatever you want.
Did you even read this code? It never returns failure, except when the
user-provided parameters are very obviously wrong (to the point of
just being UB).
Ganesh Ajjanagadde
2015-10-08 18:13:06 UTC
Permalink
Post by wm4
On Thu, 8 Oct 2015 13:50:08 -0400
Post by Ganesh Ajjanagadde
Post by Hendrik Leppkes
Post by Ganesh Ajjanagadde
Post by Hendrik Leppkes
pthread is a bit of a exception. All its functions can return errors,
but the only time they would is if you pass in an invalid argument.
No-one checks return values of pthread_mutex_lock, for example.
That is not true. Plenty of projects check for errors there for debugging.
Indeed, see for instance
http://www.libsdl.org/tmp/SDL/src/thread/pthread/SDL_sysmutex.c (SDL
mutexes) used by avplay. SDL mutex creation and destruction forwards
the error to avplay, where it is (currently) not being checked.
The real point of course is that pthread_once just cannot fail. The
spec doesn't define any error codes, and the win32 implementation
doesn't ever fail, the glibc impl never does, the musl impl never
does, and at that point I gave up trying to figure out which
implementations I should look for.
If you want to litter the codebase with dead code, well, just go ahead.
I am sorry, but I am not convinced by your claim. Unless this code has
changed recently, see e.g
https://github.com/VFR-maniac/pthreads-win32/blob/master/pthread_once.c
there is a nonzero return value.
Here EINVAL can be returned.
I want to lay out all this stuff here; feel free to do whatever you want.
Did you even read this code? It never returns failure, except when the
user-provided parameters are very obviously wrong (to the point of
just being UB).
I did read it, and I do know it is currently returned for a trivial
case. Nevertheless, it illustrates that implementations can (and
sometimes do) return error codes, since they are allowed to do so by
POSIX. One thing I have understood from the project: a lot of
portability comes from the "respect" accorded to standards such as
POSIX. This guarantees working functionality and robustness across a
wide variety of platforms (just check FATE). I do not believe that
this should be sacrificed for a trivial 2 line addition to the code.
That is my personal attitude, and you are free to disagree with it.
Furthermore, I am not imposing it on anyone else, but I want to lay
out all the facts for everyone to make an informed decision.
Post by wm4
_______________________________________________
libav-devel mailing list
https://lists.libav.org/mailman/listinfo/libav-devel
Hendrik Leppkes
2015-10-08 14:40:12 UTC
Permalink
Post by Hendrik Leppkes
pthread is a bit of a exception. All its functions can return errors,
but the only time they would is if you pass in an invalid argument.
No-one checks return values of pthread_mutex_lock, for example.
That is not true. Plenty of projects check for errors there for debugging.
Post by Hendrik Leppkes
Only functions worthy of checking are the related init functions.
I have to disagree pretty much totally here.
POSIX thread errors on use (lock, unlock, signal, wait, etc) and destroy
functions should be checked via assertions. I found quite a few bugs in
other projects thanks to that. In debug builds, error detection can be
further improved with the error-checking mutex type instead of the default.
On the other hand, checking init functions is useless. Any sane POSIX thread
implementation will just initialize memory and always return 0 (glibc does
that, probably musl too). Errors are only specified to allow naive POSIX
implementations to allocate resources; reasonable implementations allocate
all needed resources when creating processes and threads.
Except for the ETIMEDOUT error, the only really possible failure case is
pthread_create().
So, you don't disagree that much afterall, since only pthread_create can fail?
Confusing, you are.
Luca Barbato
2015-10-08 19:19:29 UTC
Permalink
Post by Derek Buitenhuis
Post by Rémi Denis-Courmont
I would assert and abort here. The most likely problems here are
deadlocks (i.e. recursive initialization) and memory corruption (once
ff_h264_vlc_init is garbage)...
I initially had this since Hendrik's patch could fail, but that is no
longer the case.
I have no strong opinion on what to do in the error case - you're screwed
regardless.
Since, as you said, you cannot improve I'm keeping that part as-is and
I'd push the set if nobody has strong opinions (the no-thread wrapper
got the pointer dereferences fixed locally).

Derek Buitenhuis
2015-10-07 16:33:00 UTC
Permalink
From: Anton Khirnov <***@khirnov.net>

There's not much reason to generate such a small table at runtime.

Signed-off-by: Derek Buitenhuis <***@vimeo.com>
---
libavcodec/cabac.c | 225 ++++++++++++++++++++++++-------------------
libavcodec/cabac.h | 3 +-
libavcodec/cabac_functions.h | 8 +-
libavcodec/h264.c | 2 -
libavcodec/hevc.c | 2 -
5 files changed, 129 insertions(+), 111 deletions(-)

diff --git a/libavcodec/cabac.c b/libavcodec/cabac.c
index b6f56f0..7df0648 100644
--- a/libavcodec/cabac.c
+++ b/libavcodec/cabac.c
@@ -31,75 +31,130 @@
#include "cabac.h"
#include "cabac_functions.h"

-uint8_t ff_h264_cabac_tables[512 + 4*2*64 + 4*64 + 63] = {
- 9,8,7,7,6,6,6,6,5,5,5,5,5,5,5,5,
- 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
- 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
- 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
- 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-};
-
-static const uint8_t lps_range[64][4]= {
-{128,176,208,240}, {128,167,197,227}, {128,158,187,216}, {123,150,178,205},
-{116,142,169,195}, {111,135,160,185}, {105,128,152,175}, {100,122,144,166},
-{ 95,116,137,158}, { 90,110,130,150}, { 85,104,123,142}, { 81, 99,117,135},
-{ 77, 94,111,128}, { 73, 89,105,122}, { 69, 85,100,116}, { 66, 80, 95,110},
-{ 62, 76, 90,104}, { 59, 72, 86, 99}, { 56, 69, 81, 94}, { 53, 65, 77, 89},
-{ 51, 62, 73, 85}, { 48, 59, 69, 80}, { 46, 56, 66, 76}, { 43, 53, 63, 72},
-{ 41, 50, 59, 69}, { 39, 48, 56, 65}, { 37, 45, 54, 62}, { 35, 43, 51, 59},
-{ 33, 41, 48, 56}, { 32, 39, 46, 53}, { 30, 37, 43, 50}, { 29, 35, 41, 48},
-{ 27, 33, 39, 45}, { 26, 31, 37, 43}, { 24, 30, 35, 41}, { 23, 28, 33, 39},
-{ 22, 27, 32, 37}, { 21, 26, 30, 35}, { 20, 24, 29, 33}, { 19, 23, 27, 31},
-{ 18, 22, 26, 30}, { 17, 21, 25, 28}, { 16, 20, 23, 27}, { 15, 19, 22, 25},
-{ 14, 18, 21, 24}, { 14, 17, 20, 23}, { 13, 16, 19, 22}, { 12, 15, 18, 21},
-{ 12, 14, 17, 20}, { 11, 14, 16, 19}, { 11, 13, 15, 18}, { 10, 12, 15, 17},
-{ 10, 12, 14, 16}, { 9, 11, 13, 15}, { 9, 11, 12, 14}, { 8, 10, 12, 14},
-{ 8, 9, 11, 13}, { 7, 9, 11, 12}, { 7, 9, 10, 12}, { 7, 8, 10, 11},
-{ 6, 8, 9, 11}, { 6, 7, 9, 10}, { 6, 7, 8, 9}, { 2, 2, 2, 2},
-};
-
-static const uint8_t mps_state[64]= {
- 1, 2, 3, 4, 5, 6, 7, 8,
- 9,10,11,12,13,14,15,16,
- 17,18,19,20,21,22,23,24,
- 25,26,27,28,29,30,31,32,
- 33,34,35,36,37,38,39,40,
- 41,42,43,44,45,46,47,48,
- 49,50,51,52,53,54,55,56,
- 57,58,59,60,61,62,62,63,
-};
-
-static const uint8_t lps_state[64]= {
- 0, 0, 1, 2, 2, 4, 4, 5,
- 6, 7, 8, 9, 9,11,11,12,
- 13,13,15,15,16,16,18,18,
- 19,19,21,21,22,22,23,24,
- 24,25,26,26,27,27,28,29,
- 29,30,30,30,31,32,32,33,
- 33,33,34,34,35,35,35,36,
- 36,36,37,37,37,38,38,63,
-};
-
-static const uint8_t last_coeff_flag_offset_8x8[63] = {
- 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
- 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
- 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
- 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8
+const uint8_t ff_h264_cabac_tables[512 + 4*2*64 + 4*64 + 63] = {
+ 9,8,7,7,6,6,6,6,5,5,5,5,5,5,5,5,
+ 4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
+ // LPS range
+ -128, -128, -128, -128, -128, -128, 123, 123,
+ 116, 116, 111, 111, 105, 105, 100, 100,
+ 95, 95, 90, 90, 85, 85, 81, 81,
+ 77, 77, 73, 73, 69, 69, 66, 66,
+ 62, 62, 59, 59, 56, 56, 53, 53,
+ 51, 51, 48, 48, 46, 46, 43, 43,
+ 41, 41, 39, 39, 37, 37, 35, 35,
+ 33, 33, 32, 32, 30, 30, 29, 29,
+ 27, 27, 26, 26, 24, 24, 23, 23,
+ 22, 22, 21, 21, 20, 20, 19, 19,
+ 18, 18, 17, 17, 16, 16, 15, 15,
+ 14, 14, 14, 14, 13, 13, 12, 12,
+ 12, 12, 11, 11, 11, 11, 10, 10,
+ 10, 10, 9, 9, 9, 9, 8, 8,
+ 8, 8, 7, 7, 7, 7, 7, 7,
+ 6, 6, 6, 6, 6, 6, 2, 2,
+ -80, -80, -89, -89, -98, -98, -106, -106,
+ -114, -114, -121, -121, -128, -128, 122, 122,
+ 116, 116, 110, 110, 104, 104, 99, 99,
+ 94, 94, 89, 89, 85, 85, 80, 80,
+ 76, 76, 72, 72, 69, 69, 65, 65,
+ 62, 62, 59, 59, 56, 56, 53, 53,
+ 50, 50, 48, 48, 45, 45, 43, 43,
+ 41, 41, 39, 39, 37, 37, 35, 35,
+ 33, 33, 31, 31, 30, 30, 28, 28,
+ 27, 27, 26, 26, 24, 24, 23, 23,
+ 22, 22, 21, 21, 20, 20, 19, 19,
+ 18, 18, 17, 17, 16, 16, 15, 15,
+ 14, 14, 14, 14, 13, 13, 12, 12,
+ 12, 12, 11, 11, 11, 11, 10, 10,
+ 9, 9, 9, 9, 9, 9, 8, 8,
+ 8, 8, 7, 7, 7, 7, 2, 2,
+ -48, -48, -59, -59, -69, -69, -78, -78,
+ -87, -87, -96, -96, -104, -104, -112, -112,
+ -119, -119, -126, -126, 123, 123, 117, 117,
+ 111, 111, 105, 105, 100, 100, 95, 95,
+ 90, 90, 86, 86, 81, 81, 77, 77,
+ 73, 73, 69, 69, 66, 66, 63, 63,
+ 59, 59, 56, 56, 54, 54, 51, 51,
+ 48, 48, 46, 46, 43, 43, 41, 41,
+ 39, 39, 37, 37, 35, 35, 33, 33,
+ 32, 32, 30, 30, 29, 29, 27, 27,
+ 26, 26, 25, 25, 23, 23, 22, 22,
+ 21, 21, 20, 20, 19, 19, 18, 18,
+ 17, 17, 16, 16, 15, 15, 15, 15,
+ 14, 14, 13, 13, 12, 12, 12, 12,
+ 11, 11, 11, 11, 10, 10, 10, 10,
+ 9, 9, 9, 9, 8, 8, 2, 2,
+ -16, -16, -29, -29, -40, -40, -51, -51,
+ -61, -61, -71, -71, -81, -81, -90, -90,
+ -98, -98, -106, -106, -114, -114, -121, -121,
+ -128, -128, 122, 122, 116, 116, 110, 110,
+ 104, 104, 99, 99, 94, 94, 89, 89,
+ 85, 85, 80, 80, 76, 76, 72, 72,
+ 69, 69, 65, 65, 62, 62, 59, 59,
+ 56, 56, 53, 53, 50, 50, 48, 48,
+ 45, 45, 43, 43, 41, 41, 39, 39,
+ 37, 37, 35, 35, 33, 33, 31, 31,
+ 30, 30, 28, 28, 27, 27, 25, 25,
+ 24, 24, 23, 23, 22, 22, 21, 21,
+ 20, 20, 19, 19, 18, 18, 17, 17,
+ 16, 16, 15, 15, 14, 14, 14, 14,
+ 13, 13, 12, 12, 12, 12, 11, 11,
+ 11, 11, 10, 10, 9, 9, 2, 2,
+ // mlps state
+ 127, 126, 77, 76, 77, 76, 75, 74,
+ 75, 74, 75, 74, 73, 72, 73, 72,
+ 73, 72, 71, 70, 71, 70, 71, 70,
+ 69, 68, 69, 68, 67, 66, 67, 66,
+ 67, 66, 65, 64, 65, 64, 63, 62,
+ 61, 60, 61, 60, 61, 60, 59, 58,
+ 59, 58, 57, 56, 55, 54, 55, 54,
+ 53, 52, 53, 52, 51, 50, 49, 48,
+ 49, 48, 47, 46, 45, 44, 45, 44,
+ 43, 42, 43, 42, 39, 38, 39, 38,
+ 37, 36, 37, 36, 33, 32, 33, 32,
+ 31, 30, 31, 30, 27, 26, 27, 26,
+ 25, 24, 23, 22, 23, 22, 19, 18,
+ 19, 18, 17, 16, 15, 14, 13, 12,
+ 11, 10, 9, 8, 9, 8, 5, 4,
+ 5, 4, 3, 2, 1, 0, 0, 1,
+ 2, 3, 4, 5, 6, 7, 8, 9,
+ 10, 11, 12, 13, 14, 15, 16, 17,
+ 18, 19, 20, 21, 22, 23, 24, 25,
+ 26, 27, 28, 29, 30, 31, 32, 33,
+ 34, 35, 36, 37, 38, 39, 40, 41,
+ 42, 43, 44, 45, 46, 47, 48, 49,
+ 50, 51, 52, 53, 54, 55, 56, 57,
+ 58, 59, 60, 61, 62, 63, 64, 65,
+ 66, 67, 68, 69, 70, 71, 72, 73,
+ 74, 75, 76, 77, 78, 79, 80, 81,
+ 82, 83, 84, 85, 86, 87, 88, 89,
+ 90, 91, 92, 93, 94, 95, 96, 97,
+ 98, 99, 100, 101, 102, 103, 104, 105,
+ 106, 107, 108, 109, 110, 111, 112, 113,
+ 114, 115, 116, 117, 118, 119, 120, 121,
+ 122, 123, 124, 125, 124, 125, 126, 127,
+ // last_coeff_flag_offset_8x8
+ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
+ 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8
};

/**
@@ -120,35 +175,3 @@ void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){
c->low+= ((*c->bytestream++)<<2) + 2;
c->range= 0x1FE;
}
-
-void ff_init_cabac_states(void)
-{
- int i, j;
- static int initialized = 0;
-
- if (initialized)
- return;
-
- for(i=0; i<64; i++){
- for(j=0; j<4; j++){ //FIXME check if this is worth the 1 shift we save
- ff_h264_lps_range[j*2*64+2*i+0]=
- ff_h264_lps_range[j*2*64+2*i+1]= lps_range[i][j];
- }
-
- ff_h264_mlps_state[128 + 2 * i + 0] = 2 * mps_state[i] + 0;
- ff_h264_mlps_state[128 + 2 * i + 1] = 2 * mps_state[i] + 1;
-
- if( i ){
- ff_h264_mlps_state[128-2*i-1]= 2*lps_state[i]+0;
- ff_h264_mlps_state[128-2*i-2]= 2*lps_state[i]+1;
- }else{
- ff_h264_mlps_state[128-2*i-1]= 1;
- ff_h264_mlps_state[128-2*i-2]= 0;
- }
- }
- for(i=0; i< 63; i++){
- ff_h264_last_coeff_flag_offset_8x8[i] = last_coeff_flag_offset_8x8[i];
- }
-
- initialized = 1;
-}
diff --git a/libavcodec/cabac.h b/libavcodec/cabac.h
index 426f338..40eefed 100644
--- a/libavcodec/cabac.h
+++ b/libavcodec/cabac.h
@@ -31,7 +31,7 @@

#include "put_bits.h"

-extern uint8_t ff_h264_cabac_tables[512 + 4*2*64 + 4*64 + 63];
+extern const uint8_t ff_h264_cabac_tables[512 + 4*2*64 + 4*64 + 63];
#define H264_NORM_SHIFT_OFFSET 0
#define H264_LPS_RANGE_OFFSET 512
#define H264_MLPS_STATE_OFFSET 1024
@@ -49,6 +49,5 @@ typedef struct CABACContext{
}CABACContext;

void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size);
-void ff_init_cabac_states(void);

#endif /* AVCODEC_CABAC_H */
diff --git a/libavcodec/cabac_functions.h b/libavcodec/cabac_functions.h
index 4b8f1bc..428457c 100644
--- a/libavcodec/cabac_functions.h
+++ b/libavcodec/cabac_functions.h
@@ -42,10 +42,10 @@
# include "x86/cabac.h"
#endif

-static uint8_t * const ff_h264_norm_shift = ff_h264_cabac_tables + H264_NORM_SHIFT_OFFSET;
-static uint8_t * const ff_h264_lps_range = ff_h264_cabac_tables + H264_LPS_RANGE_OFFSET;
-static uint8_t * const ff_h264_mlps_state = ff_h264_cabac_tables + H264_MLPS_STATE_OFFSET;
-static uint8_t * const ff_h264_last_coeff_flag_offset_8x8 = ff_h264_cabac_tables + H264_LAST_COEFF_FLAG_OFFSET_8x8_OFFSET;
+static const uint8_t * const ff_h264_norm_shift = ff_h264_cabac_tables + H264_NORM_SHIFT_OFFSET;
+static const uint8_t * const ff_h264_lps_range = ff_h264_cabac_tables + H264_LPS_RANGE_OFFSET;
+static const uint8_t * const ff_h264_mlps_state = ff_h264_cabac_tables + H264_MLPS_STATE_OFFSET;
+static const uint8_t * const ff_h264_last_coeff_flag_offset_8x8 = ff_h264_cabac_tables + H264_LAST_COEFF_FLAG_OFFSET_8x8_OFFSET;

static void refill(CABACContext *c){
#if CABAC_BITS == 16
diff --git a/libavcodec/h264.c b/libavcodec/h264.c
index d4cb030..4c1e135 100644
--- a/libavcodec/h264.c
+++ b/libavcodec/h264.c
@@ -621,8 +621,6 @@ av_cold int ff_h264_decode_init(AVCodecContext *avctx)

ff_h264_decode_init_vlc();

- ff_init_cabac_states();
-
if (avctx->codec_id == AV_CODEC_ID_H264) {
if (avctx->ticks_per_frame == 1)
h->avctx->framerate.num *= 2;
diff --git a/libavcodec/hevc.c b/libavcodec/hevc.c
index 07b7de1..e1b1be3 100644
--- a/libavcodec/hevc.c
+++ b/libavcodec/hevc.c
@@ -2984,8 +2984,6 @@ static av_cold int hevc_decode_init(AVCodecContext *avctx)
HEVCContext *s = avctx->priv_data;
int ret;

- ff_init_cabac_states();
-
avctx->internal->allocate_progress = 1;

ret = hevc_init_context(avctx);
--
1.8.3.1
Luca Barbato
2015-10-07 20:29:03 UTC
Permalink
Post by Derek Buitenhuis
There's not much reason to generate such a small table at runtime.
---
libavcodec/cabac.c | 225 ++++++++++++++++++++++++-------------------
libavcodec/cabac.h | 3 +-
libavcodec/cabac_functions.h | 8 +-
libavcodec/h264.c | 2 -
libavcodec/hevc.c | 2 -
5 files changed, 129 insertions(+), 111 deletions(-)
Ok.
Loading...