FFmpeg
mdec.c
Go to the documentation of this file.
1 /*
2  * Sony PlayStation MDEC (Motion DECoder)
3  * Copyright (c) 2003 Michael Niedermayer
4  *
5  * based upon code from Sebastian Jedruszkiewicz <elf@frogger.rules.pl>
6  *
7  * This file is part of FFmpeg.
8  *
9  * FFmpeg is free software; you can redistribute it and/or
10  * modify it under the terms of the GNU Lesser General Public
11  * License as published by the Free Software Foundation; either
12  * version 2.1 of the License, or (at your option) any later version.
13  *
14  * FFmpeg is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17  * Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public
20  * License along with FFmpeg; if not, write to the Free Software
21  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22  */
23 
24 /**
25  * @file
26  * Sony PlayStation MDEC (Motion DECoder)
27  * This is very similar to intra-only MPEG-1.
28  */
29 
30 #include "avcodec.h"
31 #include "blockdsp.h"
32 #include "bswapdsp.h"
33 #include "idctdsp.h"
34 #include "mpeg12.h"
35 #include "thread.h"
36 
37 typedef struct MDECContext {
45  int version;
46  int qscale;
47  int last_dc[3];
48  int mb_width;
49  int mb_height;
50  int mb_x, mb_y;
51  DECLARE_ALIGNED(32, int16_t, block)[6][64];
52  DECLARE_ALIGNED(16, uint16_t, quant_matrix)[64];
54  unsigned int bitstream_buffer_size;
56 } MDECContext;
57 
58 //very similar to MPEG-1
59 static inline int mdec_decode_block_intra(MDECContext *a, int16_t *block, int n)
60 {
61  int level, diff, i, j, run;
62  int component;
63  RLTable *rl = &ff_rl_mpeg1;
65  const uint16_t *quant_matrix = a->quant_matrix;
66  const int qscale = a->qscale;
67 
68  /* DC coefficient */
69  if (a->version == 2) {
70  block[0] = 2 * get_sbits(&a->gb, 10) + 1024;
71  } else {
72  component = (n <= 3 ? 0 : n - 4 + 1);
73  diff = decode_dc(&a->gb, component);
74  a->last_dc[component] += diff;
75  block[0] = a->last_dc[component] * (1 << 3);
76  }
77 
78  i = 0;
79  {
80  OPEN_READER(re, &a->gb);
81  /* now quantify & encode AC coefficients */
82  for (;;) {
83  UPDATE_CACHE(re, &a->gb);
84  GET_RL_VLC(level, run, re, &a->gb, rl->rl_vlc[0], TEX_VLC_BITS, 2, 0);
85 
86  if (level == 127) {
87  break;
88  } else if (level != 0) {
89  i += run;
90  if (i > 63) {
92  "ac-tex damaged at %d %d\n", a->mb_x, a->mb_y);
93  return AVERROR_INVALIDDATA;
94  }
95  j = scantable[i];
96  level = (level * qscale * quant_matrix[j]) >> 3;
97  level = (level ^ SHOW_SBITS(re, &a->gb, 1)) - SHOW_SBITS(re, &a->gb, 1);
98  LAST_SKIP_BITS(re, &a->gb, 1);
99  } else {
100  /* escape */
101  run = SHOW_UBITS(re, &a->gb, 6)+1; LAST_SKIP_BITS(re, &a->gb, 6);
102  UPDATE_CACHE(re, &a->gb);
103  level = SHOW_SBITS(re, &a->gb, 10); SKIP_BITS(re, &a->gb, 10);
104  i += run;
105  if (i > 63) {
107  "ac-tex damaged at %d %d\n", a->mb_x, a->mb_y);
108  return AVERROR_INVALIDDATA;
109  }
110  j = scantable[i];
111  if (level < 0) {
112  level = -level;
113  level = (level * (unsigned)qscale * quant_matrix[j]) >> 3;
114  level = (level - 1) | 1;
115  level = -level;
116  } else {
117  level = (level * (unsigned)qscale * quant_matrix[j]) >> 3;
118  level = (level - 1) | 1;
119  }
120  }
121 
122  block[j] = level;
123  }
124  CLOSE_READER(re, &a->gb);
125  }
126  a->block_last_index[n] = i;
127  return 0;
128 }
129 
130 static inline int decode_mb(MDECContext *a, int16_t block[6][64])
131 {
132  int i, ret;
133  static const int block_index[6] = { 5, 4, 0, 1, 2, 3 };
134 
135  a->bdsp.clear_blocks(block[0]);
136 
137  for (i = 0; i < 6; i++) {
138  if ((ret = mdec_decode_block_intra(a, block[block_index[i]],
139  block_index[i])) < 0)
140  return ret;
141  if (get_bits_left(&a->gb) < 0)
142  return AVERROR_INVALIDDATA;
143  }
144  return 0;
145 }
146 
147 static inline void idct_put(MDECContext *a, AVFrame *frame, int mb_x, int mb_y)
148 {
149  int16_t (*block)[64] = a->block;
150  int linesize = frame->linesize[0];
151 
152  uint8_t *dest_y = frame->data[0] + (mb_y * 16* linesize ) + mb_x * 16;
153  uint8_t *dest_cb = frame->data[1] + (mb_y * 8 * frame->linesize[1]) + mb_x * 8;
154  uint8_t *dest_cr = frame->data[2] + (mb_y * 8 * frame->linesize[2]) + mb_x * 8;
155 
156  a->idsp.idct_put(dest_y, linesize, block[0]);
157  a->idsp.idct_put(dest_y + 8, linesize, block[1]);
158  a->idsp.idct_put(dest_y + 8 * linesize, linesize, block[2]);
159  a->idsp.idct_put(dest_y + 8 * linesize + 8, linesize, block[3]);
160 
161  if (!(a->avctx->flags & AV_CODEC_FLAG_GRAY)) {
162  a->idsp.idct_put(dest_cb, frame->linesize[1], block[4]);
163  a->idsp.idct_put(dest_cr, frame->linesize[2], block[5]);
164  }
165 }
166 
168  void *data, int *got_frame,
169  AVPacket *avpkt)
170 {
171  MDECContext * const a = avctx->priv_data;
172  const uint8_t *buf = avpkt->data;
173  int buf_size = avpkt->size;
174  ThreadFrame frame = { .f = data };
175  int ret;
176 
177  if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
178  return ret;
179  frame.f->pict_type = AV_PICTURE_TYPE_I;
180  frame.f->key_frame = 1;
181 
183  if (!a->bitstream_buffer)
184  return AVERROR(ENOMEM);
185  a->bbdsp.bswap16_buf((uint16_t *)a->bitstream_buffer, (uint16_t *)buf, (buf_size + 1) / 2);
186  if ((ret = init_get_bits8(&a->gb, a->bitstream_buffer, buf_size)) < 0)
187  return ret;
188 
189  /* skip over 4 preamble bytes in stream (typically 0xXX 0xXX 0x00 0x38) */
190  skip_bits(&a->gb, 32);
191 
192  a->qscale = get_bits(&a->gb, 16);
193  a->version = get_bits(&a->gb, 16);
194 
195  a->last_dc[0] = a->last_dc[1] = a->last_dc[2] = 128;
196 
197  for (a->mb_x = 0; a->mb_x < a->mb_width; a->mb_x++) {
198  for (a->mb_y = 0; a->mb_y < a->mb_height; a->mb_y++) {
199  if ((ret = decode_mb(a, a->block)) < 0)
200  return ret;
201 
202  idct_put(a, frame.f, a->mb_x, a->mb_y);
203  }
204  }
205 
206  *got_frame = 1;
207 
208  return (get_bits_count(&a->gb) + 31) / 32 * 4;
209 }
210 
212 {
213  MDECContext * const a = avctx->priv_data;
214  int i;
215 
216  a->mb_width = (avctx->coded_width + 15) / 16;
217  a->mb_height = (avctx->coded_height + 15) / 16;
218 
219  a->avctx = avctx;
220 
221  ff_blockdsp_init(&a->bdsp, avctx);
222  ff_bswapdsp_init(&a->bbdsp);
223  ff_idctdsp_init(&a->idsp, avctx);
227 
228  avctx->pix_fmt = AV_PIX_FMT_YUVJ420P;
229  avctx->color_range = AVCOL_RANGE_JPEG;
230 
231  /* init q matrix */
232  for (i = 0; i < 64; i++) {
233  int j = a->idsp.idct_permutation[i];
234 
236  }
237 
238  return 0;
239 }
240 
242 {
243  MDECContext * const a = avctx->priv_data;
244 
246  a->bitstream_buffer_size = 0;
247 
248  return 0;
249 }
250 
252  .name = "mdec",
253  .long_name = NULL_IF_CONFIG_SMALL("Sony PlayStation MDEC (Motion DECoder)"),
254  .type = AVMEDIA_TYPE_VIDEO,
255  .id = AV_CODEC_ID_MDEC,
256  .priv_data_size = sizeof(MDECContext),
257  .init = decode_init,
258  .close = decode_end,
259  .decode = decode_frame,
261 };
static int decode_mb(MDECContext *a, int16_t block[6][64])
Definition: mdec.c:130
AVCodecContext * avctx
Definition: mdec.c:38
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
This structure describes decoded (raw) audio or video data.
Definition: frame.h:314
void(* bswap16_buf)(uint16_t *dst, const uint16_t *src, int len)
Definition: bswapdsp.h:26
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
int coded_width
Bitstream width / height, may be different from width/height e.g.
Definition: avcodec.h:719
float re
Definition: fft.c:82
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
av_cold void ff_mpeg12_init_vlcs(void)
Definition: mpeg12.c:137
AVFrame * f
Definition: thread.h:35
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
ThreadFrame frame
Definition: mdec.c:42
int mb_x
Definition: mdec.c:50
enum AVColorRange color_range
MPEG vs JPEG YUV range.
Definition: avcodec.h:1166
Scantable.
Definition: idctdsp.h:31
int size
Definition: packet.h:364
av_cold void ff_blockdsp_init(BlockDSPContext *c, AVCodecContext *avctx)
Definition: blockdsp.c:60
GetBitContext gb
Definition: mdec.c:43
The reader does not expect b to be semantically here and if the code is changed by maybe adding a a division or other the signedness will almost certainly be mistaken To avoid this confusion a new type was SUINT is the C unsigned type but it holds a signed int to use the same example SUINT a
Definition: undefined.txt:36
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:741
void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size)
Same behaviour av_fast_malloc but the buffer has additional AV_INPUT_BUFFER_PADDING_SIZE at the end w...
Definition: utils.c:72
uint8_t permutated[64]
Definition: idctdsp.h:33
uint8_t run
Definition: svq3.c:204
AVCodec.
Definition: codec.h:190
RLTable.
Definition: rl.h:39
static int get_sbits(GetBitContext *s, int n)
Definition: get_bits.h:359
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
uint8_t
#define av_cold
Definition: attributes.h:88
Multithreading support functions.
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: mdec.c:167
#define DECLARE_ALIGNED(n, t, v)
Declare a variable that is aligned in memory.
Definition: mem.h:112
uint8_t * data
Definition: packet.h:363
int mb_width
Definition: mdec.c:48
static int get_bits_count(const GetBitContext *s)
Definition: get_bits.h:219
int block_last_index[6]
Definition: mdec.c:55
#define AV_CODEC_FLAG_GRAY
Only decode/encode grayscale.
Definition: avcodec.h:308
#define av_log(a,...)
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:849
#define UPDATE_CACHE(name, gb)
Definition: get_bits.h:178
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
int qscale
Definition: mdec.c:46
void(* clear_blocks)(int16_t *blocks)
Definition: blockdsp.h:37
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:153
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:611
BswapDSPContext bbdsp
Definition: mdec.c:40
const char * name
Name of the codec implementation.
Definition: codec.h:197
int16_t block[6][64]
Definition: mdec.c:51
#define CLOSE_READER(name, gb)
Definition: get_bits.h:149
static int decode_dc(GetBitContext *gb, int component)
Definition: mpeg12.h:41
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: codec.h:106
#define GET_RL_VLC(level, run, name, gb, table, bits,max_depth, need_update)
Definition: get_bits.h:738
#define SKIP_BITS(name, gb, num)
Definition: get_bits.h:193
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before as well as code calling up to before the decode process starts Call have so the codec calls ff_thread_report set FF_CODEC_CAP_ALLOCATE_PROGRESS in AVCodec caps_internal and use ff_thread_get_buffer() to allocate frames.The frames must then be freed with ff_thread_release_buffer().Otherwise decode directly into the user-supplied frames.Call ff_thread_report_progress() after some part of the current picture has decoded.A good place to put this is where draw_horiz_band() is called-add this if it isn't called anywhere
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:397
planar YUV 4:2:0, 12bpp, full scale (JPEG), deprecated in favor of AV_PIX_FMT_YUV420P and setting col...
Definition: pixfmt.h:78
RLTable ff_rl_mpeg1
Definition: mpeg12data.c:166
int mb_height
Definition: mdec.c:49
unsigned int bitstream_buffer_size
Definition: mdec.c:54
#define LAST_SKIP_BITS(name, gb, num)
Definition: get_bits.h:199
uint8_t * bitstream_buffer
Definition: mdec.c:53
uint8_t idct_permutation[64]
IDCT input permutation.
Definition: idctdsp.h:96
void(* idct_put)(uint8_t *dest, ptrdiff_t line_size, int16_t *block)
block -> idct -> clip to unsigned 8 bit -> dest.
Definition: idctdsp.h:72
RL_VLC_ELEM * rl_vlc[32]
decoding only
Definition: rl.h:48
#define SHOW_UBITS(name, gb, num)
Definition: get_bits.h:211
Full range content.
Definition: pixfmt.h:586
Libavcodec external API header.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:345
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:677
IDCTDSPContext idsp
Definition: mdec.c:41
ScanTable scantable
Definition: mdec.c:44
main external API structure.
Definition: avcodec.h:531
#define OPEN_READER(name, gb)
Definition: get_bits.h:138
static av_cold int decode_end(AVCodecContext *avctx)
Definition: mdec.c:241
int coded_height
Definition: avcodec.h:719
static void skip_bits(GetBitContext *s, int n)
Definition: get_bits.h:467
static int mdec_decode_block_intra(MDECContext *a, int16_t *block, int n)
Definition: mdec.c:59
const uint16_t ff_mpeg1_default_intra_matrix[256]
Definition: mpeg12data.c:30
const uint8_t ff_zigzag_direct[64]
Definition: mathtables.c:98
uint16_t quant_matrix[64]
Definition: mdec.c:52
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:328
uint8_t level
Definition: svq3.c:205
BlockDSPContext bdsp
Definition: mdec.c:39
#define SHOW_SBITS(name, gb, num)
Definition: get_bits.h:212
#define TEX_VLC_BITS
Definition: dv.h:99
int mb_y
Definition: mdec.c:50
av_cold void ff_bswapdsp_init(BswapDSPContext *c)
Definition: bswapdsp.c:49
void * priv_data
Definition: avcodec.h:558
static av_always_inline int diff(const uint32_t a, const uint32_t b)
av_cold void ff_init_scantable(uint8_t *permutation, ScanTable *st, const uint8_t *src_scantable)
Definition: idctdsp.c:29
av_cold void ff_idctdsp_init(IDCTDSPContext *c, AVCodecContext *avctx)
Definition: idctdsp.c:238
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:392
AVCodec ff_mdec_decoder
Definition: mdec.c:251
static void idct_put(MDECContext *a, AVFrame *frame, int mb_x, int mb_y)
Definition: mdec.c:147
#define av_freep(p)
static av_cold int decode_init(AVCodecContext *avctx)
Definition: mdec.c:211
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
This structure stores compressed data.
Definition: packet.h:340
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:50
int last_dc[3]
Definition: mdec.c:47
int i
Definition: input.c:407
int version
Definition: mdec.c:45