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 44static 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 165int ff_dv_init_dynamic_tables(DVVideoContext *ctx, const AVDVProfile *d) 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 188av_cold int ff_dvvideo_init(AVCodecContext *avctx) 189{ 190 DVVideoContext *s = avctx->priv_data; 191 192 s->avctx = avctx; 193 avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT; 194 195 return 0; 196} 197