FFmpeg
ffv1.c
Go to the documentation of this file.
1 /*
2  * FFV1 codec for libavcodec
3  *
4  * Copyright (c) 2003-2013 Michael Niedermayer <michaelni@gmx.at>
5  *
6  * This file is part of FFmpeg.
7  *
8  * FFmpeg is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public
10  * License as published by the Free Software Foundation; either
11  * version 2.1 of the License, or (at your option) any later version.
12  *
13  * FFmpeg is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with FFmpeg; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  */
22 
23 /**
24  * @file
25  * FF Video Codec 1 (a lossless codec)
26  */
27 
28 #include "libavutil/attributes.h"
29 #include "libavutil/avassert.h"
30 #include "libavutil/mem.h"
31 
32 #include "avcodec.h"
33 #include "ffv1.h"
34 #include "libavutil/refstruct.h"
35 
37 {
38  if (!avctx->width || !avctx->height)
39  return AVERROR_INVALIDDATA;
40 
41  s->avctx = avctx;
42  s->flags = avctx->flags;
43 
44  s->width = avctx->width;
45  s->height = avctx->height;
46 
47  // defaults
48  s->num_h_slices = 1;
49  s->num_v_slices = 1;
50 
51  return 0;
52 }
53 
54 static void planes_free(AVRefStructOpaque opaque, void *obj)
55 {
56  PlaneContext *planes = obj;
57 
58  for (int i = 0; i < MAX_PLANES; i++) {
59  PlaneContext *p = &planes[i];
60 
61  av_freep(&p->state);
62  av_freep(&p->vlc_state);
63  }
64 }
65 
67 {
69  0, NULL, planes_free);
70 }
71 
73  FFV1SliceContext *sc)
74 {
75  int j, i;
76 
77  for (j = 0; j < f->plane_count; j++) {
78  PlaneContext *const p = &sc->plane[j];
79 
80  if (f->ac != AC_GOLOMB_RICE) {
81  if (!p->state)
82  p->state = av_calloc(p->context_count, CONTEXT_SIZE *
83  sizeof(uint8_t));
84  if (!p->state)
85  return AVERROR(ENOMEM);
86  } else {
87  if (!p->vlc_state) {
88  p->vlc_state = av_calloc(p->context_count, sizeof(*p->vlc_state));
89  if (!p->vlc_state)
90  return AVERROR(ENOMEM);
91  for (i = 0; i < p->context_count; i++) {
92  p->vlc_state[i].error_sum = 4;
93  p->vlc_state[i].count = 1;
94  }
95  }
96  }
97  }
98 
99  if (f->ac == AC_RANGE_CUSTOM_TAB) {
100  //FIXME only redo if state_transition changed
101  for (j = 1; j < 256; j++) {
102  sc->c. one_state[ j] = f->state_transition[j];
103  sc->c.zero_state[256 - j] = 256 - sc->c.one_state[j];
104  }
105  }
106 
107  return 0;
108 }
109 
111 {
112  int i, ret;
113  for (i = 0; i < f->max_slice_count; i++) {
114  if ((ret = ff_ffv1_init_slice_state(f, &f->slices[i])) < 0)
115  return AVERROR(ENOMEM);
116  }
117  return 0;
118 }
119 
120 int ff_need_new_slices(int width, int num_h_slices, int chroma_shift) {
121  int mpw = 1<<chroma_shift;
122  int i = width * (int64_t)(num_h_slices - 1) / num_h_slices;
123 
124  return width % mpw && (width - i) % mpw == 0;
125 }
126 
127 int ff_slice_coord(const FFV1Context *f, int width, int sx, int num_h_slices, int chroma_shift) {
128  int mpw = 1<<chroma_shift;
129  if (f->bayer)
130  mpw = FFMAX(mpw, 2);
131  int awidth = FFALIGN(width, mpw);
132 
133  if (f->combined_version <= 0x40002)
134  return width * sx / num_h_slices;
135 
136  sx = (2LL * awidth * sx + num_h_slices * mpw) / (2 * num_h_slices * mpw) * mpw;
137  if (sx == awidth)
138  sx = width;
139  return sx;
140 }
141 
143 {
144  int max_slice_count = f->num_h_slices * f->num_v_slices;
145 
146  av_assert0(max_slice_count > 0);
147 
148  f->slices = av_calloc(max_slice_count, sizeof(*f->slices));
149  if (!f->slices)
150  return AVERROR(ENOMEM);
151 
152  f->max_slice_count = max_slice_count;
153 
154  for (int i = 0; i < max_slice_count; i++) {
155  FFV1SliceContext *sc = &f->slices[i];
156  int sx = i % f->num_h_slices;
157  int sy = i / f->num_h_slices;
158  int sxs = ff_slice_coord(f, f->avctx->width , sx , f->num_h_slices, f->chroma_h_shift);
159  int sxe = ff_slice_coord(f, f->avctx->width , sx + 1, f->num_h_slices, f->chroma_h_shift);
160  int sys = ff_slice_coord(f, f->avctx->height, sy , f->num_v_slices, f->chroma_v_shift);
161  int sye = ff_slice_coord(f, f->avctx->height, sy + 1, f->num_v_slices, f->chroma_v_shift);
162 
163  sc->slice_width = sxe - sxs;
164  sc->slice_height = sye - sys;
165  sc->slice_x = sxs;
166  sc->slice_y = sys;
167  sc->sx = sx;
168  sc->sy = sy;
169 
170  sc->sample_buffer = av_malloc_array((f->width + 6), 3 * MAX_PLANES *
171  sizeof(*sc->sample_buffer));
172  sc->sample_buffer32 = av_malloc_array((f->width + 6), 3 * MAX_PLANES *
173  sizeof(*sc->sample_buffer32));
174  if (!sc->sample_buffer || !sc->sample_buffer32)
175  return AVERROR(ENOMEM);
176 
177  sc->plane = ff_ffv1_planes_alloc();
178  if (!sc->plane)
179  return AVERROR(ENOMEM);
180  }
181 
182  return 0;
183 }
184 
186 {
187  int i;
188 
189  for (i = 0; i < f->quant_table_count; i++) {
190  f->initial_states[i] = av_malloc_array(f->context_count[i],
191  sizeof(*f->initial_states[i]));
192  if (!f->initial_states[i])
193  return AVERROR(ENOMEM);
194  memset(f->initial_states[i], 128,
195  f->context_count[i] * sizeof(*f->initial_states[i]));
196  }
197  return 0;
198 }
199 
201 {
202  int i, j;
203 
204  for (i = 0; i < f->plane_count; i++) {
205  PlaneContext *p = &sc->plane[i];
206 
207  if (f->ac != AC_GOLOMB_RICE) {
208  if (f->initial_states[p->quant_table_index]) {
209  memcpy(p->state, f->initial_states[p->quant_table_index],
210  CONTEXT_SIZE * p->context_count);
211  } else
212  memset(p->state, 128, CONTEXT_SIZE * p->context_count);
213  } else {
214  for (j = 0; j < p->context_count; j++) {
215  p->vlc_state[j].drift = 0;
216  p->vlc_state[j].error_sum = 4; //FFMAX((RANGE + 32)/64, 2);
217  p->vlc_state[j].bias = 0;
218  p->vlc_state[j].count = 1;
219  }
220  }
221  }
222 }
223 
224 void ff_ffv1_compute_bits_per_plane(const FFV1Context *f, FFV1SliceContext *sc, int bits[4], int *offset, int mask[4], int bits_per_raw_sample)
225 {
226  // to simplify we use the remap_count as the symbol range in each plane
227  if (!sc->remap) {
228  sc->remap_count[0] =
229  sc->remap_count[1] =
230  sc->remap_count[2] =
231  sc->remap_count[3] = 1 << (bits_per_raw_sample > 0 ? bits_per_raw_sample : 8);
232  }
233 
234  if (sc->remap)
235  av_assert0(bits_per_raw_sample > 8); //breaks with lbd, needs review if added
236 
237  //bits with no RCT
238  for (int p=0; p<3+f->transparency+f->bayer; p++) {
239  bits[p] = av_ceil_log2(sc->remap_count[p]);
240  if (mask)
241  mask[p] = (1<<bits[p]) - 1;
242  }
243 
244  //RCT
245  if (sc->slice_coding_mode == 0) {
246  *offset = sc->remap_count[0];
247 
248  bits[0] = av_ceil_log2(FFMAX3(sc->remap_count[0], sc->remap_count[1], sc->remap_count[2]));
249  bits[1] = av_ceil_log2(sc->remap_count[0] + sc->remap_count[1]);
250  bits[2] = av_ceil_log2(sc->remap_count[0] + sc->remap_count[2]);
251  if (f->bayer)
252  bits[3] = av_ceil_log2(sc->remap_count[0] + sc->remap_count[3]);
253 
254  //old version coded a bit more than needed
255  if (f->combined_version < 0x40008) {
256  bits[0]++;
257  if(f->transparency)
258  bits[3]++;
259  }
260  }
261 }
262 
263 int ff_ffv1_get_symbol(RangeCoder *c, uint8_t *state, int is_signed)
264 {
265  return get_symbol_inline(c, state, is_signed);
266 }
267 
269 {
270  int i, j;
271 
272  for (j = 0; j < s->max_slice_count; j++) {
273  FFV1SliceContext *sc = &s->slices[j];
274 
275  av_freep(&sc->sample_buffer);
277  for(int p = 0; p < 4 ; p++) {
278  av_freep(&sc->fltmap[p]);
279  av_freep(&sc->fltmap32[p]);
280  sc->fltmap_size [p] = 0;
281  sc->fltmap32_size[p] = 0;
282  }
283 
285  }
286 
287  av_refstruct_unref(&s->slice_damaged);
288 
289  for (j = 0; j < s->quant_table_count; j++) {
290  av_freep(&s->initial_states[j]);
291  for (i = 0; i < s->max_slice_count; i++) {
292  FFV1SliceContext *sc = &s->slices[i];
293  av_freep(&sc->rc_stat2[j]);
294  }
295  av_freep(&s->rc_stat2[j]);
296  }
297 
298  av_freep(&s->slices);
299 }
FFV1SliceContext::slice_height
int slice_height
Definition: ffv1.h:78
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
AVRefStructOpaque
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition: refstruct.h:58
FFV1SliceContext::plane
PlaneContext * plane
Definition: ffv1.h:90
state
static struct @584 state
int64_t
long long int64_t
Definition: coverity.c:34
mask
int mask
Definition: mediacodecdec_common.c:154
FFV1SliceContext::fltmap_size
unsigned int fltmap_size[4]
Definition: ffv1.h:114
FFMAX
#define FFMAX(a, b)
Definition: macros.h:47
AC_RANGE_CUSTOM_TAB
#define AC_RANGE_CUSTOM_TAB
Definition: ffv1.h:54
FFV1SliceContext::slice_x
int slice_x
Definition: ffv1.h:79
ff_ffv1_clear_slice_state
void ff_ffv1_clear_slice_state(const FFV1Context *f, FFV1SliceContext *sc)
Definition: ffv1.c:200
ff_ffv1_init_slices_state
av_cold int ff_ffv1_init_slices_state(FFV1Context *f)
Definition: ffv1.c:110
av_ceil_log2
#define av_ceil_log2
Definition: common.h:97
planes_free
static void planes_free(AVRefStructOpaque opaque, void *obj)
Definition: ffv1.c:54
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:500
CONTEXT_SIZE
#define CONTEXT_SIZE
Definition: ffv1.h:45
refstruct.h
avassert.h
av_cold
#define av_cold
Definition: attributes.h:119
FFV1SliceContext::sample_buffer
int16_t * sample_buffer
Definition: ffv1.h:74
RangeCoder::one_state
uint8_t one_state[256]
Definition: rangecoder.h:41
s
#define s(width, name)
Definition: cbs_vp9.c:198
MAX_PLANES
#define MAX_PLANES
Definition: ffv1.h:44
bits
uint8_t bits
Definition: vp3data.h:128
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:42
av_refstruct_alloc_ext
static void * av_refstruct_alloc_ext(size_t size, unsigned flags, void *opaque, void(*free_cb)(AVRefStructOpaque opaque, void *obj))
A wrapper around av_refstruct_alloc_ext_c() for the common case of a non-const qualified opaque.
Definition: refstruct.h:94
FFV1SliceContext::fltmap32_size
unsigned int fltmap32_size[4]
Definition: ffv1.h:115
FFV1SliceContext::rc_stat2
uint64_t(*[MAX_QUANT_TABLES] rc_stat2)[32][2]
Definition: ffv1.h:106
FFV1SliceContext::sx
int sx
Definition: ffv1.h:81
ff_need_new_slices
int ff_need_new_slices(int width, int num_h_slices, int chroma_shift)
Definition: ffv1.c:120
NULL
#define NULL
Definition: coverity.c:32
AC_GOLOMB_RICE
#define AC_GOLOMB_RICE
Definition: ffv1.h:52
FFV1SliceContext::fltmap32
uint32_t * fltmap32[4]
Definition: ffv1.h:113
ff_ffv1_get_symbol
int ff_ffv1_get_symbol(RangeCoder *c, uint8_t *state, int is_signed)
Definition: ffv1.c:263
PlaneContext
Definition: ffv1.h:64
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
FFV1SliceContext::slice_width
int slice_width
Definition: ffv1.h:77
f
f
Definition: af_crystalizer.c:122
i
#define i(width, name, range_min, range_max)
Definition: cbs_h264.c:63
get_symbol_inline
static av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state, int is_signed)
Definition: ffv1.h:256
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
attributes.h
ff_ffv1_init_slice_state
av_cold int ff_ffv1_init_slice_state(const FFV1Context *f, FFV1SliceContext *sc)
Definition: ffv1.c:72
FFV1SliceContext::c
RangeCoder c
Definition: ffv1.h:92
av_refstruct_unref
void av_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:120
av_malloc_array
#define av_malloc_array(a, b)
Definition: tableprint_vlc.h:32
FFV1SliceContext::remap_count
int remap_count[4]
Definition: ffv1.h:109
ff_ffv1_common_init
av_cold int ff_ffv1_common_init(AVCodecContext *avctx, FFV1Context *s)
Definition: ffv1.c:36
ffv1.h
FFV1SliceContext::sample_buffer32
int32_t * sample_buffer32
Definition: ffv1.h:75
FFV1SliceContext
Definition: ffv1.h:73
AVCodecContext::height
int height
Definition: avcodec.h:604
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
planes
static const struct @586 planes[]
avcodec.h
FFV1SliceContext::fltmap
uint16_t * fltmap[4]
Definition: ffv1.h:112
ret
ret
Definition: filter_design.txt:187
FFV1SliceContext::slice_y
int slice_y
Definition: ffv1.h:80
ff_ffv1_close
av_cold void ff_ffv1_close(FFV1Context *s)
Definition: ffv1.c:268
ff_slice_coord
int ff_slice_coord(const FFV1Context *f, int width, int sx, int num_h_slices, int chroma_shift)
This is intended for both width and height.
Definition: ffv1.c:127
ff_ffv1_planes_alloc
PlaneContext * ff_ffv1_planes_alloc(void)
Definition: ffv1.c:66
ff_ffv1_allocate_initial_states
int ff_ffv1_allocate_initial_states(FFV1Context *f)
Definition: ffv1.c:185
AVCodecContext
main external API structure.
Definition: avcodec.h:443
FFV1SliceContext::remap
int remap
Definition: ffv1.h:87
FFV1SliceContext::sy
int sy
Definition: ffv1.h:81
Windows::Graphics::DirectX::Direct3D11::p
IDirect3DDxgiInterfaceAccess _COM_Outptr_ void ** p
Definition: vsrc_gfxcapture_winrt.hpp:53
mem.h
FFV1Context
Definition: ffv1.h:122
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
FFMAX3
#define FFMAX3(a, b, c)
Definition: macros.h:48
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:604
ff_ffv1_init_slice_contexts
av_cold int ff_ffv1_init_slice_contexts(FFV1Context *f)
Definition: ffv1.c:142
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
RangeCoder
Definition: mss3.c:63
width
#define width
Definition: dsp.h:89
RangeCoder::zero_state
uint8_t zero_state[256]
Definition: rangecoder.h:40
FFV1SliceContext::slice_coding_mode
int slice_coding_mode
Definition: ffv1.h:84
ff_ffv1_compute_bits_per_plane
void ff_ffv1_compute_bits_per_plane(const FFV1Context *f, FFV1SliceContext *sc, int bits[4], int *offset, int mask[4], int bits_per_raw_sample)
Definition: ffv1.c:224