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)
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 int ff_ffv1_get_symbol(RangeCoder *c, uint8_t *state, int is_signed)
223 {
224  return get_symbol_inline(c, state, is_signed);
225 }
226 
228 {
229  int i, j;
230 
231  for (j = 0; j < s->max_slice_count; j++) {
232  FFV1SliceContext *sc = &s->slices[j];
233 
234  av_freep(&sc->sample_buffer);
236 
238  }
239 
240  av_refstruct_unref(&s->slice_damaged);
241 
242  for (j = 0; j < s->quant_table_count; j++) {
243  av_freep(&s->initial_states[j]);
244  for (i = 0; i < s->max_slice_count; i++) {
245  FFV1SliceContext *sc = &s->slices[i];
246  av_freep(&sc->rc_stat2[j]);
247  }
248  av_freep(&s->rc_stat2[j]);
249  }
250 
251  av_freep(&s->slices);
252 }
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:89
int64_t
long long int64_t
Definition: coverity.c:34
PlaneContext::state
uint8_t(* state)[CONTEXT_SIZE]
Definition: ffv1.h:67
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
state
static struct @472 state
ff_ffv1_init_slices_state
av_cold int ff_ffv1_init_slices_state(FFV1Context *f)
Definition: ffv1.c:110
planes_free
static void planes_free(AVRefStructOpaque opaque, void *obj)
Definition: ffv1.c:54
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:508
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
s
#define s(width, name)
Definition: cbs_vp9.c:198
MAX_PLANES
#define MAX_PLANES
Definition: ffv1.h:44
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::rc_stat2
uint64_t(*[MAX_QUANT_TABLES] rc_stat2)[32][2]
Definition: ffv1.h:105
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
ff_ffv1_get_symbol
int ff_ffv1_get_symbol(RangeCoder *c, uint8_t *state, int is_signed)
Definition: ffv1.c:222
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:233
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:91
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:31
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:632
av_calloc
void * av_calloc(size_t nmemb, size_t size)
Definition: mem.c:264
avcodec.h
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:227
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
planes
static const struct @473 planes[]
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:451
VlcState::bias
int8_t bias
Definition: ffv1.h:60
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:110
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
AVCodecContext::width
int width
picture width / height.
Definition: avcodec.h:632
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