]> git.sesse.net Git - ffmpeg/blobdiff - libavdevice/alsa-audio-common.c
mov_chan: Pass a separate AVIOContext for reading
[ffmpeg] / libavdevice / alsa-audio-common.c
index 4cfc6e98647968ed25c82b632fc67270b1c035a0..b48e007fb3f3d6031d3c5d218371f68c52c5bc24 100644 (file)
 #include <alsa/asoundlib.h>
 #include "libavformat/avformat.h"
 #include "libavutil/avassert.h"
+#include "libavutil/audioconvert.h"
 
 #include "alsa-audio.h"
 
 static av_cold snd_pcm_format_t codec_id_to_pcm_format(int codec_id)
 {
     switch(codec_id) {
-        case CODEC_ID_PCM_F64LE: return SND_PCM_FORMAT_FLOAT64_LE;
-        case CODEC_ID_PCM_F64BE: return SND_PCM_FORMAT_FLOAT64_BE;
-        case CODEC_ID_PCM_F32LE: return SND_PCM_FORMAT_FLOAT_LE;
-        case CODEC_ID_PCM_F32BE: return SND_PCM_FORMAT_FLOAT_BE;
-        case CODEC_ID_PCM_S32LE: return SND_PCM_FORMAT_S32_LE;
-        case CODEC_ID_PCM_S32BE: return SND_PCM_FORMAT_S32_BE;
-        case CODEC_ID_PCM_U32LE: return SND_PCM_FORMAT_U32_LE;
-        case CODEC_ID_PCM_U32BE: return SND_PCM_FORMAT_U32_BE;
-        case CODEC_ID_PCM_S24LE: return SND_PCM_FORMAT_S24_3LE;
-        case CODEC_ID_PCM_S24BE: return SND_PCM_FORMAT_S24_3BE;
-        case CODEC_ID_PCM_U24LE: return SND_PCM_FORMAT_U24_3LE;
-        case CODEC_ID_PCM_U24BE: return SND_PCM_FORMAT_U24_3BE;
-        case CODEC_ID_PCM_S16LE: return SND_PCM_FORMAT_S16_LE;
-        case CODEC_ID_PCM_S16BE: return SND_PCM_FORMAT_S16_BE;
-        case CODEC_ID_PCM_U16LE: return SND_PCM_FORMAT_U16_LE;
-        case CODEC_ID_PCM_U16BE: return SND_PCM_FORMAT_U16_BE;
-        case CODEC_ID_PCM_S8:    return SND_PCM_FORMAT_S8;
-        case CODEC_ID_PCM_U8:    return SND_PCM_FORMAT_U8;
-        case CODEC_ID_PCM_MULAW: return SND_PCM_FORMAT_MU_LAW;
-        case CODEC_ID_PCM_ALAW:  return SND_PCM_FORMAT_A_LAW;
+        case AV_CODEC_ID_PCM_F64LE: return SND_PCM_FORMAT_FLOAT64_LE;
+        case AV_CODEC_ID_PCM_F64BE: return SND_PCM_FORMAT_FLOAT64_BE;
+        case AV_CODEC_ID_PCM_F32LE: return SND_PCM_FORMAT_FLOAT_LE;
+        case AV_CODEC_ID_PCM_F32BE: return SND_PCM_FORMAT_FLOAT_BE;
+        case AV_CODEC_ID_PCM_S32LE: return SND_PCM_FORMAT_S32_LE;
+        case AV_CODEC_ID_PCM_S32BE: return SND_PCM_FORMAT_S32_BE;
+        case AV_CODEC_ID_PCM_U32LE: return SND_PCM_FORMAT_U32_LE;
+        case AV_CODEC_ID_PCM_U32BE: return SND_PCM_FORMAT_U32_BE;
+        case AV_CODEC_ID_PCM_S24LE: return SND_PCM_FORMAT_S24_3LE;
+        case AV_CODEC_ID_PCM_S24BE: return SND_PCM_FORMAT_S24_3BE;
+        case AV_CODEC_ID_PCM_U24LE: return SND_PCM_FORMAT_U24_3LE;
+        case AV_CODEC_ID_PCM_U24BE: return SND_PCM_FORMAT_U24_3BE;
+        case AV_CODEC_ID_PCM_S16LE: return SND_PCM_FORMAT_S16_LE;
+        case AV_CODEC_ID_PCM_S16BE: return SND_PCM_FORMAT_S16_BE;
+        case AV_CODEC_ID_PCM_U16LE: return SND_PCM_FORMAT_U16_LE;
+        case AV_CODEC_ID_PCM_U16BE: return SND_PCM_FORMAT_U16_BE;
+        case AV_CODEC_ID_PCM_S8:    return SND_PCM_FORMAT_S8;
+        case AV_CODEC_ID_PCM_U8:    return SND_PCM_FORMAT_U8;
+        case AV_CODEC_ID_PCM_MULAW: return SND_PCM_FORMAT_MU_LAW;
+        case AV_CODEC_ID_PCM_ALAW:  return SND_PCM_FORMAT_A_LAW;
         default:                 return SND_PCM_FORMAT_UNKNOWN;
     }
 }
@@ -142,7 +143,7 @@ switch(format) {\
     case FORMAT_F32: s->reorder_func = alsa_reorder_f32_out_ ##layout;   break;\
 }
 
-static av_cold int find_reorder_func(AlsaData *s, int codec_id, int64_t layout, int out)
+static av_cold int find_reorder_func(AlsaData *s, int codec_id, uint64_t layout, int out)
 {
     int format;
 
@@ -155,20 +156,20 @@ static av_cold int find_reorder_func(AlsaData *s, int codec_id, int64_t layout,
         return 0;
 
     switch (codec_id) {
-    case CODEC_ID_PCM_S8:
-    case CODEC_ID_PCM_U8:
-    case CODEC_ID_PCM_ALAW:
-    case CODEC_ID_PCM_MULAW: format = FORMAT_I8;  break;
-    case CODEC_ID_PCM_S16LE:
-    case CODEC_ID_PCM_S16BE:
-    case CODEC_ID_PCM_U16LE:
-    case CODEC_ID_PCM_U16BE: format = FORMAT_I16; break;
-    case CODEC_ID_PCM_S32LE:
-    case CODEC_ID_PCM_S32BE:
-    case CODEC_ID_PCM_U32LE:
-    case CODEC_ID_PCM_U32BE: format = FORMAT_I32; break;
-    case CODEC_ID_PCM_F32LE:
-    case CODEC_ID_PCM_F32BE: format = FORMAT_F32; break;
+    case AV_CODEC_ID_PCM_S8:
+    case AV_CODEC_ID_PCM_U8:
+    case AV_CODEC_ID_PCM_ALAW:
+    case AV_CODEC_ID_PCM_MULAW: format = FORMAT_I8;  break;
+    case AV_CODEC_ID_PCM_S16LE:
+    case AV_CODEC_ID_PCM_S16BE:
+    case AV_CODEC_ID_PCM_U16LE:
+    case AV_CODEC_ID_PCM_U16BE: format = FORMAT_I16; break;
+    case AV_CODEC_ID_PCM_S32LE:
+    case AV_CODEC_ID_PCM_S32BE:
+    case AV_CODEC_ID_PCM_U32LE:
+    case AV_CODEC_ID_PCM_U32BE: format = FORMAT_I32; break;
+    case AV_CODEC_ID_PCM_F32LE:
+    case AV_CODEC_ID_PCM_F32BE: format = FORMAT_F32; break;
     default:                 return AVERROR(ENOSYS);
     }
 
@@ -184,7 +185,7 @@ static av_cold int find_reorder_func(AlsaData *s, int codec_id, int64_t layout,
 
 av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode,
                          unsigned int *sample_rate,
-                         int channels, enum CodecID *codec_id)
+                         int channels, enum AVCodecID *codec_id)
 {
     AlsaData *s = ctx->priv_data;
     const char *audio_device;
@@ -193,12 +194,12 @@ av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode,
     snd_pcm_t *h;
     snd_pcm_hw_params_t *hw_params;
     snd_pcm_uframes_t buffer_size, period_size;
-    int64_t layout = ctx->streams[0]->codec->channel_layout;
+    uint64_t layout = ctx->streams[0]->codec->channel_layout;
 
     if (ctx->filename[0] == 0) audio_device = "default";
     else                       audio_device = ctx->filename;
 
-    if (*codec_id == CODEC_ID_NONE)
+    if (*codec_id == AV_CODEC_ID_NONE)
         *codec_id = DEFAULT_CODEC_ID;
     format = codec_id_to_pcm_format(*codec_id);
     if (format == SND_PCM_FORMAT_UNKNOWN) {
@@ -260,6 +261,7 @@ av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode,
     }
 
     snd_pcm_hw_params_get_buffer_size_max(hw_params, &buffer_size);
+    buffer_size = FFMIN(buffer_size, ALSA_BUFFER_SIZE_MAX);
     /* TODO: maybe use ctx->max_picture_buffer somehow */
     res = snd_pcm_hw_params_set_buffer_size_near(h, hw_params, &buffer_size);
     if (res < 0) {
@@ -269,6 +271,8 @@ av_cold int ff_alsa_open(AVFormatContext *ctx, snd_pcm_stream_t mode,
     }
 
     snd_pcm_hw_params_get_period_size_min(hw_params, &period_size, NULL);
+    if (!period_size)
+        period_size = buffer_size / 4;
     res = snd_pcm_hw_params_set_period_size_near(h, hw_params, &period_size, NULL);
     if (res < 0) {
         av_log(ctx, AV_LOG_ERROR, "cannot set ALSA period size (%s)\n",