shithub: sox

Download patch

ref: 8d53f1fb52135c268b0ecb588e6ab14df7f1c11d
parent: ea37d6681fba01a0b8a2129fd9fe84b647e792af
author: rrt <rrt>
date: Fri Feb 11 14:20:39 EST 2011

Fix crash on some platforms; update use of ffmpeg APIs; add .m4b to handled extensions.

--- a/src/ffmpeg.c
+++ b/src/ffmpeg.c
@@ -1,6 +1,6 @@
 /* libSoX ffmpeg formats.
  *
- * Copyright 2007 Reuben Thomas <rrt@sc3d.org>
+ * Copyright 2007, 2011 Reuben Thomas <rrt@sc3d.org>
  *
  * Based on ffplay.c and output_example.c Copyright 2003 Fabrice Bellard
  * Note: ffplay.c is distributed under the LGPL 2.1 or later;
@@ -63,8 +63,6 @@
   AVFormatContext *ctxt;
   int audio_input_frame_size;
   AVPacket audio_pkt;
-  uint8_t *audio_pkt_data;
-  int audio_pkt_size;
 } priv_t;
 
 /* open a given stream. Return 0 if OK */
@@ -127,26 +125,27 @@
 
   for (;;) {
     /* NOTE: the audio packet can contain several frames */
-    while (ffmpeg->audio_pkt_size > 0) {
+    while (ffmpeg->audio_pkt.size > 0) {
       data_size = buf_size;
-      len1 = avcodec_decode_audio2(ffmpeg->audio_st->codec,
-                                   (int16_t *)audio_buf, &data_size,
-                                   ffmpeg->audio_pkt_data, ffmpeg->audio_pkt_size);
+      len1 = avcodec_decode_audio3(ffmpeg->audio_st->codec,
+				   (int16_t *)audio_buf, &data_size,
+				   pkt);
       if (len1 < 0) /* if error, we skip the rest of the packet */
 	return 0;
 
-      ffmpeg->audio_pkt_data += len1;
-      ffmpeg->audio_pkt_size -= len1;
+      ffmpeg->audio_pkt.data += len1;
+      ffmpeg->audio_pkt.size -= len1;
       if (data_size <= 0)
-        continue;
+	continue;
       return data_size;
     }
-
-    ffmpeg->audio_pkt_data = pkt->data;
-    ffmpeg->audio_pkt_size = pkt->size;
   }
 }
 
+/* On some platforms, libavcodec wants the output buffer aligned to 16
+ * bytes (because it uses SSE/Altivec internally). */
+#define ALIGN16(p) ((uint8_t *)(p) + (16 - (size_t)(p) % 16))
+
 static int startread(sox_format_t * ft)
 {
   priv_t * ffmpeg = (priv_t *)ft->priv;
@@ -154,7 +153,7 @@
   int ret;
   int i;
 
-  ffmpeg->audio_buf = lsx_calloc(1, (size_t)AVCODEC_MAX_AUDIO_FRAME_SIZE);
+  ffmpeg->audio_buf = ALIGN16 (lsx_calloc(1, (size_t)AVCODEC_MAX_AUDIO_FRAME_SIZE + 16));
 
   /* Signal audio stream not found */
   ffmpeg->audio_index = -1;
@@ -201,8 +200,8 @@
   ft->encoding.encoding = SOX_ENCODING_SIGN2;
   ft->signal.channels = ffmpeg->audio_st->codec->channels;
   ft->signal.length = 0; /* Currently we can't seek; no idea how to get this
-                     info from ffmpeg anyway (in time, yes, but not in
-                     samples); but ffmpeg *can* seek */
+		     info from ffmpeg anyway (in time, yes, but not in
+		     samples); but ffmpeg *can* seek */
 
   return SOX_SUCCESS;
 }
@@ -224,7 +223,7 @@
     if (ffmpeg->audio_buf_index * 2 >= ffmpeg->audio_buf_size) {
       if ((ret = av_read_frame(ffmpeg->ctxt, pkt)) < 0 &&
 	  (ret == AVERROR_EOF || url_ferror(ffmpeg->ctxt->pb)))
-        break;
+	break;
       ffmpeg->audio_buf_size = audio_decode_frame(ffmpeg, ffmpeg->audio_buf, AVCODEC_MAX_AUDIO_FRAME_SIZE);
       ffmpeg->audio_buf_index = 0;
     }
@@ -335,10 +334,10 @@
 
   /* auto detect the output format from the name. default is
      mpeg. */
-  ffmpeg->fmt = guess_format(NULL, ft->filename, NULL);
+  ffmpeg->fmt = av_guess_format(NULL, ft->filename, NULL);
   if (!ffmpeg->fmt) {
     lsx_warn("ffmpeg could not deduce output format from file extension; using MPEG");
-    ffmpeg->fmt = guess_format("mpeg", NULL, NULL);
+    ffmpeg->fmt = av_guess_format("mpeg", NULL, NULL);
     if (!ffmpeg->fmt) {
       lsx_fail("ffmpeg could not find suitable output format");
       return SOX_EOF;
@@ -346,7 +345,7 @@
   }
 
   /* allocate the output media context */
-  ffmpeg->ctxt = av_alloc_format_context();
+  ffmpeg->ctxt = avformat_alloc_context();
   if (!ffmpeg->ctxt) {
     fprintf(stderr, "ffmpeg out of memory error");
     return SOX_EOF;
@@ -408,12 +407,12 @@
     if (ffmpeg->samples_index < ffmpeg->audio_input_frame_size) {
       SOX_SAMPLE_LOCALS;
       for (; nread < len && ffmpeg->samples_index < ffmpeg->audio_input_frame_size; nread++)
-        ffmpeg->samples[ffmpeg->samples_index++] = SOX_SAMPLE_TO_SIGNED_16BIT(buf[nread], ft->clips);
+	ffmpeg->samples[ffmpeg->samples_index++] = SOX_SAMPLE_TO_SIGNED_16BIT(buf[nread], ft->clips);
     }
 
     /* If output frame full or no more data to read, write it out */
     if (ffmpeg->samples_index == ffmpeg->audio_input_frame_size ||
-        (len == 0 && ffmpeg->samples_index > 0)) {
+	(len == 0 && ffmpeg->samples_index > 0)) {
       AVCodecContext *c = ffmpeg->audio_st->codec;
       AVPacket pkt;
 
@@ -426,10 +425,10 @@
 
       /* write the compressed frame to the media file */
       if (av_write_frame(ffmpeg->ctxt, &pkt) != 0)
-        lsx_fail("ffmpeg had error while writing audio frame");
+	lsx_fail("ffmpeg had error while writing audio frame");
 
       /* Increment nwritten whether write succeeded or not; we have to
-         get rid of the input! */
+	 get rid of the input! */
       nwritten += ffmpeg->samples_index;
       ffmpeg->samples_index = 0;
     }
@@ -485,6 +484,7 @@
     "ffmpeg", /* special type to force use of ffmpeg */
     "mp4",
     "m4a",
+    "m4b",
     "avi",
     "wmv",
     "mpg",