ducatih264enc is now using ih264enc.h from ducati side, rather than re-defining enums
[glsdk/gst-plugin-ducati.git] / tools / pp-gst-sched.py
1 #! /usr/bin/python
2 # Usage:
3 #DISPLAY=:0 GST_PERFORMANCE=*:5 GST_DEBUG=*:2,GST_SCHEDULING:5 gst-launch --gst-debug-no-color -e omx_camera num-buffers=200 do-timestamp=1 mode=0 device=0 name=cam focus=off cam.src ! "video/x-raw-yuv, format=(fourcc)NV12, width=1280, height=720, framerate=30/1" ! ducatih264enc profile=66 ! ducatih264dec! dri2videosink sync=false 2>&1 | ./pp-gst-sched.py
4 # or ducatimpeg4enc ! ducatimpeg4dec 
6 import sys
7 import time
8 import fileinput
9 import re
10 import operator
11 from datetime import datetime
13 def string_to_time (d):
14   return datetime.strptime(d[0:14], "%H:%M:%S.%f")
16 def main():
17   tr = dict()
18   cam = dict()
19   dec = dict()
20   ecs = 0
22   ### Parse stdin or any file on the command line
23   for line in fileinput.input():        
25     # Filter out GST traces from other output
26     m = re.match(r"([\w:.]+)[\s]+([\w]+)[\s]+([\w]+)[\s]+([\w]+)[\s]+(.*)",line)
27     if m == None:
28       print line
29       continue
30     (tsr,pid,adr,sev,msg) = m.groups()
32     # Parse GST_SCHEDULING traces
33     m = re.match(r"GST_SCHEDULING[\s]+gstpad.c:[\w]+:([\w:.<>]+) calling chainfunction &([\w]+) with buffer ([\w]+), data ([\w]+), malloc ([\w()]+), ts ([\w:.]+), dur ([\w:.]+)", msg)
34     if m != None:
35       (func, elem, gstBuffer, data, malloc, tsb, dur) = m.groups()
36       if func == r"gst_pad_push:<cam:src>" and gstBuffer in cam:
37         tr[tsb] = [(cam[gstBuffer], "FillBufferDone")]
38       elif func == r"gst_pad_push:<ducatih264dec0:src>":
39         dec[gstBuffer] = tsb
41       if tsb not in tr:
42         tr[tsb] = []
43       tr[tsb].append((tsr, func))
44       continue
46     # Parse omx_camera traces
47     m = re.match(r"GST_PERFORMANCE gstomx_core.c:[\w]+:FillBufferDone:<cam> FillBufferDone: GstBuffer=([\w]+)", msg)
48     if m != None:
49       gstBuffer = m.group(1)
50       cam[gstBuffer] = tsr
51       continue
53     # Parse encoder traces
54     m = re.match(r"ducati gstducatividenc.c:[\w]+:gst_ducati_videnc_handle_frame:<ducatih264enc[\w]+> Encoded frame in ([\w]+) bytes", msg)
55     if m != None:
56        ecs += int(m.group(1))
57        continue
59     # Parse dri2videosink traces
60     m = re.match(r"GST_PERFORMANCE gstdri2util.c:[\w]+:gst_dri2window_buffer_show:<dri2videosink[\w]+> (Before DRI2SwapBuffersVid|After DRI2WaitSBC), buf=([\w]+)", msg)
61     if m != None:
62       (ba, dri2_buf) = m.groups()
63       if dri2_buf in dec:
64         tr[dec[dri2_buf]].append((tsr, ba))
65       continue
67   ### End of parse stdin 
69   # Display the results, frame per frame
70   avg = cnt = 0
71   for tsb, tfs in tr.iteritems():
72     cnt +=1
73     first = prev = string_to_time(tfs[0][0])
74     print "\n*** New frame %d, timestamp: %s" % (cnt, tsb)
75     for el in tfs:
76       cur = string_to_time(el[0])
77       print "At %s (%6d us later) Func: %s" % \
78         (el[0][5:14], (cur - prev).microseconds, el[1])
79       prev = cur
80     total = cur - first
81     avg += total.microseconds
82     print "*** Total: %6d us" % (total.microseconds)
84   # Display the totals
85   if (cnt != 0):
86     if (ecs != 0):
87       print "\n=-= Encoded stream size: %d KB" % (ecs / 1024)
88       ecm = "(not optimal, due to encoder traces)"
89     else:
90       print "\n=-= Encoded stream size: N/A (lack of encoder traces)"
91       ecm = ""
92     print "\n=-= Average: %6d us on %d frames %s" % (avg / cnt, cnt, ecm)
93   else:
94     print "\n=-= No frame, the pipeline have failed"
96   return 0
97 if __name__ == '__main__':
98   main()