• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "tr_public.h"
2 #include "tr_dump.h"
3 #include "tr_dump_state.h"
4 #include "tr_texture.h"
5 #include "u_inlines.h"
6 #include "u_video.h"
7 #include "tr_video.h"
8 #include "pipe/p_video_codec.h"
9 #include "pipe/p_video_enums.h"
10 #include "util/macros.h"
11 #include "util/u_memory.h"
12 #include "vl/vl_defines.h"
13 
14 static void
trace_video_codec_destroy(struct pipe_video_codec * _codec)15 trace_video_codec_destroy(struct pipe_video_codec *_codec)
16 {
17     struct trace_video_codec *tr_vcodec = trace_video_codec(_codec);
18     struct pipe_video_codec *video_codec = tr_vcodec->video_codec;
19 
20     trace_dump_call_begin("pipe_video_codec", "destroy");
21     trace_dump_arg(ptr, video_codec);
22     trace_dump_call_end();
23 
24     video_codec->destroy(video_codec);
25 
26     ralloc_free(tr_vcodec);
27 }
28 
29 static void
unwrap_refrence_frames_in_place(struct pipe_video_buffer ** refrence_frames,unsigned max_num_refrence_frame)30 unwrap_refrence_frames_in_place(struct pipe_video_buffer **refrence_frames, unsigned max_num_refrence_frame)
31 {
32     for (unsigned i=0; i < max_num_refrence_frame; i++) {
33         if (refrence_frames[i]) {
34             struct trace_video_buffer *tr_buffer = trace_video_buffer(refrence_frames[i]);
35             refrence_frames[i] = tr_buffer->video_buffer;
36         }
37     }
38 }
39 
40 static bool
unwrap_refrence_frames(struct pipe_picture_desc ** picture)41 unwrap_refrence_frames(struct pipe_picture_desc **picture)
42 {
43     // only decode pictures use video buffers for refrences
44     if ((*picture)->entry_point != PIPE_VIDEO_ENTRYPOINT_BITSTREAM)
45         return false;
46     switch (u_reduce_video_profile((*picture)->profile)) {
47     case PIPE_VIDEO_FORMAT_MPEG12: {
48         struct pipe_mpeg12_picture_desc *copied = mem_dup(*picture, sizeof(struct pipe_mpeg12_picture_desc));
49         assert(copied);
50         unwrap_refrence_frames_in_place(copied->ref, ARRAY_SIZE(copied->ref));
51         *picture = (struct pipe_picture_desc*)copied;
52         return true;
53     }
54     case PIPE_VIDEO_FORMAT_MPEG4: {
55         struct pipe_mpeg4_picture_desc *copied = mem_dup(*picture, sizeof(struct pipe_mpeg4_picture_desc));
56         assert(copied);
57         unwrap_refrence_frames_in_place(copied->ref, ARRAY_SIZE(copied->ref));
58         *picture = (struct pipe_picture_desc*)copied;
59         return true;
60     }
61     case PIPE_VIDEO_FORMAT_VC1:{
62         struct pipe_vc1_picture_desc *copied = mem_dup(*picture, sizeof(struct pipe_vc1_picture_desc));
63         assert(copied);
64         unwrap_refrence_frames_in_place(copied->ref, ARRAY_SIZE(copied->ref));
65         *picture = (struct pipe_picture_desc*)copied;
66         return true;
67     }
68     case PIPE_VIDEO_FORMAT_MPEG4_AVC: {
69         struct pipe_h264_picture_desc *copied = mem_dup(*picture, sizeof(struct pipe_h264_picture_desc));
70         assert(copied);
71         unwrap_refrence_frames_in_place(copied->ref, ARRAY_SIZE(copied->ref));
72         *picture = (struct pipe_picture_desc*)copied;
73         return true;
74     }
75     case PIPE_VIDEO_FORMAT_HEVC:{
76         struct pipe_h265_picture_desc *copied = mem_dup(*picture, sizeof(struct pipe_h265_picture_desc));
77         assert(copied);
78         unwrap_refrence_frames_in_place(copied->ref, ARRAY_SIZE(copied->ref));
79         *picture = (struct pipe_picture_desc*)copied;
80         return true;
81     }
82     case PIPE_VIDEO_FORMAT_JPEG:
83         return false;
84     case PIPE_VIDEO_FORMAT_VP9:{
85         struct pipe_vp9_picture_desc *copied = mem_dup(*picture, sizeof(struct pipe_vp9_picture_desc));
86         assert(copied);
87         unwrap_refrence_frames_in_place(copied->ref, ARRAY_SIZE(copied->ref));
88         *picture = (struct pipe_picture_desc*)copied;
89         return true;
90     }
91     case PIPE_VIDEO_FORMAT_AV1:{
92         struct pipe_av1_picture_desc *copied = mem_dup(*picture, sizeof(struct pipe_av1_picture_desc));
93         assert(copied);
94         unwrap_refrence_frames_in_place(copied->ref, ARRAY_SIZE(copied->ref));
95         unwrap_refrence_frames_in_place(&copied->film_grain_target, 1);
96         *picture = (struct pipe_picture_desc*)copied;
97         return true;
98     }
99     case PIPE_VIDEO_FORMAT_UNKNOWN:
100     default:
101         unreachable("unknown video format");
102     }
103 }
104 
105 static void
trace_video_codec_begin_frame(struct pipe_video_codec * _codec,struct pipe_video_buffer * _target,struct pipe_picture_desc * picture)106 trace_video_codec_begin_frame(struct pipe_video_codec *_codec,
107                     struct pipe_video_buffer *_target,
108                     struct pipe_picture_desc *picture)
109 {
110     struct trace_video_codec *tr_vcodec = trace_video_codec(_codec);
111     struct pipe_video_codec *codec = tr_vcodec->video_codec;
112     struct trace_video_buffer *tr_target = trace_video_buffer(_target);
113     struct pipe_video_buffer *target = tr_target->video_buffer;
114 
115     trace_dump_call_begin("pipe_video_codec", "begin_frame");
116     trace_dump_arg(ptr, codec);
117     trace_dump_arg(ptr, target);
118     trace_dump_arg(pipe_picture_desc, picture);
119     trace_dump_call_end();
120 
121     bool copied = unwrap_refrence_frames(&picture);
122     codec->begin_frame(codec, target, picture);
123     if (copied)
124         FREE(picture);
125 }
126 
127 static void
trace_video_codec_decode_macroblock(struct pipe_video_codec * _codec,struct pipe_video_buffer * _target,struct pipe_picture_desc * picture,const struct pipe_macroblock * macroblocks,unsigned num_macroblocks)128 trace_video_codec_decode_macroblock(struct pipe_video_codec *_codec,
129                             struct pipe_video_buffer *_target,
130                             struct pipe_picture_desc *picture,
131                             const struct pipe_macroblock *macroblocks,
132                             unsigned num_macroblocks)
133 {
134     struct trace_video_codec *tr_vcodec = trace_video_codec(_codec);
135     struct pipe_video_codec *codec = tr_vcodec->video_codec;
136     struct trace_video_buffer *tr_target = trace_video_buffer(_target);
137     struct pipe_video_buffer *target = tr_target->video_buffer;
138 
139     trace_dump_call_begin("pipe_video_codec", "decode_macroblock");
140     trace_dump_arg(ptr, codec);
141     trace_dump_arg(ptr, target);
142     trace_dump_arg(pipe_picture_desc, picture);
143     // TODO: how to dump pipe_macroblocks? It's only a single pointer,
144     //  but each struct has codec dependent size, so can't use generic trace_dump_arg_array
145     trace_dump_arg(ptr, macroblocks);
146     trace_dump_arg(uint, num_macroblocks);
147     trace_dump_call_end();
148 
149     bool copied = unwrap_refrence_frames(&picture);
150     codec->decode_macroblock(codec, target, picture, macroblocks, num_macroblocks);
151     if (copied)
152         FREE(picture);
153 }
154 
155 static void
trace_video_codec_decode_bitstream(struct pipe_video_codec * _codec,struct pipe_video_buffer * _target,struct pipe_picture_desc * picture,unsigned num_buffers,const void * const * buffers,const unsigned * sizes)156 trace_video_codec_decode_bitstream(struct pipe_video_codec *_codec,
157                         struct pipe_video_buffer *_target,
158                         struct pipe_picture_desc *picture,
159                         unsigned num_buffers,
160                         const void * const *buffers,
161                         const unsigned *sizes)
162 {
163     struct trace_video_codec *tr_vcodec = trace_video_codec(_codec);
164     struct pipe_video_codec *codec = tr_vcodec->video_codec;
165     struct trace_video_buffer *tr_target = trace_video_buffer(_target);
166     struct pipe_video_buffer *target = tr_target->video_buffer;
167 
168     trace_dump_call_begin("pipe_video_codec", "decode_bitstream");
169     trace_dump_arg(ptr, codec);
170     trace_dump_arg(ptr, target);
171     trace_dump_arg(pipe_picture_desc, picture);
172 
173     trace_dump_arg(uint, num_buffers);
174     trace_dump_arg_array(ptr, buffers, num_buffers);
175     trace_dump_arg_array(uint, sizes, num_buffers);
176     trace_dump_call_end();
177 
178     bool copied = unwrap_refrence_frames(&picture);
179     codec->decode_bitstream(codec, target, picture, num_buffers, buffers, sizes);
180     if (copied)
181         FREE(picture);
182 }
183 
184 static void
trace_video_codec_encode_bitstream(struct pipe_video_codec * _codec,struct pipe_video_buffer * _source,struct pipe_resource * destination,void ** feedback)185 trace_video_codec_encode_bitstream(struct pipe_video_codec *_codec,
186                         struct pipe_video_buffer *_source,
187                         struct pipe_resource *destination,
188                         void **feedback)
189 {
190     struct trace_video_codec *tr_vcodec = trace_video_codec(_codec);
191     struct pipe_video_codec *codec = tr_vcodec->video_codec;
192     struct trace_video_buffer *tr_source = trace_video_buffer(_source);
193     struct pipe_video_buffer *source = tr_source->video_buffer;
194 
195     trace_dump_call_begin("pipe_video_codec", "encode_bitstream");
196     trace_dump_arg(ptr, codec);
197     trace_dump_arg(ptr, source);
198     trace_dump_arg(ptr, destination);
199     trace_dump_arg(ptr, feedback);
200     trace_dump_call_end();
201 
202     codec->encode_bitstream(codec, source, destination, feedback);
203 }
204 
205 static void
trace_video_codec_process_frame(struct pipe_video_codec * _codec,struct pipe_video_buffer * _source,const struct pipe_vpp_desc * process_properties)206 trace_video_codec_process_frame(struct pipe_video_codec *_codec,
207                         struct pipe_video_buffer *_source,
208                         const struct pipe_vpp_desc *process_properties)
209 {
210     struct trace_video_codec *tr_vcodec = trace_video_codec(_codec);
211     struct pipe_video_codec *codec = tr_vcodec->video_codec;
212     struct trace_video_buffer *tr_source = trace_video_buffer(_source);
213     struct pipe_video_buffer *source = tr_source->video_buffer;
214 
215     trace_dump_call_begin("pipe_video_codec", "process_frame");
216     trace_dump_arg(ptr, codec);
217     trace_dump_arg(ptr, source);
218     trace_dump_arg(pipe_vpp_desc, process_properties);
219     trace_dump_call_end();
220 
221     codec->process_frame(codec, source, process_properties);
222 }
223 
224 static void
trace_video_codec_end_frame(struct pipe_video_codec * _codec,struct pipe_video_buffer * _target,struct pipe_picture_desc * picture)225 trace_video_codec_end_frame(struct pipe_video_codec *_codec,
226                     struct pipe_video_buffer *_target,
227                     struct pipe_picture_desc *picture)
228 {
229     struct trace_video_codec *tr_vcodec = trace_video_codec(_codec);
230     struct pipe_video_codec *codec = tr_vcodec->video_codec;
231     struct trace_video_buffer *tr_target = trace_video_buffer(_target);
232     struct pipe_video_buffer *target = tr_target->video_buffer;
233 
234     trace_dump_call_begin("pipe_video_codec", "end_frame");
235     trace_dump_arg(ptr, codec);
236     trace_dump_arg(ptr, target);
237     trace_dump_arg(pipe_picture_desc, picture);
238     trace_dump_call_end();
239 
240     bool copied = unwrap_refrence_frames(&picture);
241     codec->end_frame(codec, target, picture);
242     if (copied)
243         FREE(picture);
244 }
245 
246 static void
trace_video_codec_flush(struct pipe_video_codec * _codec)247 trace_video_codec_flush(struct pipe_video_codec *_codec)
248 {
249     struct trace_video_codec *tr_vcodec = trace_video_codec(_codec);
250     struct pipe_video_codec *codec = tr_vcodec->video_codec;
251 
252     trace_dump_call_begin("pipe_video_codec", "flush");
253     trace_dump_arg(ptr, codec);
254     trace_dump_call_end();
255 
256     codec->flush(codec);
257 }
258 
259 static void
trace_video_codec_get_feedback(struct pipe_video_codec * _codec,void * feedback,unsigned * size,struct pipe_enc_feedback_metadata * metadata)260 trace_video_codec_get_feedback(struct pipe_video_codec *_codec,
261                                void *feedback,
262                                unsigned *size,
263                                struct pipe_enc_feedback_metadata* metadata)
264 {
265     struct trace_video_codec *tr_vcodec = trace_video_codec(_codec);
266     struct pipe_video_codec *codec = tr_vcodec->video_codec;
267 
268     trace_dump_call_begin("pipe_video_codec", "get_feedback");
269     trace_dump_arg(ptr, codec);
270     trace_dump_arg(ptr, feedback);
271     trace_dump_arg(ptr, size);
272     trace_dump_call_end();
273 
274     codec->get_feedback(codec, feedback, size, metadata);
275 }
276 
277 static int
trace_video_codec_get_decoder_fence(struct pipe_video_codec * _codec,struct pipe_fence_handle * fence,uint64_t timeout)278 trace_video_codec_get_decoder_fence(struct pipe_video_codec *_codec,
279                         struct pipe_fence_handle *fence,
280                         uint64_t timeout)
281 {
282     struct trace_video_codec *tr_vcodec = trace_video_codec(_codec);
283     struct pipe_video_codec *codec = tr_vcodec->video_codec;
284 
285     trace_dump_call_begin("pipe_video_codec", "get_decoder_fence");
286     trace_dump_arg(ptr, codec);
287     trace_dump_arg(ptr, fence);
288     trace_dump_arg(uint, timeout);
289 
290     int ret = codec->get_decoder_fence(codec, fence, timeout);
291 
292     trace_dump_ret(int, ret);
293     trace_dump_call_end();
294 
295     return ret;
296 }
297 
298 static int
trace_video_codec_get_processor_fence(struct pipe_video_codec * _codec,struct pipe_fence_handle * fence,uint64_t timeout)299 trace_video_codec_get_processor_fence(struct pipe_video_codec *_codec,
300                             struct pipe_fence_handle *fence,
301                             uint64_t timeout)
302 {
303     struct trace_video_codec *tr_vcodec = trace_video_codec(_codec);
304     struct pipe_video_codec *codec = tr_vcodec->video_codec;
305 
306     trace_dump_call_begin("pipe_video_codec", "get_processor_fence");
307     trace_dump_arg(ptr, codec);
308     trace_dump_arg(ptr, fence);
309     trace_dump_arg(uint, timeout);
310 
311     int ret = codec->get_processor_fence(codec, fence, timeout);
312 
313     trace_dump_ret(int, ret);
314     trace_dump_call_end();
315 
316     return ret;
317 }
318 
319 static void
trace_video_codec_update_decoder_target(struct pipe_video_codec * _codec,struct pipe_video_buffer * _old,struct pipe_video_buffer * _updated)320 trace_video_codec_update_decoder_target(struct pipe_video_codec *_codec,
321                                 struct pipe_video_buffer *_old,
322                                 struct pipe_video_buffer *_updated)
323 {
324     struct trace_video_codec *tr_vcodec = trace_video_codec(_codec);
325     struct pipe_video_codec *codec = tr_vcodec->video_codec;
326     struct trace_video_buffer *tr_old = trace_video_buffer(_old);
327     struct pipe_video_buffer *old = tr_old->video_buffer;
328     struct trace_video_buffer *tr_updated = trace_video_buffer(_updated);
329     struct pipe_video_buffer *updated = tr_updated->video_buffer;
330 
331     trace_dump_call_begin("pipe_video_codec", "update_decoder_target");
332     trace_dump_arg(ptr, codec);
333     trace_dump_arg(ptr, old);
334     trace_dump_arg(ptr, updated);
335     trace_dump_call_end();
336 
337     codec->update_decoder_target(codec, old, updated);
338 }
339 
340 struct pipe_video_codec *
trace_video_codec_create(struct trace_context * tr_ctx,struct pipe_video_codec * video_codec)341 trace_video_codec_create(struct trace_context *tr_ctx,
342                          struct pipe_video_codec *video_codec)
343 {
344    struct trace_video_codec *tr_vcodec;
345 
346    if (!video_codec)
347       goto error1;
348 
349    if (!trace_enabled())
350       goto error1;
351 
352    tr_vcodec = rzalloc(NULL, struct trace_video_codec);
353    if (!tr_vcodec)
354       goto error1;
355 
356     memcpy(&tr_vcodec->base, video_codec, sizeof(struct pipe_video_codec));
357     tr_vcodec->base.context = &tr_ctx->base;
358 
359 #define TR_VC_INIT(_member) \
360    tr_vcodec->base . _member = video_codec -> _member ? trace_video_codec_ ## _member : NULL
361 
362     TR_VC_INIT(destroy);
363     TR_VC_INIT(begin_frame);
364     TR_VC_INIT(decode_macroblock);
365     TR_VC_INIT(decode_bitstream);
366     TR_VC_INIT(encode_bitstream);
367     TR_VC_INIT(process_frame);
368     TR_VC_INIT(end_frame);
369     TR_VC_INIT(flush);
370     TR_VC_INIT(get_feedback);
371     TR_VC_INIT(get_decoder_fence);
372     TR_VC_INIT(get_processor_fence);
373     TR_VC_INIT(update_decoder_target);
374 
375 #undef TR_VC_INIT
376 
377    tr_vcodec->video_codec = video_codec;
378 
379    return &tr_vcodec->base;
380 
381 error1:
382    return video_codec;
383 }
384 
385 
386 static void
trace_video_buffer_destroy(struct pipe_video_buffer * _buffer)387 trace_video_buffer_destroy(struct pipe_video_buffer *_buffer)
388 {
389     struct trace_video_buffer *tr_vbuffer = trace_video_buffer(_buffer);
390     struct pipe_video_buffer *video_buffer = tr_vbuffer->video_buffer;
391 
392     trace_dump_call_begin("pipe_video_buffer", "destroy");
393     trace_dump_arg(ptr, video_buffer);
394     trace_dump_call_end();
395 
396     for (int i=0; i < VL_NUM_COMPONENTS; i++) {
397         pipe_sampler_view_reference(&tr_vbuffer->sampler_view_planes[i], NULL);
398         pipe_sampler_view_reference(&tr_vbuffer->sampler_view_components[i], NULL);
399     }
400     for (int i=0; i < VL_MAX_SURFACES; i++) {
401         pipe_surface_reference(&tr_vbuffer->surfaces[i], NULL);
402     }
403     video_buffer->destroy(video_buffer);
404 
405     ralloc_free(tr_vbuffer);
406 }
407 
408 static void
trace_video_buffer_get_resources(struct pipe_video_buffer * _buffer,struct pipe_resource ** resources)409 trace_video_buffer_get_resources(struct pipe_video_buffer *_buffer, struct pipe_resource **resources)
410 {
411     struct trace_video_buffer *tr_vbuffer = trace_video_buffer(_buffer);
412     struct pipe_video_buffer *buffer = tr_vbuffer->video_buffer;
413 
414     trace_dump_call_begin("pipe_video_buffer", "get_resources");
415     trace_dump_arg(ptr, buffer);
416 
417     buffer->get_resources(buffer, resources);
418 
419     // TODO: A `trace_dump_ret_arg` style of function would be more appropriate
420     trace_dump_arg_array(ptr, resources, VL_NUM_COMPONENTS);
421     trace_dump_call_end();
422 }
423 
424 static struct pipe_sampler_view **
trace_video_buffer_get_sampler_view_planes(struct pipe_video_buffer * _buffer)425 trace_video_buffer_get_sampler_view_planes(struct pipe_video_buffer *_buffer)
426 {
427     struct trace_context *tr_ctx = trace_context(_buffer->context);
428     struct trace_video_buffer *tr_vbuffer = trace_video_buffer(_buffer);
429     struct pipe_video_buffer *buffer = tr_vbuffer->video_buffer;
430 
431     trace_dump_call_begin("pipe_video_buffer", "get_sampler_view_planes");
432     trace_dump_arg(ptr, buffer);
433 
434     struct pipe_sampler_view **view_planes = buffer->get_sampler_view_planes(buffer);
435 
436     trace_dump_ret_array(ptr, view_planes, VL_NUM_COMPONENTS);
437     trace_dump_call_end();
438 
439     for (int i=0; i < VL_NUM_COMPONENTS; i++) {
440         if (!view_planes || !view_planes[i]) {
441             pipe_sampler_view_reference(&tr_vbuffer->sampler_view_planes[i], NULL);
442         } else if (tr_vbuffer->sampler_view_planes[i] == NULL || (trace_sampler_view(tr_vbuffer->sampler_view_planes[i])->sampler_view != view_planes[i])) {
443             pipe_sampler_view_reference(&tr_vbuffer->sampler_view_planes[i], trace_sampler_view_create(tr_ctx, view_planes[i]->texture, view_planes[i]));
444         }
445     }
446 
447     return view_planes ? tr_vbuffer->sampler_view_planes : NULL;
448 }
449 
450 static struct pipe_sampler_view **
trace_video_buffer_get_sampler_view_components(struct pipe_video_buffer * _buffer)451 trace_video_buffer_get_sampler_view_components(struct pipe_video_buffer *_buffer)
452 {
453     struct trace_context *tr_ctx = trace_context(_buffer->context);
454     struct trace_video_buffer *tr_vbuffer = trace_video_buffer(_buffer);
455     struct pipe_video_buffer *buffer = tr_vbuffer->video_buffer;
456 
457     trace_dump_call_begin("pipe_video_buffer", "get_sampler_view_components");
458     trace_dump_arg(ptr, buffer);
459 
460     struct pipe_sampler_view **view_components = buffer->get_sampler_view_components(buffer);
461 
462     trace_dump_ret_array(ptr, view_components, VL_NUM_COMPONENTS);
463     trace_dump_call_end();
464 
465     for (int i=0; i < VL_NUM_COMPONENTS; i++) {
466         if (!view_components || !view_components[i]) {
467             pipe_sampler_view_reference(&tr_vbuffer->sampler_view_components[i], NULL);
468         } else if (tr_vbuffer->sampler_view_components[i] == NULL || (trace_sampler_view(tr_vbuffer->sampler_view_components[i])->sampler_view != view_components[i])) {
469             pipe_sampler_view_reference(&tr_vbuffer->sampler_view_components[i], trace_sampler_view_create(tr_ctx, view_components[i]->texture, view_components[i]));
470         }
471     }
472 
473     return view_components ? tr_vbuffer->sampler_view_components : NULL;
474 }
475 
476 static struct pipe_surface **
trace_video_buffer_get_surfaces(struct pipe_video_buffer * _buffer)477 trace_video_buffer_get_surfaces(struct pipe_video_buffer *_buffer)
478 {
479     struct trace_context *tr_ctx = trace_context(_buffer->context);
480     struct trace_video_buffer *tr_vbuffer = trace_video_buffer(_buffer);
481     struct pipe_video_buffer *buffer = tr_vbuffer->video_buffer;
482 
483     trace_dump_call_begin("pipe_video_buffer", "get_surfaces");
484     trace_dump_arg(ptr, buffer);
485 
486     struct pipe_surface **surfaces = buffer->get_surfaces(buffer);
487 
488     trace_dump_ret_array(ptr, surfaces, VL_MAX_SURFACES);
489     trace_dump_call_end();
490 
491     for (int i=0; i < VL_MAX_SURFACES; i++) {
492         if (!surfaces || !surfaces[i]) {
493             pipe_surface_reference(&tr_vbuffer->surfaces[i], NULL);
494         } else if (tr_vbuffer->surfaces[i] == NULL || (trace_surface(tr_vbuffer->surfaces[i])->surface != surfaces[i])){
495             pipe_surface_reference(&tr_vbuffer->surfaces[i], trace_surf_create(tr_ctx, surfaces[i]->texture, surfaces[i]));
496         }
497     }
498 
499     return surfaces ? tr_vbuffer->surfaces : NULL;
500 }
501 
502 
503 struct pipe_video_buffer *
trace_video_buffer_create(struct trace_context * tr_ctx,struct pipe_video_buffer * video_buffer)504 trace_video_buffer_create(struct trace_context *tr_ctx,
505                           struct pipe_video_buffer *video_buffer)
506 {
507    struct trace_video_buffer *tr_vbuffer;
508 
509    if (!video_buffer)
510       goto error1;
511 
512    if (!trace_enabled())
513       goto error1;
514 
515    tr_vbuffer = rzalloc(NULL, struct trace_video_buffer);
516    if (!tr_vbuffer)
517       goto error1;
518 
519     memcpy(&tr_vbuffer->base, video_buffer, sizeof(struct pipe_video_buffer));
520     tr_vbuffer->base.context = &tr_ctx->base;
521 
522 #define TR_VB_INIT(_member) \
523    tr_vbuffer->base . _member = video_buffer -> _member ? trace_video_buffer_ ## _member : NULL
524 
525     TR_VB_INIT(destroy);
526     TR_VB_INIT(get_resources);
527     TR_VB_INIT(get_sampler_view_planes);
528     TR_VB_INIT(get_sampler_view_components);
529     TR_VB_INIT(get_surfaces);
530 
531 #undef TR_VB_INIT
532 
533    tr_vbuffer->video_buffer = video_buffer;
534 
535    return &tr_vbuffer->base;
536 
537 error1:
538    return video_buffer;
539 }
540