FFmpeg  4.3.8
rpi_zc.h
Go to the documentation of this file.
1 /*
2 Copyright (c) 2018 Raspberry Pi (Trading) Ltd.
3 All rights reserved.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are met:
7  * Redistributions of source code must retain the above copyright
8  notice, this list of conditions and the following disclaimer.
9  * Redistributions in binary form must reproduce the above copyright
10  notice, this list of conditions and the following disclaimer in the
11  documentation and/or other materials provided with the distribution.
12  * Neither the name of the copyright holder nor the
13  names of its contributors may be used to endorse or promote products
14  derived from this software without specific prior written permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17 ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 
27 Authors: John Cox
28 */
29 
30 #ifndef LIBAVCODEC_RPI_ZC_H
31 #define LIBAVCODEC_RPI_ZC_H
32 
33 // Zero-Copy frame code for RPi
34 // RPi needs Y/U/V planes to be contiguous for display. By default
35 // ffmpeg will allocate separated planes so a memcpy is needed before
36 // display. This code provides a method a making ffmpeg allocate a single
37 // bit of memory for the frame when can then be reference counted until
38 // display has finished with it.
39 
40 // Frame buffer number in which to stuff an 8-bit copy of a 16-bit frame
41 // 0 disables
42 // *** This option still in development
43 // Only works if SAO active
44 // Allocates buffers that are twice the required size
45 #define RPI_ZC_SAND_8_IN_10_BUF 0
46 
47 struct AVBufferRef;
48 struct AVFrame;
49 struct AVCodecContext;
50 enum AVPixelFormat;
51 
52 // "Opaque" pointer to whatever we are using as a buffer reference
53 typedef struct AVBufferRef * AVRpiZcRefPtr;
54 
55 struct AVZcEnv;
56 typedef struct AVZcEnv * AVZcEnvPtr;
57 
58 typedef struct AVRpiZcFrameGeometry
59 {
60  unsigned int stride_y; // Luma stride (bytes)
61  unsigned int height_y; // Luma height (lines)
62  unsigned int stride_c; // Chroma stride (bytes)
63  unsigned int height_c; // Chroma stride (lines)
64  unsigned int planes_c; // Chroma plane count (U, V = 2, interleaved = 1)
65  unsigned int stripes; // Number of stripes (sand)
66  unsigned int bytes_per_pel;
67  int stripe_is_yc; // A single stripe is Y then C (false for tall sand)
68 
69  int format; // Requested format
70  unsigned int video_width; // Requested width
71  unsigned int video_height; // Requested height
73 
74 // Get expected MMAL geometry for a given format, width & height
76  const int format,
77  const unsigned int video_width, const unsigned int video_height);
78 
79 //----------------------------------------------------------------------------
80 //
81 // Calls that extract info from a ZC frame whether internally or externally
82 // allocated
83 
84 // Generate a ZC reference to the buffer(s) in this frame
85 // If the buffer doesn't appear to be one allocated by ZC
86 // then the behaviour depends on maycopy:
87 // If maycopy=0 then return NULL
88 // If maycopy=1 && the src frame is in a form where we can easily copy
89 // the data, then allocate a new buffer and copy the data into it
90 // Otherwise return NULL
91 // If maycopy == 0 then ZC may be NULL
92 AVRpiZcRefPtr av_rpi_zc_ref(void * const logging_context, const AVZcEnvPtr zc,
93  const struct AVFrame * const frame, const enum AVPixelFormat expected_format, const int maycopy);
94 
95 // Unreference the buffer refed/allocated by _zc_ref
96 // If fr_ref is NULL then this will NOP
97 void av_rpi_zc_unref(AVRpiZcRefPtr fr_ref);
98 
99 // Get the vc_handle from the frame ref
100 // Returns -1 if ref doesn't look valid
101 int av_rpi_zc_vc_handle(const AVRpiZcRefPtr fr_ref);
102 // Get the vcsm_handle from the frame ref
103 // Returns 0 if ref doesn't look valid
104 unsigned int av_rpi_zc_vcsm_handle(const AVRpiZcRefPtr fr_ref);
105 // Get offset from the start of the memory referenced
106 // by the vc_handle to valid data
107 int av_rpi_zc_offset(const AVRpiZcRefPtr fr_ref);
108 // Length of buffer data
109 int av_rpi_zc_length(const AVRpiZcRefPtr fr_ref);
110 // Get the number of bytes allocated from the frame ref
111 // Returns 0 if ref doesn't look valid
112 int av_rpi_zc_numbytes(const AVRpiZcRefPtr fr_ref);
113 // Geometry this frame was allocated with
114 const AVRpiZcFrameGeometry * av_rpi_zc_geometry(const AVRpiZcRefPtr fr_ref);
115 
116 //----------------------------------------------------------------------------
117 //
118 // Calls for external frame allocation
119 
120 // Callbacks registered in av_rpi_zc_init2
121 
122 // Callback to allocate a buf for a frame
123 // The frame itself is generated in the calling code
124 //
125 // Parameters:
126 // pool_env value passed to av-rpi_zc_init2
127 // size size wanted
128 // geo geometry of the frame to be allocated
129 // Returns:
130 // NULL Alloc failed
131 // ptr AVBufferBuf* of allocated buffer
132 // In most cases av_rpi_zc_buf will be called by this function
133 // and this will be the buf returned by that.
134 typedef AVBufferRef * av_rpi_zc_alloc_buf_fn_t(void * pool_env, size_t size,
135  const AVRpiZcFrameGeometry * geo);
136 
137 // Callback once ffmpeg is completely done with this pool
138 // Called once all allocated buffers have been derefed and ffmpegs ref to this
139 // pool has been dropped
140 typedef void av_rpi_zc_free_pool_fn_t(void * pool_env);
141 
142 // Init ZC into a context
143 // Sets opaque, get_buffer2, thread_safe_callbacks
144 // Use if you want to allocate your own pools and/or create ZC buffers for
145 // all decoders
146 // RPI HEVC decoders will allocate appropriate VCSM buffers which can be taken
147 // apart by av_rpi_zc_xxx calls without this
148 int av_rpi_zc_init2(struct AVCodecContext * const s,
149  void * pool_env, av_rpi_zc_alloc_buf_fn_t * alloc_buf_fn,
150  av_rpi_zc_free_pool_fn_t * free_pool_fn);
151 
152 // Free ZC from a context
153 void av_rpi_zc_uninit2(struct AVCodecContext * const s);
154 
155 // Get minimum pool size in frames - valid by the time the first alloc request
156 // occurs. Takes into account thread requests and DPB sizes derived from SPS
157 // rather than just adding a worst case DPB size.
159 
160 typedef struct av_rpi_zc_buf_fn_tab_s {
161  // This AVBuffer is being freed by ffmpeg - return memory
162  // to external pool. Memory may be, but need not be, unmapped.
163  // v is the ptr passed in av_rpi_zc_buf
164  void (* free)(void * v);
165 
166  // Return appropriate handles / mappings
167  // v is the ptr passed in av_rpi_zc_buf
168  unsigned int (* vcsm_handle)(void * v);
169  unsigned int (* vc_handle)(void * v);
170  void * (* map_arm)(void * v);
171  unsigned int (* map_vc)(void * v);
173 
174 // Allocate a ZC AVBufferRef and set its callback table
175 // Doesn't take a buffer address directly - relies on callbacks to return
176 // addresses as they are required. Mappings need not be generated until
177 // the map callbacks are called but they should persist from then until
178 // the buffer is freed.
179 //
180 // Parameters:
181 // numbytes Size of the buffer
182 // addr_offset Offset to first usable byte of buffer (for alignment)
183 // normally 0
184 // v Pointer passed to callbacks
185 // fn_tab Function table
186 AVBufferRef * av_rpi_zc_buf(size_t numbytes, int addr_offset, void * v, const av_rpi_zc_buf_fn_tab_t * fn_tab);
187 
188 // Get v ptr set in in av_rpi_zc_buf
189 void * av_rpi_zc_buf_v(AVBufferRef * const buf);
190 
191 //----------------------------------------------------------------------------
192 //
193 // Mostly internal calls but might possibly be wanted by outside code
194 
196 AVZcEnvPtr av_rpi_zc_int_env_alloc(void * const logctx);
197 void av_rpi_zc_set_decoder_pool_size(const AVZcEnvPtr zc, const unsigned int pool_size);
198 
199 // Test to see if the context is using zc (checks get_buffer2)
200 int av_rpi_zc_in_use(const struct AVCodecContext * const s);
201 
202 // Get buffer generates placeholders for later alloc
204 // Resolve actually does the alloc (noop if already alloced)
205 // Set data pointers on a buffer/frame that was copied before the alloc
206 // accured
207 #define ZC_RESOLVE_FAIL 0 // return error on invalid
208 #define ZC_RESOLVE_ALLOC 1 // alloc as invalid
209 #define ZC_RESOLVE_WAIT_VALID 2 // wait for valid
210 #define ZC_RESOLVE_ALLOC_VALID 3 // alloc as valid
211 int av_rpi_zc_resolve_buffer(AVBufferRef * const buf, const int may_alloc);
212 int av_rpi_zc_resolve_frame(AVFrame * const frame, const int may_alloc);
213 
216 
217 
218 
219 
221  void * pool_env,
222  av_rpi_zc_alloc_buf_fn_t * alloc_buf_fn,
223  av_rpi_zc_free_pool_fn_t * free_pool_fn);
225 
226 
227 #endif
228 
static AVFrame * frame
AVPixelFormat
Pixel format.
Definition: pixfmt.h:64
void av_rpi_zc_uninit2(struct AVCodecContext *const s)
int av_rpi_zc_in_use(const struct AVCodecContext *const s)
int av_rpi_zc_numbytes(const AVRpiZcRefPtr fr_ref)
AVRpiZcRefPtr av_rpi_zc_ref(void *const logging_context, const AVZcEnvPtr zc, const struct AVFrame *const frame, const enum AVPixelFormat expected_format, const int maycopy)
AVZcEnvPtr av_rpi_zc_int_env_alloc(void *const logctx)
int av_rpi_zc_offset(const AVRpiZcRefPtr fr_ref)
int av_rpi_zc_get_buffer(const AVZcEnvPtr zc, AVFrame *const frame)
unsigned int av_rpi_zc_vcsm_handle(const AVRpiZcRefPtr fr_ref)
void av_rpi_zc_int_env_freep(AVZcEnvPtr *zc)
void * av_rpi_zc_buf_v(AVBufferRef *const buf)
void av_rpi_zc_env_release(const AVZcEnvPtr zc)
AVZcEnvPtr av_rpi_zc_env_alloc(void *logctx, void *pool_env, av_rpi_zc_alloc_buf_fn_t *alloc_buf_fn, av_rpi_zc_free_pool_fn_t *free_pool_fn)
struct AVZcEnv * AVZcEnvPtr
Definition: rpi_zc.h:56
int av_rpi_zc_length(const AVRpiZcRefPtr fr_ref)
void av_rpi_zc_unref(AVRpiZcRefPtr fr_ref)
const AVRpiZcFrameGeometry * av_rpi_zc_geometry(const AVRpiZcRefPtr fr_ref)
int av_rpi_zc_resolve_buffer(AVBufferRef *const buf, const int may_alloc)
AVRpiZcFrameGeometry av_rpi_zc_frame_geometry(const int format, const unsigned int video_width, const unsigned int video_height)
AVBufferRef * av_rpi_zc_buf(size_t numbytes, int addr_offset, void *v, const av_rpi_zc_buf_fn_tab_t *fn_tab)
int av_rpi_zc_resolve_frame(AVFrame *const frame, const int may_alloc)
int av_rpi_zc_set_valid_frame(AVFrame *const frame)
void av_rpi_zc_set_decoder_pool_size(const AVZcEnvPtr zc, const unsigned int pool_size)
int av_rpi_zc_vc_handle(const AVRpiZcRefPtr fr_ref)
int av_rpi_zc_set_broken_frame(AVFrame *const frame)
AVBufferRef * av_rpi_zc_alloc_buf_fn_t(void *pool_env, size_t size, const AVRpiZcFrameGeometry *geo)
Definition: rpi_zc.h:134
int av_rpi_zc_init2(struct AVCodecContext *const s, void *pool_env, av_rpi_zc_alloc_buf_fn_t *alloc_buf_fn, av_rpi_zc_free_pool_fn_t *free_pool_fn)
unsigned int av_rpi_zc_get_decoder_pool_size(const AVZcEnvPtr zc)
void av_rpi_zc_free_pool_fn_t(void *pool_env)
Definition: rpi_zc.h:140
A reference to a data buffer.
Definition: buffer.h:81
main external API structure.
Definition: avcodec.h:526
This structure describes decoded (raw) audio or video data.
Definition: frame.h:300
unsigned int stride_c
Definition: rpi_zc.h:62
unsigned int planes_c
Definition: rpi_zc.h:64
unsigned int height_c
Definition: rpi_zc.h:63
unsigned int height_y
Definition: rpi_zc.h:61
unsigned int stride_y
Definition: rpi_zc.h:60
unsigned int video_width
Definition: rpi_zc.h:70
unsigned int bytes_per_pel
Definition: rpi_zc.h:66
unsigned int stripes
Definition: rpi_zc.h:65
unsigned int video_height
Definition: rpi_zc.h:71