[MPlayer-dev-eng] [PATCH 1/5] ao_alsa: remove mmap support
Clemens Ladisch
clemens at ladisch.de
Mon Jan 30 09:14:32 CET 2006
This patch removes mmap support because it doesn't have any benefit.
Directly accessing the sample buffer makes sense only when the samples
can be constructed in-place. When the samples are just copied from
another buffer (as is the case with libao2 drivers), the code to copy
those samples is just a reimplementation of snd_pcm_writei(), so we
could as well use that function.
Besides, the current mmap code does not work except in the most simple
cases: it claims to support non-interleaved and complex sample formats,
but treats them the same as interleaved formats and writes to the wrong
memory location.
Index: MPlayer/libao2/ao_alsa.c
===================================================================
--- MPlayer.orig/libao2/ao_alsa.c 2006-01-27 20:21:48.000000000 +0100
+++ MPlayer/libao2/ao_alsa.c 2006-01-28 18:30:34.000000000 +0100
@@ -17,7 +17,6 @@
#include <stdlib.h>
#include <math.h>
#include <string.h>
-#include <sys/poll.h>
#include "config.h"
#include "subopt-helper.h"
@@ -71,7 +70,6 @@ static size_t chunk_bytes;
int ao_mmap = 0;
int ao_noblock = 0;
-int first = 1;
static int open_mode;
static int set_block_mode;
@@ -81,7 +79,6 @@ static int alsa_can_pause = 0;
#undef BUFFERTIME
#define SET_CHUNKSIZE
-#undef USE_POLL
/* to set/get/query special features/parameters */
static int control(int cmd, void *arg)
@@ -241,11 +238,9 @@ static void print_help ()
{
mp_msg (MSGT_AO, MSGL_FATAL,
"\n-ao alsa commandline help:\n"
- "Example: mplayer -ao alsa:mmap:device=hw=0.3\n"
- " sets mmap-mode and first card fourth device\n"
+ "Example: mplayer -ao alsa:device=hw=0.3\n"
+ " sets first card fourth hardware device\n"
"\nOptions:\n"
- " mmap\n"
- " Set memory-mapped mode, experimental\n"
" noblock\n"
" Sets non-blocking mode\n"
" device=<device-name>\n"
@@ -401,6 +396,8 @@ static int init(int rate_hz, int channel
print_help();
return 0;
}
+ if (ao_mmap)
+ mp_msg(MSGT_AO,MSGL_WARN,"alsa-init: mmap option is obsolete and has no effect");
ao_noblock = !block;
parse_device(alsa_device, device.str, device.len);
@@ -448,10 +445,7 @@ static int init(int rate_hz, int channel
break;
default:
alsa_fragcount = 16;
- if (ao_mmap)
- chunk_size = 512;
- else
- chunk_size = 1024;
+ chunk_size = 1024;
break;
}
}
@@ -492,18 +486,8 @@ static int init(int rate_hz, int channel
return(0);
}
- if (ao_mmap) {
- snd_pcm_access_mask_t *mask = alloca(snd_pcm_access_mask_sizeof());
- snd_pcm_access_mask_none(mask);
- snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_INTERLEAVED);
- snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_NONINTERLEAVED);
- snd_pcm_access_mask_set(mask, SND_PCM_ACCESS_MMAP_COMPLEX);
- err = snd_pcm_hw_params_set_access_mask(alsa_handler, alsa_hwparams, mask);
- mp_msg(MSGT_AO,MSGL_INFO,"alsa-init: mmap set\n");
- } else {
- err = snd_pcm_hw_params_set_access(alsa_handler, alsa_hwparams,
- SND_PCM_ACCESS_RW_INTERLEAVED);
- }
+ err = snd_pcm_hw_params_set_access(alsa_handler, alsa_hwparams,
+ SND_PCM_ACCESS_RW_INTERLEAVED);
if (err < 0) {
mp_msg(MSGT_AO,MSGL_ERR,"alsa-init: unable to set access type: %s\n",
snd_strerror(err));
@@ -783,22 +767,6 @@ static void reset()
return;
}
-#ifdef USE_POLL
-static int wait_for_poll(snd_pcm_t *handle, struct pollfd *ufds, unsigned int count)
-{
- unsigned short revents;
-
- while (1) {
- poll(ufds, count, -1);
- snd_pcm_poll_descriptors_revents(handle, ufds, count, &revents);
- if (revents & POLLERR)
- return -EIO;
- if (revents & POLLOUT)
- return 0;
- }
-}
-#endif
-
#ifndef timersub
#define timersub(a, b, result) \
do { \
@@ -842,20 +810,6 @@ static int xrun(u_char *str_mode)
return(1); /* ok, data should be accepted again */
}
-static int play_normal(void* data, int len);
-static int play_mmap(void* data, int len);
-
-static int play(void* data, int len, int flags)
-{
- int result;
- if (ao_mmap)
- result = play_mmap(data, len);
- else
- result = play_normal(data, len);
-
- return result;
-}
-
/*
plays 'len' bytes of 'data'
returns: number of bytes played
@@ -863,7 +817,7 @@ static int play(void* data, int len, int
thanxs for marius <marius at rospot.com> for giving us the light ;)
*/
-static int play_normal(void* data, int len)
+static int play(void* data, int len, int flags)
{
//bytes_per_sample is always 4 for 2 chn S16_LE
@@ -922,113 +876,6 @@ static int play_normal(void* data, int l
return len - len % bytes_per_sample;
}
-/* mmap-mode mainly based on descriptions by Joshua Haberman <joshua at haberman.com>
- * 'An overview of the ALSA API' http://people.debian.org/~joshua/x66.html
- * and some help by Paul Davis <pbd at op.net> */
-
-static int play_mmap(void* data, int len)
-{
- snd_pcm_sframes_t commitres, frames_available;
- snd_pcm_uframes_t frames_transmit, size, offset;
- const snd_pcm_channel_area_t *area;
- void *outbuffer;
- int result;
-
-#ifdef USE_POLL //seems not really be needed
- struct pollfd *ufds;
- int count;
-
- count = snd_pcm_poll_descriptors_count (alsa_handler);
- ufds = malloc(sizeof(struct pollfd) * count);
- snd_pcm_poll_descriptors(alsa_handler, ufds, count);
-
- //first wait_for_poll
- if (err = (wait_for_poll(alsa_handler, ufds, count) < 0)) {
- if (snd_pcm_state(alsa_handler) == SND_PCM_STATE_XRUN ||
- snd_pcm_state(alsa_handler) == SND_PCM_STATE_SUSPENDED) {
- xrun("play");
- }
- }
-#endif
-
- outbuffer = alloca(ao_data.buffersize);
-
- //don't trust get_space() ;)
- frames_available = snd_pcm_avail_update(alsa_handler) * bytes_per_sample;
- if (frames_available < 0)
- xrun("play");
-
- if (frames_available < 4) {
- if (first) {
- first = 0;
- snd_pcm_start(alsa_handler);
- }
- else { //FIXME should break and return 0?
- snd_pcm_wait(alsa_handler, -1);
- first = 1;
- }
- }
-
- /* len is simply the available bufferspace got by get_space()
- * but real avail_buffer in frames is ab/bytes_per_sample */
- size = len / bytes_per_sample;
-
- //mp_msg(MSGT_AO,MSGL_V,"len: %i size %i, f_avail %i, bps %i ...\n", len, size, frames_available, bytes_per_sample);
-
- frames_transmit = size;
-
- /* prepare areas and set sw-pointers
- * frames_transmit returns the real available buffer-size
- * sometimes != frames_available cause of ringbuffer 'emulation' */
- snd_pcm_mmap_begin(alsa_handler, &area, &offset, &frames_transmit);
-
- /* this is specific to interleaved streams (or non-interleaved
- * streams with only one channel) */
- outbuffer = ((char *) area->addr + (area->first + area->step * offset) / 8); //8
-
- //write data
- memcpy(outbuffer, data, (frames_transmit * bytes_per_sample));
-
- commitres = snd_pcm_mmap_commit(alsa_handler, offset, frames_transmit);
-
- if (commitres < 0 || commitres != frames_transmit) {
- if (snd_pcm_state(alsa_handler) == SND_PCM_STATE_XRUN ||
- snd_pcm_state(alsa_handler) == SND_PCM_STATE_SUSPENDED) {
- xrun("play");
- }
- }
-
- //mp_msg(MSGT_AO,MSGL_V,"mmap ft: %i, cres: %i\n", frames_transmit, commitres);
-
- /* err = snd_pcm_area_copy(&area, offset, &data, offset, len, alsa_format); */
- /* if (err < 0) { */
- /* mp_msg(MSGT_AO,MSGL_ERR,"area-copy-error\n"); */
- /* return 0; */
- /* } */
-
-
- //calculate written frames!
- result = commitres * bytes_per_sample;
-
-
- /* if (verbose) { */
- /* if (len == result) */
- /* mp_msg(MSGT_AO,MSGL_V,"result: %i, frames written: %i ...\n", result, frames_transmit); */
- /* else */
- /* mp_msg(MSGT_AO,MSGL_V,"result: %i, frames written: %i, result != len ...\n", result, frames_transmit); */
- /* } */
-
- //mplayer doesn't like -result
- if (result < 0)
- result = 0;
-
-#ifdef USE_POLL
- free(ufds);
-#endif
-
- return result;
-}
-
/* how many byes are free in the buffer */
static int get_space()
{
@@ -1054,10 +901,7 @@ static int get_space()
break;
case SND_PCM_STATE_PREPARED:
str_status = "prepared";
- first = 1;
ret = snd_pcm_status_get_avail(status) * bytes_per_sample;
- if (ret == 0) //ugly workaround for hang in mmap-mode
- ret = 10;
break;
case SND_PCM_STATE_RUNNING:
ret = snd_pcm_status_get_avail(status) * bytes_per_sample;
@@ -1073,7 +917,6 @@ static int get_space()
case SND_PCM_STATE_XRUN:
xrun("space");
str_status = "xrun";
- first = 1;
ret = 0;
break;
default:
More information about the MPlayer-dev-eng
mailing list