FFmpeg  4.3
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:209
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
x
FFmpeg Automated Testing Environment ************************************Introduction Using FATE from your FFmpeg source directory Submitting the results to the FFmpeg result aggregation server Uploading new samples to the fate suite FATE makefile targets and variables Makefile targets Makefile variables Examples Introduction **************FATE is an extended regression suite on the client side and a means for results aggregation and presentation on the server side The first part of this document explains how you can use FATE from your FFmpeg source directory to test your ffmpeg binary The second part describes how you can run FATE to submit the results to FFmpeg’s FATE server In any way you can have a look at the publicly viewable FATE results by visiting this as it can be seen if some test on some platform broke with their recent contribution This usually happens on the platforms the developers could not test on The second part of this document describes how you can run FATE to submit your results to FFmpeg’s FATE server If you want to submit your results be sure to check that your combination of OS and compiler is not already listed on the above mentioned website In the third part you can find a comprehensive listing of FATE makefile targets and variables Using FATE from your FFmpeg source directory **********************************************If you want to run FATE on your machine you need to have the samples in place You can get the samples via the build target fate rsync Use this command from the top level source this will cause FATE to fail NOTE To use a custom wrapper to run the pass ‘ target exec’ to ‘configure’ or set the TARGET_EXEC Make variable Submitting the results to the FFmpeg result aggregation server ****************************************************************To submit your results to the server you should run fate through the shell script ‘tests fate sh’ from the FFmpeg sources This script needs to be invoked with a configuration file as its first argument tests fate sh path to fate_config A configuration file template with comments describing the individual configuration variables can be found at ‘doc fate_config sh template’ Create a configuration that suits your based on the configuration template The ‘slot’ configuration variable can be any string that is not yet but it is suggested that you name it adhering to the following pattern ‘ARCH OS COMPILER COMPILER VERSION’ The configuration file itself will be sourced in a shell therefore all shell features may be used This enables you to setup the environment as you need it for your build For your first test runs the ‘fate_recv’ variable should be empty or commented out This will run everything as normal except that it will omit the submission of the results to the server The following files should be present in $workdir as specified in the configuration it may help to try out the ‘ssh’ command with one or more ‘ v’ options You should get detailed output concerning your SSH configuration and the authentication process The only thing left is to automate the execution of the fate sh script and the synchronisation of the samples directory Uploading new samples to the fate suite *****************************************If you need a sample uploaded send a mail to samples request This is for developers who have an account on the fate suite server If you upload new please make sure they are as small as space on each network bandwidth and so on benefit from smaller test cases Also keep in mind older checkouts use existing sample that means in practice generally do not remove or overwrite files as it likely would break older checkouts or releases Also all needed samples for a commit should be ideally before the push If you need an account for frequently uploading samples or you wish to help others by doing that send a mail to ffmpeg devel rsync vauL Duo x
Definition: fate.txt:150
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:208
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