FFmpeg
Loading...
Searching...
No Matches
mpegpicture.c
Go to the documentation of this file.
1/*
2 * Mpeg video formats-related picture management functions
3 *
4 * This file is part of FFmpeg.
5 *
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21#include "libavutil/avassert.h"
22#include "libavutil/common.h"
23#include "libavutil/mem.h"
24#include "libavutil/pixdesc.h"
25#include "libavutil/imgutils.h"
26
27#include "avcodec.h"
28#include "mpegpicture.h"
29#include "libavutil/refstruct.h"
30
31static void mpv_pic_reset(AVRefStructOpaque unused, void *obj)
32{
33 MPVPicture *pic = obj;
34
35 av_frame_unref(pic->f);
37
39
43
44 for (int i = 0; i < 2; i++) {
47
48 pic->motion_val[i] = NULL;
49 }
50
51 pic->mb_type = NULL;
52 pic->qscale_table = NULL;
53
54 pic->mb_stride =
55 pic->mb_width =
56 pic->mb_height = 0;
57
58 pic->dummy = 0;
59 pic->field_picture = 0;
60 pic->b_frame_score = 0;
61 pic->reference = 0;
62 pic->shared = 0;
64 pic->coded_picture_number = 0;
65}
66
67static int av_cold mpv_pic_init(AVRefStructOpaque opaque, void *obj)
68{
69 MPVPicture *pic = obj;
70 int ret, init_progress = (uintptr_t)opaque.nc;
71
72 ret = ff_thread_progress_init(&pic->progress, init_progress);
73 if (ret < 0)
74 return ret;
75
76 pic->f = av_frame_alloc();
77 if (!pic->f)
78 return AVERROR(ENOMEM);
79 return 0;
80}
81
82static void av_cold mpv_pic_free(AVRefStructOpaque unused, void *obj)
83{
84 MPVPicture *pic = obj;
85
87 av_frame_free(&pic->f);
88}
89
97
99{
100 av_refstruct_unref(&pic->ptr);
101 memset(pic, 0, sizeof(*pic));
102}
103
104static void set_workpic_from_pic(MPVWorkPicture *wpic, const MPVPicture *pic)
105{
106 for (int i = 0; i < MPV_MAX_PLANES; i++) {
107 wpic->data[i] = pic->f->data[i];
108 wpic->linesize[i] = pic->f->linesize[i];
109 }
110 wpic->qscale_table = pic->qscale_table;
111 wpic->mb_type = pic->mb_type;
112 wpic->mbskip_table = pic->mbskip_table;
113
114 for (int i = 0; i < 2; i++) {
115 wpic->motion_val[i] = pic->motion_val[i];
116 wpic->ref_index[i] = pic->ref_index[i];
117 }
118 wpic->reference = pic->reference;
119}
120
122{
123 av_assert1(dst != src);
124 av_refstruct_replace(&dst->ptr, src->ptr);
125 memcpy(dst, src, sizeof(*dst));
126}
127
129{
130 av_refstruct_replace(&wpic->ptr, pic);
131 if (!pic) {
132 memset(wpic, 0, sizeof(*wpic));
133 return;
134 }
135 set_workpic_from_pic(wpic, pic);
136}
137
139 ScratchpadContext *sc, int linesize)
140{
141# define EMU_EDGE_HEIGHT (4 * 70)
142 int linesizeabs = FFABS(linesize);
143 int alloc_size = FFALIGN(linesizeabs + 64, 32);
144
145 if (linesizeabs <= sc->linesize)
146 return 0;
147
148 if (avctx->hwaccel)
149 return 0;
150
151 if (linesizeabs < 24) {
152 av_log(avctx, AV_LOG_ERROR, "Image too small, temporary buffers cannot function\n");
154 }
155
156 if (av_image_check_size2(alloc_size, EMU_EDGE_HEIGHT, avctx->max_pixels, AV_PIX_FMT_NONE, 0, avctx) < 0)
157 return AVERROR(ENOMEM);
158
161
162 // edge emu needs blocksize + filter length - 1
163 // (= 17x17 for halfpel / 21x21 for H.264)
164 // VC-1 computes luma and chroma simultaneously and needs 19X19 + 9x9
165 // at uvlinesize. It supports only YUV420 so 24x24 is enough
166 // linesize * interlaced * MBsize
167 // we also use this buffer for encoding in encode_mb_internal() needig an additional 32 lines
168 if (!FF_ALLOCZ_TYPED_ARRAY(sc->edge_emu_buffer, alloc_size * EMU_EDGE_HEIGHT) ||
169 !FF_ALLOCZ_TYPED_ARRAY(sc->scratchpad_buf, alloc_size * 4 * 16 * 2)) {
170 sc->linesize = 0;
172 return AVERROR(ENOMEM);
173 }
174 sc->linesize = linesizeabs;
175
176 sc->obmc_scratchpad = sc->scratchpad_buf + 16;
177
178 return 0;
179}
180
181int ff_mpv_pic_check_linesize(void *logctx, const AVFrame *f,
182 ptrdiff_t *linesizep, ptrdiff_t *uvlinesizep)
183{
184 ptrdiff_t linesize = *linesizep, uvlinesize = *uvlinesizep;
185
186 if ((linesize && linesize != f->linesize[0]) ||
187 (uvlinesize && uvlinesize != f->linesize[1])) {
188 av_log(logctx, AV_LOG_ERROR, "Stride change unsupported: "
189 "linesize=%td/%d uvlinesize=%td/%d)\n",
190 linesize, f->linesize[0],
191 uvlinesize, f->linesize[1]);
193 }
194
195 if (av_pix_fmt_count_planes(f->format) > 2 &&
196 f->linesize[1] != f->linesize[2]) {
197 av_log(logctx, AV_LOG_ERROR, "uv stride mismatch unsupported\n");
199 }
200 *linesizep = f->linesize[0];
201 *uvlinesizep = f->linesize[1];
202
203 return 0;
204}
205
207 int mb_height)
208{
209#define GET_BUFFER(name, buf_suffix, idx_suffix) do { \
210 pic->name ## buf_suffix idx_suffix = av_refstruct_pool_get(pools->name ## _pool); \
211 if (!pic->name ## buf_suffix idx_suffix) \
212 return AVERROR(ENOMEM); \
213} while (0)
214 GET_BUFFER(qscale_table, _base,);
215 GET_BUFFER(mb_type, _base,);
216 if (pools->motion_val_pool) {
217 if (pools->mbskip_table_pool)
218 GET_BUFFER(mbskip_table,,);
219 for (int i = 0; i < 2; i++) {
220 GET_BUFFER(ref_index,, [i]);
221 GET_BUFFER(motion_val, _base, [i]);
222 pic->motion_val[i] = pic->motion_val_base[i] + 4;
223 }
224 }
225#undef GET_BUFFER
226
227 pic->mb_width = pools->alloc_mb_width;
228 pic->mb_height = mb_height;
229 pic->mb_stride = pools->alloc_mb_stride;
230
231 pic->qscale_table = pic->qscale_table_base + 2 * pic->mb_stride + 1;
232 pic->mb_type = pic->mb_type_base + 2 * pic->mb_stride + 1;
233
234 return 0;
235}
236
239 BufferPoolContext *pools, int mb_height)
240{
241 MPVPicture *pic = wpic->ptr;
242 int ret;
243
244 ret = ff_mpv_framesize_alloc(avctx, sc, pic->f->linesize[0]);
245 if (ret < 0)
246 goto fail;
247
248 ret = alloc_picture_tables(pools, pic, mb_height);
249 if (ret < 0)
250 goto fail;
251
252 set_workpic_from_pic(wpic, pic);
253
254 return 0;
255fail:
256 av_log(avctx, AV_LOG_ERROR, "Error allocating picture accessories.\n");
257 return ret;
258}
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
simple assert() macros that are a bit more flexible than ISO C assert().
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition avassert.h:58
Libavcodec external API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
common internal and external API header
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition common.h:74
#define NULL
Definition coverity.c:32
#define fail
Definition test.h:479
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR(e)
Definition error.h:45
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition frame.c:496
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
int av_image_check_size2(unsigned int w, unsigned int h, int64_t max_pixels, enum AVPixelFormat pix_fmt, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of a plane of an image with...
Definition imgutils.c:289
misc image utilities
#define av_cold
Definition attributes.h:117
#define FF_ALLOCZ_TYPED_ARRAY(p, nelem)
Definition internal.h:72
#define FFALIGN(x, a)
Definition macros.h:78
Memory handling functions.
void ff_mpv_unref_picture(MPVWorkPicture *pic)
Definition mpegpicture.c:98
#define EMU_EDGE_HEIGHT
void ff_mpv_workpic_from_pic(MPVWorkPicture *wpic, MPVPicture *pic)
int ff_mpv_pic_check_linesize(void *logctx, const AVFrame *f, ptrdiff_t *linesizep, ptrdiff_t *uvlinesizep)
static void mpv_pic_reset(AVRefStructOpaque unused, void *obj)
Definition mpegpicture.c:31
static int alloc_picture_tables(BufferPoolContext *pools, MPVPicture *pic, int mb_height)
int ff_mpv_alloc_pic_accessories(AVCodecContext *avctx, MPVWorkPicture *wpic, ScratchpadContext *sc, BufferPoolContext *pools, int mb_height)
Allocate an MPVPicture's accessories (but not the AVFrame's buffer itself) and set the MPVWorkPicture...
av_cold AVRefStructPool * ff_mpv_alloc_pic_pool(int init_progress)
Allocate a pool of MPVPictures.
Definition mpegpicture.c:90
static void set_workpic_from_pic(MPVWorkPicture *wpic, const MPVPicture *pic)
static int av_cold mpv_pic_init(AVRefStructOpaque opaque, void *obj)
Definition mpegpicture.c:67
#define GET_BUFFER(name, buf_suffix, idx_suffix)
static void av_cold mpv_pic_free(AVRefStructOpaque unused, void *obj)
Definition mpegpicture.c:82
void ff_mpv_replace_picture(MPVWorkPicture *dst, const MPVWorkPicture *src)
int ff_mpv_framesize_alloc(AVCodecContext *avctx, ScratchpadContext *sc, int linesize)
#define MPV_MAX_PLANES
Definition mpegpicture.h:31
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition pixdesc.c:3500
@ AV_PIX_FMT_NONE
Definition pixfmt.h:72
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
void av_refstruct_replace(void *dstp, const void *src)
Ensure *dstp refers to the same object as src.
Definition refstruct.c:160
#define AV_REFSTRUCT_POOL_FLAG_FREE_ON_INIT_ERROR
If this flag is set and both init_cb and free_entry_cb callbacks are provided, then free_cb will be c...
Definition refstruct.h:213
static AVRefStructPool * av_refstruct_pool_alloc_ext(size_t size, unsigned flags, void *opaque, int(*init_cb)(AVRefStructOpaque opaque, void *obj), void(*reset_cb)(AVRefStructOpaque opaque, void *obj), void(*free_entry_cb)(AVRefStructOpaque opaque, void *obj), void(*free_cb)(AVRefStructOpaque opaque))
A wrapper around av_refstruct_pool_alloc_ext_c() for the common case of a non-const qualified opaque.
Definition refstruct.h:258
main external API structure.
Definition avcodec.h:443
int64_t max_pixels
The number of pixels per image to maximally accept.
Definition avcodec.h:1787
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition avcodec.h:1423
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:493
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition frame.h:517
AVRefStructPool is an API for a thread-safe pool of objects managed via the RefStruct API.
Definition refstruct.c:183
struct AVRefStructPool * mbskip_table_pool
Definition mpegpicture.h:45
int alloc_mb_width
mb_width used to allocate tables
Definition mpegpicture.h:50
struct AVRefStructPool * motion_val_pool
Definition mpegpicture.h:48
int alloc_mb_stride
mb_stride used to allocate tables
Definition mpegpicture.h:52
MPVPicture.
Definition mpegpicture.h:58
ThreadProgress progress
Definition mpegpicture.h:92
int b_frame_score
Definition mpegpicture.h:84
int16_t(*[2] motion_val_base)[2]
Definition mpegpicture.h:64
int dummy
Picture is a dummy and should not be output.
Definition mpegpicture.h:81
uint32_t * mb_type_base
Definition mpegpicture.h:67
uint32_t * mb_type
types and macros are defined in mpegutils.h
Definition mpegpicture.h:68
struct AVFrame * f
Definition mpegpicture.h:59
int display_picture_number
Definition mpegpicture.h:89
int coded_picture_number
Definition mpegpicture.h:90
int field_picture
whether or not the picture was encoded in separate fields
Definition mpegpicture.h:82
void * hwaccel_picture_private
RefStruct reference for hardware accelerator private data.
Definition mpegpicture.h:75
int mb_height
mb_height of the tables
Definition mpegpicture.h:78
int mb_stride
mb_stride of the tables
Definition mpegpicture.h:79
int16_t(*[2] motion_val)[2]
Definition mpegpicture.h:65
int mb_width
mb_width of the tables
Definition mpegpicture.h:77
uint8_t * mbskip_table
Definition mpegpicture.h:70
int8_t * ref_index[2]
Definition mpegpicture.h:72
int8_t * qscale_table_base
Definition mpegpicture.h:61
int8_t * qscale_table
Definition mpegpicture.h:62
uint32_t * mb_type
types and macros are defined in mpegutils.h
MPVPicture * ptr
RefStruct reference.
Definition mpegpicture.h:99
int16_t(*[2] motion_val)[2]
ptrdiff_t linesize[MPV_MAX_PLANES]
Definition mpegpicture.h:97
int8_t * ref_index[2]
uint8_t * data[MPV_MAX_PLANES]
Definition mpegpicture.h:96
uint8_t * mbskip_table
int8_t * qscale_table
int linesize
linesize that the buffers in this context have been allocated for
Definition mpegpicture.h:41
uint8_t * edge_emu_buffer
temporary buffer for if MVs point to out-of-frame data
Definition mpegpicture.h:35
uint8_t * obmc_scratchpad
Definition mpegpicture.h:36
uint8_t * scratchpad_buf
the other *_scratchpad point into this buffer
Definition mpegpicture.h:38
#define av_freep(p)
#define av_log(a,...)
#define src
Definition vp8dsp.c:248
av_cold void ff_thread_progress_destroy(ThreadProgress *pro)
Destroy a ThreadProgress.
av_cold int ff_thread_progress_init(ThreadProgress *pro, int init_mode)
Initialize a ThreadProgress.
static void ff_thread_progress_reset(ThreadProgress *pro)
Reset the ThreadProgress.progress counter; must only be called if the ThreadProgress is not in use in...
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition refstruct.h:58