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.

549 lines
15KB

  1. /*
  2. * Sierra VMD Audio & Video Decoders
  3. * Copyright (C) 2004 the ffmpeg project
  4. *
  5. * This library is free software; you can redistribute it and/or
  6. * modify it under the terms of the GNU Lesser General Public
  7. * License as published by the Free Software Foundation; either
  8. * version 2 of the License, or (at your option) any later version.
  9. *
  10. * This library is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  13. * Lesser General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Lesser General Public
  16. * License along with this library; if not, write to the Free Software
  17. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  18. *
  19. */
  20. /**
  21. * @file vmdvideo.c
  22. * Sierra VMD audio & video decoders
  23. * by Vladimir "VAG" Gneushev (vagsoft at mail.ru)
  24. *
  25. * The video decoder outputs PAL8 colorspace data. The decoder expects
  26. * a 0x330-byte VMD file header to be transmitted via extradata during
  27. * codec initialization. Each encoded frame that is sent to this decoder
  28. * is expected to be prepended with the appropriate 16-byte frame
  29. * information record from the VMD file.
  30. *
  31. * The audio decoder, like the video decoder, expects each encoded data
  32. * chunk to be prepended with the approriate 16-byte frame information
  33. * record from the VMD file. It does not require the 0x330-byte VMD file
  34. * header, but it does need the audio setup parameters passed in through
  35. * normal libavcodec API means.
  36. */
  37. #include <stdio.h>
  38. #include <stdlib.h>
  39. #include <string.h>
  40. #include <unistd.h>
  41. #include "common.h"
  42. #include "avcodec.h"
  43. #include "dsputil.h"
  44. #define VMD_HEADER_SIZE 0x330
  45. #define PALETTE_COUNT 256
  46. #define LE_16(x) ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0])
  47. #define LE_32(x) ((((uint8_t*)(x))[3] << 24) | \
  48. (((uint8_t*)(x))[2] << 16) | \
  49. (((uint8_t*)(x))[1] << 8) | \
  50. ((uint8_t*)(x))[0])
  51. /*
  52. * Video Decoder
  53. */
  54. typedef struct VmdVideoContext {
  55. AVCodecContext *avctx;
  56. DSPContext dsp;
  57. AVFrame frame;
  58. AVFrame prev_frame;
  59. unsigned char *buf;
  60. int size;
  61. unsigned char palette[PALETTE_COUNT * 4];
  62. unsigned char *unpack_buffer;
  63. } VmdVideoContext;
  64. #define QUEUE_SIZE 0x1000
  65. #define QUEUE_MASK 0x0FFF
  66. static void lz_unpack(unsigned char *src, unsigned char *dest)
  67. {
  68. unsigned char *s;
  69. unsigned char *d;
  70. unsigned char queue[QUEUE_SIZE];
  71. unsigned int qpos;
  72. unsigned int dataleft;
  73. unsigned int chainofs;
  74. unsigned int chainlen;
  75. unsigned int speclen;
  76. unsigned char tag;
  77. unsigned int i, j;
  78. s = src;
  79. d = dest;
  80. dataleft = LE_32(s);
  81. s += 4;
  82. memset(queue, QUEUE_SIZE, 0x20);
  83. if (LE_32(s) == 0x56781234) {
  84. s += 4;
  85. qpos = 0x111;
  86. speclen = 0xF + 3;
  87. } else {
  88. qpos = 0xFEE;
  89. speclen = 100; /* no speclen */
  90. }
  91. while (dataleft > 0) {
  92. tag = *s++;
  93. if ((tag == 0xFF) && (dataleft > 8)) {
  94. for (i = 0; i < 8; i++) {
  95. queue[qpos++] = *d++ = *s++;
  96. qpos &= QUEUE_MASK;
  97. }
  98. dataleft -= 8;
  99. } else {
  100. for (i = 0; i < 8; i++) {
  101. if (dataleft == 0)
  102. break;
  103. if (tag & 0x01) {
  104. queue[qpos++] = *d++ = *s++;
  105. qpos &= QUEUE_MASK;
  106. dataleft--;
  107. } else {
  108. chainofs = *s++;
  109. chainofs |= ((*s & 0xF0) << 4);
  110. chainlen = (*s++ & 0x0F) + 3;
  111. if (chainlen == speclen)
  112. chainlen = *s++ + 0xF + 3;
  113. for (j = 0; j < chainlen; j++) {
  114. *d = queue[chainofs++ & QUEUE_MASK];
  115. queue[qpos++] = *d++;
  116. qpos &= QUEUE_MASK;
  117. }
  118. dataleft -= chainlen;
  119. }
  120. tag >>= 1;
  121. }
  122. }
  123. }
  124. }
  125. static int rle_unpack(unsigned char *src, unsigned char *dest, int len)
  126. {
  127. unsigned char *ps;
  128. unsigned char *pd;
  129. int i, l;
  130. ps = src;
  131. pd = dest;
  132. if (len & 1)
  133. *pd++ = *ps++;
  134. len >>= 1;
  135. i = 0;
  136. do {
  137. l = *ps++;
  138. if (l & 0x80) {
  139. l = (l & 0x7F) * 2;
  140. memcpy(pd, ps, l);
  141. ps += l;
  142. pd += l;
  143. } else {
  144. for (i = 0; i < l; i++) {
  145. *pd++ = ps[0];
  146. *pd++ = ps[1];
  147. }
  148. ps += 2;
  149. }
  150. i += l;
  151. } while (i < len);
  152. return (ps - src);
  153. }
  154. static void vmd_decode(VmdVideoContext *s)
  155. {
  156. int i;
  157. unsigned int *palette32;
  158. unsigned char r, g, b;
  159. /* point to the start of the encoded data */
  160. unsigned char *p = s->buf + 16;
  161. unsigned char *pb;
  162. unsigned char meth;
  163. unsigned char *dp; /* pointer to current frame */
  164. unsigned char *pp; /* pointer to previous frame */
  165. unsigned char len;
  166. int ofs;
  167. int frame_x, frame_y;
  168. int frame_width, frame_height;
  169. frame_x = LE_16(&s->buf[6]);
  170. frame_y = LE_16(&s->buf[8]);
  171. frame_width = LE_16(&s->buf[10]) - frame_x + 1;
  172. frame_height = LE_16(&s->buf[12]) - frame_y + 1;
  173. /* if only a certain region will be updated, copy the entire previous
  174. * frame before the decode */
  175. if (frame_x || frame_y || (frame_width != s->avctx->width) ||
  176. (frame_height != s->avctx->height)) {
  177. memcpy(s->frame.data[0], s->prev_frame.data[0],
  178. s->avctx->height * s->frame.linesize[0]);
  179. }
  180. /* check if there is a new palette */
  181. if (s->buf[15] & 0x02) {
  182. p += 2;
  183. palette32 = (unsigned int *)s->palette;
  184. for (i = 0; i < PALETTE_COUNT; i++) {
  185. r = *p++ * 4;
  186. g = *p++ * 4;
  187. b = *p++ * 4;
  188. palette32[i] = (r << 16) | (g << 8) | (b);
  189. }
  190. s->size -= (256 * 3 + 2);
  191. }
  192. if (s->size >= 0) {
  193. /* originally UnpackFrame in VAG's code */
  194. pb = p;
  195. meth = *pb++;
  196. if (meth & 0x80) {
  197. lz_unpack(pb, s->unpack_buffer);
  198. meth &= 0x7F;
  199. pb = s->unpack_buffer;
  200. }
  201. dp = &s->frame.data[0][frame_y * s->frame.linesize[0] + frame_x];
  202. pp = &s->prev_frame.data[0][frame_y * s->prev_frame.linesize[0] + frame_x];
  203. switch (meth) {
  204. case 1:
  205. for (i = 0; i < frame_height; i++) {
  206. ofs = 0;
  207. do {
  208. len = *pb++;
  209. if (len & 0x80) {
  210. len = (len & 0x7F) + 1;
  211. memcpy(&dp[ofs], pb, len);
  212. pb += len;
  213. ofs += len;
  214. } else {
  215. /* interframe pixel copy */
  216. memcpy(&dp[ofs], &pp[ofs], len + 1);
  217. ofs += len + 1;
  218. }
  219. } while (ofs < frame_width);
  220. if (ofs > frame_width) {
  221. printf (" VMD video: offset > width (%d > %d)\n",
  222. ofs, frame_width);
  223. break;
  224. }
  225. dp += s->frame.linesize[0];
  226. pp += s->prev_frame.linesize[0];
  227. }
  228. break;
  229. case 2:
  230. for (i = 0; i < frame_height; i++) {
  231. memcpy(dp, pb, frame_width);
  232. pb += frame_width;
  233. dp += s->frame.linesize[0];
  234. pp += s->prev_frame.linesize[0];
  235. }
  236. break;
  237. case 3:
  238. for (i = 0; i < frame_height; i++) {
  239. ofs = 0;
  240. do {
  241. len = *pb++;
  242. if (len & 0x80) {
  243. len = (len & 0x7F) + 1;
  244. if (*pb++ == 0xFF)
  245. len = rle_unpack(pb, dp, len);
  246. else
  247. memcpy(&dp[ofs], pb, len);
  248. pb += len;
  249. ofs += len;
  250. } else {
  251. /* interframe pixel copy */
  252. memcpy(&dp[ofs], &pp[ofs], len + 1);
  253. ofs += len + 1;
  254. }
  255. } while (ofs < frame_width);
  256. if (ofs > frame_width) {
  257. printf (" VMD video: offset > width (%d > %d)\n",
  258. ofs, frame_width);
  259. }
  260. dp += s->frame.linesize[0];
  261. pp += s->prev_frame.linesize[0];
  262. }
  263. break;
  264. }
  265. }
  266. }
  267. static int vmdvideo_decode_init(AVCodecContext *avctx)
  268. {
  269. VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
  270. int i;
  271. unsigned int *palette32;
  272. int palette_index = 0;
  273. unsigned char r, g, b;
  274. unsigned char *vmd_header;
  275. unsigned char *raw_palette;
  276. s->avctx = avctx;
  277. avctx->pix_fmt = PIX_FMT_PAL8;
  278. avctx->has_b_frames = 0;
  279. dsputil_init(&s->dsp, avctx);
  280. /* make sure the VMD header made it */
  281. if (s->avctx->extradata_size != VMD_HEADER_SIZE) {
  282. printf(" VMD video: expected extradata size of %d\n",
  283. VMD_HEADER_SIZE);
  284. return -1;
  285. }
  286. vmd_header = (unsigned char *)avctx->extradata;
  287. s->unpack_buffer = av_malloc(LE_32(&vmd_header[800]));
  288. if (!s->unpack_buffer)
  289. return -1;
  290. /* load up the initial palette */
  291. raw_palette = &vmd_header[28];
  292. palette32 = (unsigned int *)s->palette;
  293. for (i = 0; i < PALETTE_COUNT; i++) {
  294. r = raw_palette[palette_index++] * 4;
  295. g = raw_palette[palette_index++] * 4;
  296. b = raw_palette[palette_index++] * 4;
  297. palette32[i] = (r << 16) | (g << 8) | (b);
  298. }
  299. s->frame.data[0] = s->prev_frame.data[0] = NULL;
  300. return 0;
  301. }
  302. static int vmdvideo_decode_frame(AVCodecContext *avctx,
  303. void *data, int *data_size,
  304. uint8_t *buf, int buf_size)
  305. {
  306. VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
  307. s->buf = buf;
  308. s->size = buf_size;
  309. s->frame.reference = 1;
  310. if (avctx->get_buffer(avctx, &s->frame)) {
  311. printf (" VMD Video: get_buffer() failed\n");
  312. return -1;
  313. }
  314. vmd_decode(s);
  315. /* make the palette available on the way out */
  316. memcpy(s->frame.data[1], s->palette, PALETTE_COUNT * 4);
  317. if (s->prev_frame.data[0])
  318. avctx->release_buffer(avctx, &s->prev_frame);
  319. /* shuffle frames */
  320. s->prev_frame = s->frame;
  321. *data_size = sizeof(AVFrame);
  322. *(AVFrame*)data = s->frame;
  323. /* report that the buffer was completely consumed */
  324. return buf_size;
  325. }
  326. static int vmdvideo_decode_end(AVCodecContext *avctx)
  327. {
  328. VmdVideoContext *s = (VmdVideoContext *)avctx->priv_data;
  329. if (s->prev_frame.data[0])
  330. avctx->release_buffer(avctx, &s->prev_frame);
  331. av_free(s->unpack_buffer);
  332. return 0;
  333. }
  334. /*
  335. * Audio Decoder
  336. */
  337. typedef struct VmdAudioContext {
  338. int channels;
  339. int bits;
  340. int block_align;
  341. unsigned char steps8[16];
  342. unsigned short steps16[16];
  343. unsigned short steps128[256];
  344. short predictors[2];
  345. } VmdAudioContext;
  346. static int vmdaudio_decode_init(AVCodecContext *avctx)
  347. {
  348. VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
  349. int i;
  350. s->channels = avctx->channels;
  351. s->bits = avctx->bits_per_sample;
  352. s->block_align = avctx->block_align;
  353. printf (" %d channels, %d bits/sample, block align = %d\n",
  354. s->channels, s->bits, s->block_align);
  355. /* set up the steps8 and steps16 tables */
  356. for (i = 0; i < 8; i++) {
  357. if (i < 4)
  358. s->steps8[i] = i;
  359. else
  360. s->steps8[i] = s->steps8[i - 1] + i - 1;
  361. if (i == 0)
  362. s->steps16[i] = 0;
  363. else if (i == 1)
  364. s->steps16[i] = 4;
  365. else if (i == 2)
  366. s->steps16[i] = 16;
  367. else
  368. s->steps16[i] = 1 << (i + 4);
  369. }
  370. /* set up the step128 table */
  371. s->steps128[0] = 0;
  372. s->steps128[1] = 8;
  373. for (i = 0x02; i <= 0x20; i++)
  374. s->steps128[i] = (i - 1) << 4;
  375. for (i = 0x21; i <= 0x60; i++)
  376. s->steps128[i] = (i + 0x1F) << 3;
  377. for (i = 0x61; i <= 0x70; i++)
  378. s->steps128[i] = (i - 0x51) << 6;
  379. for (i = 0x71; i <= 0x78; i++)
  380. s->steps128[i] = (i - 0x69) << 8;
  381. for (i = 0x79; i <= 0x7D; i++)
  382. s->steps128[i] = (i - 0x75) << 10;
  383. s->steps128[0x7E] = 0x3000;
  384. s->steps128[0x7F] = 0x4000;
  385. /* set up the negative half of each table */
  386. for (i = 0; i < 8; i++) {
  387. s->steps8[i + 8] = -s->steps8[i];
  388. s->steps16[i + 8] = -s->steps16[i];
  389. }
  390. for (i = 0; i < 128; i++)
  391. s->steps128[i + 128] = -s->steps128[i];
  392. return 0;
  393. }
  394. static void vmdaudio_decode_audio(VmdAudioContext *s, unsigned char *data,
  395. uint8_t *buf, int ratio) {
  396. }
  397. static void vmdaudio_loadsound(VmdAudioContext *s, unsigned char *data,
  398. uint8_t *buf, int silence)
  399. {
  400. if (s->channels == 2) {
  401. if ((s->block_align & 0x01) == 0) {
  402. if (silence)
  403. memset(data, 0, s->block_align * 2);
  404. else
  405. vmdaudio_decode_audio(s, data, buf, 1);
  406. } else {
  407. if (silence)
  408. memset(data, 0, s->block_align * 2);
  409. // else
  410. // vmdaudio_decode_audio(s, data, buf, 1);
  411. }
  412. } else {
  413. }
  414. }
  415. static int vmdaudio_decode_frame(AVCodecContext *avctx,
  416. void *data, int *data_size,
  417. uint8_t *buf, int buf_size)
  418. {
  419. VmdAudioContext *s = (VmdAudioContext *)avctx->priv_data;
  420. unsigned int sound_flags;
  421. unsigned char *output_samples = (unsigned char *)data;
  422. /* point to the start of the encoded data */
  423. unsigned char *p = buf + 16;
  424. unsigned char *p_end = buf + buf_size;
  425. if (buf[6] == 1) {
  426. /* the chunk contains audio */
  427. vmdaudio_loadsound(s, output_samples, p, 0);
  428. } else if (buf[6] == 2) {
  429. /* the chunk contains audio and silence mixed together */
  430. sound_flags = LE_32(p);
  431. p += 4;
  432. /* do something with extrabufs here? */
  433. while (p < p_end) {
  434. if (sound_flags & 0x01)
  435. /* audio */
  436. vmdaudio_loadsound(s, output_samples, p, 1);
  437. else
  438. /* silence */
  439. vmdaudio_loadsound(s, output_samples, p, 0);
  440. p += s->block_align;
  441. output_samples += (s->block_align * s->bits / 8);
  442. sound_flags >>= 1;
  443. }
  444. } else if (buf[6] == 3) {
  445. /* silent chunk */
  446. vmdaudio_loadsound(s, output_samples, p, 1);
  447. }
  448. // *datasize = ;
  449. return buf_size;
  450. }
  451. /*
  452. * Public Data Structures
  453. */
  454. AVCodec vmdvideo_decoder = {
  455. "vmdvideo",
  456. CODEC_TYPE_VIDEO,
  457. CODEC_ID_VMDVIDEO,
  458. sizeof(VmdVideoContext),
  459. vmdvideo_decode_init,
  460. NULL,
  461. vmdvideo_decode_end,
  462. vmdvideo_decode_frame,
  463. CODEC_CAP_DR1,
  464. };
  465. AVCodec vmdaudio_decoder = {
  466. "vmdaudio",
  467. CODEC_TYPE_AUDIO,
  468. CODEC_ID_VMDAUDIO,
  469. sizeof(VmdAudioContext),
  470. vmdaudio_decode_init,
  471. NULL,
  472. NULL,
  473. vmdaudio_decode_frame,
  474. };