diff --git a/src/Makefile.am b/src/Makefile.am index 1e2e8462..76035efa 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -113,7 +113,6 @@ owntone_SOURCES = main.c \ library.c library.h \ $(MDNS_SRC) mdns.h \ remote_pairing.c remote_pairing.h \ - avio_evbuffer.c avio_evbuffer.h \ httpd.c httpd.h \ httpd_rsp.c httpd_rsp.h \ httpd_daap.c httpd_daap.h \ diff --git a/src/avio_evbuffer.c b/src/avio_evbuffer.c deleted file mode 100644 index 67ce21f2..00000000 --- a/src/avio_evbuffer.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright (C) 2011 Julien BLACHE - * - * 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 -#endif - -#include - -#include - -#include "logger.h" -#include "avio_evbuffer.h" - -/* - * libav AVIO interface for evbuffers - */ - -#define BUFFER_SIZE 4096 - -struct avio_evbuffer { - struct evbuffer *evbuf; - uint8_t *buffer; -}; - -static int -avio_evbuffer_read(void *opaque, uint8_t *buf, int size) -{ - struct avio_evbuffer *ae; - int ret; - - ae = (struct avio_evbuffer *)opaque; - - ret = evbuffer_remove(ae->evbuf, buf, size); - - // Must return AVERROR, see avio.h: avio_alloc_context() - return (ret > 0) ? ret : AVERROR_EOF; -} - -static int -avio_evbuffer_write(void *opaque, uint8_t *buf, int size) -{ - struct avio_evbuffer *ae; - int ret; - - ae = (struct avio_evbuffer *)opaque; - - ret = evbuffer_add(ae->evbuf, buf, size); - - return (ret == 0) ? size : -1; -} - -static AVIOContext * -avio_evbuffer_open(struct evbuffer *evbuf, int is_output) -{ - struct avio_evbuffer *ae; - AVIOContext *s; - - ae = (struct avio_evbuffer *)malloc(sizeof(struct avio_evbuffer)); - if (!ae) - { - DPRINTF(E_LOG, L_FFMPEG, "Out of memory for avio_evbuffer\n"); - - return NULL; - } - - ae->buffer = av_mallocz(BUFFER_SIZE); - if (!ae->buffer) - { - DPRINTF(E_LOG, L_FFMPEG, "Out of memory for avio buffer\n"); - - free(ae); - return NULL; - } - - ae->evbuf = evbuf; - - if (is_output) - s = avio_alloc_context(ae->buffer, BUFFER_SIZE, 1, ae, NULL, avio_evbuffer_write, NULL); - else - s = avio_alloc_context(ae->buffer, BUFFER_SIZE, 0, ae, avio_evbuffer_read, NULL, NULL); - - if (!s) - { - DPRINTF(E_LOG, L_FFMPEG, "Could not allocate AVIOContext\n"); - - av_free(ae->buffer); - free(ae); - return NULL; - } - - s->seekable = 0; - - return s; -} - -AVIOContext * -avio_input_evbuffer_open(struct evbuffer *evbuf) -{ - return avio_evbuffer_open(evbuf, 0); -} - -AVIOContext * -avio_output_evbuffer_open(struct evbuffer *evbuf) -{ - return avio_evbuffer_open(evbuf, 1); -} - -void -avio_evbuffer_close(AVIOContext *s) -{ - struct avio_evbuffer *ae; - - if (!s) - return; - - ae = (struct avio_evbuffer *)s->opaque; - - avio_flush(s); - - av_free(s->buffer); - free(ae); - - av_free(s); -} diff --git a/src/avio_evbuffer.h b/src/avio_evbuffer.h deleted file mode 100644 index 93dc1234..00000000 --- a/src/avio_evbuffer.h +++ /dev/null @@ -1,16 +0,0 @@ - -#ifndef __AVIO_EVBUFFER_H__ -#define __AVIO_EVBUFFER_H__ - -#include - -AVIOContext * -avio_input_evbuffer_open(struct evbuffer *evbuf); - -AVIOContext * -avio_output_evbuffer_open(struct evbuffer *evbuf); - -void -avio_evbuffer_close(AVIOContext *s); - -#endif /* !__AVIO_EVBUFFER_H__ */ diff --git a/src/transcode.c b/src/transcode.c index 425445b0..6b01508e 100644 --- a/src/transcode.c +++ b/src/transcode.c @@ -39,7 +39,6 @@ #include "logger.h" #include "conffile.h" #include "db.h" -#include "avio_evbuffer.h" #include "misc.h" #include "transcode.h" @@ -51,6 +50,8 @@ #define MAX_BAD_PACKETS 5 // How long to wait (in microsec) before interrupting av_read_frame #define READ_TIMEOUT 30000000 +// Buffer size for reading/writing input and output evbuffers +#define AVIO_BUFFER_SIZE 4096 static const char *default_codecs = "mpeg,wav"; static const char *roku_codecs = "mpeg,mp4a,wma,alac,wav"; @@ -184,6 +185,12 @@ enum probe_type PROBE_TYPE_QUICK, }; +struct avio_evbuffer { + struct evbuffer *evbuf; + uint8_t *buffer; +}; + + /* -------------------------- PROFILE CONFIGURATION ------------------------ */ static int @@ -776,6 +783,106 @@ read_decode_filter_encode_write(struct transcode_ctx *ctx) return ret; } +/* ------------------------------- CUSTOM I/O ------------------------------ */ +/* For using ffmpeg with evbuffer input/output instead of files */ + +static int +avio_evbuffer_read(void *opaque, uint8_t *buf, int size) +{ + struct avio_evbuffer *ae = (struct avio_evbuffer *)opaque; + int ret; + + ret = evbuffer_remove(ae->evbuf, buf, size); + + // Must return AVERROR, see avio.h: avio_alloc_context() + return (ret > 0) ? ret : AVERROR_EOF; +} + +static int +avio_evbuffer_write(void *opaque, uint8_t *buf, int size) +{ + struct avio_evbuffer *ae = (struct avio_evbuffer *)opaque; + int ret; + + ret = evbuffer_add(ae->evbuf, buf, size); + + return (ret == 0) ? size : -1; +} + +static AVIOContext * +avio_evbuffer_open(struct evbuffer *evbuf, int is_output) +{ + struct avio_evbuffer *ae; + AVIOContext *s; + + ae = calloc(1, sizeof(struct avio_evbuffer)); + if (!ae) + { + DPRINTF(E_LOG, L_FFMPEG, "Out of memory for avio_evbuffer\n"); + + return NULL; + } + + ae->buffer = av_mallocz(AVIO_BUFFER_SIZE); + if (!ae->buffer) + { + DPRINTF(E_LOG, L_FFMPEG, "Out of memory for avio buffer\n"); + + free(ae); + return NULL; + } + + ae->evbuf = evbuf; + + if (is_output) + s = avio_alloc_context(ae->buffer, AVIO_BUFFER_SIZE, 1, ae, NULL, avio_evbuffer_write, NULL); + else + s = avio_alloc_context(ae->buffer, AVIO_BUFFER_SIZE, 0, ae, avio_evbuffer_read, NULL, NULL); + + if (!s) + { + DPRINTF(E_LOG, L_FFMPEG, "Could not allocate AVIOContext\n"); + + av_free(ae->buffer); + free(ae); + return NULL; + } + + s->seekable = 0; + + return s; +} + +static AVIOContext * +avio_input_evbuffer_open(struct evbuffer *evbuf) +{ + return avio_evbuffer_open(evbuf, 0); +} + +static AVIOContext * +avio_output_evbuffer_open(struct evbuffer *evbuf) +{ + return avio_evbuffer_open(evbuf, 1); +} + +static void +avio_evbuffer_close(AVIOContext *s) +{ + struct avio_evbuffer *ae; + + if (!s) + return; + + ae = (struct avio_evbuffer *)s->opaque; + + avio_flush(s); + + av_free(s->buffer); + free(ae); + + av_free(s); +} + /* --------------------------- INPUT/OUTPUT INIT --------------------------- */