1/* 2 * Copyright (C) 2010 Julien BLACHE <jb@jblache.org> 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation; either version 2 of the License, or 7 * (at your option) any later version. 8 * 9 * This program is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License 15 * along with this program; if not, write to the Free Software 16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 17 */ 18 19#ifdef HAVE_CONFIG_H 20# include <config.h> 21#endif 22 23#include <stdlib.h> 24 25#include <libavformat/avformat.h> 26//#include <libavformat/url.h> 27 28#include <event.h> 29 30#include "logger.h" 31#include "ffmpeg_url_evbuffer.h" 32 33/* 34 * FFmpeg URL Protocol handler for evbuffers 35 * 36 * URL: evbuffer:0x03FB33DA ("evbuffer:%p") 37 */ 38 39 40static int 41url_evbuffer_open(URLContext *h, const char *filename, int flags) 42{ 43 const char *p; 44 char *end; 45 unsigned long evbuffer_addr; 46#if 0 47 if (flags != URL_WRONLY) 48 { 49 DPRINTF(E_LOG, L_FFMPEG, "Flags other than URL_WRONLY not supported while opening '%s'\n", filename); 50 51 return AVERROR(EIO); 52 } 53#endif 54 p = strchr(filename, ':'); 55 if (!p) 56 { 57 DPRINTF(E_LOG, L_FFMPEG, "Malformed evbuffer URL: '%s'\n", filename); 58 59 return AVERROR(EIO); 60 } 61 62 p++; 63 64 errno = 0; 65 evbuffer_addr = strtoul(p, &end, 16); 66 if (((errno == ERANGE) && (evbuffer_addr == ULONG_MAX)) 67 || ((errno != 0) && (evbuffer_addr == 0))) 68 { 69 DPRINTF(E_LOG, L_FFMPEG, "Invalid buffer address in URL: '%s'\n", filename); 70 71 return AVERROR(EIO); 72 } 73 74 if (end == p) 75 { 76 DPRINTF(E_LOG, L_FFMPEG, "No buffer address found in URL: '%s'\n", filename); 77 78 return AVERROR(EIO); 79 } 80 81 h->priv_data = (void *)evbuffer_addr; 82 if (!h->priv_data) 83 { 84 DPRINTF(E_LOG, L_FFMPEG, "Got a NULL buffer address from URL '%s'\n", filename); 85 86 return AVERROR(EIO); 87 } 88 89 /* Seek not supported */ 90 h->is_streamed = 1; 91 92 return 0; 93} 94 95static int 96url_evbuffer_close(URLContext *h) 97{ 98 h->priv_data = NULL; 99 100 return 0; 101} 102 103static int 104url_evbuffer_write(URLContext *h, unsigned char *buf, int size) 105{ 106 struct evbuffer *evbuf; 107 int ret; 108 109 evbuf = (struct evbuffer *)h->priv_data; 110 111 if (!evbuf) 112 { 113 DPRINTF(E_LOG, L_FFMPEG, "Write called on evbuffer URL with priv_data = NULL!\n"); 114 115 return -1; 116 } 117 118 ret = evbuffer_add(evbuf, buf, size); 119 120 return (ret == 0) ? size : -1; 121} 122 123URLProtocol evbuffer_protocol = { 124 .name = "evbuffer", 125 .url_open = url_evbuffer_open, 126 .url_close = url_evbuffer_close, 127 .url_write = url_evbuffer_write, 128}; 129 130int 131register_ffmpeg_evbuffer_url_protocol(void) 132{ 133 int ret; 134 135// ret = av_register_protocol(&evbuffer_protocol); 136// ret=ffurl_register_protocol(&evbuffer_protocol, sizeof(struct URLProtocol)); 137 138 return ret; 139} 140