• 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 int
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     return 0;
223 }
224 
225 static int
trace_video_codec_end_frame(struct pipe_video_codec * _codec,struct pipe_video_buffer * _target,struct pipe_picture_desc * picture)226 trace_video_codec_end_frame(struct pipe_video_codec *_codec,
227                     struct pipe_video_buffer *_target,
228                     struct pipe_picture_desc *picture)
229 {
230     struct trace_video_codec *tr_vcodec = trace_video_codec(_codec);
231     struct pipe_video_codec *codec = tr_vcodec->video_codec;
232     struct trace_video_buffer *tr_target = trace_video_buffer(_target);
233     struct pipe_video_buffer *target = tr_target->video_buffer;
234 
235     trace_dump_call_begin("pipe_video_codec", "end_frame");
236     trace_dump_arg(ptr, codec);
237     trace_dump_arg(ptr, target);
238     trace_dump_arg(pipe_picture_desc, picture);
239     trace_dump_call_end();
240 
241     bool copied = unwrap_refrence_frames(&picture);
242     codec->end_frame(codec, target, picture);
243     if (copied)
244         FREE(picture);
245     return 0;
246 }
247 
248 static void
trace_video_codec_flush(struct pipe_video_codec * _codec)249 trace_video_codec_flush(struct pipe_video_codec *_codec)
250 {
251     struct trace_video_codec *tr_vcodec = trace_video_codec(_codec);
252     struct pipe_video_codec *codec = tr_vcodec->video_codec;
253 
254     trace_dump_call_begin("pipe_video_codec", "flush");
255     trace_dump_arg(ptr, codec);
256     trace_dump_call_end();
257 
258     codec->flush(codec);
259 }
260 
261 static void
trace_video_codec_get_feedback(struct pipe_video_codec * _codec,void * feedback,unsigned * size,struct pipe_enc_feedback_metadata * metadata)262 trace_video_codec_get_feedback(struct pipe_video_codec *_codec,
263                                void *feedback,
264                                unsigned *size,
265                                struct pipe_enc_feedback_metadata* metadata)
266 {
267     struct trace_video_codec *tr_vcodec = trace_video_codec(_codec);
268     struct pipe_video_codec *codec = tr_vcodec->video_codec;
269 
270     trace_dump_call_begin("pipe_video_codec", "get_feedback");
271     trace_dump_arg(ptr, codec);
272     trace_dump_arg(ptr, feedback);
273     trace_dump_arg(ptr, size);
274     trace_dump_call_end();
275 
276     codec->get_feedback(codec, feedback, size, metadata);
277 }
278 
279 static int
trace_video_codec_fence_wait(struct pipe_video_codec * _codec,struct pipe_fence_handle * fence,uint64_t timeout)280 trace_video_codec_fence_wait(struct pipe_video_codec *_codec,
281                              struct pipe_fence_handle *fence,
282                              uint64_t timeout)
283 {
284     struct trace_video_codec *tr_vcodec = trace_video_codec(_codec);
285     struct pipe_video_codec *codec = tr_vcodec->video_codec;
286 
287     trace_dump_call_begin("pipe_video_codec", "fence_wait");
288     trace_dump_arg(ptr, codec);
289     trace_dump_arg(ptr, fence);
290     trace_dump_arg(uint, timeout);
291 
292     int ret = codec->fence_wait(codec, fence, timeout);
293 
294     trace_dump_ret(int, ret);
295     trace_dump_call_end();
296 
297     return ret;
298 }
299 
300 struct pipe_video_codec *
trace_video_codec_create(struct trace_context * tr_ctx,struct pipe_video_codec * video_codec)301 trace_video_codec_create(struct trace_context *tr_ctx,
302                          struct pipe_video_codec *video_codec)
303 {
304    struct trace_video_codec *tr_vcodec;
305 
306    if (!video_codec)
307       goto error1;
308 
309    if (!trace_enabled())
310       goto error1;
311 
312    tr_vcodec = rzalloc(NULL, struct trace_video_codec);
313    if (!tr_vcodec)
314       goto error1;
315 
316     memcpy(&tr_vcodec->base, video_codec, sizeof(struct pipe_video_codec));
317     tr_vcodec->base.context = &tr_ctx->base;
318 
319 #define TR_VC_INIT(_member) \
320    tr_vcodec->base . _member = video_codec -> _member ? trace_video_codec_ ## _member : NULL
321 
322     TR_VC_INIT(destroy);
323     TR_VC_INIT(begin_frame);
324     TR_VC_INIT(decode_macroblock);
325     TR_VC_INIT(decode_bitstream);
326     TR_VC_INIT(encode_bitstream);
327     TR_VC_INIT(process_frame);
328     TR_VC_INIT(end_frame);
329     TR_VC_INIT(flush);
330     TR_VC_INIT(get_feedback);
331     TR_VC_INIT(fence_wait);
332 
333 #undef TR_VC_INIT
334 
335    tr_vcodec->video_codec = video_codec;
336 
337    return &tr_vcodec->base;
338 
339 error1:
340    return video_codec;
341 }
342 
343 
344 static void
trace_video_buffer_destroy(struct pipe_video_buffer * _buffer)345 trace_video_buffer_destroy(struct pipe_video_buffer *_buffer)
346 {
347     struct trace_video_buffer *tr_vbuffer = trace_video_buffer(_buffer);
348     struct pipe_video_buffer *video_buffer = tr_vbuffer->video_buffer;
349 
350     trace_dump_call_begin("pipe_video_buffer", "destroy");
351     trace_dump_arg(ptr, video_buffer);
352     trace_dump_call_end();
353 
354     for (int i=0; i < VL_NUM_COMPONENTS; i++) {
355         pipe_sampler_view_reference(&tr_vbuffer->sampler_view_planes[i], NULL);
356         pipe_sampler_view_reference(&tr_vbuffer->sampler_view_components[i], NULL);
357     }
358     for (int i=0; i < VL_MAX_SURFACES; i++) {
359         pipe_surface_reference(&tr_vbuffer->surfaces[i], NULL);
360     }
361     video_buffer->destroy(video_buffer);
362 
363     ralloc_free(tr_vbuffer);
364 }
365 
366 static void
trace_video_buffer_get_resources(struct pipe_video_buffer * _buffer,struct pipe_resource ** resources)367 trace_video_buffer_get_resources(struct pipe_video_buffer *_buffer, struct pipe_resource **resources)
368 {
369     struct trace_video_buffer *tr_vbuffer = trace_video_buffer(_buffer);
370     struct pipe_video_buffer *buffer = tr_vbuffer->video_buffer;
371 
372     trace_dump_call_begin("pipe_video_buffer", "get_resources");
373     trace_dump_arg(ptr, buffer);
374 
375     buffer->get_resources(buffer, resources);
376 
377     // TODO: A `trace_dump_ret_arg` style of function would be more appropriate
378     trace_dump_arg_array(ptr, resources, VL_NUM_COMPONENTS);
379     trace_dump_call_end();
380 }
381 
382 static struct pipe_sampler_view **
trace_video_buffer_get_sampler_view_planes(struct pipe_video_buffer * _buffer)383 trace_video_buffer_get_sampler_view_planes(struct pipe_video_buffer *_buffer)
384 {
385     struct trace_context *tr_ctx = trace_context(_buffer->context);
386     struct trace_video_buffer *tr_vbuffer = trace_video_buffer(_buffer);
387     struct pipe_video_buffer *buffer = tr_vbuffer->video_buffer;
388 
389     trace_dump_call_begin("pipe_video_buffer", "get_sampler_view_planes");
390     trace_dump_arg(ptr, buffer);
391 
392     struct pipe_sampler_view **view_planes = buffer->get_sampler_view_planes(buffer);
393 
394     trace_dump_ret_array(ptr, view_planes, VL_NUM_COMPONENTS);
395     trace_dump_call_end();
396 
397     for (int i=0; i < VL_NUM_COMPONENTS; i++) {
398         if (!view_planes || !view_planes[i]) {
399             pipe_sampler_view_reference(&tr_vbuffer->sampler_view_planes[i], NULL);
400         } else if (tr_vbuffer->sampler_view_planes[i] == NULL || (trace_sampler_view(tr_vbuffer->sampler_view_planes[i])->sampler_view != view_planes[i])) {
401             pipe_sampler_view_reference(&tr_vbuffer->sampler_view_planes[i], trace_sampler_view_create(tr_ctx, view_planes[i]->texture, view_planes[i]));
402         }
403     }
404 
405     return view_planes ? tr_vbuffer->sampler_view_planes : NULL;
406 }
407 
408 static struct pipe_sampler_view **
trace_video_buffer_get_sampler_view_components(struct pipe_video_buffer * _buffer)409 trace_video_buffer_get_sampler_view_components(struct pipe_video_buffer *_buffer)
410 {
411     struct trace_context *tr_ctx = trace_context(_buffer->context);
412     struct trace_video_buffer *tr_vbuffer = trace_video_buffer(_buffer);
413     struct pipe_video_buffer *buffer = tr_vbuffer->video_buffer;
414 
415     trace_dump_call_begin("pipe_video_buffer", "get_sampler_view_components");
416     trace_dump_arg(ptr, buffer);
417 
418     struct pipe_sampler_view **view_components = buffer->get_sampler_view_components(buffer);
419 
420     trace_dump_ret_array(ptr, view_components, VL_NUM_COMPONENTS);
421     trace_dump_call_end();
422 
423     for (int i=0; i < VL_NUM_COMPONENTS; i++) {
424         if (!view_components || !view_components[i]) {
425             pipe_sampler_view_reference(&tr_vbuffer->sampler_view_components[i], NULL);
426         } else if (tr_vbuffer->sampler_view_components[i] == NULL || (trace_sampler_view(tr_vbuffer->sampler_view_components[i])->sampler_view != view_components[i])) {
427             pipe_sampler_view_reference(&tr_vbuffer->sampler_view_components[i], trace_sampler_view_create(tr_ctx, view_components[i]->texture, view_components[i]));
428         }
429     }
430 
431     return view_components ? tr_vbuffer->sampler_view_components : NULL;
432 }
433 
434 static struct pipe_surface **
trace_video_buffer_get_surfaces(struct pipe_video_buffer * _buffer)435 trace_video_buffer_get_surfaces(struct pipe_video_buffer *_buffer)
436 {
437     struct trace_context *tr_ctx = trace_context(_buffer->context);
438     struct trace_video_buffer *tr_vbuffer = trace_video_buffer(_buffer);
439     struct pipe_video_buffer *buffer = tr_vbuffer->video_buffer;
440 
441     trace_dump_call_begin("pipe_video_buffer", "get_surfaces");
442     trace_dump_arg(ptr, buffer);
443 
444     struct pipe_surface **surfaces = buffer->get_surfaces(buffer);
445 
446     trace_dump_ret_array(ptr, surfaces, VL_MAX_SURFACES);
447     trace_dump_call_end();
448 
449     for (int i=0; i < VL_MAX_SURFACES; i++) {
450         if (!surfaces || !surfaces[i]) {
451             pipe_surface_reference(&tr_vbuffer->surfaces[i], NULL);
452         } else if (tr_vbuffer->surfaces[i] == NULL || (trace_surface(tr_vbuffer->surfaces[i])->surface != surfaces[i])){
453             pipe_surface_reference(&tr_vbuffer->surfaces[i], trace_surf_create(tr_ctx, surfaces[i]->texture, surfaces[i]));
454         }
455     }
456 
457     return surfaces ? tr_vbuffer->surfaces : NULL;
458 }
459 
460 
461 struct pipe_video_buffer *
trace_video_buffer_create(struct trace_context * tr_ctx,struct pipe_video_buffer * video_buffer)462 trace_video_buffer_create(struct trace_context *tr_ctx,
463                           struct pipe_video_buffer *video_buffer)
464 {
465    struct trace_video_buffer *tr_vbuffer;
466 
467    if (!video_buffer)
468       goto error1;
469 
470    if (!trace_enabled())
471       goto error1;
472 
473    tr_vbuffer = rzalloc(NULL, struct trace_video_buffer);
474    if (!tr_vbuffer)
475       goto error1;
476 
477     memcpy(&tr_vbuffer->base, video_buffer, sizeof(struct pipe_video_buffer));
478     tr_vbuffer->base.context = &tr_ctx->base;
479 
480 #define TR_VB_INIT(_member) \
481    tr_vbuffer->base . _member = video_buffer -> _member ? trace_video_buffer_ ## _member : NULL
482 
483     TR_VB_INIT(destroy);
484     TR_VB_INIT(get_resources);
485     TR_VB_INIT(get_sampler_view_planes);
486     TR_VB_INIT(get_sampler_view_components);
487     TR_VB_INIT(get_surfaces);
488 
489 #undef TR_VB_INIT
490 
491    tr_vbuffer->video_buffer = video_buffer;
492 
493    return &tr_vbuffer->base;
494 
495 error1:
496    return video_buffer;
497 }
498