[1/2] Replace all usage of strcasecmp/strncasecmp

Message ID 1320412690-74862-1-git-send-email-martin@martin.st
State Superseded
Headers show

Commit Message

Martin Storsjö Nov. 4, 2011, 1:18 p.m.
From: Reimar Döffinger <Reimar.Doeffinger@gmx.de>

All current usages of it are incompatible with localization.
For example strcasecmp("i", "I") != 0 is possible, but would
break many of the places where it is used.

Instead use our own implementations that always treat the data
as ASCII.
---
 avserver.c                 |  177 ++++++++++++++++++++++----------------------
 doc/APIchanges             |    3 +
 libavdevice/v4l2.c         |    4 +-
 libavformat/avidec.c       |    4 +-
 libavformat/http.c         |   17 ++--
 libavformat/img2.c         |    3 +-
 libavformat/matroskaenc.c  |    4 +-
 libavformat/metadata.c     |    6 +-
 libavformat/mp3enc.c       |    3 +-
 libavformat/nutdec.c       |    5 +-
 libavformat/rtpdec.c       |    4 +-
 libavformat/rtpdec_mpeg4.c |    3 +-
 libavformat/rtsp.c         |   11 +--
 libavformat/utils.c        |    7 +-
 libavutil/avstring.c       |   27 +++++++
 libavutil/avstring.h       |   12 +++
 libavutil/avutil.h         |    2 +-
 libavutil/internal.h       |    4 +
 libavutil/parseutils.c     |    7 +-
 19 files changed, 170 insertions(+), 133 deletions(-)

Comments

Luca Barbato Nov. 4, 2011, 2:31 p.m. | #1
On 11/4/11 6:18 AM, Martin Storsjö wrote:
> From: Reimar Döffinger<Reimar.Doeffinger@gmx.de>
>
> All current usages of it are incompatible with localization.
> For example strcasecmp("i", "I") != 0 is possible, but would
> break many of the places where it is used.
>
> Instead use our own implementations that always treat the data
> as ASCII.
> ---

Seems safe.
Mans Rullgard Nov. 4, 2011, 3:13 p.m. | #2
Luca Barbato <lu_zero@gentoo.org> writes:

> On 11/4/11 6:18 AM, Martin Storsjö wrote:
>> From: Reimar Döffinger<Reimar.Doeffinger@gmx.de>
>>
>> All current usages of it are incompatible with localization.
>> For example strcasecmp("i", "I") != 0 is possible, but would
>> break many of the places where it is used.
>>
>> Instead use our own implementations that always treat the data
>> as ASCII.
>> ---
>
> Seems safe.

The implementation is ugly.
Luca Barbato Nov. 4, 2011, 3:33 p.m. | #3
On 11/4/11 8:13 AM, Måns Rullgård wrote:
> Luca Barbato<lu_zero@gentoo.org>  writes:
>
>> On 11/4/11 6:18 AM, Martin Storsjö wrote:
>>> From: Reimar Döffinger<Reimar.Doeffinger@gmx.de>
>>>
>>> All current usages of it are incompatible with localization.
>>> For example strcasecmp("i", "I") != 0 is possible, but would
>>> break many of the places where it is used.
>>>
>>> Instead use our own implementations that always treat the data
>>> as ASCII.
>>> ---
>>
>> Seems safe.
>
> The implementation is ugly.

Shall we borrow the newlib implementation?

lu
Luca Barbato Nov. 4, 2011, 3:54 p.m. | #4
On 11/4/11 8:13 AM, Måns Rullgård wrote:
> Luca Barbato<lu_zero@gentoo.org>  writes:
>
>> On 11/4/11 6:18 AM, Martin Storsjö wrote:
>>> From: Reimar Döffinger<Reimar.Doeffinger@gmx.de>
>>>
>>> All current usages of it are incompatible with localization.
>>> For example strcasecmp("i", "I") != 0 is possible, but would
>>> break many of the places where it is used.
>>>
>>> Instead use our own implementations that always treat the data
>>> as ASCII.
>>> ---
>>
>> Seems safe.
>
> The implementation is ugly.

we could use toupper_l maybe?
Mans Rullgard Nov. 4, 2011, 3:59 p.m. | #5
Luca Barbato <lu_zero@gentoo.org> writes:

> On 11/4/11 8:13 AM, Måns Rullgård wrote:
>> Luca Barbato<lu_zero@gentoo.org>  writes:
>>
>>> On 11/4/11 6:18 AM, Martin Storsjö wrote:
>>>> From: Reimar Döffinger<Reimar.Doeffinger@gmx.de>
>>>>
>>>> All current usages of it are incompatible with localization.
>>>> For example strcasecmp("i", "I") != 0 is possible, but would
>>>> break many of the places where it is used.
>>>>
>>>> Instead use our own implementations that always treat the data
>>>> as ASCII.
>>>> ---
>>>
>>> Seems safe.
>>
>> The implementation is ugly.
>
> we could use toupper_l maybe?

Ugh no.
Diego Biurrun Nov. 4, 2011, 4:23 p.m. | #6
On Fri, Nov 04, 2011 at 03:59:15PM +0000, Måns Rullgård wrote:
> Luca Barbato <lu_zero@gentoo.org> writes:
> > On 11/4/11 8:13 AM, Måns Rullgård wrote:
> >> Luca Barbato<lu_zero@gentoo.org>  writes:
> >>> On 11/4/11 6:18 AM, Martin Storsjö wrote:
> >>>> From: Reimar Döffinger<Reimar.Doeffinger@gmx.de>
> >>>>
> >>>> All current usages of it are incompatible with localization.
> >>>> For example strcasecmp("i", "I") != 0 is possible, but would
> >>>> break many of the places where it is used.
> >>>>
> >>>> Instead use our own implementations that always treat the data
> >>>> as ASCII.
> >>>> ---
> >>>
> >>> Seems safe.
> >>
> >> The implementation is ugly.
> >
> > we could use toupper_l maybe?
> 
> Ugh no.

So what should we do?

Diego
Mans Rullgard Nov. 4, 2011, 4:28 p.m. | #7
Diego Biurrun <diego@biurrun.de> writes:

> On Fri, Nov 04, 2011 at 03:59:15PM +0000, Måns Rullgård wrote:
>> Luca Barbato <lu_zero@gentoo.org> writes:
>> > On 11/4/11 8:13 AM, Måns Rullgård wrote:
>> >> Luca Barbato<lu_zero@gentoo.org>  writes:
>> >>> On 11/4/11 6:18 AM, Martin Storsjö wrote:
>> >>>> From: Reimar Döffinger<Reimar.Doeffinger@gmx.de>
>> >>>>
>> >>>> All current usages of it are incompatible with localization.
>> >>>> For example strcasecmp("i", "I") != 0 is possible, but would
>> >>>> break many of the places where it is used.
>> >>>>
>> >>>> Instead use our own implementations that always treat the data
>> >>>> as ASCII.
>> >>>> ---
>> >>>
>> >>> Seems safe.
>> >>
>> >> The implementation is ugly.
>> >
>> > we could use toupper_l maybe?
>> 
>> Ugh no.
>
> So what should we do?

Write it in a non-ugly way of course.
Luca Barbato Nov. 4, 2011, 4:40 p.m. | #8
On 11/4/11 9:28 AM, Måns Rullgård wrote:
> Write it in a non-ugly way of course.

Let me expand:

- the strcasecmp/strncasecmp itself isn't much different than the usual 
libc implementation, the toupper can enjoy a better implementation (to 
be noted that in all libc I had a look into strcase uses tolower).

- we can pick any tolower macro implementation from a libc with a 
acceptable license instead of reinventing the wheel.

lu
Mans Rullgard Nov. 4, 2011, 4:42 p.m. | #9
Luca Barbato <lu_zero@gentoo.org> writes:

> On 11/4/11 9:28 AM, Måns Rullgård wrote:
>> Write it in a non-ugly way of course.
>
> Let me expand:
>
> - the strcasecmp/strncasecmp itself isn't much different than the
> usual libc implementation, the toupper can enjoy a better
> implementation (to be noted that in all libc I had a look into strcase
> uses tolower).

Yes, that macro is what I was talking about.
Kostya Shishkov Nov. 4, 2011, 4:43 p.m. | #10
On Fri, Nov 04, 2011 at 04:28:14PM +0000, Måns Rullgård wrote:
> Diego Biurrun <diego@biurrun.de> writes:
> 
> > On Fri, Nov 04, 2011 at 03:59:15PM +0000, Måns Rullgård wrote:
> >> Luca Barbato <lu_zero@gentoo.org> writes:
> >> > On 11/4/11 8:13 AM, Måns Rullgård wrote:
> >> >> Luca Barbato<lu_zero@gentoo.org>  writes:
> >> >>> On 11/4/11 6:18 AM, Martin Storsjö wrote:
> >> >>>> From: Reimar Döffinger<Reimar.Doeffinger@gmx.de>
> >> >>>>
> >> >>>> All current usages of it are incompatible with localization.
> >> >>>> For example strcasecmp("i", "I") != 0 is possible, but would
> >> >>>> break many of the places where it is used.
> >> >>>>
> >> >>>> Instead use our own implementations that always treat the data
> >> >>>> as ASCII.
> >> >>>> ---
> >> >>>
> >> >>> Seems safe.
> >> >>
> >> >> The implementation is ugly.
> >> >
> >> > we could use toupper_l maybe?
> >> 
> >> Ugh no.
> >
> > So what should we do?
> 
> Write it in a non-ugly way of course.

That comment was not really helpful.
Kostya Shishkov Nov. 4, 2011, 4:45 p.m. | #11
On Fri, Nov 04, 2011 at 04:42:11PM +0000, Måns Rullgård wrote:
> Luca Barbato <lu_zero@gentoo.org> writes:
> 
> > On 11/4/11 9:28 AM, Måns Rullgård wrote:
> >> Write it in a non-ugly way of course.
> >
> > Let me expand:
> >
> > - the strcasecmp/strncasecmp itself isn't much different than the
> > usual libc implementation, the toupper can enjoy a better
> > implementation (to be noted that in all libc I had a look into strcase
> > uses tolower).
> 
> Yes, that macro is what I was talking about.

What about

#define TOUPPER(c) \
   if (c >= 'a' && c <= 'z') \
       c ^= 0x20;
Diego Biurrun Nov. 4, 2011, 5:02 p.m. | #12
On Fri, Nov 04, 2011 at 05:43:50PM +0100, Kostya Shishkov wrote:
> On Fri, Nov 04, 2011 at 04:28:14PM +0000, Måns Rullgård wrote:
> > Diego Biurrun <diego@biurrun.de> writes:
> > 
> > > On Fri, Nov 04, 2011 at 03:59:15PM +0000, Måns Rullgård wrote:
> > >> Luca Barbato <lu_zero@gentoo.org> writes:
> > >> > On 11/4/11 8:13 AM, Måns Rullgård wrote:
> > >> >> Luca Barbato<lu_zero@gentoo.org>  writes:
> > >> >>> On 11/4/11 6:18 AM, Martin Storsjö wrote:
> > >> >>>> From: Reimar Döffinger<Reimar.Doeffinger@gmx.de>
> > >> >>>>
> > >> >>>> All current usages of it are incompatible with localization.
> > >> >>>> For example strcasecmp("i", "I") != 0 is possible, but would
> > >> >>>> break many of the places where it is used.
> > >> >>>>
> > >> >>>> Instead use our own implementations that always treat the data
> > >> >>>> as ASCII.
> > >> >>>> ---
> > >> >>>
> > >> >>> Seems safe.
> > >> >>
> > >> >> The implementation is ugly.
> > >> >
> > >> > we could use toupper_l maybe?
> > >> 
> > >> Ugh no.
> > >
> > > So what should we do?
> > 
> > Write it in a non-ugly way of course.
> 
> That comment was not really helpful.

Captain Rullgard's first name is "Obvious" :)

Diego
Luca Barbato Nov. 4, 2011, 5:58 p.m. | #13
On 11/4/11 9:45 AM, Kostya Shishkov wrote:
> On Fri, Nov 04, 2011 at 04:42:11PM +0000, Måns Rullgård wrote:
>> Luca Barbato<lu_zero@gentoo.org>  writes:
>>
>>> On 11/4/11 9:28 AM, Måns Rullgård wrote:
>>>> Write it in a non-ugly way of course.
>>>
>>> Let me expand:
>>>
>>> - the strcasecmp/strncasecmp itself isn't much different than the
>>> usual libc implementation, the toupper can enjoy a better
>>> implementation (to be noted that in all libc I had a look into strcase
>>> uses tolower).
>>
>> Yes, that macro is what I was talking about.
>
> What about
>
> #define TOUPPER(c) \
>     if (c>= 'a'&&  c<= 'z') \
>         c ^= 0x20;

Looks nicer.

lu
Mans Rullgard Nov. 4, 2011, 6:16 p.m. | #14
Luca Barbato <lu_zero@gentoo.org> writes:

> On 11/4/11 9:45 AM, Kostya Shishkov wrote:
>> On Fri, Nov 04, 2011 at 04:42:11PM +0000, Måns Rullgård wrote:
>>> Luca Barbato<lu_zero@gentoo.org>  writes:
>>>
>>>> On 11/4/11 9:28 AM, Måns Rullgård wrote:
>>>>> Write it in a non-ugly way of course.
>>>>
>>>> Let me expand:
>>>>
>>>> - the strcasecmp/strncasecmp itself isn't much different than the
>>>> usual libc implementation, the toupper can enjoy a better
>>>> implementation (to be noted that in all libc I had a look into strcase
>>>> uses tolower).
>>>
>>> Yes, that macro is what I was talking about.
>>
>> What about
>>
>> #define TOUPPER(c) \
>>     if (c>= 'a'&&  c<= 'z') \
>>         c ^= 0x20;
>
> Looks nicer.

I'd make it a bit more function-like or even an inline function.

Patch

diff --git a/avserver.c b/avserver.c
index fb719e2..5b9dcc9 100644
--- a/avserver.c
+++ b/avserver.c
@@ -24,7 +24,6 @@ 
 #define closesocket close
 #endif
 #include <string.h>
-#include <strings.h>
 #include <stdlib.h>
 #include "libavformat/avformat.h"
 #include "libavformat/ffm.h"
@@ -1085,13 +1084,13 @@  static int extract_rates(char *rates, int ratelen, const char *request)
     const char *p;
 
     for (p = request; *p && *p != '\r' && *p != '\n'; ) {
-        if (strncasecmp(p, "Pragma:", 7) == 0) {
+        if (av_strncasecmp(p, "Pragma:", 7) == 0) {
             const char *q = p + 7;
 
             while (*q && *q != '\n' && isspace(*q))
                 q++;
 
-            if (strncasecmp(q, "stream-switch-entry=", 20) == 0) {
+            if (av_strncasecmp(q, "stream-switch-entry=", 20) == 0) {
                 int stream_no;
                 int rate_no;
 
@@ -1271,9 +1270,9 @@  static void parse_acl_row(FFStream *stream, FFStream* feed, IPAddressACL *ext_ac
     int errors = 0;
 
     get_arg(arg, sizeof(arg), &p);
-    if (strcasecmp(arg, "allow") == 0)
+    if (av_strcasecmp(arg, "allow") == 0)
         acl.action = IP_ALLOW;
-    else if (strcasecmp(arg, "deny") == 0)
+    else if (av_strcasecmp(arg, "deny") == 0)
         acl.action = IP_DENY;
     else {
         fprintf(stderr, "%s:%d: ACL action '%s' is not ALLOW or DENY\n",
@@ -1358,7 +1357,7 @@  static IPAddressACL* parse_dynamic_acl(FFStream *stream, HTTPContext *c)
             continue;
         get_arg(cmd, sizeof(cmd), &p);
 
-        if (!strcasecmp(cmd, "ACL"))
+        if (!av_strcasecmp(cmd, "ACL"))
             parse_acl_row(NULL, NULL, acl, p, stream->dynamic_acl, line_num);
     }
     fclose(f);
@@ -1500,7 +1499,7 @@  static int http_parse_request(HTTPContext *c)
     av_strlcpy(filename, url + ((*url == '/') ? 1 : 0), sizeof(filename)-1);
 
     for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
-        if (strncasecmp(p, "User-Agent:", 11) == 0) {
+        if (av_strncasecmp(p, "User-Agent:", 11) == 0) {
             useragent = p + 11;
             if (*useragent && *useragent != '\n' && isspace(*useragent))
                 useragent++;
@@ -1518,7 +1517,7 @@  static int http_parse_request(HTTPContext *c)
         redir_type = REDIR_ASX;
         filename[strlen(filename)-1] = 'f';
     } else if (av_match_ext(filename, "asf") &&
-        (!useragent || strncasecmp(useragent, "NSPlayer", 8) != 0)) {
+        (!useragent || av_strncasecmp(useragent, "NSPlayer", 8) != 0)) {
         /* if this isn't WMP or lookalike, return the redirector file */
         redir_type = REDIR_ASF;
     } else if (av_match_ext(filename, "rpm,ram")) {
@@ -1613,7 +1612,7 @@  static int http_parse_request(HTTPContext *c)
         char *hostinfo = 0;
 
         for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
-            if (strncasecmp(p, "Host:", 5) == 0) {
+            if (av_strncasecmp(p, "Host:", 5) == 0) {
                 hostinfo = p + 5;
                 break;
             }
@@ -1742,11 +1741,11 @@  static int http_parse_request(HTTPContext *c)
             int client_id = 0;
 
             for (p = c->buffer; *p && *p != '\r' && *p != '\n'; ) {
-                if (strncasecmp(p, "Pragma: log-line=", 17) == 0) {
+                if (av_strncasecmp(p, "Pragma: log-line=", 17) == 0) {
                     logline = p;
                     break;
                 }
-                if (strncasecmp(p, "Pragma: client-id=", 18) == 0)
+                if (av_strncasecmp(p, "Pragma: client-id=", 18) == 0)
                     client_id = strtol(p + 18, 0, 10);
                 p = strchr(p, '\n');
                 if (!p)
@@ -4059,40 +4058,40 @@  static int parse_ffconfig(const char *filename)
 
         get_arg(cmd, sizeof(cmd), &p);
 
-        if (!strcasecmp(cmd, "Port")) {
+        if (!av_strcasecmp(cmd, "Port")) {
             get_arg(arg, sizeof(arg), &p);
             val = atoi(arg);
             if (val < 1 || val > 65536) {
                 ERROR("Invalid_port: %s\n", arg);
             }
             my_http_addr.sin_port = htons(val);
-        } else if (!strcasecmp(cmd, "BindAddress")) {
+        } else if (!av_strcasecmp(cmd, "BindAddress")) {
             get_arg(arg, sizeof(arg), &p);
             if (resolve_host(&my_http_addr.sin_addr, arg) != 0) {
                 ERROR("%s:%d: Invalid host/IP address: %s\n", arg);
             }
-        } else if (!strcasecmp(cmd, "NoDaemon")) {
+        } else if (!av_strcasecmp(cmd, "NoDaemon")) {
             avserver_daemon = 0;
-        } else if (!strcasecmp(cmd, "RTSPPort")) {
+        } else if (!av_strcasecmp(cmd, "RTSPPort")) {
             get_arg(arg, sizeof(arg), &p);
             val = atoi(arg);
             if (val < 1 || val > 65536) {
                 ERROR("%s:%d: Invalid port: %s\n", arg);
             }
             my_rtsp_addr.sin_port = htons(atoi(arg));
-        } else if (!strcasecmp(cmd, "RTSPBindAddress")) {
+        } else if (!av_strcasecmp(cmd, "RTSPBindAddress")) {
             get_arg(arg, sizeof(arg), &p);
             if (resolve_host(&my_rtsp_addr.sin_addr, arg) != 0) {
                 ERROR("Invalid host/IP address: %s\n", arg);
             }
-        } else if (!strcasecmp(cmd, "MaxHTTPConnections")) {
+        } else if (!av_strcasecmp(cmd, "MaxHTTPConnections")) {
             get_arg(arg, sizeof(arg), &p);
             val = atoi(arg);
             if (val < 1 || val > 65536) {
                 ERROR("Invalid MaxHTTPConnections: %s\n", arg);
             }
             nb_max_http_connections = val;
-        } else if (!strcasecmp(cmd, "MaxClients")) {
+        } else if (!av_strcasecmp(cmd, "MaxClients")) {
             get_arg(arg, sizeof(arg), &p);
             val = atoi(arg);
             if (val < 1 || val > nb_max_http_connections) {
@@ -4100,7 +4099,7 @@  static int parse_ffconfig(const char *filename)
             } else {
                 nb_max_connections = val;
             }
-        } else if (!strcasecmp(cmd, "MaxBandwidth")) {
+        } else if (!av_strcasecmp(cmd, "MaxBandwidth")) {
             int64_t llval;
             get_arg(arg, sizeof(arg), &p);
             llval = atoll(arg);
@@ -4108,10 +4107,10 @@  static int parse_ffconfig(const char *filename)
                 ERROR("Invalid MaxBandwidth: %s\n", arg);
             } else
                 max_bandwidth = llval;
-        } else if (!strcasecmp(cmd, "CustomLog")) {
+        } else if (!av_strcasecmp(cmd, "CustomLog")) {
             if (!avserver_debug)
                 get_arg(logfilename, sizeof(logfilename), &p);
-        } else if (!strcasecmp(cmd, "<Feed")) {
+        } else if (!av_strcasecmp(cmd, "<Feed")) {
             /*********************************************/
             /* Feed related options */
             char *q;
@@ -4145,7 +4144,7 @@  static int parse_ffconfig(const char *filename)
                 *last_feed = feed;
                 last_feed = &feed->next_feed;
             }
-        } else if (!strcasecmp(cmd, "Launch")) {
+        } else if (!av_strcasecmp(cmd, "Launch")) {
             if (feed) {
                 int i;
 
@@ -4167,24 +4166,24 @@  static int parse_ffconfig(const char *filename)
                     inet_ntoa(my_http_addr.sin_addr),
                     ntohs(my_http_addr.sin_port), feed->filename);
             }
-        } else if (!strcasecmp(cmd, "ReadOnlyFile")) {
+        } else if (!av_strcasecmp(cmd, "ReadOnlyFile")) {
             if (feed) {
                 get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
                 feed->readonly = 1;
             } else if (stream) {
                 get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
             }
-        } else if (!strcasecmp(cmd, "File")) {
+        } else if (!av_strcasecmp(cmd, "File")) {
             if (feed) {
                 get_arg(feed->feed_filename, sizeof(feed->feed_filename), &p);
             } else if (stream)
                 get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
-        } else if (!strcasecmp(cmd, "Truncate")) {
+        } else if (!av_strcasecmp(cmd, "Truncate")) {
             if (feed) {
                 get_arg(arg, sizeof(arg), &p);
                 feed->truncate = strtod(arg, NULL);
             }
-        } else if (!strcasecmp(cmd, "FileMaxSize")) {
+        } else if (!av_strcasecmp(cmd, "FileMaxSize")) {
             if (feed) {
                 char *p1;
                 double fsize;
@@ -4208,12 +4207,12 @@  static int parse_ffconfig(const char *filename)
                     ERROR("Feed max file size is too small, must be at least %d\n", FFM_PACKET_SIZE*4);
                 }
             }
-        } else if (!strcasecmp(cmd, "</Feed>")) {
+        } else if (!av_strcasecmp(cmd, "</Feed>")) {
             if (!feed) {
                 ERROR("No corresponding <Feed> for </Feed>\n");
             }
             feed = NULL;
-        } else if (!strcasecmp(cmd, "<Stream")) {
+        } else if (!av_strcasecmp(cmd, "<Stream")) {
             /*********************************************/
             /* Stream related options */
             char *q;
@@ -4246,7 +4245,7 @@  static int parse_ffconfig(const char *filename)
                 *last_stream = stream;
                 last_stream = &stream->next;
             }
-        } else if (!strcasecmp(cmd, "Feed")) {
+        } else if (!av_strcasecmp(cmd, "Feed")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream) {
                 FFStream *sfeed;
@@ -4262,7 +4261,7 @@  static int parse_ffconfig(const char *filename)
                 else
                     stream->feed = sfeed;
             }
-        } else if (!strcasecmp(cmd, "Format")) {
+        } else if (!av_strcasecmp(cmd, "Format")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream) {
                 if (!strcmp(arg, "status")) {
@@ -4283,7 +4282,7 @@  static int parse_ffconfig(const char *filename)
                     video_id = stream->fmt->video_codec;
                 }
             }
-        } else if (!strcasecmp(cmd, "InputFormat")) {
+        } else if (!av_strcasecmp(cmd, "InputFormat")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream) {
                 stream->ifmt = av_find_input_format(arg);
@@ -4291,65 +4290,65 @@  static int parse_ffconfig(const char *filename)
                     ERROR("Unknown input format: %s\n", arg);
                 }
             }
-        } else if (!strcasecmp(cmd, "FaviconURL")) {
+        } else if (!av_strcasecmp(cmd, "FaviconURL")) {
             if (stream && stream->stream_type == STREAM_TYPE_STATUS) {
                 get_arg(stream->feed_filename, sizeof(stream->feed_filename), &p);
             } else {
                 ERROR("FaviconURL only permitted for status streams\n");
             }
-        } else if (!strcasecmp(cmd, "Author")) {
+        } else if (!av_strcasecmp(cmd, "Author")) {
             if (stream)
                 get_arg(stream->author, sizeof(stream->author), &p);
-        } else if (!strcasecmp(cmd, "Comment")) {
+        } else if (!av_strcasecmp(cmd, "Comment")) {
             if (stream)
                 get_arg(stream->comment, sizeof(stream->comment), &p);
-        } else if (!strcasecmp(cmd, "Copyright")) {
+        } else if (!av_strcasecmp(cmd, "Copyright")) {
             if (stream)
                 get_arg(stream->copyright, sizeof(stream->copyright), &p);
-        } else if (!strcasecmp(cmd, "Title")) {
+        } else if (!av_strcasecmp(cmd, "Title")) {
             if (stream)
                 get_arg(stream->title, sizeof(stream->title), &p);
-        } else if (!strcasecmp(cmd, "Preroll")) {
+        } else if (!av_strcasecmp(cmd, "Preroll")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream)
                 stream->prebuffer = atof(arg) * 1000;
-        } else if (!strcasecmp(cmd, "StartSendOnKey")) {
+        } else if (!av_strcasecmp(cmd, "StartSendOnKey")) {
             if (stream)
                 stream->send_on_key = 1;
-        } else if (!strcasecmp(cmd, "AudioCodec")) {
+        } else if (!av_strcasecmp(cmd, "AudioCodec")) {
             get_arg(arg, sizeof(arg), &p);
             audio_id = opt_audio_codec(arg);
             if (audio_id == CODEC_ID_NONE) {
                 ERROR("Unknown AudioCodec: %s\n", arg);
             }
-        } else if (!strcasecmp(cmd, "VideoCodec")) {
+        } else if (!av_strcasecmp(cmd, "VideoCodec")) {
             get_arg(arg, sizeof(arg), &p);
             video_id = opt_video_codec(arg);
             if (video_id == CODEC_ID_NONE) {
                 ERROR("Unknown VideoCodec: %s\n", arg);
             }
-        } else if (!strcasecmp(cmd, "MaxTime")) {
+        } else if (!av_strcasecmp(cmd, "MaxTime")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream)
                 stream->max_time = atof(arg) * 1000;
-        } else if (!strcasecmp(cmd, "AudioBitRate")) {
+        } else if (!av_strcasecmp(cmd, "AudioBitRate")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream)
                 audio_enc.bit_rate = lrintf(atof(arg) * 1000);
-        } else if (!strcasecmp(cmd, "AudioChannels")) {
+        } else if (!av_strcasecmp(cmd, "AudioChannels")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream)
                 audio_enc.channels = atoi(arg);
-        } else if (!strcasecmp(cmd, "AudioSampleRate")) {
+        } else if (!av_strcasecmp(cmd, "AudioSampleRate")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream)
                 audio_enc.sample_rate = atoi(arg);
-        } else if (!strcasecmp(cmd, "AudioQuality")) {
+        } else if (!av_strcasecmp(cmd, "AudioQuality")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream) {
 //                audio_enc.quality = atof(arg) * 1000;
             }
-        } else if (!strcasecmp(cmd, "VideoBitRateRange")) {
+        } else if (!av_strcasecmp(cmd, "VideoBitRateRange")) {
             if (stream) {
                 int minrate, maxrate;
 
@@ -4362,32 +4361,32 @@  static int parse_ffconfig(const char *filename)
                     ERROR("Incorrect format for VideoBitRateRange -- should be <min>-<max>: %s\n", arg);
                 }
             }
-        } else if (!strcasecmp(cmd, "Debug")) {
+        } else if (!av_strcasecmp(cmd, "Debug")) {
             if (stream) {
                 get_arg(arg, sizeof(arg), &p);
                 video_enc.debug = strtol(arg,0,0);
             }
-        } else if (!strcasecmp(cmd, "Strict")) {
+        } else if (!av_strcasecmp(cmd, "Strict")) {
             if (stream) {
                 get_arg(arg, sizeof(arg), &p);
                 video_enc.strict_std_compliance = atoi(arg);
             }
-        } else if (!strcasecmp(cmd, "VideoBufferSize")) {
+        } else if (!av_strcasecmp(cmd, "VideoBufferSize")) {
             if (stream) {
                 get_arg(arg, sizeof(arg), &p);
                 video_enc.rc_buffer_size = atoi(arg) * 8*1024;
             }
-        } else if (!strcasecmp(cmd, "VideoBitRateTolerance")) {
+        } else if (!av_strcasecmp(cmd, "VideoBitRateTolerance")) {
             if (stream) {
                 get_arg(arg, sizeof(arg), &p);
                 video_enc.bit_rate_tolerance = atoi(arg) * 1000;
             }
-        } else if (!strcasecmp(cmd, "VideoBitRate")) {
+        } else if (!av_strcasecmp(cmd, "VideoBitRate")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream) {
                 video_enc.bit_rate = atoi(arg) * 1000;
             }
-        } else if (!strcasecmp(cmd, "VideoSize")) {
+        } else if (!av_strcasecmp(cmd, "VideoSize")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream) {
                 av_parse_video_size(&video_enc.width, &video_enc.height, arg);
@@ -4396,7 +4395,7 @@  static int parse_ffconfig(const char *filename)
                     ERROR("Image size must be a multiple of 16\n");
                 }
             }
-        } else if (!strcasecmp(cmd, "VideoFrameRate")) {
+        } else if (!av_strcasecmp(cmd, "VideoFrameRate")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream) {
                 AVRational frame_rate;
@@ -4407,29 +4406,29 @@  static int parse_ffconfig(const char *filename)
                     video_enc.time_base.den = frame_rate.num;
                 }
             }
-        } else if (!strcasecmp(cmd, "VideoGopSize")) {
+        } else if (!av_strcasecmp(cmd, "VideoGopSize")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream)
                 video_enc.gop_size = atoi(arg);
-        } else if (!strcasecmp(cmd, "VideoIntraOnly")) {
+        } else if (!av_strcasecmp(cmd, "VideoIntraOnly")) {
             if (stream)
                 video_enc.gop_size = 1;
-        } else if (!strcasecmp(cmd, "VideoHighQuality")) {
+        } else if (!av_strcasecmp(cmd, "VideoHighQuality")) {
             if (stream)
                 video_enc.mb_decision = FF_MB_DECISION_BITS;
-        } else if (!strcasecmp(cmd, "Video4MotionVector")) {
+        } else if (!av_strcasecmp(cmd, "Video4MotionVector")) {
             if (stream) {
                 video_enc.mb_decision = FF_MB_DECISION_BITS; //FIXME remove
                 video_enc.flags |= CODEC_FLAG_4MV;
             }
-        } else if (!strcasecmp(cmd, "AVOptionVideo") ||
-                   !strcasecmp(cmd, "AVOptionAudio")) {
+        } else if (!av_strcasecmp(cmd, "AVOptionVideo") ||
+                   !av_strcasecmp(cmd, "AVOptionAudio")) {
             char arg2[1024];
             AVCodecContext *avctx;
             int type;
             get_arg(arg, sizeof(arg), &p);
             get_arg(arg2, sizeof(arg2), &p);
-            if (!strcasecmp(cmd, "AVOptionVideo")) {
+            if (!av_strcasecmp(cmd, "AVOptionVideo")) {
                 avctx = &video_enc;
                 type = AV_OPT_FLAG_VIDEO_PARAM;
             } else {
@@ -4439,12 +4438,12 @@  static int parse_ffconfig(const char *filename)
             if (avserver_opt_default(arg, arg2, avctx, type|AV_OPT_FLAG_ENCODING_PARAM)) {
                 ERROR("AVOption error: %s %s\n", arg, arg2);
             }
-        } else if (!strcasecmp(cmd, "AVPresetVideo") ||
-                   !strcasecmp(cmd, "AVPresetAudio")) {
+        } else if (!av_strcasecmp(cmd, "AVPresetVideo") ||
+                   !av_strcasecmp(cmd, "AVPresetAudio")) {
             AVCodecContext *avctx;
             int type;
             get_arg(arg, sizeof(arg), &p);
-            if (!strcasecmp(cmd, "AVPresetVideo")) {
+            if (!av_strcasecmp(cmd, "AVPresetVideo")) {
                 avctx = &video_enc;
                 video_enc.codec_id = video_id;
                 type = AV_OPT_FLAG_VIDEO_PARAM;
@@ -4456,26 +4455,26 @@  static int parse_ffconfig(const char *filename)
             if (avserver_opt_preset(arg, avctx, type|AV_OPT_FLAG_ENCODING_PARAM, &audio_id, &video_id)) {
                 ERROR("AVPreset error: %s\n", arg);
             }
-        } else if (!strcasecmp(cmd, "VideoTag")) {
+        } else if (!av_strcasecmp(cmd, "VideoTag")) {
             get_arg(arg, sizeof(arg), &p);
             if ((strlen(arg) == 4) && stream)
                 video_enc.codec_tag = MKTAG(arg[0], arg[1], arg[2], arg[3]);
-        } else if (!strcasecmp(cmd, "BitExact")) {
+        } else if (!av_strcasecmp(cmd, "BitExact")) {
             if (stream)
                 video_enc.flags |= CODEC_FLAG_BITEXACT;
-        } else if (!strcasecmp(cmd, "DctFastint")) {
+        } else if (!av_strcasecmp(cmd, "DctFastint")) {
             if (stream)
                 video_enc.dct_algo  = FF_DCT_FASTINT;
-        } else if (!strcasecmp(cmd, "IdctSimple")) {
+        } else if (!av_strcasecmp(cmd, "IdctSimple")) {
             if (stream)
                 video_enc.idct_algo = FF_IDCT_SIMPLE;
-        } else if (!strcasecmp(cmd, "Qscale")) {
+        } else if (!av_strcasecmp(cmd, "Qscale")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream) {
                 video_enc.flags |= CODEC_FLAG_QSCALE;
                 video_enc.global_quality = FF_QP2LAMBDA * atoi(arg);
             }
-        } else if (!strcasecmp(cmd, "VideoQDiff")) {
+        } else if (!av_strcasecmp(cmd, "VideoQDiff")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream) {
                 video_enc.max_qdiff = atoi(arg);
@@ -4483,7 +4482,7 @@  static int parse_ffconfig(const char *filename)
                     ERROR("VideoQDiff out of range\n");
                 }
             }
-        } else if (!strcasecmp(cmd, "VideoQMax")) {
+        } else if (!av_strcasecmp(cmd, "VideoQMax")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream) {
                 video_enc.qmax = atoi(arg);
@@ -4491,7 +4490,7 @@  static int parse_ffconfig(const char *filename)
                     ERROR("VideoQMax out of range\n");
                 }
             }
-        } else if (!strcasecmp(cmd, "VideoQMin")) {
+        } else if (!av_strcasecmp(cmd, "VideoQMin")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream) {
                 video_enc.qmin = atoi(arg);
@@ -4499,39 +4498,39 @@  static int parse_ffconfig(const char *filename)
                     ERROR("VideoQMin out of range\n");
                 }
             }
-        } else if (!strcasecmp(cmd, "LumaElim")) {
+        } else if (!av_strcasecmp(cmd, "LumaElim")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream)
                 video_enc.luma_elim_threshold = atoi(arg);
-        } else if (!strcasecmp(cmd, "ChromaElim")) {
+        } else if (!av_strcasecmp(cmd, "ChromaElim")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream)
                 video_enc.chroma_elim_threshold = atoi(arg);
-        } else if (!strcasecmp(cmd, "LumiMask")) {
+        } else if (!av_strcasecmp(cmd, "LumiMask")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream)
                 video_enc.lumi_masking = atof(arg);
-        } else if (!strcasecmp(cmd, "DarkMask")) {
+        } else if (!av_strcasecmp(cmd, "DarkMask")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream)
                 video_enc.dark_masking = atof(arg);
-        } else if (!strcasecmp(cmd, "NoVideo")) {
+        } else if (!av_strcasecmp(cmd, "NoVideo")) {
             video_id = CODEC_ID_NONE;
-        } else if (!strcasecmp(cmd, "NoAudio")) {
+        } else if (!av_strcasecmp(cmd, "NoAudio")) {
             audio_id = CODEC_ID_NONE;
-        } else if (!strcasecmp(cmd, "ACL")) {
+        } else if (!av_strcasecmp(cmd, "ACL")) {
             parse_acl_row(stream, feed, NULL, p, filename, line_num);
-        } else if (!strcasecmp(cmd, "DynamicACL")) {
+        } else if (!av_strcasecmp(cmd, "DynamicACL")) {
             if (stream) {
                 get_arg(stream->dynamic_acl, sizeof(stream->dynamic_acl), &p);
             }
-        } else if (!strcasecmp(cmd, "RTSPOption")) {
+        } else if (!av_strcasecmp(cmd, "RTSPOption")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream) {
                 av_freep(&stream->rtsp_option);
                 stream->rtsp_option = av_strdup(arg);
             }
-        } else if (!strcasecmp(cmd, "MulticastAddress")) {
+        } else if (!av_strcasecmp(cmd, "MulticastAddress")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream) {
                 if (resolve_host(&stream->multicast_ip, arg) != 0) {
@@ -4540,18 +4539,18 @@  static int parse_ffconfig(const char *filename)
                 stream->is_multicast = 1;
                 stream->loop = 1; /* default is looping */
             }
-        } else if (!strcasecmp(cmd, "MulticastPort")) {
+        } else if (!av_strcasecmp(cmd, "MulticastPort")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream)
                 stream->multicast_port = atoi(arg);
-        } else if (!strcasecmp(cmd, "MulticastTTL")) {
+        } else if (!av_strcasecmp(cmd, "MulticastTTL")) {
             get_arg(arg, sizeof(arg), &p);
             if (stream)
                 stream->multicast_ttl = atoi(arg);
-        } else if (!strcasecmp(cmd, "NoLoop")) {
+        } else if (!av_strcasecmp(cmd, "NoLoop")) {
             if (stream)
                 stream->loop = 0;
-        } else if (!strcasecmp(cmd, "</Stream>")) {
+        } else if (!av_strcasecmp(cmd, "</Stream>")) {
             if (!stream) {
                 ERROR("No corresponding <Stream> for </Stream>\n");
             } else {
@@ -4569,7 +4568,7 @@  static int parse_ffconfig(const char *filename)
                 }
                 stream = NULL;
             }
-        } else if (!strcasecmp(cmd, "<Redirect")) {
+        } else if (!av_strcasecmp(cmd, "<Redirect")) {
             /*********************************************/
             char *q;
             if (stream || feed || redirect) {
@@ -4585,10 +4584,10 @@  static int parse_ffconfig(const char *filename)
                     *q = '\0';
                 redirect->stream_type = STREAM_TYPE_REDIRECT;
             }
-        } else if (!strcasecmp(cmd, "URL")) {
+        } else if (!av_strcasecmp(cmd, "URL")) {
             if (redirect)
                 get_arg(redirect->feed_filename, sizeof(redirect->feed_filename), &p);
-        } else if (!strcasecmp(cmd, "</Redirect>")) {
+        } else if (!av_strcasecmp(cmd, "</Redirect>")) {
             if (!redirect) {
                 ERROR("No corresponding <Redirect> for </Redirect>\n");
             } else {
@@ -4597,7 +4596,7 @@  static int parse_ffconfig(const char *filename)
                 }
                 redirect = NULL;
             }
-        } else if (!strcasecmp(cmd, "LoadModule")) {
+        } else if (!av_strcasecmp(cmd, "LoadModule")) {
             get_arg(arg, sizeof(arg), &p);
 #if HAVE_DLOPEN
             load_module(arg);
diff --git a/doc/APIchanges b/doc/APIchanges
index 79aa202..d0746f8 100644
--- a/doc/APIchanges
+++ b/doc/APIchanges
@@ -13,6 +13,9 @@  libavutil:   2011-04-18
 
 API changes, most recent first:
 
+2011-11-04 - xxxxxxx - lavu 51.13.0
+  Add av_strcasecmp() and av_strncasecmp() to avstring.h.
+
 2011-xx-xx - xxxxxxx - lavc 53.15.0
   Remove avcodec_parse_frame.
   Deprecate AVCodecContext.parse_only and CODEC_CAP_PARSE_ONLY.
diff --git a/libavdevice/v4l2.c b/libavdevice/v4l2.c
index 59b1e55..372d090 100644
--- a/libavdevice/v4l2.c
+++ b/libavdevice/v4l2.c
@@ -42,12 +42,12 @@ 
 #include <linux/videodev2.h>
 #endif
 #include <time.h>
-#include <strings.h>
 #include "libavutil/imgutils.h"
 #include "libavutil/log.h"
 #include "libavutil/opt.h"
 #include "libavutil/parseutils.h"
 #include "libavutil/pixdesc.h"
+#include "libavutil/avstring.h"
 
 static const int desired_video_buffers = 256;
 
@@ -493,7 +493,7 @@  static int v4l2_set_parameters(AVFormatContext *s1, AVFormatParameters *ap)
                 return AVERROR(EIO);
             }
 
-            if (!strcasecmp(standard.name, s->standard)) {
+            if (!av_strcasecmp(standard.name, s->standard)) {
                 break;
             }
         }
diff --git a/libavformat/avidec.c b/libavformat/avidec.c
index 68d652a..0cd84c0 100644
--- a/libavformat/avidec.c
+++ b/libavformat/avidec.c
@@ -19,11 +19,11 @@ 
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <strings.h>
 #include "libavutil/intreadwrite.h"
 #include "libavutil/mathematics.h"
 #include "libavutil/bswap.h"
 #include "libavutil/dict.h"
+#include "libavutil/avstring.h"
 #include "avformat.h"
 #include "avi.h"
 #include "dv.h"
@@ -281,7 +281,7 @@  static void avi_metadata_creation_time(AVDictionary **metadata, char *date)
     if (sscanf(date, "%*3s%*[ ]%3s%*[ ]%2d%*[ ]%8s%*[ ]%4d",
                month, &day, time, &year) == 4) {
         for (i=0; i<12; i++)
-            if (!strcasecmp(month, months[i])) {
+            if (!av_strcasecmp(month, months[i])) {
                 snprintf(buffer, sizeof(buffer), "%.4d-%.2d-%.2d %s",
                          year, i+1, day, time);
                 av_dict_set(metadata, "creation_time", buffer, 0);
diff --git a/libavformat/http.c b/libavformat/http.c
index 1db9e82..1b12d80 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -22,7 +22,6 @@ 
 #include "libavutil/avstring.h"
 #include "avformat.h"
 #include <unistd.h>
-#include <strings.h>
 #include "internal.h"
 #include "network.h"
 #include "http.h"
@@ -250,12 +249,12 @@  static int process_line(URLContext *h, char *line, int line_count,
         p++;
         while (isspace(*p))
             p++;
-        if (!strcasecmp(tag, "Location")) {
+        if (!av_strcasecmp(tag, "Location")) {
             strcpy(s->location, p);
             *new_location = 1;
-        } else if (!strcasecmp (tag, "Content-Length") && s->filesize == -1) {
+        } else if (!av_strcasecmp (tag, "Content-Length") && s->filesize == -1) {
             s->filesize = atoll(p);
-        } else if (!strcasecmp (tag, "Content-Range")) {
+        } else if (!av_strcasecmp (tag, "Content-Range")) {
             /* "bytes $from-$to/$document_size" */
             const char *slash;
             if (!strncmp (p, "bytes ", 6)) {
@@ -265,16 +264,16 @@  static int process_line(URLContext *h, char *line, int line_count,
                     s->filesize = atoll(slash+1);
             }
             h->is_streamed = 0; /* we _can_ in fact seek */
-        } else if (!strcasecmp(tag, "Accept-Ranges") && !strncmp(p, "bytes", 5)) {
+        } else if (!av_strcasecmp(tag, "Accept-Ranges") && !strncmp(p, "bytes", 5)) {
             h->is_streamed = 0;
-        } else if (!strcasecmp (tag, "Transfer-Encoding") && !strncasecmp(p, "chunked", 7)) {
+        } else if (!av_strcasecmp (tag, "Transfer-Encoding") && !av_strncasecmp(p, "chunked", 7)) {
             s->filesize = -1;
             s->chunksize = 0;
-        } else if (!strcasecmp (tag, "WWW-Authenticate")) {
+        } else if (!av_strcasecmp (tag, "WWW-Authenticate")) {
             ff_http_auth_handle_header(&s->auth_state, tag, p);
-        } else if (!strcasecmp (tag, "Authentication-Info")) {
+        } else if (!av_strcasecmp (tag, "Authentication-Info")) {
             ff_http_auth_handle_header(&s->auth_state, tag, p);
-        } else if (!strcasecmp (tag, "Connection")) {
+        } else if (!av_strcasecmp (tag, "Connection")) {
             if (!strcmp(p, "close"))
                 s->willclose = 1;
         }
diff --git a/libavformat/img2.c b/libavformat/img2.c
index 34ab79f..25c3f76 100644
--- a/libavformat/img2.c
+++ b/libavformat/img2.c
@@ -29,7 +29,6 @@ 
 #include "avformat.h"
 #include "avio_internal.h"
 #include "internal.h"
-#include <strings.h>
 
 typedef struct {
     const AVClass *class;  /**< Class for private options. */
@@ -121,7 +120,7 @@  static enum CodecID av_str2id(const IdStrMap *tags, const char *str)
     str++;
 
     while (tags->id) {
-        if (!strcasecmp(str, tags->str))
+        if (!av_strcasecmp(str, tags->str))
             return tags->id;
 
         tags++;
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index 1adb479..5edd2be 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -33,9 +33,9 @@ 
 #include "libavutil/random_seed.h"
 #include "libavutil/lfg.h"
 #include "libavutil/dict.h"
+#include "libavutil/avstring.h"
 #include "libavcodec/xiph.h"
 #include "libavcodec/mpeg4audio.h"
-#include <strings.h>
 
 typedef struct ebml_master {
     int64_t         pos;                ///< absolute offset in the file where the master's elements start
@@ -760,7 +760,7 @@  static int mkv_write_tag(AVFormatContext *s, AVDictionary *m, unsigned int eleme
     end_ebml_master(s->pb, targets);
 
     while ((t = av_dict_get(m, "", t, AV_DICT_IGNORE_SUFFIX)))
-        if (strcasecmp(t->key, "title"))
+        if (av_strcasecmp(t->key, "title"))
             mkv_write_simpletag(s->pb, t);
 
     end_ebml_master(s->pb, tag);
diff --git a/libavformat/metadata.c b/libavformat/metadata.c
index d8957df..7d85363 100644
--- a/libavformat/metadata.c
+++ b/libavformat/metadata.c
@@ -18,10 +18,10 @@ 
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <strings.h>
 #include "avformat.h"
 #include "metadata.h"
 #include "libavutil/dict.h"
+#include "libavutil/avstring.h"
 
 #if FF_API_OLD_METADATA2
 AVDictionaryEntry *
@@ -69,13 +69,13 @@  void ff_metadata_conv(AVDictionary **pm, const AVMetadataConv *d_conv,
         key = mtag->key;
         if (s_conv)
             for (sc=s_conv; sc->native; sc++)
-                if (!strcasecmp(key, sc->native)) {
+                if (!av_strcasecmp(key, sc->native)) {
                     key = sc->generic;
                     break;
                 }
         if (d_conv)
             for (dc=d_conv; dc->native; dc++)
-                if (!strcasecmp(key, dc->generic)) {
+                if (!av_strcasecmp(key, dc->generic)) {
                     key = dc->native;
                     break;
                 }
diff --git a/libavformat/mp3enc.c b/libavformat/mp3enc.c
index e3c0987..ce547ea 100644
--- a/libavformat/mp3enc.c
+++ b/libavformat/mp3enc.c
@@ -19,7 +19,6 @@ 
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <strings.h>
 #include "avformat.h"
 #include "avio_internal.h"
 #include "id3v1.h"
@@ -64,7 +63,7 @@  static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
     buf[127] = 0xFF; /* default to unknown genre */
     if ((tag = av_dict_get(s->metadata, "TCON", NULL, 0))) { //genre
         for(i = 0; i <= ID3v1_GENRE_MAX; i++) {
-            if (!strcasecmp(tag->value, ff_id3v1_genre_str[i])) {
+            if (!av_strcasecmp(tag->value, ff_id3v1_genre_str[i])) {
                 buf[127] = i;
                 count++;
                 break;
diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
index 8903424..c41b4ce 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -20,7 +20,6 @@ 
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
-#include <strings.h>
 #include "libavutil/avstring.h"
 #include "libavutil/bswap.h"
 #include "libavutil/dict.h"
@@ -459,8 +458,8 @@  static int decode_info_header(NUTContext *nut){
                 set_disposition_bits(s, str_value, stream_id_plus1 - 1);
                 continue;
             }
-            if(metadata && strcasecmp(name,"Uses")
-               && strcasecmp(name,"Depends") && strcasecmp(name,"Replaces"))
+            if(metadata && av_strcasecmp(name,"Uses")
+               && av_strcasecmp(name,"Depends") && av_strcasecmp(name,"Replaces"))
                 av_dict_set(metadata, name, str_value, 0);
         }
     }
diff --git a/libavformat/rtpdec.c b/libavformat/rtpdec.c
index 92535ec..1e6bd6e 100644
--- a/libavformat/rtpdec.c
+++ b/libavformat/rtpdec.c
@@ -20,13 +20,13 @@ 
  */
 
 #include "libavutil/mathematics.h"
+#include "libavutil/avstring.h"
 #include "libavcodec/get_bits.h"
 #include "avformat.h"
 #include "mpegts.h"
 #include "url.h"
 
 #include <unistd.h>
-#include <strings.h>
 #include "network.h"
 
 #include "rtpdec.h"
@@ -91,7 +91,7 @@  RTPDynamicProtocolHandler *ff_rtp_handler_find_by_name(const char *name,
     RTPDynamicProtocolHandler *handler;
     for (handler = RTPFirstDynamicPayloadHandler;
          handler; handler = handler->next)
-        if (!strcasecmp(name, handler->enc_name) &&
+        if (!av_strcasecmp(name, handler->enc_name) &&
             codec_type == handler->codec_type)
             return handler;
     return NULL;
diff --git a/libavformat/rtpdec_mpeg4.c b/libavformat/rtpdec_mpeg4.c
index 7a63cc3..65071bd 100644
--- a/libavformat/rtpdec_mpeg4.c
+++ b/libavformat/rtpdec_mpeg4.c
@@ -31,7 +31,6 @@ 
 #include "internal.h"
 #include "libavutil/avstring.h"
 #include "libavcodec/get_bits.h"
-#include <strings.h>
 
 /** Structure listing useful vars to parse RTP packet payload*/
 struct PayloadContext
@@ -206,7 +205,7 @@  static int parse_fmtp(AVStream *stream, PayloadContext *data,
     if (codec->codec_id == CODEC_ID_AAC) {
         /* Looking for a known attribute */
         for (i = 0; attr_names[i].str; ++i) {
-            if (!strcasecmp(attr, attr_names[i].str)) {
+            if (!av_strcasecmp(attr, attr_names[i].str)) {
                 if (attr_names[i].type == ATTR_NAME_TYPE_INT) {
                     *(int *)((char *)data+
                         attr_names[i].offset) = atoi(value);
diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c
index b9ef0bf..106190a 100644
--- a/libavformat/rtsp.c
+++ b/libavformat/rtsp.c
@@ -33,7 +33,6 @@ 
 #if HAVE_POLL_H
 #include <poll.h>
 #endif
-#include <strings.h>
 #include "internal.h"
 #include "network.h"
 #include "os_support.h"
@@ -660,7 +659,7 @@  static void rtsp_parse_transport(RTSPMessageHeader *reply, const char *p)
 
         get_word_sep(transport_protocol, sizeof(transport_protocol),
                      "/", &p);
-        if (!strcasecmp (transport_protocol, "rtp")) {
+        if (!av_strcasecmp (transport_protocol, "rtp")) {
             get_word_sep(profile, sizeof(profile), "/;,", &p);
             lower_transport[0] = '\0';
             /* rtp/avp/<protocol> */
@@ -669,14 +668,14 @@  static void rtsp_parse_transport(RTSPMessageHeader *reply, const char *p)
                              ";,", &p);
             }
             th->transport = RTSP_TRANSPORT_RTP;
-        } else if (!strcasecmp (transport_protocol, "x-pn-tng") ||
-                   !strcasecmp (transport_protocol, "x-real-rdt")) {
+        } else if (!av_strcasecmp (transport_protocol, "x-pn-tng") ||
+                   !av_strcasecmp (transport_protocol, "x-real-rdt")) {
             /* x-pn-tng/<protocol> */
             get_word_sep(lower_transport, sizeof(lower_transport), "/;,", &p);
             profile[0] = '\0';
             th->transport = RTSP_TRANSPORT_RDT;
         }
-        if (!strcasecmp(lower_transport, "TCP"))
+        if (!av_strcasecmp(lower_transport, "TCP"))
             th->lower_transport = RTSP_LOWER_TRANSPORT_TCP;
         else
             th->lower_transport = RTSP_LOWER_TRANSPORT_UDP;
@@ -1555,7 +1554,7 @@  redirect:
         if (rt->server_type != RTSP_SERVER_REAL && reply->real_challenge[0]) {
             rt->server_type = RTSP_SERVER_REAL;
             continue;
-        } else if (!strncasecmp(reply->server, "WMServer/", 9)) {
+        } else if (!av_strncasecmp(reply->server, "WMServer/", 9)) {
             rt->server_type = RTSP_SERVER_WMS;
         } else if (rt->server_type == RTSP_SERVER_REAL)
             strcpy(real_challenge, reply->real_challenge);
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 1158079..9872466 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -37,7 +37,6 @@ 
 #include "url.h"
 #include <sys/time.h>
 #include <time.h>
-#include <strings.h>
 #include <stdarg.h>
 #if CONFIG_NETWORK
 #include "network.h"
@@ -169,7 +168,7 @@  int av_match_ext(const char *filename, const char *extensions)
             while (*p != '\0' && *p != ',' && q-ext1<sizeof(ext1)-1)
                 *q++ = *p++;
             *q = '\0';
-            if (!strcasecmp(ext1, ext))
+            if (!av_strcasecmp(ext1, ext))
                 return 1;
             if (*p == '\0')
                 break;
@@ -190,11 +189,11 @@  static int match_format(const char *name, const char *names)
     namelen = strlen(name);
     while ((p = strchr(names, ','))) {
         len = FFMAX(p - names, namelen);
-        if (!strncasecmp(name, names, len))
+        if (!av_strncasecmp(name, names, len))
             return 1;
         names = p+1;
     }
-    return !strcasecmp(name, names);
+    return !av_strcasecmp(name, names);
 }
 
 AVOutputFormat *av_guess_format(const char *short_name, const char *filename,
diff --git a/libavutil/avstring.c b/libavutil/avstring.c
index 2b8c2d4..0f01eab 100644
--- a/libavutil/avstring.c
+++ b/libavutil/avstring.c
@@ -134,6 +134,33 @@  char *av_get_token(const char **buf, const char *term)
     return ret;
 }
 
+#define TOUPPER(c) do { if (c >= 'a' && c <= 'z') c -= 'a' - 'A'; } while (0)
+
+int av_strcasecmp(const char *a, const char *b)
+{
+    uint8_t c1, c2;
+    do {
+        c1 = *a++;
+        c2 = *b++;
+        TOUPPER(c1);
+        TOUPPER(c2);
+    } while (c1 && c1 == c2);
+    return c1 - c2;
+}
+
+int av_strncasecmp(const char *a, const char *b, size_t n)
+{
+    const char *end = a + n;
+    uint8_t c1, c2;
+    do {
+        c1 = *a++;
+        c2 = *b++;
+        TOUPPER(c1);
+        TOUPPER(c2);
+    } while (a < end && c1 && c1 == c2);
+    return c1 - c2;
+}
+
 #ifdef TEST
 
 #undef printf
diff --git a/libavutil/avstring.h b/libavutil/avstring.h
index 44ed89d..4d99653 100644
--- a/libavutil/avstring.h
+++ b/libavutil/avstring.h
@@ -131,4 +131,16 @@  char *av_d2str(double d);
  */
 char *av_get_token(const char **buf, const char *term);
 
+/**
+ * Locale independent case-insensitive compare.
+ * Note: This means only ASCII-range characters are case-insensitive
+ */
+int av_strcasecmp(const char *a, const char *b);
+
+/**
+ * Locale independent case-insensitive compare.
+ * Note: This means only ASCII-range characters are case-insensitive
+ */
+int av_strncasecmp(const char *a, const char *b, size_t n);
+
 #endif /* AVUTIL_AVSTRING_H */
diff --git a/libavutil/avutil.h b/libavutil/avutil.h
index fae6801..b688321 100644
--- a/libavutil/avutil.h
+++ b/libavutil/avutil.h
@@ -40,7 +40,7 @@ 
 #define AV_VERSION(a, b, c) AV_VERSION_DOT(a, b, c)
 
 #define LIBAVUTIL_VERSION_MAJOR 51
-#define LIBAVUTIL_VERSION_MINOR 12
+#define LIBAVUTIL_VERSION_MINOR 13
 #define LIBAVUTIL_VERSION_MICRO  0
 
 #define LIBAVUTIL_VERSION_INT   AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
diff --git a/libavutil/internal.h b/libavutil/internal.h
index 5ed3fb8..07e1ef1 100644
--- a/libavutil/internal.h
+++ b/libavutil/internal.h
@@ -155,6 +155,10 @@  struct AVDictionary {
 #define puts please_use_av_log_instead_of_puts
 #undef  perror
 #define perror please_use_av_log_instead_of_perror
+#undef strcasecmp
+#define strcasecmp please_use_av_strcasecmp
+#undef strncasecmp
+#define strncasecmp please_use_av_strncasecmp
 
 #define FF_ALLOC_OR_GOTO(ctx, p, size, label)\
 {\
diff --git a/libavutil/parseutils.c b/libavutil/parseutils.c
index 1f8f7a8..c1647a0 100644
--- a/libavutil/parseutils.c
+++ b/libavutil/parseutils.c
@@ -21,7 +21,6 @@ 
  * misc parsing utilities
  */
 
-#include <strings.h>
 #include <sys/time.h>
 #include <time.h>
 
@@ -294,7 +293,7 @@  static ColorEntry color_table[] = {
 
 static int color_table_compare(const void *lhs, const void *rhs)
 {
-    return strcasecmp(lhs, ((const ColorEntry *)rhs)->name);
+    return av_strcasecmp(lhs, ((const ColorEntry *)rhs)->name);
 }
 
 #define ALPHA_SEP '@'
@@ -320,7 +319,7 @@  int av_parse_color(uint8_t *rgba_color, const char *color_string, int slen,
     len = strlen(color_string2);
     rgba_color[3] = 255;
 
-    if (!strcasecmp(color_string2, "random") || !strcasecmp(color_string2, "bikeshed")) {
+    if (!av_strcasecmp(color_string2, "random") || !av_strcasecmp(color_string2, "bikeshed")) {
         int rgba = av_get_random_seed();
         rgba_color[0] = rgba >> 24;
         rgba_color[1] = rgba >> 16;
@@ -515,7 +514,7 @@  int av_parse_time(int64_t *timeval, const char *timestr, int duration)
     p = timestr;
     q = NULL;
     if (!duration) {
-        if (!strncasecmp(timestr, "now", len)) {
+        if (!av_strncasecmp(timestr, "now", len)) {
             *timeval = (int64_t) now * 1000000;
             return 0;
         }