FFmpeg
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
jvdec.c
Go to the documentation of this file.
1 /*
2  * Bitmap Brothers JV video decoder
3  * Copyright (c) 2011 Peter Ross <pross@xvid.org>
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 /**
23  * @file
24  * Bitmap Brothers JV video decoder
25  * @author Peter Ross <pross@xvid.org>
26  */
27 
28 #include "libavutil/intreadwrite.h"
29 
30 #include "avcodec.h"
31 #include "blockdsp.h"
32 #include "get_bits.h"
33 #include "internal.h"
34 
35 typedef struct JvContext {
40 } JvContext;
41 
43 {
44  JvContext *s = avctx->priv_data;
45 
46  s->frame = av_frame_alloc();
47  if (!s->frame)
48  return AVERROR(ENOMEM);
49 
50  avctx->pix_fmt = AV_PIX_FMT_PAL8;
51  ff_blockdsp_init(&s->bdsp, avctx);
52  return 0;
53 }
54 
55 /**
56  * Decode 2x2 block
57  */
58 static inline void decode2x2(GetBitContext *gb, uint8_t *dst, int linesize)
59 {
60  int i, j, v[2];
61 
62  switch (get_bits(gb, 2)) {
63  case 1:
64  v[0] = get_bits(gb, 8);
65  for (j = 0; j < 2; j++)
66  memset(dst + j * linesize, v[0], 2);
67  break;
68  case 2:
69  v[0] = get_bits(gb, 8);
70  v[1] = get_bits(gb, 8);
71  for (j = 0; j < 2; j++)
72  for (i = 0; i < 2; i++)
73  dst[j * linesize + i] = v[get_bits1(gb)];
74  break;
75  case 3:
76  for (j = 0; j < 2; j++)
77  for (i = 0; i < 2; i++)
78  dst[j * linesize + i] = get_bits(gb, 8);
79  }
80 }
81 
82 /**
83  * Decode 4x4 block
84  */
85 static inline void decode4x4(GetBitContext *gb, uint8_t *dst, int linesize)
86 {
87  int i, j, v[2];
88 
89  switch (get_bits(gb, 2)) {
90  case 1:
91  v[0] = get_bits(gb, 8);
92  for (j = 0; j < 4; j++)
93  memset(dst + j * linesize, v[0], 4);
94  break;
95  case 2:
96  v[0] = get_bits(gb, 8);
97  v[1] = get_bits(gb, 8);
98  for (j = 2; j >= 0; j -= 2) {
99  for (i = 0; i < 4; i++)
100  dst[j * linesize + i] = v[get_bits1(gb)];
101  for (i = 0; i < 4; i++)
102  dst[(j + 1) * linesize + i] = v[get_bits1(gb)];
103  }
104  break;
105  case 3:
106  for (j = 0; j < 4; j += 2)
107  for (i = 0; i < 4; i += 2)
108  decode2x2(gb, dst + j * linesize + i, linesize);
109  }
110 }
111 
112 /**
113  * Decode 8x8 block
114  */
115 static inline void decode8x8(GetBitContext *gb, uint8_t *dst, int linesize,
116  BlockDSPContext *bdsp)
117 {
118  int i, j, v[2];
119 
120  switch (get_bits(gb, 2)) {
121  case 1:
122  v[0] = get_bits(gb, 8);
123  bdsp->fill_block_tab[1](dst, v[0], linesize, 8);
124  break;
125  case 2:
126  v[0] = get_bits(gb, 8);
127  v[1] = get_bits(gb, 8);
128  for (j = 7; j >= 0; j--)
129  for (i = 0; i < 8; i++)
130  dst[j * linesize + i] = v[get_bits1(gb)];
131  break;
132  case 3:
133  for (j = 0; j < 8; j += 4)
134  for (i = 0; i < 8; i += 4)
135  decode4x4(gb, dst + j * linesize + i, linesize);
136  }
137 }
138 
139 static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame,
140  AVPacket *avpkt)
141 {
142  JvContext *s = avctx->priv_data;
143  const uint8_t *buf = avpkt->data;
144  const uint8_t *buf_end = buf + avpkt->size;
145  int video_size, video_type, i, j, ret;
146 
147  if (avpkt->size < 6)
148  return AVERROR_INVALIDDATA;
149 
150  video_size = AV_RL32(buf);
151  video_type = buf[4];
152  buf += 5;
153 
154  if (video_size) {
155  if (video_size < 0 || video_size > avpkt->size - 5) {
156  av_log(avctx, AV_LOG_ERROR, "video size %d invalid\n", video_size);
157  return AVERROR_INVALIDDATA;
158  }
159  if ((ret = ff_reget_buffer(avctx, s->frame)) < 0)
160  return ret;
161 
162  if (video_type == 0 || video_type == 1) {
163  GetBitContext gb;
164  init_get_bits(&gb, buf, 8 * video_size);
165 
166  for (j = 0; j < avctx->height; j += 8)
167  for (i = 0; i < avctx->width; i += 8)
168  decode8x8(&gb,
169  s->frame->data[0] + j * s->frame->linesize[0] + i,
170  s->frame->linesize[0], &s->bdsp);
171 
172  buf += video_size;
173  } else if (video_type == 2) {
174  int v = *buf++;
175  for (j = 0; j < avctx->height; j++)
176  memset(s->frame->data[0] + j * s->frame->linesize[0],
177  v, avctx->width);
178  } else {
179  av_log(avctx, AV_LOG_WARNING,
180  "unsupported frame type %i\n", video_type);
181  return AVERROR_INVALIDDATA;
182  }
183  }
184 
185  if (buf_end - buf >= AVPALETTE_COUNT * 3) {
186  for (i = 0; i < AVPALETTE_COUNT; i++) {
187  uint32_t pal = AV_RB24(buf);
188  s->palette[i] = 0xFFU << 24 | pal << 2 | ((pal >> 4) & 0x30303);
189  buf += 3;
190  }
191  s->palette_has_changed = 1;
192  }
193 
194  if (video_size) {
195  s->frame->key_frame = 1;
198  s->palette_has_changed = 0;
199  memcpy(s->frame->data[1], s->palette, AVPALETTE_SIZE);
200 
201  if ((ret = av_frame_ref(data, s->frame)) < 0)
202  return ret;
203  *got_frame = 1;
204  }
205 
206  return avpkt->size;
207 }
208 
210 {
211  JvContext *s = avctx->priv_data;
212 
213  av_frame_free(&s->frame);
214 
215  return 0;
216 }
217 
219  .name = "jv",
220  .long_name = NULL_IF_CONFIG_SMALL("Bitmap Brothers JV video"),
221  .type = AVMEDIA_TYPE_VIDEO,
222  .id = AV_CODEC_ID_JV,
223  .priv_data_size = sizeof(JvContext),
224  .init = decode_init,
225  .close = decode_close,
226  .decode = decode_frame,
227  .capabilities = CODEC_CAP_DR1,
228 };