[xiph-commits] r8829 - icecast/branches/ices0/pipe/src

brendan at motherfish-iii.xiph.org brendan at motherfish-iii.xiph.org
Thu Feb 3 22:59:06 PST 2005


Author: brendan
Date: 2005-02-03 22:59:04 -0800 (Thu, 03 Feb 2005)
New Revision: 8829

Added:
   icecast/branches/ices0/pipe/src/encode_pipe.c
Log:
pipe encoder, WIP


Added: icecast/branches/ices0/pipe/src/encode_pipe.c
===================================================================
--- icecast/branches/ices0/pipe/src/encode_pipe.c	2005-02-04 06:57:21 UTC (rev 8828)
+++ icecast/branches/ices0/pipe/src/encode_pipe.c	2005-02-04 06:59:04 UTC (rev 8829)
@@ -0,0 +1,190 @@
+/* encode_pipe.c
+* Encode PCM to output format via pipe
+* Copyright (c) 2005 Brendan Cully
+*
+* This program is free software; you can redistribute it and/or
+* modify it under the terms of the GNU General Public License
+* as published by the Free Software Foundation; either version 2
+* of the License, or (at your option) any later version.
+* 
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+* GNU General Public License for more details.
+* 
+* You should have received a copy of the GNU General Public License
+* along with this program; if not, write to the Free Software
+* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
+*
+*/
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "definitions.h"
+
+#include <sys/select.h>
+#include <unistd.h>
+
+extern ices_config_t ices_config;
+
+static int pipe_init(ices_stream_t* stream);
+static int pipe_new_source(ices_stream_t* stream, input_stream_t* source);
+static int pipe_encode(ices_stream_t* stream, int samples, int16_t* left,
+                       int16_t* right, unsigned char* out, size_t olen);
+
+static void pipe_shutdown(void);
+
+static ices_encoder_t PipeEncoder = {
+  pipe_init,
+  pipe_new_source,
+  pipe_encode,
+  pipe_shutdown
+};
+
+typedef struct {
+  int rfd;
+  int wfd;
+  int16_t* buf;
+  size_t blen;
+} encoder_state_t;
+
+ices_encoder_t *pipe_encoder(void) {
+  return &PipeEncoder;
+};
+
+static int pipe_init(ices_stream_t* stream) {
+  encoder_state_t* encoder;
+
+  encoder = (encoder_state_t*)calloc(1, sizeof(encoder_state_t));
+  if (!encoder) {
+    ices_log_error("Could not allocate encoder state");
+    return 0;
+  }
+  stream->enc2_state = encoder;
+
+  /* TODO: extract sample rate, bit rate, channels, other opts here */
+  ices_log_debug("Encoder pipe initialised: %d kbps", stream->bitrate);
+  
+  return 1;
+}
+
+static int pipe_new_source(ices_stream_t* stream, input_stream_t* source) {
+  encoder_state_t* encoder;
+  int pin[2], pout[2];
+  int pid;
+
+  encoder = (encoder_state_t*)stream->enc2_state;
+    
+  if (encoder->rfd) {
+    close(encoder->rfd);
+    close(encoder->wfd);
+    encoder->rfd = 0;
+    encoder->wfd = 0;
+  }
+  if (encoder->blen) {
+    free (encoder->buf);
+    encoder->blen = 0;
+  }
+
+  if (pipe (pin) == -1) {
+    ices_log_error("Error opening encoder read pipe");
+    return 0;
+  }
+  if (pipe (pout) == -1) {
+    ices_log_error("Error opening encoder write pipe");
+    return 0;
+  }
+  
+  if ((pid = fork()) == 0) {
+    if (dup2 (pout[0], STDIN_FILENO) < 0 || dup2(pin[1], STDOUT_FILENO) < 0)
+      _exit(127);
+    close(pin[0]);
+    close(pin[1]);
+    close(pout[0]);
+    close(pout[1]);
+    close(STDERR_FILENO);
+    
+    setsid();
+    
+    execl("/bin/sh", "sh", "-c", "lame -b64 - -", NULL);
+    _exit(127);
+  }
+  
+  if (pid < 0) {
+    close(pin[0]);
+    close(pin[1]);
+    close(pout[0]);
+    close(pout[1]);
+    ices_log_error("Error forking encoder");
+    return 0;
+  }
+  
+  close(pin[1]);
+  close(pout[0]);
+  
+  encoder->rfd = pin[0];
+  encoder->wfd = pout[1];
+
+  fcntl(encoder->rfd, F_SETFD, FD_CLOEXEC);
+  fcntl(encoder->wfd, F_SETFD, FD_CLOEXEC);
+
+  ices_log_debug("Encoder pipe opened");
+
+  return 1;
+}
+
+static int pipe_encode(ices_stream_t* stream, int samples, int16_t* left,
+                       int16_t* right, unsigned char* out, size_t olen)
+{
+  encoder_state_t* encoder;
+  int rc;
+  int i = 0;
+  ssize_t bytesread = 0;
+  fd_set rfds;
+  fd_set wfds;
+
+  encoder = (encoder_state_t*)stream->enc2_state;
+
+  if (encoder->blen < samples * 4) {
+    if (encoder->blen)
+      free (encoder->buf);
+    encoder->blen = samples * 4;
+    encoder->buf = malloc(encoder->blen);
+  }
+  for (i = 0; i < samples; i++) {
+    encoder->buf[i*2] = left[i];
+    encoder->buf[i*2+1] = right[i];
+  }
+
+  i = 0;
+  FD_ZERO(&rfds);
+  FD_ZERO(&wfds);
+  while (i < samples*4) {
+    FD_SET(encoder->rfd, &rfds);
+    FD_SET(encoder->wfd, &wfds);
+    select(FD_SETSIZE, &rfds, &wfds, NULL, NULL);
+    if (FD_ISSET(encoder->wfd, &wfds)) {
+      rc = write(encoder->wfd, ((char*)encoder->buf)+i, samples*4 - i);
+      if (rc > 0) {
+        i += rc;
+      }
+    }
+
+    if (FD_ISSET(encoder->rfd, &rfds)) {
+      rc = read(encoder->rfd, out + bytesread, olen - bytesread);
+      if (rc > 0) {
+        bytesread += rc;
+      }
+      if (bytesread == olen)
+        break;
+    }
+  }
+
+  return bytesread;
+}
+
+static void pipe_shutdown(void) {
+  ices_log_debug("Encoder pipe shutting down");
+}
\ No newline at end of file


Property changes on: icecast/branches/ices0/pipe/src/encode_pipe.c
___________________________________________________________________
Name: svn:keywords
   + Id
Name: svn:eol-style
   + native



More information about the commits mailing list