Re: [FFmpeg-devel] [PATCH] w32pthreads: add pthread_once emulation

2015-10-10 Thread Hendrik Leppkes
On Wed, Oct 7, 2015 at 6:29 PM, Hendrik Leppkes  wrote:
> On Wed, Oct 7, 2015 at 6:23 PM, Matt Oliver  wrote:
>> On 6 October 2015 at 21:36, Hendrik Leppkes  wrote:
>>
>>> The emulation uses native InitOnce* APIs on Windows Vista+, and a
>>> lock-free/allocation-free approach using atomics and spinning for Windows
>>> XP.
>>> ---
>>>
>>> This is in preparation to use pthread_once for global static init
>>> functions,
>>> and eventually removing the global lock in avcodec_open2
>>>
>>> compat/w32pthreads.h | 68
>>> 
>>>  1 file changed, 68 insertions(+)
>>>
>>> diff --git a/compat/w32pthreads.h b/compat/w32pthreads.h
>>> index deb1c53..8523976 100644
>>> --- a/compat/w32pthreads.h
>>> +++ b/compat/w32pthreads.h
>>> @@ -154,6 +154,19 @@ static inline int pthread_cond_signal(pthread_cond_t
>>> *cond)
>>>  return 0;
>>>  }
>>>
>>> +typedef INIT_ONCE pthread_once_t;
>>> +#define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
>>> +
>>> +static av_unused int pthread_once(pthread_once_t *once_control, void
>>> (*init_routine)(void))
>>> +{
>>> +BOOL pending = FALSE;
>>> +InitOnceBeginInitialize(once_control, 0, , NULL);
>>> +if (pending)
>>> +init_routine();
>>> +InitOnceComplete(once_control, 0, NULL);
>>> +return 0;
>>> +}
>>> +
>>>  #else // _WIN32_WINNT < 0x0600
>>>  /* for pre-Windows 6.0 platforms we need to define and use our own
>>> condition
>>>   * variable and api */
>>> @@ -304,6 +317,57 @@ static av_unused int
>>> pthread_cond_signal(pthread_cond_t *cond)
>>>  pthread_mutex_unlock(_cond->mtx_broadcast);
>>>  return 0;
>>>  }
>>> +
>>> +/* for pre-Windows 6.0 platforms, define INIT_ONCE struct,
>>> + * compatible to the one used in the native API */
>>> +
>>> +typedef union pthread_once_t  {
>>> +void * Ptr;///< For the Windows 6.0+ native functions
>>> +LONG state;///< For the pre-Windows 6.0 compat code
>>> +} pthread_once_t;
>>> +
>>> +#define PTHREAD_ONCE_INIT {0}
>>> +
>>> +/* function pointers to init once API on windows 6.0+ kernels */
>>> +static BOOL (WINAPI *initonce_begin)(pthread_once_t *lpInitOnce, DWORD
>>> dwFlags, BOOL *fPending, void **lpContext);
>>> +static BOOL (WINAPI *initonce_complete)(pthread_once_t *lpInitOnce, DWORD
>>> dwFlags, void *lpContext);
>>> +
>>> +static av_unused int pthread_once(pthread_once_t *once_control, void
>>> (*init_routine)(void))
>>> +{
>>> +/* Use native functions on Windows 6.0+ */
>>> +if (initonce_begin && initonce_complete)
>>> +{
>>> +BOOL pending = FALSE;
>>> +initonce_begin(once_control, 0, , NULL);
>>> +if (pending)
>>> +init_routine();
>>> +initonce_complete(once_control, 0, NULL);
>>> +return 0;
>>> +}
>>> +
>>> +/* pre-Windows 6.0 compat using a spin-lock */
>>> +switch (InterlockedCompareExchange(_control->state, 1, 0))
>>> +{
>>> +/* Initial run */
>>> +case 0:
>>> +init_routine();
>>> +InterlockedExchange(_control->state, 2);
>>> +break;
>>> +/* Another thread is running init */
>>> +case 1:
>>> +while (1) {
>>> +MemoryBarrier();
>>> +if (once_control->state == 2)
>>> +break;
>>> +Sleep(0);
>>> +}
>>> +break;
>>> +/* Initialization complete */
>>> +case 2:
>>> +break;
>>> +}
>>> +return 0;
>>> +}
>>>  #endif
>>>
>>>  static av_unused void w32thread_init(void)
>>> @@ -319,6 +383,10 @@ static av_unused void w32thread_init(void)
>>>  (void*)GetProcAddress(kernel_dll, "WakeConditionVariable");
>>>  cond_wait  =
>>>  (void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS");
>>> +initonce_begin =
>>> +(void*)GetProcAddress(kernel_dll, "InitOnceBeginInitialize");
>>> +initonce_complete =
>>> +(void*)GetProcAddress(kernel_dll, "InitOnceComplete");
>>>  #endif
>>>
>>>  }
>>> --
>>> 2.5.3.windows.1
>>
>>
>> LGTM
>
> There is a new version of the patch which also solves the
> w32thread_init mess, so this one isn't the final version anymore.
> Current working version is here:
> https://github.com/Nevcairiel/FFmpeg/commits/pthread_once
>

This version has been applied.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] w32pthreads: add pthread_once emulation

2015-10-07 Thread Hendrik Leppkes
On Wed, Oct 7, 2015 at 7:06 PM, Matt Oliver  wrote:
> On 8 October 2015 at 03:29, Hendrik Leppkes  wrote:
>
>> On Wed, Oct 7, 2015 at 6:23 PM, Matt Oliver  wrote:
>> > On 6 October 2015 at 21:36, Hendrik Leppkes  wrote:
>> >
>> >> The emulation uses native InitOnce* APIs on Windows Vista+, and a
>> >> lock-free/allocation-free approach using atomics and spinning for
>> Windows
>> >> XP.
>> >> ---
>> >>
>> >> This is in preparation to use pthread_once for global static init
>> >> functions,
>> >> and eventually removing the global lock in avcodec_open2
>> >>
>> >> compat/w32pthreads.h | 68
>> >> 
>> >>  1 file changed, 68 insertions(+)
>> >>
>> >> diff --git a/compat/w32pthreads.h b/compat/w32pthreads.h
>> >> index deb1c53..8523976 100644
>> >> --- a/compat/w32pthreads.h
>> >> +++ b/compat/w32pthreads.h
>> >> @@ -154,6 +154,19 @@ static inline int
>> pthread_cond_signal(pthread_cond_t
>> >> *cond)
>> >>  return 0;
>> >>  }
>> >>
>> >> +typedef INIT_ONCE pthread_once_t;
>> >> +#define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
>> >> +
>> >> +static av_unused int pthread_once(pthread_once_t *once_control, void
>> >> (*init_routine)(void))
>> >> +{
>> >> +BOOL pending = FALSE;
>> >> +InitOnceBeginInitialize(once_control, 0, , NULL);
>> >> +if (pending)
>> >> +init_routine();
>> >> +InitOnceComplete(once_control, 0, NULL);
>> >> +return 0;
>> >> +}
>> >> +
>> >>  #else // _WIN32_WINNT < 0x0600
>> >>  /* for pre-Windows 6.0 platforms we need to define and use our own
>> >> condition
>> >>   * variable and api */
>> >> @@ -304,6 +317,57 @@ static av_unused int
>> >> pthread_cond_signal(pthread_cond_t *cond)
>> >>  pthread_mutex_unlock(_cond->mtx_broadcast);
>> >>  return 0;
>> >>  }
>> >> +
>> >> +/* for pre-Windows 6.0 platforms, define INIT_ONCE struct,
>> >> + * compatible to the one used in the native API */
>> >> +
>> >> +typedef union pthread_once_t  {
>> >> +void * Ptr;///< For the Windows 6.0+ native functions
>> >> +LONG state;///< For the pre-Windows 6.0 compat code
>> >> +} pthread_once_t;
>> >> +
>> >> +#define PTHREAD_ONCE_INIT {0}
>> >> +
>> >> +/* function pointers to init once API on windows 6.0+ kernels */
>> >> +static BOOL (WINAPI *initonce_begin)(pthread_once_t *lpInitOnce, DWORD
>> >> dwFlags, BOOL *fPending, void **lpContext);
>> >> +static BOOL (WINAPI *initonce_complete)(pthread_once_t *lpInitOnce,
>> DWORD
>> >> dwFlags, void *lpContext);
>> >> +
>> >> +static av_unused int pthread_once(pthread_once_t *once_control, void
>> >> (*init_routine)(void))
>> >> +{
>> >> +/* Use native functions on Windows 6.0+ */
>> >> +if (initonce_begin && initonce_complete)
>> >> +{
>> >> +BOOL pending = FALSE;
>> >> +initonce_begin(once_control, 0, , NULL);
>> >> +if (pending)
>> >> +init_routine();
>> >> +initonce_complete(once_control, 0, NULL);
>> >> +return 0;
>> >> +}
>> >> +
>> >> +/* pre-Windows 6.0 compat using a spin-lock */
>> >> +switch (InterlockedCompareExchange(_control->state, 1, 0))
>> >> +{
>> >> +/* Initial run */
>> >> +case 0:
>> >> +init_routine();
>> >> +InterlockedExchange(_control->state, 2);
>> >> +break;
>> >> +/* Another thread is running init */
>> >> +case 1:
>> >> +while (1) {
>> >> +MemoryBarrier();
>> >> +if (once_control->state == 2)
>> >> +break;
>> >> +Sleep(0);
>> >> +}
>> >> +break;
>> >> +/* Initialization complete */
>> >> +case 2:
>> >> +break;
>> >> +}
>> >> +return 0;
>> >> +}
>> >>  #endif
>> >>
>> >>  static av_unused void w32thread_init(void)
>> >> @@ -319,6 +383,10 @@ static av_unused void w32thread_init(void)
>> >>  (void*)GetProcAddress(kernel_dll, "WakeConditionVariable");
>> >>  cond_wait  =
>> >>  (void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS");
>> >> +initonce_begin =
>> >> +(void*)GetProcAddress(kernel_dll, "InitOnceBeginInitialize");
>> >> +initonce_complete =
>> >> +(void*)GetProcAddress(kernel_dll, "InitOnceComplete");
>> >>  #endif
>> >>
>> >>  }
>> >> --
>> >> 2.5.3.windows.1
>> >
>> >
>> > LGTM
>>
>> There is a new version of the patch which also solves the
>> w32thread_init mess, so this one isn't the final version anymore.
>> Current working version is here:
>> https://github.com/Nevcairiel/FFmpeg/commits/pthread_once
>>
>>
> This looks better.
> So by win32thread_init mess im assuming your referring to a need to have
> called it before hand. Given that youve added it to the only 2 functions
> that need it then doesnt that mean that win32thread_init be completely
> removed from all other code and only used locally 

Re: [FFmpeg-devel] [PATCH] w32pthreads: add pthread_once emulation

2015-10-07 Thread Matt Oliver
On 6 October 2015 at 21:36, Hendrik Leppkes  wrote:

> The emulation uses native InitOnce* APIs on Windows Vista+, and a
> lock-free/allocation-free approach using atomics and spinning for Windows
> XP.
> ---
>
> This is in preparation to use pthread_once for global static init
> functions,
> and eventually removing the global lock in avcodec_open2
>
> compat/w32pthreads.h | 68
> 
>  1 file changed, 68 insertions(+)
>
> diff --git a/compat/w32pthreads.h b/compat/w32pthreads.h
> index deb1c53..8523976 100644
> --- a/compat/w32pthreads.h
> +++ b/compat/w32pthreads.h
> @@ -154,6 +154,19 @@ static inline int pthread_cond_signal(pthread_cond_t
> *cond)
>  return 0;
>  }
>
> +typedef INIT_ONCE pthread_once_t;
> +#define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
> +
> +static av_unused int pthread_once(pthread_once_t *once_control, void
> (*init_routine)(void))
> +{
> +BOOL pending = FALSE;
> +InitOnceBeginInitialize(once_control, 0, , NULL);
> +if (pending)
> +init_routine();
> +InitOnceComplete(once_control, 0, NULL);
> +return 0;
> +}
> +
>  #else // _WIN32_WINNT < 0x0600
>  /* for pre-Windows 6.0 platforms we need to define and use our own
> condition
>   * variable and api */
> @@ -304,6 +317,57 @@ static av_unused int
> pthread_cond_signal(pthread_cond_t *cond)
>  pthread_mutex_unlock(_cond->mtx_broadcast);
>  return 0;
>  }
> +
> +/* for pre-Windows 6.0 platforms, define INIT_ONCE struct,
> + * compatible to the one used in the native API */
> +
> +typedef union pthread_once_t  {
> +void * Ptr;///< For the Windows 6.0+ native functions
> +LONG state;///< For the pre-Windows 6.0 compat code
> +} pthread_once_t;
> +
> +#define PTHREAD_ONCE_INIT {0}
> +
> +/* function pointers to init once API on windows 6.0+ kernels */
> +static BOOL (WINAPI *initonce_begin)(pthread_once_t *lpInitOnce, DWORD
> dwFlags, BOOL *fPending, void **lpContext);
> +static BOOL (WINAPI *initonce_complete)(pthread_once_t *lpInitOnce, DWORD
> dwFlags, void *lpContext);
> +
> +static av_unused int pthread_once(pthread_once_t *once_control, void
> (*init_routine)(void))
> +{
> +/* Use native functions on Windows 6.0+ */
> +if (initonce_begin && initonce_complete)
> +{
> +BOOL pending = FALSE;
> +initonce_begin(once_control, 0, , NULL);
> +if (pending)
> +init_routine();
> +initonce_complete(once_control, 0, NULL);
> +return 0;
> +}
> +
> +/* pre-Windows 6.0 compat using a spin-lock */
> +switch (InterlockedCompareExchange(_control->state, 1, 0))
> +{
> +/* Initial run */
> +case 0:
> +init_routine();
> +InterlockedExchange(_control->state, 2);
> +break;
> +/* Another thread is running init */
> +case 1:
> +while (1) {
> +MemoryBarrier();
> +if (once_control->state == 2)
> +break;
> +Sleep(0);
> +}
> +break;
> +/* Initialization complete */
> +case 2:
> +break;
> +}
> +return 0;
> +}
>  #endif
>
>  static av_unused void w32thread_init(void)
> @@ -319,6 +383,10 @@ static av_unused void w32thread_init(void)
>  (void*)GetProcAddress(kernel_dll, "WakeConditionVariable");
>  cond_wait  =
>  (void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS");
> +initonce_begin =
> +(void*)GetProcAddress(kernel_dll, "InitOnceBeginInitialize");
> +initonce_complete =
> +(void*)GetProcAddress(kernel_dll, "InitOnceComplete");
>  #endif
>
>  }
> --
> 2.5.3.windows.1
>
> ___
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


LGTM
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] [PATCH] w32pthreads: add pthread_once emulation

2015-10-07 Thread Matt Oliver
On 8 October 2015 at 03:29, Hendrik Leppkes  wrote:

> On Wed, Oct 7, 2015 at 6:23 PM, Matt Oliver  wrote:
> > On 6 October 2015 at 21:36, Hendrik Leppkes  wrote:
> >
> >> The emulation uses native InitOnce* APIs on Windows Vista+, and a
> >> lock-free/allocation-free approach using atomics and spinning for
> Windows
> >> XP.
> >> ---
> >>
> >> This is in preparation to use pthread_once for global static init
> >> functions,
> >> and eventually removing the global lock in avcodec_open2
> >>
> >> compat/w32pthreads.h | 68
> >> 
> >>  1 file changed, 68 insertions(+)
> >>
> >> diff --git a/compat/w32pthreads.h b/compat/w32pthreads.h
> >> index deb1c53..8523976 100644
> >> --- a/compat/w32pthreads.h
> >> +++ b/compat/w32pthreads.h
> >> @@ -154,6 +154,19 @@ static inline int
> pthread_cond_signal(pthread_cond_t
> >> *cond)
> >>  return 0;
> >>  }
> >>
> >> +typedef INIT_ONCE pthread_once_t;
> >> +#define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
> >> +
> >> +static av_unused int pthread_once(pthread_once_t *once_control, void
> >> (*init_routine)(void))
> >> +{
> >> +BOOL pending = FALSE;
> >> +InitOnceBeginInitialize(once_control, 0, , NULL);
> >> +if (pending)
> >> +init_routine();
> >> +InitOnceComplete(once_control, 0, NULL);
> >> +return 0;
> >> +}
> >> +
> >>  #else // _WIN32_WINNT < 0x0600
> >>  /* for pre-Windows 6.0 platforms we need to define and use our own
> >> condition
> >>   * variable and api */
> >> @@ -304,6 +317,57 @@ static av_unused int
> >> pthread_cond_signal(pthread_cond_t *cond)
> >>  pthread_mutex_unlock(_cond->mtx_broadcast);
> >>  return 0;
> >>  }
> >> +
> >> +/* for pre-Windows 6.0 platforms, define INIT_ONCE struct,
> >> + * compatible to the one used in the native API */
> >> +
> >> +typedef union pthread_once_t  {
> >> +void * Ptr;///< For the Windows 6.0+ native functions
> >> +LONG state;///< For the pre-Windows 6.0 compat code
> >> +} pthread_once_t;
> >> +
> >> +#define PTHREAD_ONCE_INIT {0}
> >> +
> >> +/* function pointers to init once API on windows 6.0+ kernels */
> >> +static BOOL (WINAPI *initonce_begin)(pthread_once_t *lpInitOnce, DWORD
> >> dwFlags, BOOL *fPending, void **lpContext);
> >> +static BOOL (WINAPI *initonce_complete)(pthread_once_t *lpInitOnce,
> DWORD
> >> dwFlags, void *lpContext);
> >> +
> >> +static av_unused int pthread_once(pthread_once_t *once_control, void
> >> (*init_routine)(void))
> >> +{
> >> +/* Use native functions on Windows 6.0+ */
> >> +if (initonce_begin && initonce_complete)
> >> +{
> >> +BOOL pending = FALSE;
> >> +initonce_begin(once_control, 0, , NULL);
> >> +if (pending)
> >> +init_routine();
> >> +initonce_complete(once_control, 0, NULL);
> >> +return 0;
> >> +}
> >> +
> >> +/* pre-Windows 6.0 compat using a spin-lock */
> >> +switch (InterlockedCompareExchange(_control->state, 1, 0))
> >> +{
> >> +/* Initial run */
> >> +case 0:
> >> +init_routine();
> >> +InterlockedExchange(_control->state, 2);
> >> +break;
> >> +/* Another thread is running init */
> >> +case 1:
> >> +while (1) {
> >> +MemoryBarrier();
> >> +if (once_control->state == 2)
> >> +break;
> >> +Sleep(0);
> >> +}
> >> +break;
> >> +/* Initialization complete */
> >> +case 2:
> >> +break;
> >> +}
> >> +return 0;
> >> +}
> >>  #endif
> >>
> >>  static av_unused void w32thread_init(void)
> >> @@ -319,6 +383,10 @@ static av_unused void w32thread_init(void)
> >>  (void*)GetProcAddress(kernel_dll, "WakeConditionVariable");
> >>  cond_wait  =
> >>  (void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS");
> >> +initonce_begin =
> >> +(void*)GetProcAddress(kernel_dll, "InitOnceBeginInitialize");
> >> +initonce_complete =
> >> +(void*)GetProcAddress(kernel_dll, "InitOnceComplete");
> >>  #endif
> >>
> >>  }
> >> --
> >> 2.5.3.windows.1
> >
> >
> > LGTM
>
> There is a new version of the patch which also solves the
> w32thread_init mess, so this one isn't the final version anymore.
> Current working version is here:
> https://github.com/Nevcairiel/FFmpeg/commits/pthread_once
>
>
This looks better.
So by win32thread_init mess im assuming your referring to a need to have
called it before hand. Given that youve added it to the only 2 functions
that need it then doesnt that mean that win32thread_init be completely
removed from all other code and only used locally in w32pthread.h and only
when WIN32_WINNT<0x600.
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


[FFmpeg-devel] [PATCH] w32pthreads: add pthread_once emulation

2015-10-06 Thread Hendrik Leppkes
The emulation uses native InitOnce* APIs on Windows Vista+, and a
lock-free/allocation-free approach using atomics and spinning for Windows XP.
---

This is in preparation to use pthread_once for global static init functions,
and eventually removing the global lock in avcodec_open2

compat/w32pthreads.h | 68 
 1 file changed, 68 insertions(+)

diff --git a/compat/w32pthreads.h b/compat/w32pthreads.h
index deb1c53..8523976 100644
--- a/compat/w32pthreads.h
+++ b/compat/w32pthreads.h
@@ -154,6 +154,19 @@ static inline int pthread_cond_signal(pthread_cond_t *cond)
 return 0;
 }
 
+typedef INIT_ONCE pthread_once_t;
+#define PTHREAD_ONCE_INIT INIT_ONCE_STATIC_INIT
+
+static av_unused int pthread_once(pthread_once_t *once_control, void 
(*init_routine)(void))
+{
+BOOL pending = FALSE;
+InitOnceBeginInitialize(once_control, 0, , NULL);
+if (pending)
+init_routine();
+InitOnceComplete(once_control, 0, NULL);
+return 0;
+}
+
 #else // _WIN32_WINNT < 0x0600
 /* for pre-Windows 6.0 platforms we need to define and use our own condition
  * variable and api */
@@ -304,6 +317,57 @@ static av_unused int pthread_cond_signal(pthread_cond_t 
*cond)
 pthread_mutex_unlock(_cond->mtx_broadcast);
 return 0;
 }
+
+/* for pre-Windows 6.0 platforms, define INIT_ONCE struct,
+ * compatible to the one used in the native API */
+
+typedef union pthread_once_t  {
+void * Ptr;///< For the Windows 6.0+ native functions
+LONG state;///< For the pre-Windows 6.0 compat code
+} pthread_once_t;
+
+#define PTHREAD_ONCE_INIT {0}
+
+/* function pointers to init once API on windows 6.0+ kernels */
+static BOOL (WINAPI *initonce_begin)(pthread_once_t *lpInitOnce, DWORD 
dwFlags, BOOL *fPending, void **lpContext);
+static BOOL (WINAPI *initonce_complete)(pthread_once_t *lpInitOnce, DWORD 
dwFlags, void *lpContext);
+
+static av_unused int pthread_once(pthread_once_t *once_control, void 
(*init_routine)(void))
+{
+/* Use native functions on Windows 6.0+ */
+if (initonce_begin && initonce_complete)
+{
+BOOL pending = FALSE;
+initonce_begin(once_control, 0, , NULL);
+if (pending)
+init_routine();
+initonce_complete(once_control, 0, NULL);
+return 0;
+}
+
+/* pre-Windows 6.0 compat using a spin-lock */
+switch (InterlockedCompareExchange(_control->state, 1, 0))
+{
+/* Initial run */
+case 0:
+init_routine();
+InterlockedExchange(_control->state, 2);
+break;
+/* Another thread is running init */
+case 1:
+while (1) {
+MemoryBarrier();
+if (once_control->state == 2)
+break;
+Sleep(0);
+}
+break;
+/* Initialization complete */
+case 2:
+break;
+}
+return 0;
+}
 #endif
 
 static av_unused void w32thread_init(void)
@@ -319,6 +383,10 @@ static av_unused void w32thread_init(void)
 (void*)GetProcAddress(kernel_dll, "WakeConditionVariable");
 cond_wait  =
 (void*)GetProcAddress(kernel_dll, "SleepConditionVariableCS");
+initonce_begin =
+(void*)GetProcAddress(kernel_dll, "InitOnceBeginInitialize");
+initonce_complete =
+(void*)GetProcAddress(kernel_dll, "InitOnceComplete");
 #endif
 
 }
-- 
2.5.3.windows.1

___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel