Libav
|
00001 /* 00002 * RTMP network protocol 00003 * Copyright (c) 2010 Howard Chu 00004 * 00005 * This file is part of FFmpeg. 00006 * 00007 * FFmpeg is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU Lesser General Public 00009 * License as published by the Free Software Foundation; either 00010 * version 2.1 of the License, or (at your option) any later version. 00011 * 00012 * FFmpeg is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00015 * Lesser General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU Lesser General Public 00018 * License along with FFmpeg; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00020 */ 00021 00027 #include "avformat.h" 00028 00029 #include <librtmp/rtmp.h> 00030 #include <librtmp/log.h> 00031 00032 static void rtmp_log(int level, const char *fmt, va_list args) 00033 { 00034 switch (level) { 00035 default: 00036 case RTMP_LOGCRIT: level = AV_LOG_FATAL; break; 00037 case RTMP_LOGERROR: level = AV_LOG_ERROR; break; 00038 case RTMP_LOGWARNING: level = AV_LOG_WARNING; break; 00039 case RTMP_LOGINFO: level = AV_LOG_INFO; break; 00040 case RTMP_LOGDEBUG: level = AV_LOG_VERBOSE; break; 00041 case RTMP_LOGDEBUG2: level = AV_LOG_DEBUG; break; 00042 } 00043 00044 av_vlog(NULL, level, fmt, args); 00045 av_log(NULL, level, "\n"); 00046 } 00047 00048 static int rtmp_close(URLContext *s) 00049 { 00050 RTMP *r = s->priv_data; 00051 00052 RTMP_Close(r); 00053 av_free(r); 00054 return 0; 00055 } 00056 00069 static int rtmp_open(URLContext *s, const char *uri, int flags) 00070 { 00071 RTMP *r; 00072 int rc; 00073 00074 r = av_mallocz(sizeof(RTMP)); 00075 if (!r) 00076 return AVERROR(ENOMEM); 00077 00078 switch (av_log_get_level()) { 00079 default: 00080 case AV_LOG_FATAL: rc = RTMP_LOGCRIT; break; 00081 case AV_LOG_ERROR: rc = RTMP_LOGERROR; break; 00082 case AV_LOG_WARNING: rc = RTMP_LOGWARNING; break; 00083 case AV_LOG_INFO: rc = RTMP_LOGINFO; break; 00084 case AV_LOG_VERBOSE: rc = RTMP_LOGDEBUG; break; 00085 case AV_LOG_DEBUG: rc = RTMP_LOGDEBUG2; break; 00086 } 00087 RTMP_LogSetLevel(rc); 00088 RTMP_LogSetCallback(rtmp_log); 00089 00090 RTMP_Init(r); 00091 if (!RTMP_SetupURL(r, s->filename)) { 00092 rc = -1; 00093 goto fail; 00094 } 00095 00096 if (flags & URL_WRONLY) 00097 r->Link.protocol |= RTMP_FEATURE_WRITE; 00098 00099 if (!RTMP_Connect(r, NULL) || !RTMP_ConnectStream(r, 0)) { 00100 rc = -1; 00101 goto fail; 00102 } 00103 00104 s->priv_data = r; 00105 s->is_streamed = 1; 00106 return 0; 00107 fail: 00108 av_free(r); 00109 return rc; 00110 } 00111 00112 static int rtmp_write(URLContext *s, uint8_t *buf, int size) 00113 { 00114 RTMP *r = s->priv_data; 00115 00116 return RTMP_Write(r, buf, size); 00117 } 00118 00119 static int rtmp_read(URLContext *s, uint8_t *buf, int size) 00120 { 00121 RTMP *r = s->priv_data; 00122 00123 return RTMP_Read(r, buf, size); 00124 } 00125 00126 static int rtmp_read_pause(URLContext *s, int pause) 00127 { 00128 RTMP *r = s->priv_data; 00129 00130 if (pause) 00131 r->m_pauseStamp = 00132 r->m_channelTimestamp[r->m_mediaChannel]; 00133 if (!RTMP_SendPause(r, pause, r->m_pauseStamp)) 00134 return -1; 00135 return 0; 00136 } 00137 00138 static int64_t rtmp_read_seek(URLContext *s, int stream_index, 00139 int64_t timestamp, int flags) 00140 { 00141 RTMP *r = s->priv_data; 00142 00143 if (flags & AVSEEK_FLAG_BYTE) 00144 return AVERROR(ENOSYS); 00145 00146 /* seeks are in milliseconds */ 00147 if (stream_index < 0) 00148 timestamp = av_rescale_rnd(timestamp, 1000, AV_TIME_BASE, 00149 flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP); 00150 00151 if (!RTMP_SendSeek(r, timestamp)) 00152 return -1; 00153 return timestamp; 00154 } 00155 00156 static int rtmp_get_file_handle(URLContext *s) 00157 { 00158 RTMP *r = s->priv_data; 00159 00160 return r->m_sb.sb_socket; 00161 } 00162 00163 URLProtocol rtmp_protocol = { 00164 "rtmp", 00165 rtmp_open, 00166 rtmp_read, 00167 rtmp_write, 00168 NULL, /* seek */ 00169 rtmp_close, 00170 NULL, /* next */ 00171 rtmp_read_pause, 00172 rtmp_read_seek, 00173 rtmp_get_file_handle 00174 }; 00175 00176 URLProtocol rtmpt_protocol = { 00177 "rtmpt", 00178 rtmp_open, 00179 rtmp_read, 00180 rtmp_write, 00181 NULL, /* seek */ 00182 rtmp_close, 00183 NULL, /* next */ 00184 rtmp_read_pause, 00185 rtmp_read_seek, 00186 rtmp_get_file_handle 00187 }; 00188 00189 URLProtocol rtmpe_protocol = { 00190 "rtmpe", 00191 rtmp_open, 00192 rtmp_read, 00193 rtmp_write, 00194 NULL, /* seek */ 00195 rtmp_close, 00196 NULL, /* next */ 00197 rtmp_read_pause, 00198 rtmp_read_seek, 00199 rtmp_get_file_handle 00200 }; 00201 00202 URLProtocol rtmpte_protocol = { 00203 "rtmpte", 00204 rtmp_open, 00205 rtmp_read, 00206 rtmp_write, 00207 NULL, /* seek */ 00208 rtmp_close, 00209 NULL, /* next */ 00210 rtmp_read_pause, 00211 rtmp_read_seek, 00212 rtmp_get_file_handle 00213 }; 00214 00215 URLProtocol rtmps_protocol = { 00216 "rtmps", 00217 rtmp_open, 00218 rtmp_read, 00219 rtmp_write, 00220 NULL, /* seek */ 00221 rtmp_close, 00222 NULL, /* next */ 00223 rtmp_read_pause, 00224 rtmp_read_seek, 00225 rtmp_get_file_handle 00226 };