FFmpeg
dv.c
Go to the documentation of this file.
1 /*
2  * DV decoder
3  * Copyright (c) 2002 Fabrice Bellard
4  * Copyright (c) 2004 Roman Shaposhnik
5  *
6  * DV encoder
7  * Copyright (c) 2003 Roman Shaposhnik
8  *
9  * 50 Mbps (DVCPRO50) support
10  * Copyright (c) 2006 Daniel Maas <dmaas@maasdigital.com>
11  *
12  * 100 Mbps (DVCPRO HD) support
13  * Initial code by Daniel Maas <dmaas@maasdigital.com> (funded by BBC R&D)
14  * Final code by Roman Shaposhnik
15  *
16  * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth
17  * of DV technical info.
18  *
19  * This file is part of FFmpeg.
20  *
21  * FFmpeg is free software; you can redistribute it and/or
22  * modify it under the terms of the GNU Lesser General Public
23  * License as published by the Free Software Foundation; either
24  * version 2.1 of the License, or (at your option) any later version.
25  *
26  * FFmpeg is distributed in the hope that it will be useful,
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
29  * Lesser General Public License for more details.
30  *
31  * You should have received a copy of the GNU Lesser General Public
32  * License along with FFmpeg; if not, write to the Free Software
33  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
34  */
35 
36 /**
37  * @file
38  * DV codec.
39  */
40 
41 #include "libavutil/internal.h"
42 #include "libavutil/pixdesc.h"
43 
44 #include "avcodec.h"
45 #include "dv.h"
46 #include "dvdata.h"
47 #include "internal.h"
48 #include "put_bits.h"
49 #include "simple_idct.h"
50 
51 /* XXX: also include quantization */
53 
54 static inline void dv_calc_mb_coordinates(const AVDVProfile *d, int chan,
55  int seq, int slot, uint16_t *tbl)
56 {
57  static const uint8_t off[] = { 2, 6, 8, 0, 4 };
58  static const uint8_t shuf1[] = { 36, 18, 54, 0, 72 };
59  static const uint8_t shuf2[] = { 24, 12, 36, 0, 48 };
60  static const uint8_t shuf3[] = { 18, 9, 27, 0, 36 };
61 
62  static const uint8_t l_start[] = { 0, 4, 9, 13, 18, 22, 27, 31, 36, 40 };
63  static const uint8_t l_start_shuffled[] = { 9, 4, 13, 0, 18 };
64 
65  static const uint8_t serpent1[] = {
66  0, 1, 2, 2, 1, 0,
67  0, 1, 2, 2, 1, 0,
68  0, 1, 2, 2, 1, 0,
69  0, 1, 2, 2, 1, 0,
70  0, 1, 2
71  };
72  static const uint8_t serpent2[] = {
73  0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
74  0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
75  0, 1, 2, 3, 4, 5
76  };
77 
78  static const uint8_t remap[][2] = {
79  { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, /* dummy */
80  { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 10, 0 },
81  { 10, 1 }, { 10, 2 }, { 10, 3 }, { 20, 0 }, { 20, 1 },
82  { 20, 2 }, { 20, 3 }, { 30, 0 }, { 30, 1 }, { 30, 2 },
83  { 30, 3 }, { 40, 0 }, { 40, 1 }, { 40, 2 }, { 40, 3 },
84  { 50, 0 }, { 50, 1 }, { 50, 2 }, { 50, 3 }, { 60, 0 },
85  { 60, 1 }, { 60, 2 }, { 60, 3 }, { 70, 0 }, { 70, 1 },
86  { 70, 2 }, { 70, 3 }, { 0, 64 }, { 0, 65 }, { 0, 66 },
87  { 10, 64 }, { 10, 65 }, { 10, 66 }, { 20, 64 }, { 20, 65 },
88  { 20, 66 }, { 30, 64 }, { 30, 65 }, { 30, 66 }, { 40, 64 },
89  { 40, 65 }, { 40, 66 }, { 50, 64 }, { 50, 65 }, { 50, 66 },
90  { 60, 64 }, { 60, 65 }, { 60, 66 }, { 70, 64 }, { 70, 65 },
91  { 70, 66 }, { 0, 67 }, { 20, 67 }, { 40, 67 }, { 60, 67 }
92  };
93 
94  int i, k, m;
95  int x, y, blk;
96 
97  for (m = 0; m < 5; m++) {
98  switch (d->width) {
99  case 1440:
100  blk = (chan * 11 + seq) * 27 + slot;
101 
102  if (chan == 0 && seq == 11) {
103  x = m * 27 + slot;
104  if (x < 90) {
105  y = 0;
106  } else {
107  x = (x - 90) * 2;
108  y = 67;
109  }
110  } else {
111  i = (4 * chan + blk + off[m]) % 11;
112  k = (blk / 11) % 27;
113 
114  x = shuf1[m] + (chan & 1) * 9 + k % 9;
115  y = (i * 3 + k / 9) * 2 + (chan >> 1) + 1;
116  }
117  tbl[m] = (x << 1) | (y << 9);
118  break;
119  case 1280:
120  blk = (chan * 10 + seq) * 27 + slot;
121 
122  i = (4 * chan + (seq / 5) + 2 * blk + off[m]) % 10;
123  k = (blk / 5) % 27;
124 
125  x = shuf1[m] + (chan & 1) * 9 + k % 9;
126  y = (i * 3 + k / 9) * 2 + (chan >> 1) + 4;
127 
128  if (x >= 80) {
129  x = remap[y][0] + ((x - 80) << (y > 59));
130  y = remap[y][1];
131  }
132  tbl[m] = (x << 1) | (y << 9);
133  break;
134  case 960:
135  blk = (chan * 10 + seq) * 27 + slot;
136 
137  i = (4 * chan + (seq / 5) + 2 * blk + off[m]) % 10;
138  k = (blk / 5) % 27 + (i & 1) * 3;
139 
140  x = shuf2[m] + k % 6 + 6 * (chan & 1);
141  y = l_start[i] + k / 6 + 45 * (chan >> 1);
142  tbl[m] = (x << 1) | (y << 9);
143  break;
144  case 720:
145  switch (d->pix_fmt) {
146  case AV_PIX_FMT_YUV422P:
147  x = shuf3[m] + slot / 3;
148  y = serpent1[slot] +
149  ((((seq + off[m]) % d->difseg_size) << 1) + chan) * 3;
150  tbl[m] = (x << 1) | (y << 8);
151  break;
152  case AV_PIX_FMT_YUV420P:
153  x = shuf3[m] + slot / 3;
154  y = serpent1[slot] +
155  ((seq + off[m]) % d->difseg_size) * 3;
156  tbl[m] = (x << 1) | (y << 9);
157  break;
158  case AV_PIX_FMT_YUV411P:
159  i = (seq + off[m]) % d->difseg_size;
160  k = slot + ((m == 1 || m == 2) ? 3 : 0);
161 
162  x = l_start_shuffled[m] + k / 6;
163  y = serpent2[k] + i * 6;
164  if (x > 21)
165  y = y * 2 - i * 6;
166  tbl[m] = (x << 2) | (y << 8);
167  break;
168  }
169  default:
170  break;
171  }
172  }
173 }
174 
176 {
177  int j, i, c, s, p;
178 
179  p = i = 0;
180  for (c = 0; c < d->n_difchan; c++) {
181  for (s = 0; s < d->difseg_size; s++) {
182  p += 6;
183  for (j = 0; j < 27; j++) {
184  p += !(j % 3);
185  if (!(DV_PROFILE_IS_1080i50(d) && c != 0 && s == 11) &&
186  !(DV_PROFILE_IS_720p50(d) && s > 9)) {
187  dv_calc_mb_coordinates(d, c, s, j, &ctx->work_chunks[i].mb_coordinates[0]);
188  ctx->work_chunks[i++].buf_offset = p;
189  }
190  p += 5;
191  }
192  }
193  }
194 
195  return 0;
196 }
197 
199 {
200  DVVideoContext *s = avctx->priv_data;
201  static int done = 0;
202  int i, j;
203 
204  if (!done) {
205  VLC dv_vlc;
206  uint16_t new_dv_vlc_bits[NB_DV_VLC * 2];
207  uint8_t new_dv_vlc_len[NB_DV_VLC * 2];
208  uint8_t new_dv_vlc_run[NB_DV_VLC * 2];
209  int16_t new_dv_vlc_level[NB_DV_VLC * 2];
210 
211  done = 1;
212 
213  /* it's faster to include sign bit in a generic VLC parsing scheme */
214  for (i = 0, j = 0; i < NB_DV_VLC; i++, j++) {
215  new_dv_vlc_bits[j] = ff_dv_vlc_bits[i];
216  new_dv_vlc_len[j] = ff_dv_vlc_len[i];
217  new_dv_vlc_run[j] = ff_dv_vlc_run[i];
218  new_dv_vlc_level[j] = ff_dv_vlc_level[i];
219 
220  if (ff_dv_vlc_level[i]) {
221  new_dv_vlc_bits[j] <<= 1;
222  new_dv_vlc_len[j]++;
223 
224  j++;
225  new_dv_vlc_bits[j] = (ff_dv_vlc_bits[i] << 1) | 1;
226  new_dv_vlc_len[j] = ff_dv_vlc_len[i] + 1;
227  new_dv_vlc_run[j] = ff_dv_vlc_run[i];
228  new_dv_vlc_level[j] = -ff_dv_vlc_level[i];
229  }
230  }
231 
232  /* NOTE: as a trick, we use the fact the no codes are unused
233  * to accelerate the parsing of partial codes */
234  init_vlc(&dv_vlc, TEX_VLC_BITS, j, new_dv_vlc_len,
235  1, 1, new_dv_vlc_bits, 2, 2, 0);
236  av_assert1(dv_vlc.table_size == 1664);
237 
238  for (i = 0; i < dv_vlc.table_size; i++) {
239  int code = dv_vlc.table[i][0];
240  int len = dv_vlc.table[i][1];
241  int level, run;
242 
243  if (len < 0) { // more bits needed
244  run = 0;
245  level = code;
246  } else {
247  run = new_dv_vlc_run[code] + 1;
248  level = new_dv_vlc_level[code];
249  }
250  ff_dv_rl_vlc[i].len = len;
251  ff_dv_rl_vlc[i].level = level;
252  ff_dv_rl_vlc[i].run = run;
253  }
254  ff_free_vlc(&dv_vlc);
255  }
256 
257  s->avctx = avctx;
259 
260  return 0;
261 }
262 
int table_size
Definition: vlc.h:29
const uint8_t ff_dv_vlc_len[NB_DV_VLC]
Definition: dvdata.c:132
uint8_t run
Definition: svq3.c:206
#define blk(i)
Definition: sha.c:185
#define DV_PROFILE_IS_1080i50(p)
Definition: dv.h:85
AVCodecContext * avctx
Definition: dv.h:45
uint8_t
#define av_cold
Definition: attributes.h:82
Undefined Behavior In the C some operations are like signed integer dereferencing freed accessing outside allocated Undefined Behavior must not occur in a C it is not safe even if the output of undefined operations is unused The unsafety may seem nit picking but Optimizing compilers have in fact optimized code on the assumption that no undefined Behavior occurs Optimizing code based on wrong assumptions can and has in some cases lead to effects beyond the output of computations The signed integer overflow problem in speed critical code Code which is highly optimized and works with signed integers sometimes has the problem that often the output of the computation does not c
Definition: undefined.txt:32
int difseg_size
Definition: dv_profile.h:43
#define DV_PROFILE_IS_720p50(p)
Definition: dv.h:87
enum AVPixelFormat pix_fmt
Definition: dv_profile.h:50
enum AVChromaLocation chroma_sample_location
This defines the location of chroma samples.
Definition: avcodec.h:2210
#define NB_DV_VLC
Definition: dvdata.h:29
const uint16_t ff_dv_vlc_bits[NB_DV_VLC]
Definition: dvdata.c:77
DVwork_chunk work_chunks[4 *12 *27]
Definition: dv.h:54
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
uint16_t mb_coordinates[5]
Definition: dv.h:38
#define init_vlc(vlc, nb_bits, nb_codes,bits, bits_wrap, bits_size,codes, codes_wrap, codes_size,flags)
Definition: vlc.h:38
int8_t len
Definition: vlc.h:34
Definition: vlc.h:26
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
common internal API header
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2.
Definition: pixfmt.h:546
AVFormatContext * ctx
Definition: movenc.c:48
RL_VLC_ELEM ff_dv_rl_vlc[1664]
Definition: dv.c:52
#define s(width, name)
Definition: cbs_vp9.c:257
Libavcodec external API header.
static const int remap[16]
Definition: msvideo1enc.c:63
main external API structure.
Definition: avcodec.h:1568
av_cold int ff_dvvideo_init(AVCodecContext *avctx)
Definition: dv.c:198
and forward the test the status of outputs and forward it to the corresponding return FFERROR_NOT_READY If the filters stores internally one or a few frame for some it can consider them to be part of the FIFO and delay acknowledging a status change accordingly Example code
uint8_t level
Definition: svq3.c:207
uint8_t run
Definition: vlc.h:35
static void dv_calc_mb_coordinates(const AVDVProfile *d, int chan, int seq, int slot, uint16_t *tbl)
Definition: dv.c:54
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
common internal api header.
#define TEX_VLC_BITS
Definition: dv.h:99
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
Constants for DV codec.
int ff_dv_init_dynamic_tables(DVVideoContext *ctx, const AVDVProfile *d)
Definition: dv.c:175
uint16_t buf_offset
Definition: dv.h:37
void * priv_data
Definition: avcodec.h:1595
simple idct header.
int len
VLC_TYPE(* table)[2]
code, bits
Definition: vlc.h:28
int16_t level
Definition: vlc.h:33
const uint8_t ff_dv_vlc_run[NB_DV_VLC]
Definition: dvdata.c:187
int n_difchan
Definition: dv_profile.h:44
void ff_free_vlc(VLC *vlc)
Definition: bitstream.c:359
const uint8_t ff_dv_vlc_level[NB_DV_VLC]
Definition: dvdata.c:242
bitstream writer API