00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00027 #include "libavutil/mathematics.h"
00028 #include "avformat.h"
00029 #include "url.h"
00030
00031 #include <librtmp/rtmp.h>
00032 #include <librtmp/log.h>
00033
00034 static void rtmp_log(int level, const char *fmt, va_list args)
00035 {
00036 switch (level) {
00037 default:
00038 case RTMP_LOGCRIT: level = AV_LOG_FATAL; break;
00039 case RTMP_LOGERROR: level = AV_LOG_ERROR; break;
00040 case RTMP_LOGWARNING: level = AV_LOG_WARNING; break;
00041 case RTMP_LOGINFO: level = AV_LOG_INFO; break;
00042 case RTMP_LOGDEBUG: level = AV_LOG_VERBOSE; break;
00043 case RTMP_LOGDEBUG2: level = AV_LOG_DEBUG; break;
00044 }
00045
00046 av_vlog(NULL, level, fmt, args);
00047 av_log(NULL, level, "\n");
00048 }
00049
00050 static int rtmp_close(URLContext *s)
00051 {
00052 RTMP *r = s->priv_data;
00053
00054 RTMP_Close(r);
00055 return 0;
00056 }
00057
00070 static int rtmp_open(URLContext *s, const char *uri, int flags)
00071 {
00072 RTMP *r = s->priv_data;
00073 int rc;
00074
00075 switch (av_log_get_level()) {
00076 default:
00077 case AV_LOG_FATAL: rc = RTMP_LOGCRIT; break;
00078 case AV_LOG_ERROR: rc = RTMP_LOGERROR; break;
00079 case AV_LOG_WARNING: rc = RTMP_LOGWARNING; break;
00080 case AV_LOG_INFO: rc = RTMP_LOGINFO; break;
00081 case AV_LOG_VERBOSE: rc = RTMP_LOGDEBUG; break;
00082 case AV_LOG_DEBUG: rc = RTMP_LOGDEBUG2; break;
00083 }
00084 RTMP_LogSetLevel(rc);
00085 RTMP_LogSetCallback(rtmp_log);
00086
00087 RTMP_Init(r);
00088 if (!RTMP_SetupURL(r, s->filename)) {
00089 rc = -1;
00090 goto fail;
00091 }
00092
00093 if (flags & AVIO_FLAG_WRITE)
00094 RTMP_EnableWrite(r);
00095
00096 if (!RTMP_Connect(r, NULL) || !RTMP_ConnectStream(r, 0)) {
00097 rc = -1;
00098 goto fail;
00099 }
00100
00101 s->is_streamed = 1;
00102 return 0;
00103 fail:
00104 return rc;
00105 }
00106
00107 static int rtmp_write(URLContext *s, const uint8_t *buf, int size)
00108 {
00109 RTMP *r = s->priv_data;
00110
00111 return RTMP_Write(r, buf, size);
00112 }
00113
00114 static int rtmp_read(URLContext *s, uint8_t *buf, int size)
00115 {
00116 RTMP *r = s->priv_data;
00117
00118 return RTMP_Read(r, buf, size);
00119 }
00120
00121 static int rtmp_read_pause(URLContext *s, int pause)
00122 {
00123 RTMP *r = s->priv_data;
00124
00125 if (!RTMP_Pause(r, pause))
00126 return -1;
00127 return 0;
00128 }
00129
00130 static int64_t rtmp_read_seek(URLContext *s, int stream_index,
00131 int64_t timestamp, int flags)
00132 {
00133 RTMP *r = s->priv_data;
00134
00135 if (flags & AVSEEK_FLAG_BYTE)
00136 return AVERROR(ENOSYS);
00137
00138
00139 if (stream_index < 0)
00140 timestamp = av_rescale_rnd(timestamp, 1000, AV_TIME_BASE,
00141 flags & AVSEEK_FLAG_BACKWARD ? AV_ROUND_DOWN : AV_ROUND_UP);
00142
00143 if (!RTMP_SendSeek(r, timestamp))
00144 return -1;
00145 return timestamp;
00146 }
00147
00148 static int rtmp_get_file_handle(URLContext *s)
00149 {
00150 RTMP *r = s->priv_data;
00151
00152 return RTMP_Socket(r);
00153 }
00154
00155 URLProtocol ff_rtmp_protocol = {
00156 .name = "rtmp",
00157 .url_open = rtmp_open,
00158 .url_read = rtmp_read,
00159 .url_write = rtmp_write,
00160 .url_close = rtmp_close,
00161 .url_read_pause = rtmp_read_pause,
00162 .url_read_seek = rtmp_read_seek,
00163 .url_get_file_handle = rtmp_get_file_handle,
00164 .priv_data_size = sizeof(RTMP),
00165 };
00166
00167 URLProtocol ff_rtmpt_protocol = {
00168 .name = "rtmpt",
00169 .url_open = rtmp_open,
00170 .url_read = rtmp_read,
00171 .url_write = rtmp_write,
00172 .url_close = rtmp_close,
00173 .url_read_pause = rtmp_read_pause,
00174 .url_read_seek = rtmp_read_seek,
00175 .url_get_file_handle = rtmp_get_file_handle,
00176 .priv_data_size = sizeof(RTMP),
00177 };
00178
00179 URLProtocol ff_rtmpe_protocol = {
00180 .name = "rtmpe",
00181 .url_open = rtmp_open,
00182 .url_read = rtmp_read,
00183 .url_write = rtmp_write,
00184 .url_close = rtmp_close,
00185 .url_read_pause = rtmp_read_pause,
00186 .url_read_seek = rtmp_read_seek,
00187 .url_get_file_handle = rtmp_get_file_handle,
00188 .priv_data_size = sizeof(RTMP),
00189 };
00190
00191 URLProtocol ff_rtmpte_protocol = {
00192 .name = "rtmpte",
00193 .url_open = rtmp_open,
00194 .url_read = rtmp_read,
00195 .url_write = rtmp_write,
00196 .url_close = rtmp_close,
00197 .url_read_pause = rtmp_read_pause,
00198 .url_read_seek = rtmp_read_seek,
00199 .url_get_file_handle = rtmp_get_file_handle,
00200 .priv_data_size = sizeof(RTMP),
00201 };
00202
00203 URLProtocol ff_rtmps_protocol = {
00204 .name = "rtmps",
00205 .url_open = rtmp_open,
00206 .url_read = rtmp_read,
00207 .url_write = rtmp_write,
00208 .url_close = rtmp_close,
00209 .url_read_pause = rtmp_read_pause,
00210 .url_read_seek = rtmp_read_seek,
00211 .url_get_file_handle = rtmp_get_file_handle,
00212 .priv_data_size = sizeof(RTMP),
00213 };