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  FFV1Context *s = avctx->priv_data;
39 
40  if (!avctx->width || !avctx->height)
41  return AVERROR_INVALIDDATA;
42 
43  s->avctx = avctx;
44  s->flags = avctx->flags;
45 
46  s->width = avctx->width;
47  s->height = avctx->height;
48 
49  // defaults
50  s->num_h_slices = 1;
51  s->num_v_slices = 1;
52 
53  return 0;
54 }
55 
56 static void planes_free(AVRefStructOpaque opaque, void *obj)
57 {
58  PlaneContext *planes = obj;
59 
60  for (int i = 0; i < MAX_PLANES; i++) {
61  PlaneContext *p = &planes[i];
62 
63  av_freep(&p->state);
64  av_freep(&p->vlc_state);
65  }
66 }
67 
69 {
71  0, NULL, planes_free);
72 }
73 
75  FFV1SliceContext *sc)
76 {
77  int j, i;
78 
79  for (j = 0; j < f->plane_count; j++) {
80  PlaneContext *const p = &sc->plane[j];
81 
82  if (f->ac != AC_GOLOMB_RICE) {
83  if (!p->state)
85  sizeof(uint8_t));
86  if (!p->state)
87  return AVERROR(ENOMEM);
88  } else {
89  if (!p->vlc_state) {
90  p->vlc_state = av_calloc(p->context_count, sizeof(*p->vlc_state));
91  if (!p->vlc_state)
92  return AVERROR(ENOMEM);
93  for (i = 0; i < p->context_count; i++) {
94  p->vlc_state[i].error_sum = 4;
95  p->vlc_state[i].count = 1;
96  }
97  }
98  }
99  }
100 
101  if (f->ac == AC_RANGE_CUSTOM_TAB) {
102  //FIXME only redo if state_transition changed
103  for (j = 1; j < 256; j++) {
104  sc->c. one_state[ j] = f->state_transition[j];
105  sc->c.zero_state[256 - j] = 256 - sc->c.one_state[j];
106  }
107  }
108 
109  return 0;
110 }
111 
113 {
114  int i, ret;
115  for (i = 0; i < f->max_slice_count; i++) {
116  if ((ret = ff_ffv1_init_slice_state(f, &f->slices[i])) < 0)
117  return AVERROR(ENOMEM);
118  }
119  return 0;
120 }
121 
122 int ff_need_new_slices(int width, int num_h_slices, int chroma_shift) {
123  int mpw = 1<<chroma_shift;
124  int i = width * (int64_t)(num_h_slices - 1) / num_h_slices;
125 
126  return width % mpw && (width - i) % mpw == 0;
127 }
128 
129 int ff_slice_coord(const FFV1Context *f, int width, int sx, int num_h_slices, int chroma_shift) {
130  int mpw = 1<<chroma_shift;
131  int awidth = FFALIGN(width, mpw);
132 
133  if (f->version < 4 || f->version == 4 && f->micro_version < 3)
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],
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 
226 {
227  FFV1Context *s = avctx->priv_data;
228  int i, j;
229 
230  for (j = 0; j < s->max_slice_count; j++) {
231  FFV1SliceContext *sc = &s->slices[j];
232 
233  av_freep(&sc->sample_buffer);
235 
237  }
238 
239  av_refstruct_unref(&s->slice_damaged);
240 
241  av_freep(&avctx->stats_out);
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 
253  return 0;
254 }
FFV1SliceContext::slice_height
int slice_height
Definition: ffv1.h:77
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:88
int64_t
long long int64_t
Definition: coverity.c:34
ff_ffv1_common_init
av_cold int ff_ffv1_common_init(AVCodecContext *avctx)
Definition: ffv1.c:36
PlaneContext::state
uint8_t(* state)[CONTEXT_SIZE]
Definition: ffv1.h:66
AC_RANGE_CUSTOM_TAB
#define AC_RANGE_CUSTOM_TAB
Definition: ffv1.h:53
FFV1SliceContext::slice_x
int slice_x
Definition: ffv1.h:78
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:112
planes_free
static void planes_free(AVRefStructOpaque opaque, void *obj)
Definition: ffv1.c:56
AVCodecContext::flags
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:508
CONTEXT_SIZE
#define CONTEXT_SIZE
Definition: ffv1.h:44
PlaneContext::context_count
int context_count
Definition: ffv1.h:65
refstruct.h
avassert.h
av_cold
#define av_cold
Definition: attributes.h:90
FFV1SliceContext::sample_buffer
int16_t * sample_buffer
Definition: ffv1.h:73
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:43
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:104
FFV1SliceContext::sx
int sx
Definition: ffv1.h:80
ff_need_new_slices
int ff_need_new_slices(int width, int num_h_slices, int chroma_shift)
Definition: ffv1.c:122
NULL
#define NULL
Definition: coverity.c:32
PlaneContext::vlc_state
VlcState * vlc_state
Definition: ffv1.h:67
AC_GOLOMB_RICE
#define AC_GOLOMB_RICE
Definition: ffv1.h:51
PlaneContext
Definition: ffv1.h:63
FFV1SliceContext::slice_width
int slice_width
Definition: ffv1.h:76
AVCodecContext::stats_out
char * stats_out
pass1 encoding statistics output buffer
Definition: avcodec.h:1352
f
f
Definition: af_crystalizer.c:122
planes
static const struct @472 planes[]
ff_ffv1_close
av_cold int ff_ffv1_close(AVCodecContext *avctx)
Definition: ffv1.c:225
VlcState::count
uint8_t count
Definition: ffv1.h:60
attributes.h
ff_ffv1_init_slice_state
av_cold int ff_ffv1_init_slice_state(const FFV1Context *f, FFV1SliceContext *sc)
Definition: ffv1.c:74
PlaneContext::quant_table_index
int quant_table_index
Definition: ffv1.h:64
VlcState::drift
int16_t drift
Definition: ffv1.h:58
FFV1SliceContext::c
RangeCoder c
Definition: ffv1.h:90
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
ffv1.h
FFV1SliceContext::sample_buffer32
int32_t * sample_buffer32
Definition: ffv1.h:74
FFV1SliceContext
Definition: ffv1.h:72
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:79
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:129
ff_ffv1_planes_alloc
PlaneContext * ff_ffv1_planes_alloc(void)
Definition: ffv1.c:68
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:451
VlcState::bias
int8_t bias
Definition: ffv1.h:59
FFV1SliceContext::sy
int sy
Definition: ffv1.h:80
VlcState::error_sum
uint32_t error_sum
Definition: ffv1.h:57
mem.h
FFV1Context
Definition: ffv1.h:109
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
AVCodecContext::priv_data
void * priv_data
Definition: avcodec.h:478
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:142
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
width
#define width
Definition: dsp.h:85
RangeCoder::zero_state
uint8_t zero_state[256]
Definition: rangecoder.h:40