FFmpeg
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 "refstruct.h"
30 
31 static void mpv_pic_reset(FFRefStructOpaque 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;
63  pic->display_picture_number = 0;
64  pic->coded_picture_number = 0;
65 }
66 
67 static int av_cold mpv_pic_init(FFRefStructOpaque 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 
82 static void av_cold mpv_pic_free(FFRefStructOpaque unused, void *obj)
83 {
84  MPVPicture *pic = obj;
85 
87  av_frame_free(&pic->f);
88 }
89 
91 {
94  (void*)(uintptr_t)init_progress,
96 }
97 
99 {
100  ff_refstruct_unref(&pic->ptr);
101  memset(pic, 0, sizeof(*pic));
102 }
103 
104 static 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  ff_refstruct_replace(&dst->ptr, src->ptr);
125  memcpy(dst, src, sizeof(*dst));
126 }
127 
129 {
130  ff_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");
153  return AVERROR_PATCHWELCOME;
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 
160  av_freep(&sc->scratchpad_buf);
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 
181 int 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=%"PTRDIFF_SPECIFIER"/%d uvlinesize=%"PTRDIFF_SPECIFIER"/%d)\n",
190  linesize, f->linesize[0],
191  uvlinesize, f->linesize[1]);
192  return AVERROR_PATCHWELCOME;
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");
198  return AVERROR_PATCHWELCOME;
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 = ff_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 
238  ScratchpadContext *sc,
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;
255 fail:
256  av_log(avctx, AV_LOG_ERROR, "Error allocating picture accessories.\n");
257  return ret;
258 }
FF_ALLOCZ_TYPED_ARRAY
#define FF_ALLOCZ_TYPED_ARRAY(p, nelem)
Definition: internal.h:78
MPV_MAX_PLANES
#define MPV_MAX_PLANES
Definition: mpegpicture.h:30
MPVWorkPicture::linesize
ptrdiff_t linesize[MPV_MAX_PLANES]
Definition: mpegpicture.h:97
AVCodecContext::hwaccel
const struct AVHWAccel * hwaccel
Hardware accelerator in use.
Definition: avcodec.h:1427
EMU_EDGE_HEIGHT
#define EMU_EDGE_HEIGHT
ScratchpadContext::obmc_scratchpad
uint8_t * obmc_scratchpad
Definition: mpegpicture.h:35
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
MPVPicture::mbskip_table
uint8_t * mbskip_table
Definition: mpegpicture.h:70
av_frame_free
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:160
AVFrame
This structure describes decoded (raw) audio or video data.
Definition: frame.h:374
pixdesc.h
set_workpic_from_pic
static void set_workpic_from_pic(MPVWorkPicture *wpic, const MPVPicture *pic)
Definition: mpegpicture.c:104
FFRefStructOpaque
RefStruct is an API for creating reference-counted objects with minimal overhead.
Definition: refstruct.h:58
MPVPicture::mb_type_base
uint32_t * mb_type_base
Definition: mpegpicture.h:67
MPVWorkPicture::mb_type
uint32_t * mb_type
types and macros are defined in mpegutils.h
Definition: mpegpicture.h:105
AVFrame::data
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:395
ScratchpadContext
Definition: mpegpicture.h:33
MPVWorkPicture::motion_val
int16_t(*[2] motion_val)[2]
Definition: mpegpicture.h:103
mpv_pic_free
static void av_cold mpv_pic_free(FFRefStructOpaque unused, void *obj)
Definition: mpegpicture.c:82
MPVPicture::motion_val_base
int16_t(*[2] motion_val_base)[2]
Definition: mpegpicture.h:64
av_pix_fmt_count_planes
int av_pix_fmt_count_planes(enum AVPixelFormat pix_fmt)
Definition: pixdesc.c:3005
MPVPicture::mb_type
uint32_t * mb_type
types and macros are defined in mpegutils.h
Definition: mpegpicture.h:68
fail
#define fail()
Definition: checkasm.h:184
MPVPicture::motion_val
int16_t(*[2] motion_val)[2]
Definition: mpegpicture.h:65
refstruct.h
BufferPoolContext::alloc_mb_stride
int alloc_mb_stride
mb_stride used to allocate tables
Definition: mpegpicture.h:52
av_image_check_size2
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
MPVWorkPicture::mbskip_table
uint8_t * mbskip_table
Definition: mpegpicture.h:107
GET_BUFFER
#define GET_BUFFER(name, buf_suffix, idx_suffix)
av_frame_alloc
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:148
FF_REFSTRUCT_POOL_FLAG_FREE_ON_INIT_ERROR
#define FF_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
MPVPicture::dummy
int dummy
Picture is a dummy and should not be output.
Definition: mpegpicture.h:81
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
av_cold
#define av_cold
Definition: attributes.h:90
MPVPicture::shared
int shared
Definition: mpegpicture.h:87
MPVPicture::coded_picture_number
int coded_picture_number
Definition: mpegpicture.h:90
ff_mpv_framesize_alloc
int ff_mpv_framesize_alloc(AVCodecContext *avctx, ScratchpadContext *sc, int linesize)
Definition: mpegpicture.c:138
MPVWorkPicture::ptr
MPVPicture * ptr
RefStruct reference.
Definition: mpegpicture.h:99
MPVWorkPicture::reference
int reference
Definition: mpegpicture.h:111
BufferPoolContext::motion_val_pool
struct FFRefStructPool * motion_val_pool
Definition: mpegpicture.h:48
AVCodecContext::max_pixels
int64_t max_pixels
The number of pixels per image to maximally accept.
Definition: avcodec.h:1935
FFRefStructPool
FFRefStructPool is an API for a thread-safe pool of objects managed via the RefStruct API.
Definition: refstruct.c:183
BufferPoolContext::mbskip_table_pool
struct FFRefStructPool * mbskip_table_pool
Definition: mpegpicture.h:45
MPVPicture::qscale_table_base
int8_t * qscale_table_base
Definition: mpegpicture.h:61
FFABS
#define FFABS(a)
Absolute value, Note, INT_MIN / INT64_MIN result in undefined behavior as they are not representable ...
Definition: common.h:74
ff_mpv_unref_picture
void ff_mpv_unref_picture(MPVWorkPicture *pic)
Definition: mpegpicture.c:98
ff_mpv_alloc_pic_pool
av_cold FFRefStructPool * ff_mpv_alloc_pic_pool(int init_progress)
Allocate a pool of MPVPictures.
Definition: mpegpicture.c:90
PTRDIFF_SPECIFIER
#define PTRDIFF_SPECIFIER
Definition: internal.h:128
NULL
#define NULL
Definition: coverity.c:32
AVERROR_PATCHWELCOME
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition: error.h:64
MPVWorkPicture::data
uint8_t * data[MPV_MAX_PLANES]
Definition: mpegpicture.h:96
MPVPicture::field_picture
int field_picture
whether or not the picture was encoded in separate fields
Definition: mpegpicture.h:82
ScratchpadContext::linesize
int linesize
linesize that the buffers in this context have been allocated for
Definition: mpegpicture.h:41
MPVPicture::display_picture_number
int display_picture_number
Definition: mpegpicture.h:89
MPVPicture::reference
int reference
Definition: mpegpicture.h:86
f
f
Definition: af_crystalizer.c:121
MPVPicture::mb_stride
int mb_stride
mb_stride of the tables
Definition: mpegpicture.h:79
FFRefStructOpaque::nc
void * nc
Definition: refstruct.h:59
mpv_pic_reset
static void mpv_pic_reset(FFRefStructOpaque unused, void *obj)
Definition: mpegpicture.c:31
mpegpicture.h
ScratchpadContext::scratchpad_buf
uint8_t * scratchpad_buf
the other *_scratchpad point into this buffer
Definition: mpegpicture.h:37
MPVPicture::mb_width
int mb_width
mb_width of the tables
Definition: mpegpicture.h:77
MPVWorkPicture::qscale_table
int8_t * qscale_table
Definition: mpegpicture.h:101
MPVPicture::hwaccel_picture_private
void * hwaccel_picture_private
RefStruct reference for hardware accelerator private data.
Definition: mpegpicture.h:75
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:256
MPVPicture::qscale_table
int8_t * qscale_table
Definition: mpegpicture.h:62
common.h
av_assert1
#define av_assert1(cond)
assert() equivalent, that does not lie in speed critical code.
Definition: avassert.h:56
ff_thread_progress_init
av_cold int ff_thread_progress_init(ThreadProgress *pro, int init_mode)
Initialize a ThreadProgress.
Definition: threadprogress.c:33
av_frame_unref
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:606
MPVPicture::mb_height
int mb_height
mb_height of the tables
Definition: mpegpicture.h:78
MPVPicture::b_frame_score
int b_frame_score
Definition: mpegpicture.h:84
avcodec.h
ff_mpv_workpic_from_pic
void ff_mpv_workpic_from_pic(MPVWorkPicture *wpic, MPVPicture *pic)
Definition: mpegpicture.c:128
ret
ret
Definition: filter_design.txt:187
ff_refstruct_replace
void ff_refstruct_replace(void *dstp, const void *src)
Ensure *dstp refers to the same object as src.
Definition: refstruct.c:160
ff_thread_progress_destroy
av_cold void ff_thread_progress_destroy(ThreadProgress *pro)
Destroy a ThreadProgress.
Definition: threadprogress.c:44
MPVPicture::f
struct AVFrame * f
Definition: mpegpicture.h:59
AVCodecContext
main external API structure.
Definition: avcodec.h:445
ScratchpadContext::edge_emu_buffer
uint8_t * edge_emu_buffer
temporary buffer for if MVs point to out-of-frame data
Definition: mpegpicture.h:34
AV_PIX_FMT_NONE
@ AV_PIX_FMT_NONE
Definition: pixfmt.h:72
ff_refstruct_pool_alloc_ext
static FFRefStructPool * ff_refstruct_pool_alloc_ext(size_t size, unsigned flags, void *opaque, int(*init_cb)(FFRefStructOpaque opaque, void *obj), void(*reset_cb)(FFRefStructOpaque opaque, void *obj), void(*free_entry_cb)(FFRefStructOpaque opaque, void *obj), void(*free_cb)(FFRefStructOpaque opaque))
A wrapper around ff_refstruct_pool_alloc_ext_c() for the common case of a non-const qualified opaque.
Definition: refstruct.h:258
ff_mpv_pic_check_linesize
int ff_mpv_pic_check_linesize(void *logctx, const AVFrame *f, ptrdiff_t *linesizep, ptrdiff_t *uvlinesizep)
Definition: mpegpicture.c:181
ff_thread_progress_reset
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...
Definition: threadprogress.h:72
ff_mpv_replace_picture
void ff_mpv_replace_picture(MPVWorkPicture *dst, const MPVWorkPicture *src)
Definition: mpegpicture.c:121
mem.h
MPVWorkPicture::ref_index
int8_t * ref_index[2]
Definition: mpegpicture.h:109
MPVWorkPicture
Definition: mpegpicture.h:95
MPVPicture::progress
ThreadProgress progress
Definition: mpegpicture.h:92
FFALIGN
#define FFALIGN(x, a)
Definition: macros.h:78
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
imgutils.h
AVFrame::linesize
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:419
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
BufferPoolContext
Definition: mpegpicture.h:44
mpv_pic_init
static int av_cold mpv_pic_init(FFRefStructOpaque opaque, void *obj)
Definition: mpegpicture.c:67
MPVPicture
MPVPicture.
Definition: mpegpicture.h:58
BufferPoolContext::alloc_mb_width
int alloc_mb_width
mb_width used to allocate tables
Definition: mpegpicture.h:50
ff_mpv_alloc_pic_accessories
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...
Definition: mpegpicture.c:237
MPVPicture::ref_index
int8_t * ref_index[2]
Definition: mpegpicture.h:72
ff_refstruct_unref
void ff_refstruct_unref(void *objp)
Decrement the reference count of the underlying object and automatically free the object if there are...
Definition: refstruct.c:120
alloc_picture_tables
static int alloc_picture_tables(BufferPoolContext *pools, MPVPicture *pic, int mb_height)
Definition: mpegpicture.c:206