avdevice: Add missing header for NULL_IF_CONFIG_SMALL
[ffmpeg.git] / libavdevice / pulse.c
index 1edd24f..aaff447 100644 (file)
  * @file
  * PulseAudio input using the simple API.
  * @author Luca Barbato <lu_zero@gentoo.org>
- *
  */
 
 #include <pulse/simple.h>
 #include <pulse/rtclock.h>
 #include <pulse/error.h>
 
-#include "libavformat/avformat.h"
+#include "libavutil/internal.h"
 #include "libavutil/opt.h"
+#include "libavutil/time.h"
+
+#include "libavformat/avformat.h"
+#include "libavformat/internal.h"
 
-#define DEFAULT_CODEC_ID AV_NE(CODEC_ID_PCM_S16BE, CODEC_ID_PCM_S16LE)
+#define DEFAULT_CODEC_ID AV_NE(AV_CODEC_ID_PCM_S16BE, AV_CODEC_ID_PCM_S16LE)
 
 typedef struct PulseData {
     AVClass *class;
@@ -46,34 +49,35 @@ typedef struct PulseData {
     int  fragment_size;
     pa_simple *s;
     int64_t pts;
+    int64_t frame_duration;
+    int wallclock;
 } PulseData;
 
 static pa_sample_format_t codec_id_to_pulse_format(int codec_id) {
     switch (codec_id) {
-    case CODEC_ID_PCM_U8:    return PA_SAMPLE_U8;
-    case CODEC_ID_PCM_ALAW:  return PA_SAMPLE_ALAW;
-    case CODEC_ID_PCM_MULAW: return PA_SAMPLE_ULAW;
-    case CODEC_ID_PCM_S16LE: return PA_SAMPLE_S16LE;
-    case CODEC_ID_PCM_S16BE: return PA_SAMPLE_S16BE;
-    case CODEC_ID_PCM_F32LE: return PA_SAMPLE_FLOAT32LE;
-    case CODEC_ID_PCM_F32BE: return PA_SAMPLE_FLOAT32BE;
-    case CODEC_ID_PCM_S32LE: return PA_SAMPLE_S32LE;
-    case CODEC_ID_PCM_S32BE: return PA_SAMPLE_S32BE;
-    case CODEC_ID_PCM_S24LE: return PA_SAMPLE_S24LE;
-    case CODEC_ID_PCM_S24BE: return PA_SAMPLE_S24BE;
+    case AV_CODEC_ID_PCM_U8:    return PA_SAMPLE_U8;
+    case AV_CODEC_ID_PCM_ALAW:  return PA_SAMPLE_ALAW;
+    case AV_CODEC_ID_PCM_MULAW: return PA_SAMPLE_ULAW;
+    case AV_CODEC_ID_PCM_S16LE: return PA_SAMPLE_S16LE;
+    case AV_CODEC_ID_PCM_S16BE: return PA_SAMPLE_S16BE;
+    case AV_CODEC_ID_PCM_F32LE: return PA_SAMPLE_FLOAT32LE;
+    case AV_CODEC_ID_PCM_F32BE: return PA_SAMPLE_FLOAT32BE;
+    case AV_CODEC_ID_PCM_S32LE: return PA_SAMPLE_S32LE;
+    case AV_CODEC_ID_PCM_S32BE: return PA_SAMPLE_S32BE;
+    case AV_CODEC_ID_PCM_S24LE: return PA_SAMPLE_S24LE;
+    case AV_CODEC_ID_PCM_S24BE: return PA_SAMPLE_S24BE;
     default:                 return PA_SAMPLE_INVALID;
     }
 }
 
-static av_cold int pulse_read_header(AVFormatContext *s,
-                                     AVFormatParameters *ap)
+static av_cold int pulse_read_header(AVFormatContext *s)
 {
     PulseData *pd = s->priv_data;
     AVStream *st;
     char *device = NULL;
     int ret;
-    enum CodecID codec_id =
-        s->audio_codec_id == CODEC_ID_NONE ? DEFAULT_CODEC_ID : s->audio_codec_id;
+    enum AVCodecID codec_id =
+        s->audio_codec_id == AV_CODEC_ID_NONE ? DEFAULT_CODEC_ID : s->audio_codec_id;
     const pa_sample_spec ss = { codec_id_to_pulse_format(codec_id),
                                 pd->sample_rate,
                                 pd->channels };
@@ -107,9 +111,11 @@ static av_cold int pulse_read_header(AVFormatContext *s,
     st->codec->codec_id    = codec_id;
     st->codec->sample_rate = pd->sample_rate;
     st->codec->channels    = pd->channels;
-    av_set_pts_info(st, 64, 1, 1000000);  /* 64 bits pts in us */
+    avpriv_set_pts_info(st, 64, 1, 1000000);  /* 64 bits pts in us */
 
     pd->pts = AV_NOPTS_VALUE;
+    pd->frame_duration = (pd->frame_size * 1000000LL * 8) /
+        (pd->sample_rate * pd->channels * av_get_bits_per_sample(codec_id));
 
     return 0;
 }
@@ -119,8 +125,6 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt)
     PulseData *pd  = s->priv_data;
     int res;
     pa_usec_t latency;
-    uint64_t frame_duration =
-        (pd->frame_size*1000000LL) / (pd->sample_rate * pd->channels);
 
     if (av_new_packet(pkt, pd->frame_size) < 0) {
         return AVERROR(ENOMEM);
@@ -141,11 +145,13 @@ static int pulse_read_packet(AVFormatContext *s, AVPacket *pkt)
 
     if (pd->pts == AV_NOPTS_VALUE) {
         pd->pts = -latency;
+        if (pd->wallclock)
+            pd->pts += av_gettime();
     }
 
     pkt->pts = pd->pts;
 
-    pd->pts += frame_duration;
+    pd->pts += pd->frame_duration;
 
     return 0;
 }
@@ -164,10 +170,11 @@ static const AVOption options[] = {
     { "server",        "pulse server name",                              OFFSET(server),        AV_OPT_TYPE_STRING, {.str = NULL},     0, 0, D },
     { "name",          "application name",                               OFFSET(name),          AV_OPT_TYPE_STRING, {.str = "libav"},  0, 0, D },
     { "stream_name",   "stream description",                             OFFSET(stream_name),   AV_OPT_TYPE_STRING, {.str = "record"}, 0, 0, D },
-    { "sample_rate",   "sample rate in Hz",                              OFFSET(sample_rate),   AV_OPT_TYPE_INT,    {.dbl = 48000},    1, INT_MAX, D },
-    { "channels",      "number of audio channels",                       OFFSET(channels),      AV_OPT_TYPE_INT,    {.dbl = 2},        1, INT_MAX, D },
-    { "frame_size",    "number of bytes per frame",                      OFFSET(frame_size),    AV_OPT_TYPE_INT,    {.dbl = 1024},     1, INT_MAX, D },
-    { "fragment_size", "buffering size, affects latency and cpu usage",  OFFSET(fragment_size), AV_OPT_TYPE_INT,    {.dbl = -1},      -1, INT_MAX, D },
+    { "sample_rate",   "sample rate in Hz",                              OFFSET(sample_rate),   AV_OPT_TYPE_INT,    {.i64 = 48000},    1, INT_MAX, D },
+    { "channels",      "number of audio channels",                       OFFSET(channels),      AV_OPT_TYPE_INT,    {.i64 = 2},        1, INT_MAX, D },
+    { "frame_size",    "number of bytes per frame",                      OFFSET(frame_size),    AV_OPT_TYPE_INT,    {.i64 = 1024},     1, INT_MAX, D },
+    { "fragment_size", "buffering size, affects latency and cpu usage",  OFFSET(fragment_size), AV_OPT_TYPE_INT,    {.i64 = -1},      -1, INT_MAX, D },
+    { "wallclock",     "set the initial pts using the current time",     OFFSET(wallclock),     AV_OPT_TYPE_INT,    {.i64 = 1},       -1, 1, D },
     { NULL },
 };