/* * 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); return ret; } 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); }