Ticket #51207: patch-moc-2.6-alpha1-ffmpeg-3.0.diff

File patch-moc-2.6-alpha1-ffmpeg-3.0.diff, 33.8 KB (added by dbevans (David B. Evans), 8 years ago)

Proposed patch updating to version 2.6-alpha1 with upstream ffmpeg fixes

  • Portfile

     
    33PortSystem          1.0
    44
    55name                moc
    6 version             2.5.0-beta1
    7 revision            3
     6version             2.6-alpha1
    87license             GPL-2
    98categories          multimedia
    109maintainers         martinvazquez.net:eu
     
    1918
    2019homepage            http://moc.daper.net
    2120platforms           darwin
    22 master_sites        ftp://ftp.daper.net/pub/soft/moc/unstable/
     21master_sites        http://ftp.daper.net/pub/soft/moc/unstable/
    2322
    24 checksums           md5     795ecba86847e082aa2f21937cc04804 \
    25                     sha1    4030a1fa5c7cfef06909c54d8c7a1fbb93f23caa \
    26                     rmd160  ca7095f71e5fe8155eda41e98547db541d6a4cab
     23checksums           rmd160  283f9945abbd3b3d4e15f23485228c00983edfe8 \
     24                    sha256  0b0a3515c65b4c47a250e350c663535778239352db859921f5d564ed727a0bbc
    2725
    28 use_bzip2           yes
     26use_xz              yes
    2927
    3028depends_build       port:pkgconfig
    3129
     
    4139                    port:jack \
    4240                    port:curl
    4341
    44 patchfiles          patch-ffmpeg-r2529.diff
     42patchfiles          patch-ffmpeg-3.0.diff
    4543
    4644use_autoreconf      yes
    4745autoreconf.args     -fvi
     
    5957        configure.args-delete   --without-vorbis
    6058}
    6159
    62 livecheck.regex     <title>music on console (.*)</title>
     60livecheck.regex     ">${name}-\(\.*\)\.tar"
  • files/patch-configure.diff

     
    1 diff -ur ../moc-2.4.3.orig/configure ./configure
    2 --- ../moc-2.4.3.orig/configure 2007-07-30 17:49:11.000000000 +0200
    3 +++ ./configure 2008-03-26 19:32:00.000000000 +0100
    4 @@ -21998,7 +21998,7 @@
    5                 ;;
    6  esac
    7  
    8 -LDFLAGS="$LDFLAGS -export-dynamic"
    9 +LDFLAGS="$LDFLAGS ${export_dynamic_flag}"
    10  
    11  { echo "$as_me:$LINENO: checking for ANSI C header files" >&5
    12  echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6; }
  • files/patch-ffmpeg-3.0.diff

     
     1Index: configure.in
     2===================================================================
     3--- configure.in        (revision 2781)
     4+++ configure.in        (revision 2785)
     5@@ -457,19 +457,3 @@
     6        echo "         you will not hear any sound!"
     7        echo
     8 fi
     9-
     10-dnl
     11-dnl  If the warning below gets reported, then for further guidance:
     12-dnl
     13-dnl         vi +/REQUEST_CHANNELS decoder_plugins/ffmpeg/ffmpeg.c
     14-dnl
     15-if test "x$want_ffmpeg" = "xyes" && \
     16-   test "x$ac_cv_member_struct_AVCodecContext_request_channels" != "xyes"
     17-then
     18-       echo "WARNING: It appears that the FFmpeg/LibAV API has changed and no longer"
     19-       echo "         supports downmixing to stereo as it did previously.  Report"
     20-       echo "         this message along with the output of 'ffmpeg -version' to"
     21-       echo "         <$PACKAGE_BUGREPORT>.  Meanwhile, you may have to live without"
     22-       echo "         stereo downmixing."
     23-       echo
     24-fi
     25Index: decoder_plugins/ffmpeg/ffmpeg.m4
     26===================================================================
     27--- decoder_plugins/ffmpeg/ffmpeg.m4    (revision 2781)
     28+++ decoder_plugins/ffmpeg/ffmpeg.m4    (revision 2785)
     29@@ -39,6 +39,8 @@
     30                LIBS="$LIBS $ffmpeg_LIBS"
     31                AC_CHECK_MEMBERS([struct AVCodecContext.request_channels], [], [],
     32                             [#include <libavcodec/avcodec.h>])
     33+               AC_CHECK_HEADERS([ffmpeg/avformat.h \
     34+                                 libavformat/avformat.h libavutil/channel_layout.h])
     35                AC_SEARCH_LIBS(avcodec_open2, avcodec,
     36                        [AC_DEFINE([HAVE_AVCODEC_OPEN2], 1,
     37                                [Define to 1 if you have the `avcodec_open2' function.])])
     38@@ -46,6 +48,9 @@
     39                        [AC_DEFINE([HAVE_AVCODEC_DECODE_AUDIO4], 1,
     40                                [Define to 1 if you have the `avcodec_decode_audio4' function.])],
     41                        [AX_FUNC_POSIX_MEMALIGN])
     42+               AC_SEARCH_LIBS(av_packet_unref, avcodec,
     43+                       [AC_DEFINE([HAVE_AV_PACKET_UNREF], 1,
     44+                               [Define to 1 if you have the `av_packet_unref' function.])])
     45                AC_SEARCH_LIBS(avformat_close_input, avformat,
     46                        [AC_DEFINE([HAVE_AVFORMAT_CLOSE_INPUT], 1,
     47                                [Define to 1 if you have the `avformat_close_input' function.])])
     48Index: decoder_plugins/ffmpeg/ffmpeg.c
     49===================================================================
     50--- decoder_plugins/ffmpeg/ffmpeg.c     (revision 2781)
     51+++ decoder_plugins/ffmpeg/ffmpeg.c     (revision 2785)
     52@@ -41,7 +41,11 @@
     53 GCC_DIAG_ON(deprecated-declarations)
     54 #include <libavutil/mathematics.h>
     55 #ifdef HAVE_AV_GET_CHANNEL_LAYOUT_NB_CHANNELS
     56-#include <libavutil/audioconvert.h>
     57+# if HAVE_LIBAVUTIL_CHANNEL_LAYOUT_H
     58+#  include <libavutil/channel_layout.h>
     59+# else
     60+#  include <libavutil/audioconvert.h>
     61+# endif
     62 #endif
     63 
     64 /* FFmpeg also likes common names, without that, our common.h and log.h
     65@@ -769,32 +773,11 @@
     66                return;
     67 #endif
     68 
     69-       data->enc->channels = 2;
     70-
     71 #ifdef HAVE_STRUCT_AVCODECCONTEXT_REQUEST_CHANNELS
     72-
     73-       /*
     74-        * When FFmpeg breaks its API (and it will), this code will be
     75-        * disabled and users will complain that MOC no longer downmixes
     76-        * to stereo.  This is because the 'request_channels' field in
     77-        * AVCodecContext is marked as deprecated (and so will probably
     78-        * be removed at some time) but FFmpeg requires it to be set to
     79-        * trigger downmixing (go figure!).  Currently, there is no
     80-        * guidance on how it will work in the future, but looking at
     81-        * where 's->downmixed' is set near the end of 'ac3_decode_init()'
     82-        * in the FFmpeg's source code file 'libavcodec/ac3dec.c' might
     83-        * help (in the absence of proper documentation).
     84-        */
     85-
     86        set_request_channels (data->enc, 2);
     87-
     88-#ifdef AV_CH_LAYOUT_STEREO_DOWNMIX
     89-       data->enc->request_channel_layout = AV_CH_LAYOUT_STEREO_DOWNMIX;
     90 #else
     91-       data->enc->request_channel_layout = CH_LAYOUT_STEREO_DOWNMIX;
     92+       data->enc->request_channel_layout = AV_CH_LAYOUT_STEREO;
     93 #endif
     94-
     95-#endif
     96 }
     97 
     98 static void *ffmpeg_open (const char *file)
     99@@ -1064,7 +1047,12 @@
     100 {
     101        assert (pkt);
     102 
     103+#if HAVE_AV_PACKET_UNREF
     104+       av_packet_unref (pkt);
     105+#else
     106        av_free_packet (pkt);
     107+#endif
     108+
     109        free (pkt);
     110 }
     111 
     112Index: decoder_plugins/ffmpeg/ffmpeg.m4
     113===================================================================
     114--- decoder_plugins/ffmpeg/ffmpeg.m4    (revision 2799)
     115+++ decoder_plugins/ffmpeg/ffmpeg.m4    (revision 2800)
     116@@ -39,8 +39,7 @@
     117                LIBS="$LIBS $ffmpeg_LIBS"
     118                AC_CHECK_MEMBERS([struct AVCodecContext.request_channels], [], [],
     119                             [#include <libavcodec/avcodec.h>])
     120-               AC_CHECK_HEADERS([ffmpeg/avformat.h \
     121-                                 libavformat/avformat.h libavutil/channel_layout.h])
     122+               AC_CHECK_HEADERS([libavutil/channel_layout.h])
     123                AC_SEARCH_LIBS(avcodec_open2, avcodec,
     124                        [AC_DEFINE([HAVE_AVCODEC_OPEN2], 1,
     125                                [Define to 1 if you have the `avcodec_open2' function.])])
  • files/patch-ffmpeg-r2529.diff

     
    1 Index: THANKS
    2 ===================================================================
    3 --- THANKS      (revision 2506)
    4 +++ THANKS      (revision 2529)
    5 @@ -10,6 +10,9 @@
    6         * Fixed miscellaneous coding errors.
    7         * Assisted with testing.
    8  
    9 +Gregory Maxwell:
    10 +       * Provided patch for off_t in io_* functions.
    11 +
    12  Morten Grunnet Buhl:
    13         * Provided Yellow/Red theme.
    14  
    15 @@ -44,6 +47,7 @@
    16         * Headed the effort to port MOC to OpenWRT.
    17         * Provided signficant information on DTS, AAC and other formats.
    18         * Also contributed much time in the refinement of feature ideas.
    19 +       * Provided 24-bit format conversion bug fixes.
    20  
    21  Juho Hämäläinen:
    22         * Added -Q (--format) FORMAT_STRING option to display file information.
    23 @@ -202,6 +206,9 @@
    24         * Fixed segfault when trying to play a file using FFmpeg.
    25         * Migrated to newer FFmpeg API.
    26  
    27 +"firejox"
    28 +       * Fixed screen upsets due to UTF-8 character handing.
    29 +
    30  "fluxid":
    31         * Fixed incorrect setting for themes red channel value.
    32  
    33 Index: mocp.1
    34 ===================================================================
    35 --- mocp.1      (revision 2506)
    36 +++ mocp.1      (revision 2529)
    37 @@ -69,6 +69,11 @@
    38  set in the configuration file as \fBStartInMusicDir\fP.
    39  .LP
    40  .TP
    41 +\fB\-q\fP, \fB\-\-enqueue\fP
    42 +Add files given after command line options to the queue.  Don't start the
    43 +interface.
    44 +.LP
    45 +.TP
    46  \fB\-a\fP, \fB\-\-append\fP
    47  Append files, directories (recursively) and playlists given after command
    48  line options to the playlist.  Don't start the interface.
    49 Index: menu.c
    50 ===================================================================
    51 --- menu.c      (revision 2506)
    52 +++ menu.c      (revision 2529)
    53 @@ -90,9 +90,14 @@
    54         getyx (menu->win, y, x);
    55         if (title_width <= title_space || mi->align == MENU_ALIGN_LEFT)
    56                 xwaddnstr (menu->win, mi->title, title_space);
    57 -       else
    58 -               xwaddstr (menu->win, mi->title + title_width - title_space);
    59 +       else {
    60 +               char *ptr;
    61  
    62 +               ptr = xstrtail (mi->title, title_space);
    63 +               xwaddstr (menu->win, ptr);
    64 +               free (ptr);
    65 +       }
    66 +
    67         /* Fill the remainder of the title field with spaces. */
    68         if (mi == menu->selected) {
    69                 getyx (menu->win, y, ix);
    70 Index: configure.in
    71 ===================================================================
    72 --- configure.in        (revision 2506)
    73 +++ configure.in        (revision 2529)
    74 @@ -142,7 +142,7 @@
    75  
    76  PKG_PROG_PKG_CONFIG([0.20])
    77  
    78 -if test "x$PKG_CONFIG" == "x"
    79 +if test "x$PKG_CONFIG" = "x"
    80  then
    81         AC_MSG_WARN([No pkg-config utility found or it's too old, I will have trouble finding installed libraries.])
    82  fi
    83 @@ -293,7 +293,6 @@
    84  
    85  dnl optional functions
    86  AC_CHECK_FUNCS([strcasestr strerror_r syslog])
    87 -AC_CHECK_FUNCS([getrlimit pthread_attr_getstacksize])
    88  AX_CHECK_UNAME_SYSCALL
    89  
    90  dnl MIME magic
    91 @@ -322,6 +321,7 @@
    92  CC="$PTHREAD_CC"
    93  CFLAGS="$PTHREAD_CFLAGS $CFLAGS"
    94  EXTRA_LIBS="$EXTRA_LIBS $PTHREAD_LIBS"
    95 +AC_CHECK_FUNCS([getrlimit pthread_attr_getstacksize])
    96  
    97  dnl __FUNCTION__
    98  AC_TRY_COMPILE(,[printf(__FUNCTION__);], [AC_DEFINE([HAVE__FUNCTION__], 1,
    99 @@ -342,7 +342,7 @@
    100  fi
    101  
    102  dnl popt
    103 -AC_SEARCH_LIBS([poptGetContext], [popt], , [POPT_MISSING="yes"])
    104 +AC_CHECK_LIB([popt], [poptGetContext], [true], [POPT_MISSING="yes"])
    105  
    106  dnl getopt
    107  AC_CHECK_FUNC(getopt_long,
    108 Index: utf8.c
    109 ===================================================================
    110 --- utf8.c      (revision 2506)
    111 +++ utf8.c      (revision 2529)
    112 @@ -199,47 +199,50 @@
    113  
    114  int xwaddnstr (WINDOW *win, const char *str, const int n)
    115  {
    116 -       int res;
    117 +       int res, width, inv_char;
    118 +       wchar_t *ucs;
    119 +       char *mstr, *lstr;
    120 +       size_t size, num_chars;
    121  
    122         assert (n > 0);
    123         assert (str != NULL);
    124  
    125 -       if (using_utf8) {
    126 +       mstr = iconv_str (iconv_desc, str);
    127  
    128 -               /* This nasty hack is because we need to count n in chars, but
    129 -                * [w]addnstr() takes arguments in bytes (in UTF-8 a char can be
    130 -                * longer than 1 byte).  There are also problems with [w]addnwstr()
    131 -                * (screen garbled).  I have no better idea. */
    132 +       size = xmbstowcs (NULL, mstr, -1, NULL) + 1;
    133 +       ucs = (wchar_t *)xmalloc (sizeof(wchar_t) * size);
    134 +       xmbstowcs (ucs, mstr, size, &inv_char);
    135 +       width = wcswidth (ucs, WIDTH_MAX);
    136  
    137 -               wchar_t *ucs;
    138 -               size_t size;
    139 -               size_t utf_num_chars;
    140 -               int inv_char;
    141 -
    142 -               size = xmbstowcs (NULL, str, -1, NULL) + 1;
    143 -               ucs = (wchar_t *)xmalloc (sizeof(wchar_t) * size);
    144 -               xmbstowcs (ucs, str, size, &inv_char);
    145 -               if ((size_t)n < size - 1)
    146 -                       ucs[n] = L'\0';
    147 -               utf_num_chars = wcstombs (NULL, ucs, 0);
    148 -               if (inv_char) {
    149 -                       char *utf8 = (char *)xmalloc (utf_num_chars + 1);
    150 -
    151 -                       wcstombs (utf8, ucs, utf_num_chars + 1);
    152 -                       res = waddstr (win, utf8);
    153 -                       free (utf8);
    154 +       if (width == -1) {
    155 +               size_t clidx;
    156 +               for (clidx = 0; clidx < size - 1; clidx++) {
    157 +                       if (wcwidth (ucs[clidx]) == -1)
    158 +                               ucs[clidx] = L'?';
    159                 }
    160 -               else
    161 -                       res = waddnstr (win, str, utf_num_chars);
    162 -               free (ucs);
    163 +               width = wcswidth (ucs, WIDTH_MAX);
    164 +               inv_char = 1;
    165         }
    166 -       else {
    167 -               char *lstr = iconv_str (iconv_desc, str);
    168  
    169 -               res = waddnstr (win, lstr, n);
    170 -               free (lstr);
    171 +       if (width > n) {
    172 +               while (width > n)
    173 +                       width -= wcwidth (ucs[--size]);
    174 +               ucs[size] = L'\0';
    175         }
    176  
    177 +       num_chars = wcstombs (NULL, ucs, 0);
    178 +       lstr = (char *)xmalloc (num_chars + 1);
    179 +
    180 +       if (inv_char)
    181 +               wcstombs (lstr, ucs, num_chars + 1);
    182 +       else
    183 +               snprintf (lstr, num_chars + 1, "%s", mstr);
    184 +
    185 +       res = waddstr (win, lstr);
    186 +
    187 +       free (ucs);
    188 +       free (lstr);
    189 +       free (mstr);
    190         return res;
    191  }
    192  
    193 Index: audio_conversion.c
    194 ===================================================================
    195 --- audio_conversion.c  (revision 2506)
    196 +++ audio_conversion.c  (revision 2529)
    197 @@ -189,7 +189,7 @@
    198         size_t i;
    199  
    200         /* maximum and minimum values of 32-bit samples */
    201 -       const unsigned int U32_MAX = (1 << 24);
    202 +       const unsigned int U32_MAX = (1 << 24) - 1;
    203         const int S32_MAX = (1 << 23) - 1;
    204         const int S32_MIN = -(1 << 23);
    205  
    206 @@ -201,7 +201,7 @@
    207                 float f = in[i] * S32_MAX;
    208  
    209                 if (f >= S32_MAX)
    210 -                       *out_val = U32_MAX;
    211 +                       *out_val = U32_MAX << 8;
    212                 else if (f <= S32_MIN)
    213                         *out_val = 0;
    214                 else {
    215 @@ -231,9 +231,9 @@
    216                 float f = in[i] * S32_MAX;
    217  
    218                 if (f >= S32_MAX)
    219 -                       *out_val = S32_MAX;
    220 +                       *out_val = S32_MAX << 8;
    221                 else if (f <= S32_MIN)
    222 -                       *out_val = S32_MIN;
    223 +                       *out_val = S32_MIN << 8;
    224                 else {
    225  #ifdef HAVE_LRINTF
    226                         *out_val = lrintf(f) << 8;
    227 Index: io.c
    228 ===================================================================
    229 --- io.c        (revision 2506)
    230 +++ io.c        (revision 2529)
    231 @@ -141,20 +141,20 @@
    232  }
    233  
    234  #ifdef HAVE_MMAP
    235 -static off_t io_seek_mmap (struct io_stream *s, const long where)
    236 +static off_t io_seek_mmap (struct io_stream *s, const off_t where)
    237  {
    238 -       assert (RANGE(0, where, (long)s->size));
    239 +       assert (RANGE(0, where, (off_t)s->size));
    240  
    241         return (s->mem_pos = where);
    242  }
    243  #endif
    244  
    245 -static off_t io_seek_fd (struct io_stream *s, const int where)
    246 +static off_t io_seek_fd (struct io_stream *s, const off_t where)
    247  {
    248         return lseek (s->fd, where, SEEK_SET);
    249  }
    250  
    251 -static off_t io_seek_buffered (struct io_stream *s, const long where)
    252 +static off_t io_seek_buffered (struct io_stream *s, const off_t where)
    253  {
    254         off_t res = -1;
    255  
    256 @@ -180,7 +180,7 @@
    257         return res;
    258  }
    259  
    260 -static off_t io_seek_unbuffered (struct io_stream *s, const long where)
    261 +static off_t io_seek_unbuffered (struct io_stream *s, const off_t where)
    262  {
    263         off_t res = -1;
    264  
    265 Index: decoder_plugins/mp3/mp3.c
    266 ===================================================================
    267 --- decoder_plugins/mp3/mp3.c   (revision 2506)
    268 +++ decoder_plugins/mp3/mp3.c   (revision 2529)
    269 @@ -696,17 +696,19 @@
    270  {
    271         char *ext;
    272  
    273 +       strcpy (buf, "MPx");
    274 +
    275         ext = ext_pos (file);
    276 -       if (!strcasecmp (ext, "mp3"))
    277 -               strcpy (buf, "MP3");
    278 -       else if (!strcasecmp (ext, "mp2"))
    279 -               strcpy (buf, "MP2");
    280 -       else if (!strcasecmp (ext, "mp1"))
    281 -               strcpy (buf, "MP1");
    282 -       else if (!strcasecmp (ext, "mpga"))
    283 -               strcpy (buf, "MPG");
    284 -       else
    285 -               strcpy (buf, "MPx");
    286 +       if (ext) {
    287 +               if (!strcasecmp (ext, "mp3"))
    288 +                       strcpy (buf, "MP3");
    289 +               else if (!strcasecmp (ext, "mp2"))
    290 +                       strcpy (buf, "MP2");
    291 +               else if (!strcasecmp (ext, "mp1"))
    292 +                       strcpy (buf, "MP1");
    293 +               else if (!strcasecmp (ext, "mpga"))
    294 +                       strcpy (buf, "MPG");
    295 +       }
    296  }
    297  
    298  static int mp3_our_format_ext (const char *ext)
    299 Index: decoder_plugins/ffmpeg/ffmpeg.m4
    300 ===================================================================
    301 --- decoder_plugins/ffmpeg/ffmpeg.m4    (revision 2506)
    302 +++ decoder_plugins/ffmpeg/ffmpeg.m4    (revision 2529)
    303 @@ -88,6 +88,27 @@
    304                                  [#include <libavcodec/avcodec.h>])
    305                 AC_CHECK_DECLS([AV_CODEC_ID_OPUS], , ,
    306                                  [#include <libavcodec/avcodec.h>])
    307 +               AC_SEARCH_LIBS(avcodec_free_frame, avcodec,
    308 +                       [AC_DEFINE([HAVE_AVCODEC_FREE_FRAME], 1,
    309 +                               [Define to 1 if you have the `avcodec_free_frame' function.])])
    310 +               AC_CHECK_DECLS([CODEC_ID_PCM_S8_PLANAR], , ,
    311 +                                [#include <libavcodec/avcodec.h>])
    312 +               AC_CHECK_DECLS([AV_SAMPLE_FMT_U8P], , ,
    313 +                                [#include <libavcodec/avcodec.h>])
    314 +               AC_CHECK_DECLS([AV_SAMPLE_FMT_S16P], , ,
    315 +                                [#include <libavcodec/avcodec.h>])
    316 +               AC_CHECK_DECLS([AV_SAMPLE_FMT_S32P], , ,
    317 +                                [#include <libavcodec/avcodec.h>])
    318 +               AC_CHECK_DECLS([AV_SAMPLE_FMT_FLTP], , ,
    319 +                                [#include <libavcodec/avcodec.h>])
    320 +               AC_CHECK_DECLS([CODEC_CAP_EXPERIMENTAL], , ,
    321 +                                [#include <libavcodec/avcodec.h>])
    322 +               AC_SEARCH_LIBS(av_get_sample_fmt_name, avutil,
    323 +                       [AC_DEFINE([HAVE_AV_GET_SAMPLE_FMT_NAME], 1,
    324 +                               [Define to 1 if you have the `av_get_sample_fmt_name' function.])])
    325 +               AC_SEARCH_LIBS(av_lockmgr_register, avcodec,
    326 +                       [AC_DEFINE([HAVE_LOCKMGR_REGISTER], 1,
    327 +                               [Define to 1 if you have the `av_lockmgr_register' function.])])
    328                 CPPFLAGS="$save_CPPFLAGS"
    329                 CFLAGS="$save_CFLAGS"
    330                 LIBS="$save_LIBS"
    331 Index: decoder_plugins/ffmpeg/ffmpeg.c
    332 ===================================================================
    333 --- decoder_plugins/ffmpeg/ffmpeg.c     (revision 2506)
    334 +++ decoder_plugins/ffmpeg/ffmpeg.c     (revision 2529)
    335 @@ -99,6 +99,7 @@
    336         bool okay; /* was this stream successfully opened? */
    337         struct decoder_error error;
    338         long fmt;
    339 +       int sample_width;
    340         int bitrate;            /* in bits per second */
    341         int avg_bitrate;        /* in bits per second */
    342  #if SEEK_IN_DECODER
    343 @@ -106,6 +107,7 @@
    344         int seek_sec;           /* second to which to seek */
    345  #endif
    346         bool seek_broken;       /* FFmpeg seeking is broken */
    347 +       bool timing_broken;     /* FFmpeg trashes duration and bit_rate */
    348  #if SEEK_IN_DECODER && defined(DEBUG)
    349         pthread_t thread_id;
    350  #endif
    351 @@ -277,8 +279,72 @@
    352         }
    353  }
    354  
    355 +/* Handle FFmpeg's locking requirements. */
    356 +#ifdef HAVE_LOCKMGR_REGISTER
    357 +static int locking_cb (void **mutex, enum AVLockOp op)
    358 +{
    359 +       int result;
    360 +
    361 +       switch (op) {
    362 +       case AV_LOCK_CREATE:
    363 +               *mutex = xmalloc (sizeof (pthread_mutex_t));
    364 +               result = pthread_mutex_init (*mutex, NULL);
    365 +               break;
    366 +       case AV_LOCK_OBTAIN:
    367 +               result = pthread_mutex_lock (*mutex);
    368 +               break;
    369 +       case AV_LOCK_RELEASE:
    370 +               result = pthread_mutex_unlock (*mutex);
    371 +               break;
    372 +       case AV_LOCK_DESTROY:
    373 +               result = pthread_mutex_destroy (*mutex);
    374 +               free (*mutex);
    375 +               *mutex = NULL;
    376 +               break;
    377 +       }
    378 +
    379 +       return result;
    380 +}
    381 +#endif
    382 +
    383 +/* Here we attempt to determine if FFmpeg/LibAV has trashed the 'duration'
    384 + * and 'bit_rate' fields in AVFormatContext for large files.  Determining
    385 + * whether or not they are likely to be valid is imprecise and will vary
    386 + * depending (at least) on:
    387 + *
    388 + * - The file's size,
    389 + * - The file's codec,
    390 + * - The number and size of tags,
    391 + * - The version of FFmpeg/LibAV, and
    392 + * - Whether it's FFmpeg or LibAV.
    393 + *
    394 + * This function represents a best guess.
    395 +*/
    396 +static bool is_timing_broken (AVFormatContext *ic)
    397 +{
    398 +       int64_t file_size;
    399 +
    400 +       if (ic->duration < 0 || ic->bit_rate < 0)
    401 +               return true;
    402 +
    403 +#ifdef HAVE_AVIO_SIZE
    404 +       file_size = avio_size (ic->pb);
    405 +#else
    406 +       file_size = ic->file_size;
    407 +#endif
    408 +
    409 +       if (file_size < UINT32_MAX)
    410 +               return false;
    411 +
    412 +       return true;
    413 +}
    414 +
    415  static void ffmpeg_init ()
    416  {
    417 +#ifdef HAVE_LOCKMGR_REGISTER
    418 +       int rc;
    419 +#endif
    420 +
    421  #ifdef DEBUG
    422         av_log_set_level (AV_LOG_INFO);
    423  #else
    424 @@ -291,10 +357,20 @@
    425         supported_extns = lists_strs_new (16);
    426         load_audio_extns (supported_extns);
    427         load_video_extns (supported_extns);
    428 +
    429 +#ifdef HAVE_LOCKMGR_REGISTER
    430 +       rc = av_lockmgr_register (locking_cb);
    431 +       if (rc < 0)
    432 +               fatal ("Lock manager initialisation failed");
    433 +#endif
    434  }
    435  
    436  static void ffmpeg_destroy ()
    437  {
    438 +#ifdef HAVE_LOCKMGR_REGISTER
    439 +       av_lockmgr_register (NULL);
    440 +#endif
    441 +
    442         av_log_set_level (AV_LOG_QUIET);
    443         ffmpeg_log_repeats (NULL);
    444  
    445 @@ -341,9 +417,9 @@
    446         }
    447  #endif
    448  
    449 -       if (tags_sel & TAGS_TIME) {
    450 +       if (!is_timing_broken (ic) && tags_sel & TAGS_TIME) {
    451                 info->time = -1;
    452 -               if (ic->duration >= 0)
    453 +               if (ic->duration != (int64_t)AV_NOPTS_VALUE && ic->duration >= 0)
    454                         info->time = ic->duration / AV_TIME_BASE;
    455         }
    456  
    457 @@ -426,12 +502,6 @@
    458  
    459  #endif
    460  
    461 -       if (tags_sel & TAGS_TIME) {
    462 -               info->time = -1;
    463 -               if (ic->duration != (int64_t)AV_NOPTS_VALUE && ic->duration >= 0)
    464 -                       info->time = ic->duration / AV_TIME_BASE;
    465 -       }
    466 -
    467  end:
    468  #ifdef HAVE_AVFORMAT_CLOSE_INPUT
    469         avformat_close_input (&ic);
    470 @@ -450,6 +520,9 @@
    471                 if (!strcmp (data->ic->iformat->name, "wav")) {
    472                         switch (data->enc->codec_id) {
    473                         case CODEC_ID_PCM_S8:
    474 +#if HAVE_DECL_CODEC_ID_PCM_S8_PLANAR
    475 +                       case CODEC_ID_PCM_S8_PLANAR:
    476 +#endif
    477                                 result = SFMT_S8;
    478                                 break;
    479                         case CODEC_ID_PCM_U8:
    480 @@ -456,6 +529,7 @@
    481                                 result = SFMT_U8;
    482                                 break;
    483                         case CODEC_ID_PCM_S16LE:
    484 +                       case CODEC_ID_PCM_S16LE_PLANAR:
    485                         case CODEC_ID_PCM_S16BE:
    486                                 result = SFMT_S16;
    487                                 break;
    488 @@ -490,15 +564,27 @@
    489  
    490         switch (data->enc->sample_fmt) {
    491         case AV_SAMPLE_FMT_U8:
    492 +#if HAVE_DECL_AV_SAMPLE_FMT_U8P
    493 +       case AV_SAMPLE_FMT_U8P:
    494 +#endif
    495                 result = SFMT_U8;
    496                 break;
    497         case AV_SAMPLE_FMT_S16:
    498 +#if HAVE_DECL_AV_SAMPLE_FMT_S16P
    499 +       case AV_SAMPLE_FMT_S16P:
    500 +#endif
    501                 result = SFMT_S16;
    502                 break;
    503         case AV_SAMPLE_FMT_S32:
    504 +#if HAVE_DECL_AV_SAMPLE_FMT_S32P
    505 +       case AV_SAMPLE_FMT_S32P:
    506 +#endif
    507                 result = SFMT_S32;
    508                 break;
    509         case AV_SAMPLE_FMT_FLT:
    510 +#if HAVE_DECL_AV_SAMPLE_FMT_FLTP
    511 +       case AV_SAMPLE_FMT_FLTP:
    512 +#endif
    513                 result = SFMT_FLOAT;
    514                 break;
    515         default:
    516 @@ -597,6 +683,7 @@
    517         data->stream = NULL;
    518         data->enc = NULL;
    519         data->codec = NULL;
    520 +       data->sample_width = 0;
    521         data->bitrate = 0;
    522         data->avg_bitrate = 0;
    523  
    524 @@ -624,6 +711,7 @@
    525         data->seek_sec = 0;
    526  #endif
    527         data->seek_broken = false;
    528 +       data->timing_broken = false;
    529  
    530         decoder_error_init (&data->error);
    531  
    532 @@ -655,6 +743,9 @@
    533         err = av_find_stream_info (data->ic);
    534  #endif
    535         if (err < 0) {
    536 +               /* Depending on the particular FFmpeg/LibAV version in use, this
    537 +                * may misreport experimental codecs.  Given we don't know the
    538 +                * codec at this time, we will have to live with it. */
    539                 decoder_error (&data->error, ERROR_FATAL, 0,
    540                                 "Could not find codec parameters (err %d)",
    541                                 err);
    542 @@ -683,6 +774,19 @@
    543         debug ("FFmpeg thinks '%s' is format(codec) '%s(%s)'",
    544                 fn, data->ic->iformat->name, data->codec->name);
    545  
    546 +#if HAVE_DECL_CODEC_CAP_EXPERIMENTAL
    547 +       /* This may or may not work depending on the particular version of
    548 +        * FFmpeg/LibAV in use.  For some versions this will be caught in
    549 +        * *_find_stream_info() above and misreported as an unfound codec
    550 +        * parameters error. */
    551 +       if (data->codec->capabilities & CODEC_CAP_EXPERIMENTAL) {
    552 +               decoder_error (&data->error, ERROR_FATAL, 0,
    553 +                               "The codec is experimental and may damage MOC: %s",
    554 +                               data->codec->name);
    555 +               goto end;
    556 +       }
    557 +#endif
    558 +
    559         set_downmixing (data);
    560         if (data->codec->capabilities & CODEC_CAP_TRUNCATED)
    561                 data->enc->flags |= CODEC_FLAG_TRUNCATED;
    562 @@ -702,27 +806,38 @@
    563         if (data->fmt == 0)
    564                 data->fmt = fmt_from_sample_fmt (data);
    565         if (data->fmt == 0) {
    566 +#ifdef HAVE_AV_GET_SAMPLE_FMT_NAME
    567                 decoder_error (&data->error, ERROR_FATAL, 0,
    568 +                              "Cannot get sample size from unknown sample format: %s",
    569 +                              av_get_sample_fmt_name (data->enc->sample_fmt));
    570 +#else
    571 +               decoder_error (&data->error, ERROR_FATAL, 0,
    572                                "Unsupported sample size!");
    573 +#endif
    574 +               avcodec_close (data->enc);
    575                 goto end;
    576         }
    577 +       data->sample_width = sfmt_Bps (data->fmt);
    578         if (data->codec->capabilities & CODEC_CAP_DELAY)
    579                 data->delay = true;
    580         data->seek_broken = is_seek_broken (data);
    581 +       data->timing_broken = is_timing_broken (data->ic);
    582  
    583         data->okay = true;
    584  
    585 -       if (data->ic->duration >= AV_TIME_BASE) {
    586 +       if (!data->timing_broken && data->ic->duration >= AV_TIME_BASE) {
    587  #ifdef HAVE_AVIO_SIZE
    588                 data->avg_bitrate = (int) (avio_size (data->ic->pb) /
    589 -                                         (data->ic->duration / AV_TIME_BASE) * 8);
    590 +                                          (data->ic->duration / AV_TIME_BASE) * 8);
    591  #else
    592                 data->avg_bitrate = (int) (data->ic->file_size /
    593 -                                         (data->ic->duration / AV_TIME_BASE) * 8);
    594 +                                          (data->ic->duration / AV_TIME_BASE) * 8);
    595  #endif
    596         }
    597 -       data->bitrate = data->ic->bit_rate;
    598  
    599 +       if (!data->timing_broken && data->ic->bit_rate > 0)
    600 +               data->bitrate = data->ic->bit_rate;
    601 +
    602         return data;
    603  
    604  end:
    605 @@ -908,8 +1023,6 @@
    606                                             &data_size, pkt->data, pkt->size);
    607  #endif
    608  
    609 -               debug ("Decoded %dB", data_size);
    610 -
    611                 if (len < 0)  {
    612                         /* skip frame */
    613                         decoder_error (&data->error, ERROR_STREAM, 0, "Error in the stream!");
    614 @@ -916,14 +1029,16 @@
    615                         break;
    616                 }
    617  
    618 +               debug ("Decoded %dB", data_size);
    619 +
    620 +               pkt->data += len;
    621 +               pkt->size -= len;
    622 +
    623                 if (data->eof && data_size == 0) {
    624                         data->eos = true;
    625                         break;
    626                 }
    627  
    628 -               pkt->data += len;
    629 -               pkt->size -= len;
    630 -
    631                 copied = copy_or_buffer (data, data->avbuf, data_size, buf, buf_len);
    632  
    633                 buf += copied;
    634 @@ -943,12 +1058,15 @@
    635                            char *buf, int buf_len)
    636  {
    637         int filled = 0;
    638 +       char *packed;
    639 +       AVFrame *frame;
    640  
    641 +       frame = avcodec_alloc_frame ();
    642 +
    643         do {
    644 -               int len, got_frame, is_planar, plane_size, data_size, copied;
    645 -               AVFrame frame;
    646 +               int len, got_frame, is_planar, packed_size, copied;
    647  
    648 -               len = avcodec_decode_audio4 (data->enc, &frame, &got_frame, pkt);
    649 +               len = avcodec_decode_audio4 (data->enc, frame, &got_frame, pkt);
    650  
    651                 if (len < 0)  {
    652                         /* skip frame */
    653 @@ -956,45 +1074,56 @@
    654                         break;
    655                 }
    656  
    657 -               if (!got_frame) {
    658 -                       data->eos = data->eof;
    659 -                       break;
    660 -               }
    661 -
    662                 debug ("Decoded %dB", len);
    663  
    664                 pkt->data += len;
    665                 pkt->size -= len;
    666  
    667 -               is_planar = av_sample_fmt_is_planar (data->enc->sample_fmt);
    668 -               data_size = av_samples_get_buffer_size (&plane_size,
    669 -                                                       data->enc->channels,                                                   frame.nb_samples,
    670 -                                                       data->enc->sample_fmt, 1);
    671 +               if (!got_frame) {
    672 +                       data->eos = data->eof && (pkt->size == 0);
    673 +                       continue;
    674 +               }
    675  
    676 -               if (data_size == 0)
    677 +               if (frame->nb_samples == 0)
    678                         continue;
    679  
    680 -               copied = copy_or_buffer (data, (char *)frame.extended_data[0],
    681 -                                        plane_size, buf, buf_len);
    682 +               is_planar = av_sample_fmt_is_planar (data->enc->sample_fmt);
    683 +               packed = (char *)frame->extended_data[0];
    684 +               packed_size = frame->nb_samples * data->sample_width
    685 +                                               * data->enc->channels;
    686 +
    687 +               if (is_planar && data->enc->channels > 1) {
    688 +                       int sample, ch;
    689 +
    690 +                       packed = xmalloc (packed_size);
    691 +
    692 +                       for (sample = 0; sample < frame->nb_samples; sample += 1) {
    693 +                               for (ch = 0; ch < data->enc->channels; ch += 1)
    694 +                                       memcpy (packed + (sample * data->enc->channels + ch)
    695 +                                                                * data->sample_width,
    696 +                                               (char *)frame->extended_data[ch] + sample * data->sample_width,
    697 +                                               data->sample_width);
    698 +                       }
    699 +               }
    700 +
    701 +               copied = copy_or_buffer (data, packed, packed_size, buf, buf_len);
    702                 buf += copied;
    703                 filled += copied;
    704                 buf_len -= copied;
    705  
    706 -        if (is_planar && data->enc->channels > 1) {
    707 -                       int ch;
    708 +               debug ("Copying %dB (%dB filled)", packed_size, filled);
    709  
    710 -            for (ch = 1; ch < data->enc->channels; ch += 1) {
    711 -                               copied = copy_or_buffer (data, (char *)frame.extended_data[ch],
    712 -                                                        plane_size, buf, buf_len);
    713 -                               buf += copied;
    714 -                               filled += copied;
    715 -                               buf_len -= copied;
    716 -            }
    717 -        }
    718 -
    719 -               debug ("Copying %dB (%dB filled)", data_size, filled);
    720 +               if (packed != (char *)frame->extended_data[0])
    721 +                       free (packed);
    722         } while (pkt->size > 0);
    723  
    724 +       avcodec_get_frame_defaults (frame);
    725 +#ifdef HAVE_AVCODEC_FREE_FRAME
    726 +       avcodec_free_frame (&frame);
    727 +#else
    728 +       av_freep (&frame);
    729 +#endif
    730 +
    731         return filled;
    732  }
    733  #endif
    734 @@ -1122,9 +1251,10 @@
    735                 free_packet (pkt);
    736         } while (!bytes_produced && !data->eos);
    737  
    738 -       data->bitrate = compute_bitrate (sound_params, bytes_used,
    739 -                                        bytes_produced + data->remain_buf_len,
    740 -                                        data->bitrate);
    741 +       if (!data->timing_broken)
    742 +               data->bitrate = compute_bitrate (sound_params, bytes_used,
    743 +                                                bytes_produced + data->remain_buf_len,
    744 +                                                data->bitrate);
    745  
    746         return bytes_produced;
    747  }
    748 @@ -1185,7 +1315,7 @@
    749  {
    750         struct ffmpeg_data *data = (struct ffmpeg_data *)prv_data;
    751  
    752 -       return data->bitrate / 1000;
    753 +       return data->timing_broken ? -1 : data->bitrate / 1000;
    754  }
    755  
    756  static int ffmpeg_get_avg_bitrate (void *prv_data)
    757 @@ -1192,7 +1322,7 @@
    758  {
    759         struct ffmpeg_data *data = (struct ffmpeg_data *)prv_data;
    760  
    761 -       return data->avg_bitrate / 1000;
    762 +       return data->timing_broken ? -1 : data->avg_bitrate / 1000;
    763  }
    764  
    765  static int ffmpeg_get_duration (void *prv_data)
    766 @@ -1199,6 +1329,9 @@
    767  {
    768         struct ffmpeg_data *data = (struct ffmpeg_data *)prv_data;
    769  
    770 +       if (data->timing_broken)
    771 +               return -1;
    772 +
    773         if (!data->stream)
    774                 return -1;
    775  
    776 Index: decoder_plugins/vorbis/vorbis.c
    777 ===================================================================
    778 --- decoder_plugins/vorbis/vorbis.c     (revision 2506)
    779 +++ decoder_plugins/vorbis/vorbis.c     (revision 2529)
    780 @@ -47,9 +47,9 @@
    781  
    782  /* Tremor defines time as 64-bit integer milliseconds. */
    783  #ifndef HAVE_TREMOR
    784 -static const double time_scaler = 1;
    785 +static const int64_t time_scaler = 1;
    786  #else
    787 -static const ogg_int64_t time_scaler = 1000;
    788 +static const int64_t time_scaler = 1000;
    789  #endif
    790  
    791  struct vorbis_data
    792 @@ -171,11 +171,11 @@
    793                 get_comment_tags (&vf, info);
    794  
    795         if (tags_sel & TAGS_TIME) {
    796 -               int vorbis_time;
    797 +               int64_t vorbis_time;
    798  
    799 -           vorbis_time = ov_time_total (&vf, -1) / time_scaler;
    800 -           if (vorbis_time >= 0)
    801 -                       info->time = vorbis_time;
    802 +               vorbis_time = ov_time_total (&vf, -1);
    803 +               if (vorbis_time >= 0)
    804 +                       info->time = vorbis_time / time_scaler;
    805         }
    806  
    807         ov_clear (&vf);
    808 @@ -244,12 +244,15 @@
    809                 io_close (data->stream);
    810         }
    811         else {
    812 +               int64_t duration;
    813 +
    814                 data->last_section = -1;
    815                 data->avg_bitrate = ov_bitrate (&data->vf, -1) / 1000;
    816                 data->bitrate = data->avg_bitrate;
    817 -               data->duration = ov_time_total (&data->vf, -1) / time_scaler;
    818 -               if (data->duration == OV_EINVAL)
    819 -                       data->duration = -1;
    820 +               data->duration = -1;
    821 +               duration = ov_time_total (&data->vf, -1);
    822 +               if (duration >= 0)
    823 +                       data->duration = duration / time_scaler;
    824                 data->ok = 1;
    825                 get_comment_tags (&data->vf, data->tags);
    826         }
    827 @@ -280,9 +283,9 @@
    828  
    829  static int vorbis_can_decode (struct io_stream *stream)
    830  {
    831 -       char buf[34];
    832 +       char buf[35];
    833  
    834 -       if (io_peek (stream, buf, 34) == 34 && !memcmp (buf, "OggS", 4)
    835 +       if (io_peek (stream, buf, 35) == 35 && !memcmp (buf, "OggS", 4)
    836                         && !memcmp (buf + 28, "\01vorbis", 7))
    837                 return 1;
    838  
    839 Index: decoder_plugins/flac/flac.c
    840 ===================================================================
    841 --- decoder_plugins/flac/flac.c (revision 2506)
    842 +++ decoder_plugins/flac/flac.c (revision 2529)
    843 @@ -54,7 +54,7 @@
    844         int abort; /* abort playing (due to an error) */
    845  
    846         unsigned length;
    847 -       unsigned total_samples;
    848 +       FLAC__uint64 total_samples;
    849  
    850         FLAC__byte sample_buffer[SAMPLE_BUFFER_SIZE];
    851         unsigned sample_buffer_fill;
    852 @@ -156,11 +156,8 @@
    853         if (metadata->type == FLAC__METADATA_TYPE_STREAMINFO) {
    854                 debug ("Got metadata info");
    855  
    856 -               data->total_samples =
    857 -                       (unsigned)(metadata->data.stream_info.total_samples
    858 -                                  & 0xffffffff);
    859 -               data->bits_per_sample =
    860 -                       metadata->data.stream_info.bits_per_sample;
    861 +               data->total_samples = metadata->data.stream_info.total_samples;
    862 +               data->bits_per_sample = metadata->data.stream_info.bits_per_sample;
    863                 data->channels = metadata->data.stream_info.channels;
    864                 data->sample_rate = metadata->data.stream_info.sample_rate;
    865                 data->length = data->total_samples / data->sample_rate;
    866 @@ -536,9 +533,10 @@
    867         if ((unsigned)sec > data->length)
    868                 return -1;
    869  
    870 -       target_sample = (FLAC__uint64)((sec/(double)data->length) *
    871 -                       (double)data->total_samples);
    872 +       target_sample = (FLAC__uint64)(((double)sec / (double)data->length) *
    873 +                                      (double)data->total_samples);
    874  
    875 +
    876  #ifdef LEGACY_FLAC
    877         if (FLAC__seekable_stream_decoder_seek_absolute(data->decoder,
    878                                 target_sample))
    879 Index: audio.c
    880 ===================================================================
    881 --- audio.c     (revision 2506)
    882 +++ audio.c     (revision 2529)
    883 @@ -169,7 +169,7 @@
    884         if (fmt1 & (SFMT_S16 | SFMT_U16)
    885                         && fmt2 & (SFMT_S16 | SFMT_U16))
    886                 return 1;
    887 -       if (fmt1 & (SFMT_S8 | SFMT_U8)
    888 +       if (fmt1 & (SFMT_S32 | SFMT_U32)
    889                         && fmt2 & (SFMT_S32 | SFMT_U32))
    890                 return 1;
    891         if (fmt1 & fmt2 & SFMT_FLOAT)
    892 Index: TODO
    893 ===================================================================
    894 --- TODO        (revision 2506)
    895 +++ TODO        (revision 2529)
    896 @@ -9,8 +9,6 @@
    897    - Recognition of ID3 tags v1 is broken (example: small.mp3).  [node/234]
    898    - Perhaps MOC can add support for the frame field_type to differentiate
    899      between ID3_FIELD_TYPE_LATIN1 and ID3_FIELD_TYPE_STRING.  [node/234]
    900 -  - Characters which are represented in more than one screen column cause
    901 -    the text to overflow its field.  [node/82, 99 and 788]
    902    - Some Cyrillic characters in file and directory names don't get displayed
    903      correctly.
    904  * Program crashes:
  • files/patch-options.c.diff

     
    1 diff -ur ../moc-2.4.3.orig/options.c ./options.c
    2 --- ../moc-2.4.3.orig/options.c 2007-05-22 20:24:34.000000000 +0200
    3 +++ ./options.c 2008-03-26 20:02:14.000000000 +0100
    4 @@ -172,8 +172,8 @@
    5         option_add_int ("SyncPlaylist", 1);
    6         option_add_int ("InputBuffer", 512);
    7         option_add_int ("Prebuffering", 64);
    8 -       option_add_str ("JackOutLeft", "alsa_pcm:playback_1");
    9 -       option_add_str ("JackOutRight", "alsa_pcm:playback_2");
    10 +       option_add_str ("JackOutLeft", "system:playback_1");
    11 +       option_add_str ("JackOutRight", "system:playback_2");
    12         option_add_int ("ASCIILines", 0);
    13         option_add_str ("FastDir1", NULL);
    14         option_add_str ("FastDir2", NULL);