aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec/dv.h
blob: 0205d7234759a3d994a2ba124968ef0ee11f7a3d (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
/*
 * Constants for DV codec
 * Copyright (c) 2002 Fabrice Bellard
 *
 * This file is part of FFmpeg.
 *
 * FFmpeg is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * FFmpeg is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with FFmpeg; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

/**
 * @file
 * Constants for DV codec.
 */

#ifndef AVCODEC_DV_H
#define AVCODEC_DV_H

#include "avcodec.h"
#include "dv_profile.h"
#include "me_cmp.h"
#include "vlc.h"
#include "idctdsp.h"

typedef struct DVwork_chunk {
    uint16_t buf_offset;
    uint16_t mb_coordinates[5];
} DVwork_chunk;

typedef struct DVVideoContext {
    AVClass *avclass;
    const AVDVProfile *sys;
    const AVFrame   *frame;
    AVCodecContext  *avctx;
    uint8_t         *buf;

    uint8_t dv_zigzag[2][64];

    void (*get_pixels)(int16_t *block, const uint8_t *pixels, ptrdiff_t linesize);
    void (*fdct[2])(int16_t *block);
    void (*idct_put[2])(uint8_t *dest, ptrdiff_t stride, int16_t *block);
    me_cmp_func ildct_cmp;
    DVwork_chunk work_chunks[4 * 12 * 27];
    uint32_t idct_factor[2 * 4 * 16 * 64];
    IDCTDSPContext idsp;

    int quant_deadzone;
} DVVideoContext;

enum dv_section_type {
    dv_sect_header  = 0x1f,
    dv_sect_subcode = 0x3f,
    dv_sect_vaux    = 0x56,
    dv_sect_audio   = 0x76,
    dv_sect_video   = 0x96,
};

enum dv_pack_type {
    dv_header525     = 0x3f,  /* see dv_write_pack for important details on */
    dv_header625     = 0xbf,  /* these two packs */
    dv_timecode      = 0x13,
    dv_audio_source  = 0x50,
    dv_audio_control = 0x51,
    dv_audio_recdate = 0x52,
    dv_audio_rectime = 0x53,
    dv_video_source  = 0x60,
    dv_video_control = 0x61,
    dv_video_recdate = 0x62,
    dv_video_rectime = 0x63,
    dv_unknown_pack  = 0xff,
};

#define DV_PROFILE_IS_HD(p) ((p)->video_stype & 0x10)
#define DV_PROFILE_IS_1080i50(p) (((p)->video_stype == 0x14) && ((p)->dsf == 1))
#define DV_PROFILE_IS_1080i60(p) (((p)->video_stype == 0x14) && ((p)->dsf == 0))
#define DV_PROFILE_IS_720p50(p)  (((p)->video_stype == 0x18) && ((p)->dsf == 1))

/**
 * largest possible DV frame, in bytes (1080i50)
 */
#define DV_MAX_FRAME_SIZE 576000

/**
 * maximum number of blocks per macroblock in any DV format
 */
#define DV_MAX_BPM 8

#define TEX_VLC_BITS 10

extern RL_VLC_ELEM ff_dv_rl_vlc[1664];

int ff_dv_init_dynamic_tables(DVVideoContext *s, const AVDVProfile *d);

int ff_dvvideo_init(AVCodecContext *avctx);

static inline int dv_work_pool_size(const AVDVProfile *d)
{
    int size = d->n_difchan * d->difseg_size * 27;
    if (DV_PROFILE_IS_1080i50(d))
        size -= 3 * 27;
    if (DV_PROFILE_IS_720p50(d))
        size -= 4 * 27;
    return size;
}

static inline void dv_calculate_mb_xy(DVVideoContext *s,
                                      DVwork_chunk *work_chunk,
                                      int m, int *mb_x, int *mb_y)
{
    *mb_x = work_chunk->mb_coordinates[m] & 0xff;
    *mb_y = work_chunk->mb_coordinates[m] >> 8;

    /* We work with 720p frames split in half.
     * The odd half-frame (chan == 2,3) is displaced :-( */
    if (s->sys->height == 720 && !(s->buf[1] & 0x0C))
        /* shifting the Y coordinate down by 72/2 macro blocks */
        *mb_y -= (*mb_y > 17) ? 18 : -72;
}

#endif /* AVCODEC_DV_H */