FFmpeg
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Modules Pages
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)
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  int awidth = FFALIGN(width, mpw);
130 
131  if (f->combined_version <= 0x40002)
132  return width * sx / num_h_slices;
133 
134  sx = (2LL * awidth * sx + num_h_slices * mpw) / (2 * num_h_slices * mpw) * mpw;
135  if (sx == awidth)
136  sx = width;
137  return sx;
138 }
139 
141 {
142  int max_slice_count = f->num_h_slices * f->num_v_slices;
143 
144  av_assert0(max_slice_count > 0);
145 
146  f->slices = av_calloc(max_slice_count, sizeof(*f->slices));
147  if (!f->slices)
148  return AVERROR(ENOMEM);
149 
150  f->max_slice_count = max_slice_count;
151 
152  for (int i = 0; i < max_slice_count; i++) {
153  FFV1SliceContext *sc = &f->slices[i];
154  int sx = i % f->num_h_slices;
155  int sy = i / f->num_h_slices;
156  int sxs = ff_slice_coord(f, f->avctx->width , sx , f->num_h_slices, f->chroma_h_shift);
157  int sxe = ff_slice_coord(f, f->avctx->width , sx + 1, f->num_h_slices, f->chroma_h_shift);
158  int sys = ff_slice_coord(f, f->avctx->height, sy , f->num_v_slices, f->chroma_v_shift);
159  int sye = ff_slice_coord(f, f->avctx->height, sy + 1, f->num_v_slices, f->chroma_v_shift);
160 
161  sc->slice_width = sxe - sxs;
162  sc->slice_height = sye - sys;
163  sc->slice_x = sxs;
164  sc->slice_y = sys;
165  sc->sx = sx;
166  sc->sy = sy;
167 
168  sc->sample_buffer = av_malloc_array((f->width + 6), 3 * MAX_PLANES *
169  sizeof(*sc->sample_buffer));
170  sc->sample_buffer32 = av_malloc_array((f->width + 6), 3 * MAX_PLANES *
171  sizeof(*sc->sample_buffer32));
172  if (!sc->sample_buffer || !sc->sample_buffer32)
173  return AVERROR(ENOMEM);
174 
175  sc->plane = ff_ffv1_planes_alloc();
176  if (!sc->plane)
177  return AVERROR(ENOMEM);
178  }
179 
180  return 0;
181 }
182 
184 {
185  int i;
186 
187  for (i = 0; i < f->quant_table_count; i++) {
188  f->initial_states[i] = av_malloc_array(f->context_count[i],
189  sizeof(*f->initial_states[i]));
190  if (!f->initial_states[i])
191  return AVERROR(ENOMEM);
192  memset(f->initial_states[i], 128,
193  f->context_count[i] * sizeof(*f->initial_states[i]));
194  }
195  return 0;
196 }
197 
199 {
200  int i, j;
201 
202  for (i = 0; i < f->plane_count; i++) {
203  PlaneContext *p = &sc->plane[i];
204 
205  if (f->ac != AC_GOLOMB_RICE) {
206  if (f->initial_states[p->quant_table_index]) {
207  memcpy(p->state, f->initial_states[p->quant_table_index],
209  } else
210  memset(p->state, 128, CONTEXT_SIZE * p->context_count);
211  } else {
212  for (j = 0; j < p->context_count; j++) {
213  p->vlc_state[j].drift = 0;
214  p->vlc_state[j].error_sum = 4; //FFMAX((RANGE + 32)/64, 2);
215  p->vlc_state[j].bias = 0;
216  p->vlc_state[j].count = 1;
217  }
218  }
219  }
220 }
221 
222 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)
223 {
224  // to simplify we use the remap_count as the symbol range in each plane
225  if (!sc->remap) {
226  sc->remap_count[0] =
227  sc->remap_count[1] =
228  sc->remap_count[2] =
229  sc->remap_count[3] = 1 << (bits_per_raw_sample > 0 ? bits_per_raw_sample : 8);
230  }
231 
232  if (sc->remap)
233  av_assert0(bits_per_raw_sample > 8); //breaks with lbd, needs review if added
234 
235  //bits with no RCT
236  for (int p=0; p<3+f->transparency; p++) {
237  bits[p] = av_ceil_log2(sc->remap_count[p]);
238  if (mask)
239  mask[p] = (1<<bits[p]) - 1;
240  }
241 
242  //RCT
243  if (sc->slice_coding_mode == 0) {
244  *offset = sc->remap_count[0];
245 
246  bits[0] = av_ceil_log2(FFMAX3(sc->remap_count[0], sc->remap_count[1], sc->remap_count[2]));
247  bits[1] = av_ceil_log2(sc->remap_count[0] + sc->remap_count[1]);
248  bits[2] = av_ceil_log2(sc->remap_count[0] + sc->remap_count[2]);
249 
250  //old version coded a bit more than needed
251  if (f->combined_version < 0x40008) {
252  bits[0]++;
253  if(f->transparency)
254  bits[3]++;
255  }
256  }
257 }
258 
259 int ff_ffv1_get_symbol(RangeCoder *c, uint8_t *state, int is_signed)
260 {
261  return get_symbol_inline(c, state, is_signed);
262 }
263 
265 {
266  int i, j;
267 
268  for (j = 0; j < s->max_slice_count; j++) {
269  FFV1SliceContext *sc = &s->slices[j];
270 
271  av_freep(&sc->sample_buffer);
273  for(int p = 0; p < 4 ; p++) {
274  av_freep(&sc->fltmap[p]);
275  av_freep(&sc->fltmap32[p]);
276  sc->fltmap_size [p] = 0;
277  sc->fltmap32_size[p] = 0;
278  }
279 
281  }
282 
283  av_refstruct_unref(&s->slice_damaged);
284 
285  for (j = 0; j < s->quant_table_count; j++) {
286  av_freep(&s->initial_states[j]);
287  for (i = 0; i < s->max_slice_count; i++) {
288  FFV1SliceContext *sc = &s->slices[i];
289  av_freep(&sc->rc_stat2[j]);
290  }
291  av_freep(&s->rc_stat2[j]);
292  }
293 
294  av_freep(&s->slices);
295 }
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
int64_t
long long int64_t
Definition: coverity.c:34
mask
int mask
Definition: mediacodecdec_common.c:154
PlaneContext::state
uint8_t(* state)[CONTEXT_SIZE]
Definition: ffv1.h:67
FFV1SliceContext::fltmap_size
unsigned int fltmap_size[4]
Definition: ffv1.h:114
planes
static const struct @487 planes[]
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:198
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:488
CONTEXT_SIZE
#define CONTEXT_SIZE
Definition: ffv1.h:45
PlaneContext::context_count
int context_count
Definition: ffv1.h:66
refstruct.h
avassert.h
av_cold
#define av_cold
Definition: attributes.h:90
FFV1SliceContext::sample_buffer
int16_t * sample_buffer
Definition: ffv1.h:74
RangeCoder::one_state
uint8_t one_state[256]
Definition: rangecoder.h:41
state
static struct @486 state
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:40
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
PlaneContext::vlc_state
VlcState * vlc_state
Definition: ffv1.h:68
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:259
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
VlcState::count
uint8_t count
Definition: ffv1.h:61
get_symbol_inline
static av_flatten int get_symbol_inline(RangeCoder *c, uint8_t *state, int is_signed)
Definition: ffv1.h:251
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
PlaneContext::quant_table_index
int quant_table_index
Definition: ffv1.h:65
VlcState::drift
int16_t drift
Definition: ffv1.h:59
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
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
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:592
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
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:264
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:183
AVCodecContext
main external API structure.
Definition: avcodec.h:431
VlcState::bias
int8_t bias
Definition: ffv1.h:60
FFV1SliceContext::remap
int remap
Definition: ffv1.h:87
FFV1SliceContext::sy
int sy
Definition: ffv1.h:81
VlcState::error_sum
uint32_t error_sum
Definition: ffv1.h:58
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:592
ff_ffv1_init_slice_contexts
av_cold int ff_ffv1_init_slice_contexts(FFV1Context *f)
Definition: ffv1.c:140
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:85
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:222