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.

146 lines
4.1KB

  1. /*
  2. * Interplay MVE Video Decoder
  3. * Copyright (C) 2003 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 roqvideo.c
  22. * Interplay MVE Video Decoder by Mike Melanson
  23. * For more information about the Interplay MVE format, visit:
  24. * http://www.pcisys.net/~melanson/codecs/
  25. */
  26. #include <stdio.h>
  27. #include <stdlib.h>
  28. #include <string.h>
  29. #include <unistd.h>
  30. #include "common.h"
  31. #include "avcodec.h"
  32. #include "dsputil.h"
  33. typedef struct IpvideoContext {
  34. AVCodecContext *avctx;
  35. DSPContext dsp;
  36. AVFrame last_frame;
  37. AVFrame current_frame;
  38. int first_frame;
  39. int receiving_decoding_map;
  40. unsigned char *decoding_map;
  41. int decoding_map_size;
  42. unsigned char *buf;
  43. int size;
  44. } IpvideoContext;
  45. static int ipvideo_decode_init(AVCodecContext *avctx)
  46. {
  47. IpvideoContext *s = avctx->priv_data;
  48. s->avctx = avctx;
  49. avctx->pix_fmt = PIX_FMT_YUV444P;
  50. avctx->has_b_frames = 0;
  51. dsputil_init(&s->dsp, avctx);
  52. s->first_frame = 1;
  53. s->receiving_decoding_map = 1; /* decoding map will be received first */
  54. /* decoding map contains 4 bits of information per 8x8 block */
  55. s->decoding_map_size = avctx->width * avctx->height / (8 * 8 * 2);
  56. s->decoding_map = av_malloc(s->decoding_map_size);
  57. return 0;
  58. }
  59. static int ipvideo_decode_frame(AVCodecContext *avctx,
  60. void *data, int *data_size,
  61. uint8_t *buf, int buf_size)
  62. {
  63. IpvideoContext *s = avctx->priv_data;
  64. if (s->receiving_decoding_map) {
  65. /* receiving the decoding map on this iteration */
  66. s->receiving_decoding_map = 0;
  67. if (buf_size != s->decoding_map_size)
  68. printf (" Interplay video: buf_size != decoding_map_size (%d != %d)\n",
  69. buf_size, s->decoding_map_size);
  70. else
  71. memcpy(s->decoding_map, buf, buf_size);
  72. *data_size = 0;
  73. *(AVFrame*)data = s->last_frame;
  74. } else {
  75. /* receiving the compressed video data on this iteration */
  76. s->receiving_decoding_map = 1;
  77. s->buf = buf;
  78. s->size = buf_size;
  79. if (avctx->get_buffer(avctx, &s->current_frame)) {
  80. printf (" Interplay Video: get_buffer() failed\n");
  81. return -1;
  82. }
  83. // ipvideo_decode_frame(s);
  84. memset(s->current_frame.data[0], 0x80, s->current_frame.linesize[0] * avctx->height);
  85. memset(s->current_frame.data[1], 0x80, s->current_frame.linesize[1] * avctx->height / 4);
  86. memset(s->current_frame.data[2], 0x80, s->current_frame.linesize[2] * avctx->height / 4);
  87. /* release the last frame if it is allocated */
  88. if (s->first_frame)
  89. s->first_frame = 0;
  90. else
  91. avctx->release_buffer(avctx, &s->last_frame);
  92. /* shuffle frames */
  93. s->last_frame = s->current_frame;
  94. *data_size = sizeof(AVFrame);
  95. *(AVFrame*)data = s->current_frame;
  96. }
  97. /* always report that the buffer was completely consumed */
  98. return buf_size;
  99. }
  100. static int ipvideo_decode_end(AVCodecContext *avctx)
  101. {
  102. IpvideoContext *s = avctx->priv_data;
  103. /* release the last frame */
  104. avctx->release_buffer(avctx, &s->last_frame);
  105. av_free(s->decoding_map);
  106. return 0;
  107. }
  108. AVCodec interplay_video_decoder = {
  109. "interplayvideo",
  110. CODEC_TYPE_VIDEO,
  111. CODEC_ID_INTERPLAY_VIDEO,
  112. sizeof(IpvideoContext),
  113. ipvideo_decode_init,
  114. NULL,
  115. ipvideo_decode_end,
  116. ipvideo_decode_frame,
  117. CODEC_CAP_DR1,
  118. };