1cabdff1aSopenharmony_ci/* 2cabdff1aSopenharmony_ci * DV decoder 3cabdff1aSopenharmony_ci * Copyright (c) 2002 Fabrice Bellard 4cabdff1aSopenharmony_ci * Copyright (c) 2004 Roman Shaposhnik 5cabdff1aSopenharmony_ci * 6cabdff1aSopenharmony_ci * DV encoder 7cabdff1aSopenharmony_ci * Copyright (c) 2003 Roman Shaposhnik 8cabdff1aSopenharmony_ci * 9cabdff1aSopenharmony_ci * 50 Mbps (DVCPRO50) support 10cabdff1aSopenharmony_ci * Copyright (c) 2006 Daniel Maas <dmaas@maasdigital.com> 11cabdff1aSopenharmony_ci * 12cabdff1aSopenharmony_ci * 100 Mbps (DVCPRO HD) support 13cabdff1aSopenharmony_ci * Initial code by Daniel Maas <dmaas@maasdigital.com> (funded by BBC R&D) 14cabdff1aSopenharmony_ci * Final code by Roman Shaposhnik 15cabdff1aSopenharmony_ci * 16cabdff1aSopenharmony_ci * Many thanks to Dan Dennedy <dan@dennedy.org> for providing wealth 17cabdff1aSopenharmony_ci * of DV technical info. 18cabdff1aSopenharmony_ci * 19cabdff1aSopenharmony_ci * This file is part of FFmpeg. 20cabdff1aSopenharmony_ci * 21cabdff1aSopenharmony_ci * FFmpeg is free software; you can redistribute it and/or 22cabdff1aSopenharmony_ci * modify it under the terms of the GNU Lesser General Public 23cabdff1aSopenharmony_ci * License as published by the Free Software Foundation; either 24cabdff1aSopenharmony_ci * version 2.1 of the License, or (at your option) any later version. 25cabdff1aSopenharmony_ci * 26cabdff1aSopenharmony_ci * FFmpeg is distributed in the hope that it will be useful, 27cabdff1aSopenharmony_ci * but WITHOUT ANY WARRANTY; without even the implied warranty of 28cabdff1aSopenharmony_ci * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 29cabdff1aSopenharmony_ci * Lesser General Public License for more details. 30cabdff1aSopenharmony_ci * 31cabdff1aSopenharmony_ci * You should have received a copy of the GNU Lesser General Public 32cabdff1aSopenharmony_ci * License along with FFmpeg; if not, write to the Free Software 33cabdff1aSopenharmony_ci * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 34cabdff1aSopenharmony_ci */ 35cabdff1aSopenharmony_ci 36cabdff1aSopenharmony_ci/** 37cabdff1aSopenharmony_ci * @file 38cabdff1aSopenharmony_ci * DV codec. 39cabdff1aSopenharmony_ci */ 40cabdff1aSopenharmony_ci 41cabdff1aSopenharmony_ci#include "avcodec.h" 42cabdff1aSopenharmony_ci#include "dv.h" 43cabdff1aSopenharmony_ci 44cabdff1aSopenharmony_cistatic inline void dv_calc_mb_coordinates(const AVDVProfile *d, int chan, 45cabdff1aSopenharmony_ci int seq, int slot, uint16_t *tbl) 46cabdff1aSopenharmony_ci{ 47cabdff1aSopenharmony_ci static const uint8_t off[] = { 2, 6, 8, 0, 4 }; 48cabdff1aSopenharmony_ci static const uint8_t shuf1[] = { 36, 18, 54, 0, 72 }; 49cabdff1aSopenharmony_ci static const uint8_t shuf2[] = { 24, 12, 36, 0, 48 }; 50cabdff1aSopenharmony_ci static const uint8_t shuf3[] = { 18, 9, 27, 0, 36 }; 51cabdff1aSopenharmony_ci 52cabdff1aSopenharmony_ci static const uint8_t l_start[] = { 0, 4, 9, 13, 18, 22, 27, 31, 36, 40 }; 53cabdff1aSopenharmony_ci static const uint8_t l_start_shuffled[] = { 9, 4, 13, 0, 18 }; 54cabdff1aSopenharmony_ci 55cabdff1aSopenharmony_ci static const uint8_t serpent1[] = { 56cabdff1aSopenharmony_ci 0, 1, 2, 2, 1, 0, 57cabdff1aSopenharmony_ci 0, 1, 2, 2, 1, 0, 58cabdff1aSopenharmony_ci 0, 1, 2, 2, 1, 0, 59cabdff1aSopenharmony_ci 0, 1, 2, 2, 1, 0, 60cabdff1aSopenharmony_ci 0, 1, 2 61cabdff1aSopenharmony_ci }; 62cabdff1aSopenharmony_ci static const uint8_t serpent2[] = { 63cabdff1aSopenharmony_ci 0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0, 64cabdff1aSopenharmony_ci 0, 1, 2, 3, 4, 5, 5, 4, 3, 2, 1, 0, 65cabdff1aSopenharmony_ci 0, 1, 2, 3, 4, 5 66cabdff1aSopenharmony_ci }; 67cabdff1aSopenharmony_ci 68cabdff1aSopenharmony_ci static const uint8_t remap[][2] = { 69cabdff1aSopenharmony_ci { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, /* dummy */ 70cabdff1aSopenharmony_ci { 0, 0 }, { 0, 1 }, { 0, 2 }, { 0, 3 }, { 10, 0 }, 71cabdff1aSopenharmony_ci { 10, 1 }, { 10, 2 }, { 10, 3 }, { 20, 0 }, { 20, 1 }, 72cabdff1aSopenharmony_ci { 20, 2 }, { 20, 3 }, { 30, 0 }, { 30, 1 }, { 30, 2 }, 73cabdff1aSopenharmony_ci { 30, 3 }, { 40, 0 }, { 40, 1 }, { 40, 2 }, { 40, 3 }, 74cabdff1aSopenharmony_ci { 50, 0 }, { 50, 1 }, { 50, 2 }, { 50, 3 }, { 60, 0 }, 75cabdff1aSopenharmony_ci { 60, 1 }, { 60, 2 }, { 60, 3 }, { 70, 0 }, { 70, 1 }, 76cabdff1aSopenharmony_ci { 70, 2 }, { 70, 3 }, { 0, 64 }, { 0, 65 }, { 0, 66 }, 77cabdff1aSopenharmony_ci { 10, 64 }, { 10, 65 }, { 10, 66 }, { 20, 64 }, { 20, 65 }, 78cabdff1aSopenharmony_ci { 20, 66 }, { 30, 64 }, { 30, 65 }, { 30, 66 }, { 40, 64 }, 79cabdff1aSopenharmony_ci { 40, 65 }, { 40, 66 }, { 50, 64 }, { 50, 65 }, { 50, 66 }, 80cabdff1aSopenharmony_ci { 60, 64 }, { 60, 65 }, { 60, 66 }, { 70, 64 }, { 70, 65 }, 81cabdff1aSopenharmony_ci { 70, 66 }, { 0, 67 }, { 20, 67 }, { 40, 67 }, { 60, 67 } 82cabdff1aSopenharmony_ci }; 83cabdff1aSopenharmony_ci 84cabdff1aSopenharmony_ci int i, k, m; 85cabdff1aSopenharmony_ci int x, y, blk; 86cabdff1aSopenharmony_ci 87cabdff1aSopenharmony_ci for (m = 0; m < 5; m++) { 88cabdff1aSopenharmony_ci switch (d->width) { 89cabdff1aSopenharmony_ci case 1440: 90cabdff1aSopenharmony_ci blk = (chan * 11 + seq) * 27 + slot; 91cabdff1aSopenharmony_ci 92cabdff1aSopenharmony_ci if (chan == 0 && seq == 11) { 93cabdff1aSopenharmony_ci x = m * 27 + slot; 94cabdff1aSopenharmony_ci if (x < 90) { 95cabdff1aSopenharmony_ci y = 0; 96cabdff1aSopenharmony_ci } else { 97cabdff1aSopenharmony_ci x = (x - 90) * 2; 98cabdff1aSopenharmony_ci y = 67; 99cabdff1aSopenharmony_ci } 100cabdff1aSopenharmony_ci } else { 101cabdff1aSopenharmony_ci i = (4 * chan + blk + off[m]) % 11; 102cabdff1aSopenharmony_ci k = (blk / 11) % 27; 103cabdff1aSopenharmony_ci 104cabdff1aSopenharmony_ci x = shuf1[m] + (chan & 1) * 9 + k % 9; 105cabdff1aSopenharmony_ci y = (i * 3 + k / 9) * 2 + (chan >> 1) + 1; 106cabdff1aSopenharmony_ci } 107cabdff1aSopenharmony_ci tbl[m] = (x << 1) | (y << 9); 108cabdff1aSopenharmony_ci break; 109cabdff1aSopenharmony_ci case 1280: 110cabdff1aSopenharmony_ci blk = (chan * 10 + seq) * 27 + slot; 111cabdff1aSopenharmony_ci 112cabdff1aSopenharmony_ci i = (4 * chan + (seq / 5) + 2 * blk + off[m]) % 10; 113cabdff1aSopenharmony_ci k = (blk / 5) % 27; 114cabdff1aSopenharmony_ci 115cabdff1aSopenharmony_ci x = shuf1[m] + (chan & 1) * 9 + k % 9; 116cabdff1aSopenharmony_ci y = (i * 3 + k / 9) * 2 + (chan >> 1) + 4; 117cabdff1aSopenharmony_ci 118cabdff1aSopenharmony_ci if (x >= 80) { 119cabdff1aSopenharmony_ci x = remap[y][0] + ((x - 80) << (y > 59)); 120cabdff1aSopenharmony_ci y = remap[y][1]; 121cabdff1aSopenharmony_ci } 122cabdff1aSopenharmony_ci tbl[m] = (x << 1) | (y << 9); 123cabdff1aSopenharmony_ci break; 124cabdff1aSopenharmony_ci case 960: 125cabdff1aSopenharmony_ci blk = (chan * 10 + seq) * 27 + slot; 126cabdff1aSopenharmony_ci 127cabdff1aSopenharmony_ci i = (4 * chan + (seq / 5) + 2 * blk + off[m]) % 10; 128cabdff1aSopenharmony_ci k = (blk / 5) % 27 + (i & 1) * 3; 129cabdff1aSopenharmony_ci 130cabdff1aSopenharmony_ci x = shuf2[m] + k % 6 + 6 * (chan & 1); 131cabdff1aSopenharmony_ci y = l_start[i] + k / 6 + 45 * (chan >> 1); 132cabdff1aSopenharmony_ci tbl[m] = (x << 1) | (y << 9); 133cabdff1aSopenharmony_ci break; 134cabdff1aSopenharmony_ci case 720: 135cabdff1aSopenharmony_ci switch (d->pix_fmt) { 136cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV422P: 137cabdff1aSopenharmony_ci x = shuf3[m] + slot / 3; 138cabdff1aSopenharmony_ci y = serpent1[slot] + 139cabdff1aSopenharmony_ci ((((seq + off[m]) % d->difseg_size) << 1) + chan) * 3; 140cabdff1aSopenharmony_ci tbl[m] = (x << 1) | (y << 8); 141cabdff1aSopenharmony_ci break; 142cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV420P: 143cabdff1aSopenharmony_ci x = shuf3[m] + slot / 3; 144cabdff1aSopenharmony_ci y = serpent1[slot] + 145cabdff1aSopenharmony_ci ((seq + off[m]) % d->difseg_size) * 3; 146cabdff1aSopenharmony_ci tbl[m] = (x << 1) | (y << 9); 147cabdff1aSopenharmony_ci break; 148cabdff1aSopenharmony_ci case AV_PIX_FMT_YUV411P: 149cabdff1aSopenharmony_ci i = (seq + off[m]) % d->difseg_size; 150cabdff1aSopenharmony_ci k = slot + ((m == 1 || m == 2) ? 3 : 0); 151cabdff1aSopenharmony_ci 152cabdff1aSopenharmony_ci x = l_start_shuffled[m] + k / 6; 153cabdff1aSopenharmony_ci y = serpent2[k] + i * 6; 154cabdff1aSopenharmony_ci if (x > 21) 155cabdff1aSopenharmony_ci y = y * 2 - i * 6; 156cabdff1aSopenharmony_ci tbl[m] = (x << 2) | (y << 8); 157cabdff1aSopenharmony_ci break; 158cabdff1aSopenharmony_ci } 159cabdff1aSopenharmony_ci default: 160cabdff1aSopenharmony_ci break; 161cabdff1aSopenharmony_ci } 162cabdff1aSopenharmony_ci } 163cabdff1aSopenharmony_ci} 164cabdff1aSopenharmony_ci 165cabdff1aSopenharmony_ciint ff_dv_init_dynamic_tables(DVVideoContext *ctx, const AVDVProfile *d) 166cabdff1aSopenharmony_ci{ 167cabdff1aSopenharmony_ci int j, i, c, s, p; 168cabdff1aSopenharmony_ci 169cabdff1aSopenharmony_ci p = i = 0; 170cabdff1aSopenharmony_ci for (c = 0; c < d->n_difchan; c++) { 171cabdff1aSopenharmony_ci for (s = 0; s < d->difseg_size; s++) { 172cabdff1aSopenharmony_ci p += 6; 173cabdff1aSopenharmony_ci for (j = 0; j < 27; j++) { 174cabdff1aSopenharmony_ci p += !(j % 3); 175cabdff1aSopenharmony_ci if (!(DV_PROFILE_IS_1080i50(d) && c != 0 && s == 11) && 176cabdff1aSopenharmony_ci !(DV_PROFILE_IS_720p50(d) && s > 9)) { 177cabdff1aSopenharmony_ci dv_calc_mb_coordinates(d, c, s, j, &ctx->work_chunks[i].mb_coordinates[0]); 178cabdff1aSopenharmony_ci ctx->work_chunks[i++].buf_offset = p; 179cabdff1aSopenharmony_ci } 180cabdff1aSopenharmony_ci p += 5; 181cabdff1aSopenharmony_ci } 182cabdff1aSopenharmony_ci } 183cabdff1aSopenharmony_ci } 184cabdff1aSopenharmony_ci 185cabdff1aSopenharmony_ci return 0; 186cabdff1aSopenharmony_ci} 187cabdff1aSopenharmony_ci 188cabdff1aSopenharmony_ciav_cold int ff_dvvideo_init(AVCodecContext *avctx) 189cabdff1aSopenharmony_ci{ 190cabdff1aSopenharmony_ci DVVideoContext *s = avctx->priv_data; 191cabdff1aSopenharmony_ci 192cabdff1aSopenharmony_ci s->avctx = avctx; 193cabdff1aSopenharmony_ci avctx->chroma_sample_location = AVCHROMA_LOC_TOPLEFT; 194cabdff1aSopenharmony_ci 195cabdff1aSopenharmony_ci return 0; 196cabdff1aSopenharmony_ci} 197