|
1 |
| -# pi_h264 |
| 1 | +##Live real time stream with no delay from Raspberry Pi to browser |
| 2 | +based on boradway https://github.com/mbebenita/Broadway h264 decoder. |
| 3 | + |
| 4 | +In browser it use broadway h264 software decoder to decode NAL h264 packets and rende decoded frame to html canvas. |
| 5 | +For receive NAL h264 baseline packets from server (Raspberry Pi) it use websocket over sockets.io. |
| 6 | +On server it use raspberry camera for get NAL baseline h264 packets from spawned process and send it over sockets.io. |
| 7 | + |
| 8 | +``` |
| 9 | + var proc = spawn('raspivid', [ |
| 10 | + '-t', '0', |
| 11 | + '-o', '-',// out h264 to std out |
| 12 | + "-n", |
| 13 | + '-w', 640, |
| 14 | + '-h', 360, |
| 15 | + '-fps', 30, |
| 16 | + '-pf', "baseline"//only accepted profile for decoder |
| 17 | + ]); |
| 18 | +``` |
| 19 | + Is it possible to use ffmpeg 3.2 with h264_omx support (need modify libavcodec/omx.c for enable baseline h264 profile, because default is High profile). |
| 20 | + |
| 21 | +ADD to libavcodec/omx.c at line 518 v3.2 for support baseline profile |
| 22 | +!!!Do not need configure again if you already have compiled ffmpeg, just run make command!!! |
| 23 | +``` |
| 24 | + avc.eProfile=OMX_VIDEO_AVCProfileBaseline; |
| 25 | +``` |
| 26 | +Example: |
| 27 | +``` |
| 28 | + if (avctx->codec->id == AV_CODEC_ID_H264) { |
| 29 | + OMX_VIDEO_PARAM_AVCTYPE avc = { 0 }; |
| 30 | + INIT_STRUCT(avc); |
| 31 | + avc.nPortIndex = s->out_port; |
| 32 | + err = OMX_GetParameter(s->handle, OMX_IndexParamVideoAvc, &avc); |
| 33 | + CHECK(err); |
| 34 | + avc.nBFrames = 0; |
| 35 | + avc.nPFrames = avctx->gop_size - 1; |
| 36 | + //add |
| 37 | + avc.eProfile=OMX_VIDEO_AVCProfileBaseline;/////////////////////////////// change h264 profile to baseline |
| 38 | + //avc.eLevel=OMX_VIDEO_AVCLevel3;//////////////////////////////////////// change level if you want |
| 39 | + //add |
| 40 | + err = OMX_SetParameter(s->handle, OMX_IndexParamVideoAvc, &avc); |
| 41 | + CHECK(err); |
| 42 | + } |
| 43 | + ``` |
| 44 | + Possible profile values: |
| 45 | + ``` |
| 46 | +OMX_VIDEO_AVCProfileBaseline Baseline profile |
| 47 | +OMX_VIDEO_AVCProfileMain Main profile |
| 48 | +OMX_VIDEO_AVCProfileExtended Extended profile |
| 49 | +OMX_VIDEO_AVCProfileHigh High profile |
| 50 | +OMX_VIDEO_AVCProfileHigh10 High 10 profile |
| 51 | +OMX_VIDEO_AVCProfileHigh422 High 4:2:2 profile |
| 52 | +OMX_VIDEO_AVCProfileHigh444 High 4:4:4 profile |
| 53 | +OMX_VIDEO_AVCProfileMax |
| 54 | + ``` |
| 55 | + Possible level value: |
| 56 | + ``` |
| 57 | +OMX_VIDEO_AVCLevel1 Level 1 |
| 58 | +OMX_VIDEO_AVCLevel1b Level 1b |
| 59 | +OMX_VIDEO_AVCLevel11 Level 1.1 |
| 60 | +OMX_VIDEO_AVCLevel12 Level 1.2 |
| 61 | +OMX_VIDEO_AVCLevel13 Level 1.3 |
| 62 | +OMX_VIDEO_AVCLevel2 Level 2 |
| 63 | +OMX_VIDEO_AVCLevel21 Level 2.1 |
| 64 | +OMX_VIDEO_AVCLevel22 Level 2.2 |
| 65 | +OMX_VIDEO_AVCLevel3 Level 3 |
| 66 | +OMX_VIDEO_AVCLevel31 Level 3.1 |
| 67 | +OMX_VIDEO_AVCLevel32 Level 3.2 |
| 68 | +OMX_VIDEO_AVCLevel4 Level 4 |
| 69 | +OMX_VIDEO_AVCLevel41 Level 4.1 |
| 70 | +OMX_VIDEO_AVCLevel42 Level 4.2 |
| 71 | +OMX_VIDEO_AVCLevel5 Level 5 |
| 72 | +OMX_VIDEO_AVCLevel51 Level 5.1 |
| 73 | +OMX_VIDEO_AVCLevelMax |
| 74 | + ``` |
| 75 | + |
| 76 | +``` |
| 77 | +>./configure --disable-encoders --enable-encoder='aac,h264_omx,mjpeg,libx264' --disable-decoders --enable-decoder='rawvideo,mjpeg,aac,h264_mmal' --enable-libfreetype --enable-static --enable-mmal --enable-omx-rpi --enable-yasm --enable-nonfree --enable-gpl --disable-doc |
| 78 | +
|
| 79 | +>make -j 4 |
| 80 | +
|
| 81 | +>sudo make install |
| 82 | +//comilation time 2h-3h |
| 83 | +``` |
| 84 | +After check ffmpeg decoder and encoders: |
| 85 | +``` |
| 86 | +ffmpeg -decoders |
| 87 | + V..... h264_mmal h264 (mmal) (codec h264) |
| 88 | + V....D mjpeg MJPEG (Motion JPEG) |
| 89 | + V..... rawvideo raw video |
| 90 | + A....D aac AAC (Advanced Audio Coding) |
| 91 | +``` |
| 92 | +``` |
| 93 | + V..... h264_omx OpenMAX IL H.264 video encoder (codec h264) |
| 94 | + VFS... mjpeg MJPEG (Motion JPEG) |
| 95 | + A..... aac AAC (Advanced Audio Coding) |
| 96 | +``` |
| 97 | + |
| 98 | +Spawn ffmpeg for get h264 stream from Raspberry Pi camera: |
| 99 | +``` |
| 100 | +var proc=spawn("ffmpeg",[ |
| 101 | + "-s","640x360", |
| 102 | + "-re", |
| 103 | + "-framerate","30", |
| 104 | + "-pixel_format","yuv420p",//"yuv420p",//yuyv422 |
| 105 | + "-i","/dev/video0", |
| 106 | + // "-c:v","h264_mmal", |
| 107 | + // "-i","/home/pi/360.mp4", |
| 108 | + "-c:v","h264_omx", |
| 109 | + "-b:v","1M", |
| 110 | + "-s","640x360", |
| 111 | + //"-s","1920x1080", |
| 112 | + "-an", |
| 113 | + //"-profile:v","baseline",//baseline |
| 114 | + //"-vf","drawtext='fontfile=/home/pi/ffmpeg/freefont/FreeSans.ttf:text=%{localtime\}':fontsize=50:fontcolor=yellow@1:box=1:[email protected]:x=(w-tw)/2:y=10", |
| 115 | + "-loglevel","error", |
| 116 | + "-stats", |
| 117 | + "-tune","zerolatency", |
| 118 | + "-f","h264", |
| 119 | + //"-reset_timestamps", "1", |
| 120 | + //"-movflags","isml+empty_moov+faststart",//+faststart//"frag_keyframe+empty_moov", |
| 121 | + //"-fflags","nobuffer", |
| 122 | + //"-frag_duration","5", |
| 123 | + "-y", |
| 124 | + //"cam_video.mp4" |
| 125 | + "-" |
| 126 | + ]) |
| 127 | +``` |
| 128 | +With -vf (video filter option) you can write text, time, etc on video frame encoded in h264! |
| 129 | + |
| 130 | +Raw stream from spawned procees must be parsed as separate NAL units and sended over socket to client. |
| 131 | +``` |
| 132 | + var rawstream=proc.stdout.pipe(new Split(NALseparator)) |
| 133 | +
|
| 134 | + rawstream.on("data",function(data){ |
| 135 | + socket.emit("nal_packet",Buffer.concat([NALseparator, data])) |
| 136 | + }) |
| 137 | +
|
| 138 | +``` |
| 139 | + |
| 140 | +##Client (html) |
| 141 | +Open page http://_raspberry_ip:8080 |
| 142 | + |
| 143 | +After page was loaded socket connected to server and now you can push start/stop button to start/stop live stream. |
0 commit comments