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.

314 lines
8.5KB

  1. /*
  2. * Vivo stream demuxer
  3. * Copyright (c) 2009 Daniel Verkamp <daniel at drv.nu>
  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
  23. * @brief Vivo stream demuxer
  24. * @author Daniel Verkamp <daniel at drv.nu>
  25. * @sa http://wiki.multimedia.cx/index.php?title=Vivo
  26. */
  27. #include "libavutil/parseutils.h"
  28. #include "avformat.h"
  29. #include "internal.h"
  30. typedef struct VivoContext {
  31. int version;
  32. int type;
  33. int sequence;
  34. int length;
  35. uint8_t text[1024 + 1];
  36. } VivoContext;
  37. static int vivo_probe(AVProbeData *p)
  38. {
  39. const unsigned char *buf = p->buf;
  40. unsigned c, length = 0;
  41. // stream must start with packet of type 0 and sequence number 0
  42. if (*buf++ != 0)
  43. return 0;
  44. // read at most 2 bytes of coded length
  45. c = *buf++;
  46. length = c & 0x7F;
  47. if (c & 0x80) {
  48. c = *buf++;
  49. length = (length << 7) | (c & 0x7F);
  50. }
  51. if (c & 0x80 || length > 1024 || length < 21)
  52. return 0;
  53. if (memcmp(buf, "\r\nVersion:Vivo/", 15))
  54. return 0;
  55. buf += 15;
  56. if (*buf < '0' && *buf > '2')
  57. return 0;
  58. return AVPROBE_SCORE_MAX;
  59. }
  60. static int vivo_get_packet_header(AVFormatContext *s)
  61. {
  62. VivoContext *vivo = s->priv_data;
  63. AVIOContext *pb = s->pb;
  64. unsigned c, get_length = 0;
  65. if (url_feof(pb))
  66. return AVERROR_EOF;
  67. c = avio_r8(pb);
  68. if (c == 0x82) {
  69. get_length = 1;
  70. c = avio_r8(pb);
  71. }
  72. vivo->type = c >> 4;
  73. vivo->sequence = c & 0xF;
  74. switch (vivo->type) {
  75. case 0: get_length = 1; break;
  76. case 1: vivo->length = 128; break;
  77. case 2: get_length = 1; break;
  78. case 3: vivo->length = 40; break;
  79. case 4: vivo->length = 24; break;
  80. default:
  81. av_log(s, AV_LOG_ERROR, "unknown packet type %d\n", vivo->type);
  82. return AVERROR_INVALIDDATA;
  83. }
  84. if (get_length) {
  85. c = avio_r8(pb);
  86. vivo->length = c & 0x7F;
  87. if (c & 0x80) {
  88. c = avio_r8(pb);
  89. vivo->length = (vivo->length << 7) | (c & 0x7F);
  90. if (c & 0x80) {
  91. av_log(s, AV_LOG_ERROR, "coded length is more than two bytes\n");
  92. return AVERROR_INVALIDDATA;
  93. }
  94. }
  95. }
  96. return 0;
  97. }
  98. static int vivo_read_header(AVFormatContext *s)
  99. {
  100. VivoContext *vivo = s->priv_data;
  101. AVRational fps = { 1, 25};
  102. AVStream *ast, *vst;
  103. unsigned char *line, *line_end, *key, *value;
  104. long value_int;
  105. int ret, value_used;
  106. int64_t duration = 0;
  107. char *end_value;
  108. vst = avformat_new_stream(s, NULL);
  109. ast = avformat_new_stream(s, NULL);
  110. if (!ast || !vst)
  111. return AVERROR(ENOMEM);
  112. ast->codec->sample_rate = 8000;
  113. while (1) {
  114. if ((ret = vivo_get_packet_header(s)) < 0)
  115. return ret;
  116. // done reading all text header packets?
  117. if (vivo->sequence || vivo->type)
  118. break;
  119. if (vivo->length <= 1024) {
  120. avio_read(s->pb, vivo->text, vivo->length);
  121. vivo->text[vivo->length] = 0;
  122. } else {
  123. av_log(s, AV_LOG_WARNING, "too big header, skipping\n");
  124. avio_skip(s->pb, vivo->length);
  125. continue;
  126. }
  127. line = vivo->text;
  128. while (*line) {
  129. line_end = strstr(line, "\r\n");
  130. if (!line_end)
  131. break;
  132. *line_end = 0;
  133. key = line;
  134. line = line_end + 2; // skip \r\n
  135. if (line_end == key) // skip blank lines
  136. continue;
  137. value = strchr(key, ':');
  138. if (!value) {
  139. av_log(s, AV_LOG_WARNING, "missing colon in key:value pair '%s'\n",
  140. value);
  141. continue;
  142. }
  143. *value++ = 0;
  144. av_log(s, AV_LOG_DEBUG, "header: '%s' = '%s'\n", key, value);
  145. value_int = strtol(value, &end_value, 10);
  146. value_used = 0;
  147. if (*end_value == 0) { // valid integer
  148. av_log(s, AV_LOG_DEBUG, "got a valid integer (%ld)\n", value_int);
  149. value_used = 1;
  150. if (!strcmp(key, "Duration")) {
  151. duration = value_int;
  152. } else if (!strcmp(key, "Width")) {
  153. vst->codec->width = value_int;
  154. } else if (!strcmp(key, "Height")) {
  155. vst->codec->height = value_int;
  156. } else if (!strcmp(key, "TimeUnitNumerator")) {
  157. fps.num = value_int / 1000;
  158. } else if (!strcmp(key, "TimeUnitDenominator")) {
  159. fps.den = value_int;
  160. } else if (!strcmp(key, "SamplingFrequency")) {
  161. ast->codec->sample_rate = value_int;
  162. } else if (!strcmp(key, "NominalBitrate")) {
  163. } else if (!strcmp(key, "Length")) {
  164. // size of file
  165. } else {
  166. value_used = 0;
  167. }
  168. }
  169. if (!strcmp(key, "Version")) {
  170. if (sscanf(value, "Vivo/%d.", &vivo->version) != 1)
  171. return AVERROR_INVALIDDATA;
  172. value_used = 1;
  173. } else if (!strcmp(key, "FPS")) {
  174. AVRational tmp;
  175. value_used = 1;
  176. if (!av_parse_ratio(&tmp, value, 10000, AV_LOG_WARNING, s))
  177. fps = av_inv_q(tmp);
  178. }
  179. if (!value_used)
  180. av_dict_set(&s->metadata, key, value, 0);
  181. }
  182. }
  183. avpriv_set_pts_info(ast, 64, 1, ast->codec->sample_rate);
  184. avpriv_set_pts_info(vst, 64, fps.num, fps.den);
  185. if (duration)
  186. s->duration = av_rescale(duration, 1000, 1);
  187. vst->start_time = 0;
  188. vst->codec->codec_tag = 0;
  189. vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
  190. if (vivo->version == 1) {
  191. vst->codec->codec_id = AV_CODEC_ID_H263;
  192. ast->codec->codec_id = AV_CODEC_ID_G723_1;
  193. ast->codec->bits_per_coded_sample = 8;
  194. ast->codec->block_align = 24;
  195. ast->codec->bit_rate = 6400;
  196. }
  197. ast->start_time = 0;
  198. ast->codec->codec_tag = 0;
  199. ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
  200. ast->codec->channels = 1;
  201. return 0;
  202. }
  203. static int vivo_read_packet(AVFormatContext *s, AVPacket *pkt)
  204. {
  205. VivoContext *vivo = s->priv_data;
  206. AVIOContext *pb = s->pb;
  207. unsigned old_sequence = vivo->sequence, old_type = vivo->type;
  208. int stream_index, ret = 0;
  209. restart:
  210. if (url_feof(pb))
  211. return AVERROR_EOF;
  212. switch (vivo->type) {
  213. case 0:
  214. avio_skip(pb, vivo->length);
  215. if ((ret = vivo_get_packet_header(s)) < 0)
  216. return ret;
  217. goto restart;
  218. case 1:
  219. case 2: // video
  220. stream_index = 0;
  221. break;
  222. case 3:
  223. case 4: // audio
  224. stream_index = 1;
  225. break;
  226. default:
  227. av_log(s, AV_LOG_ERROR, "unknown packet type %d\n", vivo->type);
  228. return AVERROR_INVALIDDATA;
  229. }
  230. if ((ret = av_get_packet(pb, pkt, vivo->length)) < 0)
  231. goto fail;
  232. // get next packet header
  233. if ((ret = vivo_get_packet_header(s)) < 0)
  234. goto fail;
  235. while (vivo->sequence == old_sequence &&
  236. (((vivo->type - 1) >> 1) == ((old_type - 1) >> 1))) {
  237. if (url_feof(pb)) {
  238. ret = AVERROR_EOF;
  239. break;
  240. }
  241. if ((ret = av_append_packet(pb, pkt, vivo->length)) < 0)
  242. break;
  243. // get next packet header
  244. if ((ret = vivo_get_packet_header(s)) < 0)
  245. break;
  246. }
  247. pkt->stream_index = stream_index;
  248. fail:
  249. if (ret < 0)
  250. av_free_packet(pkt);
  251. return ret;
  252. }
  253. AVInputFormat ff_vivo_demuxer = {
  254. .name = "vivo",
  255. .long_name = NULL_IF_CONFIG_SMALL("Vivo"),
  256. .priv_data_size = sizeof(VivoContext),
  257. .read_probe = vivo_probe,
  258. .read_header = vivo_read_header,
  259. .read_packet = vivo_read_packet,
  260. .extensions = "viv",
  261. };