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 "avcodec.h"
42 #include "dv.h"
43 
44 static inline void dv_calc_mb_coordinates(const AVDVProfile *d, int chan,
45  int seq, int slot, uint16_t *tbl)
46 {
47  static const uint8_t off[] = { 2, 6, 8, 0, 4 };
48  static const uint8_t shuf1[] = { 36, 18, 54, 0, 72 };
49  static const uint8_t shuf2[] = { 24, 12, 36, 0, 48 };
50  static const uint8_t shuf3[] = { 18, 9, 27, 0, 36 };
51 
52  static const uint8_t l_start[] = { 0, 4, 9, 13, 18, 22, 27, 31, 36, 40 };
53  static const uint8_t l_start_shuffled[] = { 9, 4, 13, 0, 18 };
54 
55  static const uint8_t serpent1[] = {
56  0, 1, 2, 2, 1, 0,
57  0, 1, 2, 2, 1, 0,
58  0, 1, 2, 2, 1, 0,
59  0, 1, 2, 2, 1, 0,
60  0, 1, 2
61  };
62  static const uint8_t serpent2[] = {
63  0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
64  0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0,
65  0, 1, 2, 3, 4, 5
66  };
67 
68  static const uint8_t remap[][2] = {
69  { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, /* dummy */
70  { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 10, 0 },
71  { 10, 1 }, { 10, 2 }, { 10, 3 }, { 20, 0 }, { 20, 1 },
72  { 20, 2 }, { 20, 3 }, { 30, 0 }, { 30, 1 }, { 30, 2 },
73  { 30, 3 }, { 40, 0 }, { 40, 1 }, { 40, 2 }, { 40, 3 },
74  { 50, 0 }, { 50, 1 }, { 50, 2 }, { 50, 3 }, { 60, 0 },
75  { 60, 1 }, { 60, 2 }, { 60, 3 }, { 70, 0 }, { 70, 1 },
76  { 70, 2 }, { 70, 3 }, { 0, 64 }, { 0, 65 }, { 0, 66 },
77  { 10, 64 }, { 10, 65 }, { 10, 66 }, { 20, 64 }, { 20, 65 },
78  { 20, 66 }, { 30, 64 }, { 30, 65 }, { 30, 66 }, { 40, 64 },
79  { 40, 65 }, { 40, 66 }, { 50, 64 }, { 50, 65 }, { 50, 66 },
80  { 60, 64 }, { 60, 65 }, { 60, 66 }, { 70, 64 }, { 70, 65 },
81  { 70, 66 }, { 0, 67 }, { 20, 67 }, { 40, 67 }, { 60, 67 }
82  };
83 
84  int i, k, m;
85  int x, y, blk;
86 
87  for (m = 0; m < 5; m++) {
88  switch (d->width) {
89  case 1440:
90  blk = (chan * 11 + seq) * 27 + slot;
91 
92  if (chan == 0 && seq == 11) {
93  x = m * 27 + slot;
94  if (x < 90) {
95  y = 0;
96  } else {
97  x = (x - 90) * 2;
98  y = 67;
99  }
100  } else {
101  i = (4 * chan + blk + off[m]) % 11;
102  k = (blk / 11) % 27;
103 
104  x = shuf1[m] + (chan & 1) * 9 + k % 9;
105  y = (i * 3 + k / 9) * 2 + (chan >> 1) + 1;
106  }
107  tbl[m] = (x << 1) | (y << 9);
108  break;
109  case 1280:
110  blk = (chan * 10 + seq) * 27 + slot;
111 
112  i = (4 * chan + (seq / 5) + 2 * blk + off[m]) % 10;
113  k = (blk / 5) % 27;
114 
115  x = shuf1[m] + (chan & 1) * 9 + k % 9;
116  y = (i * 3 + k / 9) * 2 + (chan >> 1) + 4;
117 
118  if (x >= 80) {
119  x = remap[y][0] + ((x - 80) << (y > 59));
120  y = remap[y][1];
121  }
122  tbl[m] = (x << 1) | (y << 9);
123  break;
124  case 960:
125  blk = (chan * 10 + seq) * 27 + slot;
126 
127  i = (4 * chan + (seq / 5) + 2 * blk + off[m]) % 10;
128  k = (blk / 5) % 27 + (i & 1) * 3;
129 
130  x = shuf2[m] + k % 6 + 6 * (chan & 1);
131  y = l_start[i] + k / 6 + 45 * (chan >> 1);
132  tbl[m] = (x << 1) | (y << 9);
133  break;
134  case 720:
135  switch (d->pix_fmt) {
136  case AV_PIX_FMT_YUV422P:
137  x = shuf3[m] + slot / 3;
138  y = serpent1[slot] +
139  ((((seq + off[m]) % d->difseg_size) << 1) + chan) * 3;
140  tbl[m] = (x << 1) | (y << 8);
141  break;
142  case AV_PIX_FMT_YUV420P:
143  x = shuf3[m] + slot / 3;
144  y = serpent1[slot] +
145  ((seq + off[m]) % d->difseg_size) * 3;
146  tbl[m] = (x << 1) | (y << 9);
147  break;
148  case AV_PIX_FMT_YUV411P:
149  i = (seq + off[m]) % d->difseg_size;
150  k = slot + ((m == 1 || m == 2) ? 3 : 0);
151 
152  x = l_start_shuffled[m] + k / 6;
153  y = serpent2[k] + i * 6;
154  if (x > 21)
155  y = y * 2 - i * 6;
156  tbl[m] = (x << 2) | (y << 8);
157  break;
158  }
159  default:
160  break;
161  }
162  }
163 }
164 
166 {
167  int j, i, c, s, p;
168 
169  p = i = 0;
170  for (c = 0; c < d->n_difchan; c++) {
171  for (s = 0; s < d->difseg_size; s++) {
172  p += 6;
173  for (j = 0; j < 27; j++) {
174  p += !(j % 3);
175  if (!(DV_PROFILE_IS_1080i50(d) && c != 0 && s == 11) &&
176  !(DV_PROFILE_IS_720p50(d) && s > 9)) {
177  dv_calc_mb_coordinates(d, c, s, j, &ctx->work_chunks[i].mb_coordinates[0]);
178  ctx->work_chunks[i++].buf_offset = p;
179  }
180  p += 5;
181  }
182  }
183  }
184 
185  return 0;
186 }
187 
189 {
190  DVVideoContext *s = avctx->priv_data;
191 
192  s->avctx = avctx;
194 
195  return 0;
196 }
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:44
DV_PROFILE_IS_1080i50
#define DV_PROFILE_IS_1080i50(p)
Definition: dv.h:84
ff_dv_init_dynamic_tables
int ff_dv_init_dynamic_tables(DVVideoContext *ctx, const AVDVProfile *d)
Definition: dv.c:165
av_cold
#define av_cold
Definition: attributes.h:90
s
#define s(width, name)
Definition: cbs_vp9.c:256
ctx
AVFormatContext * ctx
Definition: movenc.c:48
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:186
DV_PROFILE_IS_720p50
#define DV_PROFILE_IS_720p50(p)
Definition: dv.h:86
AVCHROMA_LOC_TOPLEFT
@ AVCHROMA_LOC_TOPLEFT
ITU-R 601, SMPTE 274M 296M S314M(DV 4:1:1), mpeg2 4:2:2.
Definition: pixfmt.h:622
DVVideoContext
Definition: dv.h:40
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
dv.h
remap
static const int remap[16]
Definition: msvideo1enc.c:65
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
AVCodecContext::chroma_sample_location
enum AVChromaLocation chroma_sample_location
This defines the location of chroma samples.
Definition: avcodec.h:980
avcodec.h
AVCodecContext
main external API structure.
Definition: avcodec.h:389
AVDVProfile
Definition: dv_profile.h:38
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:188
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:416
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
d
d
Definition: ffmpeg_filter.c:153