You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

388 lines
12KB

  1. /*
  2. * RTP Theora Protocol
  3. * Copyright (c) 2010 Josh Allmann
  4. *
  5. * This file is part of FFmpeg.
  6. *
  7. * FFmpeg is free software; you can redistribute it and/or
  8. * modify it under the terms of the GNU Lesser General Public
  9. * License as published by the Free Software Foundation; either
  10. * version 2.1 of the License, or (at your option) any later version.
  11. *
  12. * FFmpeg is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with FFmpeg; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  20. */
  21. /**
  22. * @file libavformat/rtpdec_theora.c
  23. * @brief Theora / RTP Code
  24. * @author Josh Allmann <joshua.allmann@gmail.com>
  25. */
  26. #include "libavutil/avstring.h"
  27. #include "libavutil/base64.h"
  28. #include "libavcodec/bytestream.h"
  29. #include <assert.h>
  30. #include "rtpdec.h"
  31. #include "rtpdec_theora.h"
  32. /**
  33. * RTP/Theora specific private data.
  34. */
  35. struct PayloadContext {
  36. unsigned ident; ///< 24-bit stream configuration identifier
  37. uint32_t timestamp;
  38. ByteIOContext* fragment; ///< buffer for split payloads
  39. };
  40. static PayloadContext *theora_new_context(void)
  41. {
  42. return av_mallocz(sizeof(PayloadContext));
  43. }
  44. static inline void free_fragment_if_needed(PayloadContext * data)
  45. {
  46. if (data->fragment) {
  47. uint8_t* p;
  48. url_close_dyn_buf(data->fragment, &p);
  49. av_free(p);
  50. data->fragment = NULL;
  51. }
  52. }
  53. static void theora_free_context(PayloadContext * data)
  54. {
  55. free_fragment_if_needed(data);
  56. av_free(data);
  57. }
  58. static int theora_handle_packet(AVFormatContext * ctx,
  59. PayloadContext * data,
  60. AVStream * st,
  61. AVPacket * pkt,
  62. uint32_t * timestamp,
  63. const uint8_t * buf, int len, int flags)
  64. {
  65. int ident, fragmented, tdt, num_pkts, pkt_len;
  66. if (len < 6) {
  67. av_log(ctx, AV_LOG_ERROR, "Invalid %d byte packet\n", len);
  68. return AVERROR_INVALIDDATA;
  69. }
  70. // read theora rtp headers
  71. ident = AV_RB24(buf);
  72. fragmented = buf[3] >> 6;
  73. tdt = (buf[3] >> 4) & 3;
  74. num_pkts = buf[3] & 7;
  75. pkt_len = AV_RB16(buf + 4);
  76. if (pkt_len > len - 6) {
  77. av_log(ctx, AV_LOG_ERROR,
  78. "Invalid packet length %d in %d byte packet\n", pkt_len,
  79. len);
  80. return AVERROR_INVALIDDATA;
  81. }
  82. if (ident != data->ident) {
  83. av_log(ctx, AV_LOG_ERROR,
  84. "Unimplemented Theora SDP configuration change detected\n");
  85. return AVERROR_PATCHWELCOME;
  86. }
  87. if (tdt) {
  88. av_log(ctx, AV_LOG_ERROR,
  89. "Unimplemented RTP Theora packet settings (%d,%d,%d)\n",
  90. fragmented, tdt, num_pkts);
  91. return AVERROR_PATCHWELCOME;
  92. }
  93. buf += 6; // move past header bits
  94. len -= 6;
  95. if (fragmented == 0) {
  96. // whole frame(s)
  97. int i, data_len, write_len;
  98. buf -= 2;
  99. len += 2;
  100. // fast first pass to calculate total length
  101. for (i = 0, data_len = 0; (i < num_pkts) && (len >= 2); i++) {
  102. int off = data_len + (i << 1);
  103. pkt_len = AV_RB16(buf + off);
  104. data_len += pkt_len;
  105. len -= pkt_len + 2;
  106. }
  107. if (len < 0 || i < num_pkts) {
  108. av_log(ctx, AV_LOG_ERROR,
  109. "Bad packet: %d bytes left at frame %d of %d\n",
  110. len, i, num_pkts);
  111. return AVERROR_INVALIDDATA;
  112. }
  113. if (av_new_packet(pkt, data_len)) {
  114. av_log(ctx, AV_LOG_ERROR, "Out of memory.\n");
  115. return AVERROR_NOMEM;
  116. }
  117. pkt->stream_index = st->index;
  118. // concatenate frames
  119. for (i = 0, write_len = 0; write_len < data_len; i++) {
  120. pkt_len = AV_RB16(buf);
  121. buf += 2;
  122. memcpy(pkt->data + write_len, buf, pkt_len);
  123. write_len += pkt_len;
  124. buf += pkt_len;
  125. }
  126. assert(write_len == data_len);
  127. return 0;
  128. } else if (fragmented == 1) {
  129. // start of theora data fragment
  130. int res;
  131. // end packet has been lost somewhere, so drop buffered data
  132. free_fragment_if_needed(data);
  133. if((res = url_open_dyn_buf(&data->fragment)) < 0)
  134. return res;
  135. put_buffer(data->fragment, buf, pkt_len);
  136. data->timestamp = *timestamp;
  137. } else {
  138. assert(fragmented < 4);
  139. if (data->timestamp != *timestamp) {
  140. // skip if fragmented timestamp is incorrect;
  141. // a start packet has been lost somewhere
  142. free_fragment_if_needed(data);
  143. av_log(ctx, AV_LOG_ERROR, "RTP timestamps don't match!\n");
  144. return AVERROR_INVALIDDATA;
  145. }
  146. // copy data to fragment buffer
  147. put_buffer(data->fragment, buf, pkt_len);
  148. if (fragmented == 3) {
  149. // end of theora data packet
  150. uint8_t* theora_data;
  151. int frame_size = url_close_dyn_buf(data->fragment, &theora_data);
  152. if (frame_size < 0) {
  153. av_log(ctx, AV_LOG_ERROR,
  154. "Error occurred when getting fragment buffer.");
  155. return frame_size;
  156. }
  157. if (av_new_packet(pkt, frame_size)) {
  158. av_log(ctx, AV_LOG_ERROR, "Out of memory.\n");
  159. return AVERROR_NOMEM;
  160. }
  161. memcpy(pkt->data, theora_data, frame_size);
  162. pkt->stream_index = st->index;
  163. av_free(theora_data);
  164. data->fragment = NULL;
  165. return 0;
  166. }
  167. }
  168. return AVERROR(EAGAIN);
  169. }
  170. /**
  171. * Length encoding described in RFC5215 section 3.1.1.
  172. */
  173. static int get_base128(const uint8_t ** buf, const uint8_t * buf_end)
  174. {
  175. int n = 0;
  176. for (; *buf < buf_end; ++*buf) {
  177. n <<= 7;
  178. n += **buf & 0x7f;
  179. if (!(**buf & 0x80)) {
  180. ++*buf;
  181. return n;
  182. }
  183. }
  184. return 0;
  185. }
  186. /**
  187. * Based off parse_packed_headers in Vorbis RTP
  188. */
  189. static unsigned int
  190. parse_packed_headers(const uint8_t * packed_headers,
  191. const uint8_t * packed_headers_end,
  192. AVCodecContext * codec, PayloadContext * theora_data)
  193. {
  194. unsigned num_packed, num_headers, length, length1, length2, extradata_alloc;
  195. uint8_t *ptr;
  196. if (packed_headers_end - packed_headers < 9) {
  197. av_log(codec, AV_LOG_ERROR,
  198. "Invalid %d byte packed header.",
  199. packed_headers_end - packed_headers);
  200. return AVERROR_INVALIDDATA;
  201. }
  202. num_packed = bytestream_get_be32(&packed_headers);
  203. theora_data->ident = bytestream_get_be24(&packed_headers);
  204. length = bytestream_get_be16(&packed_headers);
  205. num_headers = get_base128(&packed_headers, packed_headers_end);
  206. length1 = get_base128(&packed_headers, packed_headers_end);
  207. length2 = get_base128(&packed_headers, packed_headers_end);
  208. if (num_packed != 1 || num_headers > 3) {
  209. av_log(codec, AV_LOG_ERROR,
  210. "Unimplemented number of headers: %d packed headers, %d headers\n",
  211. num_packed, num_headers);
  212. return AVERROR_PATCHWELCOME;
  213. }
  214. if (packed_headers_end - packed_headers != length ||
  215. length1 > length || length2 > length - length1) {
  216. av_log(codec, AV_LOG_ERROR,
  217. "Bad packed header lengths (%d,%d,%d,%d)\n", length1,
  218. length2, packed_headers_end - packed_headers, length);
  219. return AVERROR_INVALIDDATA;
  220. }
  221. /* allocate extra space:
  222. * -- length/255 +2 for xiphlacing
  223. * -- one for the '2' marker
  224. * -- FF_INPUT_BUFFER_PADDING_SIZE required */
  225. extradata_alloc = length + length/255 + 3 + FF_INPUT_BUFFER_PADDING_SIZE;
  226. ptr = codec->extradata = av_malloc(extradata_alloc);
  227. if (!ptr) {
  228. av_log(codec, AV_LOG_ERROR, "Out of memory\n");
  229. return AVERROR_NOMEM;
  230. }
  231. *ptr++ = 2;
  232. ptr += av_xiphlacing(ptr, length1);
  233. ptr += av_xiphlacing(ptr, length2);
  234. memcpy(ptr, packed_headers, length);
  235. ptr += length;
  236. codec->extradata_size = ptr - codec->extradata;
  237. // clear out remaining parts of the buffer
  238. memset(ptr, 0, extradata_alloc - codec->extradata_size);
  239. return 0;
  240. }
  241. static int theora_parse_fmtp_pair(AVCodecContext * codec,
  242. PayloadContext *theora_data,
  243. char *attr, char *value)
  244. {
  245. int result = 0;
  246. if (!strcmp(attr, "sampling")) {
  247. return AVERROR_PATCHWELCOME;
  248. } else if (!strcmp(attr, "width")) {
  249. /* This is an integer between 1 and 1048561
  250. * and MUST be in multiples of 16. */
  251. codec->width = atoi(value);
  252. return 0;
  253. } else if (!strcmp(attr, "height")) {
  254. /* This is an integer between 1 and 1048561
  255. * and MUST be in multiples of 16. */
  256. codec->height = atoi(value);
  257. return 0;
  258. } else if (!strcmp(attr, "delivery-method")) {
  259. /* Possible values are: inline, in_band, out_band/specific_name. */
  260. return AVERROR_PATCHWELCOME;
  261. } else if (!strcmp(attr, "configuration-uri")) {
  262. /* NOTE: configuration-uri is supported only under 2 conditions:
  263. *--after the delivery-method tag
  264. * --with a delivery-method value of out_band */
  265. return AVERROR_PATCHWELCOME;
  266. } else if (!strcmp(attr, "configuration")) {
  267. /* NOTE: configuration is supported only AFTER the delivery-method tag
  268. * The configuration value is a base64 encoded packed header */
  269. uint8_t *decoded_packet = NULL;
  270. int packet_size;
  271. size_t decoded_alloc = strlen(value) / 4 * 3 + 4;
  272. if (decoded_alloc <= INT_MAX) {
  273. decoded_packet = av_malloc(decoded_alloc);
  274. if (decoded_packet) {
  275. packet_size =
  276. av_base64_decode(decoded_packet, value, decoded_alloc);
  277. result = parse_packed_headers
  278. (decoded_packet, decoded_packet + packet_size, codec,
  279. theora_data);
  280. } else {
  281. av_log(codec, AV_LOG_ERROR,
  282. "Out of memory while decoding SDP configuration.\n");
  283. result = AVERROR_NOMEM;
  284. }
  285. } else {
  286. av_log(codec, AV_LOG_ERROR, "Packet too large\n");
  287. result = AVERROR_INVALIDDATA;
  288. }
  289. av_free(decoded_packet);
  290. }
  291. return result;
  292. }
  293. static int theora_parse_sdp_line(AVFormatContext *s, int st_index,
  294. PayloadContext *data, const char *line)
  295. {
  296. const char *p;
  297. char *value;
  298. char attr[25];
  299. int value_size = strlen(line), attr_size = sizeof(attr), res = 0;
  300. AVCodecContext* codec = s->streams[st_index]->codec;
  301. assert(codec->id == CODEC_ID_THEORA);
  302. assert(data);
  303. if (!(value = av_malloc(value_size))) {
  304. av_log(codec, AV_LOG_ERROR, "Out of memory\n");
  305. return AVERROR_NOMEM;
  306. }
  307. if (av_strstart(line, "fmtp:", &p)) {
  308. // remove protocol identifier
  309. while (*p && *p == ' ') p++; // strip spaces
  310. while (*p && *p != ' ') p++; // eat protocol identifier
  311. while (*p && *p == ' ') p++; // strip trailing spaces
  312. while (ff_rtsp_next_attr_and_value(&p,
  313. attr, attr_size,
  314. value, value_size)) {
  315. res = theora_parse_fmtp_pair(codec, data, attr, value);
  316. if (res < 0 && res != AVERROR_PATCHWELCOME)
  317. return res;
  318. }
  319. }
  320. av_free(value);
  321. return 0;
  322. }
  323. RTPDynamicProtocolHandler ff_theora_dynamic_handler = {
  324. .enc_name = "theora",
  325. .codec_type = CODEC_TYPE_VIDEO,
  326. .codec_id = CODEC_ID_THEORA,
  327. .parse_sdp_a_line = theora_parse_sdp_line,
  328. .open = theora_new_context,
  329. .close = theora_free_context,
  330. .parse_packet = theora_handle_packet
  331. };