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;
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 
level
uint8_t level
Definition: svq3.c:210
NB_DV_VLC
#define NB_DV_VLC
Definition: dvdata.h:29
pixdesc.h
internal.h
init_vlc
#define init_vlc(vlc, nb_bits, nb_codes, bits, bits_wrap, bits_size, codes, codes_wrap, codes_size, flags)
Definition: vlc.h:38
RL_VLC_ELEM::run
uint8_t run
Definition: vlc.h:35
dv_calc_mb_coordinates
static void dv_calc_mb_coordinates(const AVDVProfile *d, int chan, int seq, int slot, uint16_t *tbl)
Definition: dv.c:54
AVDVProfile::difseg_size
int difseg_size
Definition: dv_profile.h:43
ff_dv_rl_vlc
RL_VLC_ELEM ff_dv_rl_vlc[1664]
Definition: dv.c:52
DV_PROFILE_IS_1080i50
#define DV_PROFILE_IS_1080i50(p)
Definition: dv.h:85
ff_dv_init_dynamic_tables
int ff_dv_init_dynamic_tables(DVVideoContext *ctx, const AVDVProfile *d)
Definition: dv.c:175
av_cold
#define av_cold
Definition: attributes.h:90
s
#define s(width, name)
Definition: cbs_vp9.c:257
ctx
AVFormatContext * ctx
Definition: movenc.c:48
AVDVProfile::pix_fmt
enum AVPixelFormat pix_fmt
Definition: dv_profile.h:50
simple_idct.h
ff_free_vlc
void ff_free_vlc(VLC *vlc)
Definition: bitstream.c:359
AV_PIX_FMT_YUV420P
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition: pixfmt.h:66
blk
#define blk(i)
Definition: sha.c:185
DV_PROFILE_IS_720p50
#define DV_PROFILE_IS_720p50(p)
Definition: dv.h:87
run
uint8_t run
Definition: svq3.c:209
AVDVProfile::n_difchan
int n_difchan
Definition: dv_profile.h:44
AVCHROMA_LOC_TOPLEFT
@ AVCHROMA_LOC_TOPLEFT
ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2.
Definition: pixfmt.h:558
DVVideoContext
Definition: dv.h:41
c
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
RL_VLC_ELEM::len
int8_t len
Definition: vlc.h:34
dv.h
RL_VLC_ELEM
Definition: vlc.h:32
remap
static const int remap[16]
Definition: msvideo1enc.c:63
ff_dv_vlc_level
const uint8_t ff_dv_vlc_level[NB_DV_VLC]
Definition: dvdata.c:242
ff_dv_vlc_run
const uint8_t ff_dv_vlc_run[NB_DV_VLC]
Definition: dvdata.c:187
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
code
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
Definition: filter_design.txt:178
ff_dv_vlc_bits
const uint16_t ff_dv_vlc_bits[NB_DV_VLC]
Definition: dvdata.c:77
internal.h
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:53
TEX_VLC_BITS
#define TEX_VLC_BITS
Definition: dv.h:99
AVDVProfile::width
int width
Definition: dv_profile.h:48
uint8_t
uint8_t
Definition: audio_convert.c:194
AVCodecContext::chroma_sample_location
enum AVChromaLocation chroma_sample_location
This defines the location of chroma samples.
Definition: avcodec.h:1168
len
int len
Definition: vorbis_enc_data.h:452
avcodec.h
ff_dv_vlc_len
const uint8_t ff_dv_vlc_len[NB_DV_VLC]
Definition: dvdata.c:132
AVCodecContext
main external API structure.
Definition: avcodec.h:526
VLC
Definition: vlc.h:26
AVDVProfile
Definition: dv_profile.h:39
VLC::table_size
int table_size
Definition: vlc.h:29
AV_PIX_FMT_YUV422P
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition: pixfmt.h:70
ff_dvvideo_init
av_cold int ff_dvvideo_init(AVCodecContext *avctx)
Definition: dv.c:198
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:553
AV_PIX_FMT_YUV411P
@ AV_PIX_FMT_YUV411P
planar YUV 4:1:1, 12bpp, (1 Cr & Cb sample per 4x1 Y samples)
Definition: pixfmt.h:73
put_bits.h
VLC::table
VLC_TYPE(* table)[2]
code, bits
Definition: vlc.h:28
RL_VLC_ELEM::level
int16_t level
Definition: vlc.h:33
dvdata.h