00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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,
00169 rtmp_close,
00170 NULL,
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,
00182 rtmp_close,
00183 NULL,
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,
00195 rtmp_close,
00196 NULL,
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,
00208 rtmp_close,
00209 NULL,
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,
00221 rtmp_close,
00222 NULL,
00223 rtmp_read_pause,
00224 rtmp_read_seek,
00225 rtmp_get_file_handle
00226 };