Live555 live video of camera images from v4l2

Source: Internet
Author: User
Combined with the previous collection of v4l2 videos, live555 is used to publish real-time streams through rtsp. capture. h, capture. cpp, vcompress. h, vcompress. cpp should refer to the previous articles. here we only paste v4l2_x264_service.cpp [cpp] viewplaincopy # includestdio. h # define destdlib. h # includeunistd

Combined with the previous collection of v4l2 videos, live555 is used to publish real-time streams through rtsp. capture. h, capture. cpp, vcompress. h, vcompress. cpp should refer to the previous articles. here we only paste v4l2_x264_service.cpp [cpp] view plaincopy # includestdio. h # define destdlib. h # includeunistd

Combined with the previous collection of v4l2 videos, live555 is used to publish real-time streams through rtsp. capture. h, capture. cpp, vcompress. h, vcompress. cpp should refer to the previous articles. here we only paste v4l2_x264_service.cpp

[Cpp]View plaincopy

  1. # Include
  2. # Include
  3. # Include
  4. # Include
  5. # Include
  6. # Include
  7. # Include
  8. # Include
  9. # Include
  10. # Include "capture. h"
  11. # Include "vcompress. h"
  12. Static UsageEnvironment * _ env = 0;
  13. # Define SINK_PORT 3030
  14. # Define VIDEO_WIDTH 320
  15. # Define VIDEO_HEIGHT 240
  16. # Define FRAME_PER_SEC 5.0
  17. Pid_t gettid ()
  18. {
  19. Return syscall (SYS_gettid );
  20. }
  21. // Use webcam + x264
  22. Class WebcamFrameSource: public FramedSource
  23. {
  24. Void * mp_capture, * mp_compress; // v4l2 + x264 encoder
  25. Int m_started;
  26. Void * mp_token;
  27. Public:
  28. WebcamFrameSource (UsageEnvironment & env)
  29. : FramedSource (env)
  30. {
  31. Fprintf (stderr, "[% d] % s... calling \ n", gettid (), _ func __);
  32. Mp_capture = capture_open ("/dev/video0", VIDEO_WIDTH, VIDEO_HEIGHT, PIX_FMT_YUV420P );
  33. If (! Mp_capture ){
  34. Fprintf (stderr, "% s: open/dev/video0 err \ n", _ func __);
  35. Exit (-1 );
  36. }
  37. Mp_compress = vc_open (VIDEO_WIDTH, VIDEO_HEIGHT, FRAME_PER_SEC );
  38. If (! Mp_compress ){
  39. Fprintf (stderr, "% s: open x264 err \ n", _ func __);
  40. Exit (-1 );
  41. }
  42. M_started = 0;
  43. Mp_token = 0;
  44. }
  45. ~ WebcamFrameSource ()
  46. {
  47. Fprintf (stderr, "[% d] % s... calling \ n", gettid (), _ func __);
  48. If (m_started ){
  49. Envir (). taskScheduler (). unscheduleDelayedTask (mp_token );
  50. }
  51. If (mp_compress)
  52. Vc_close (mp_compress );
  53. If (mp_capture)
  54. Capture_close (mp_capture );
  55. }
  56. Protected:
  57. Virtual void doGetNextFrame ()
  58. {
  59. If (m_started) return;
  60. M_started = 1;
  61. // Calculate the wait time based on fps
  62. Double delay= 1000.0/FRAME_PER_SEC;
  63. Int to_delay = delay * 1000; // us
  64. Mp_token = envir (). taskScheduler (). scheduleDelayedTask (to_delay,
  65. GetNextFrame, this );
  66. }

[Cpp]View plaincopy

  1. Virtual unsigned maxFrameSize () const // This is very important. If it is not set, it may cause getNextFrame () to show that the fMaxSize is smaller than the actual Encoding Frame, resulting in incomplete images.

[Cpp]View plaincopy

  1. {Return 100*1024 ;}

[Cpp]View plaincopy

  1. Private:
  2. Static void getNextFrame (void * ptr)
  3. {
  4. (WebcamFrameSource *) ptr)-> getNextFrame1 ();
  5. }
  6. Void getNextFrame1 ()
  7. {
  8. // Capture:
  9. Picture pic;
  10. If (capture_get_picture (mp_capture, & pic) <0 ){
  11. Fprintf (stderr, "===% s: capture_get_picture err \ n", _ func __);
  12. M_started = 0;
  13. Return;
  14. }
  15. // Compress
  16. Const void * outbuf;
  17. Int outlen;
  18. If (vc_compress (mp_compress, pic. data, pic. stride, & outbuf, & outlen) <0 ){
  19. Fprintf (stderr, "===% s: vc_compress err \ n", _ func __);
  20. M_started = 0;
  21. Return;
  22. }
  23. Int64_t pts, dts;
  24. Int key;
  25. Vc_get_last_frame_info (mp_compress, & key, & pts, & dts );
  26. // Save outbuf
  27. Gettimeofday (& fPresentationTime, 0 );
  28. FFrameSize = outlen;
  29. If (fFrameSize> fMaxSize ){
  30. FNumTruncatedBytes = fFrameSize-fMaxSize;
  31. FFrameSize = fMaxSize;
  32. }
  33. Else {
  34. FNumTruncatedBytes = 0;
  35. }
  36. Memmove (fTo, outbuf, fFrameSize );
  37. // Notify
  38. AfterGetting (this );
  39. M_started = 0;
  40. }
  41. };
  42. Class WebcamOndemandMediaSubsession: public OnDemandServerMediaSubsession
  43. {
  44. Public:
  45. Static WebcamOndemandMediaSubsession * createNew (UsageEnvironment & env, FramedSource * source)
  46. {
  47. Return new WebcamOndemandMediaSubsession (env, source );
  48. }
  49. Protected:
  50. WebcamOndemandMediaSubsession (UsageEnvironment & env, FramedSource * source)
  51. : OnDemandServerMediaSubsession (env, True) // reuse the first source
  52. {
  53. Fprintf (stderr, "[% d] % s... calling \ n", gettid (), _ func __);
  54. Mp_source = source;
  55. Mp_sdp_line = 0;
  56. }
  57. ~ WebcamOndemandMediaSubsession ()
  58. {
  59. Fprintf (stderr, "[% d] % s... calling \ n", gettid (), _ func __);
  60. If (mp_sdp_line) free (mp_sdp_line );
  61. }
  62. Private:
  63. Static void afterPlayingDummy (void * ptr)
  64. {
  65. Fprintf (stderr, "[% d] % s... calling \ n", gettid (), _ func __);
  66. // OK
  67. WebcamOndemandMediaSubsession * This = (WebcamOndemandMediaSubsession *) ptr;
  68. This-> m_done = 0xff;
  69. }
  70. Static void chkForAuxSDPLine (void * ptr)
  71. {
  72. WebcamOndemandMediaSubsession * This = (WebcamOndemandMediaSubsession *) ptr;
  73. This-> chkForAuxSDPLine1 ();
  74. }
  75. Void chkForAuxSDPLine1 ()
  76. {
  77. Fprintf (stderr, "[% d] % s... calling \ n", gettid (), _ func __);
  78. If (mp_dummy_rtpsink-> auxSDPLine ())
  79. M_done = 0xff;
  80. Else {
  81. Int delay = 100*1000; // 100 ms
  82. NextTask () = envir (). taskScheduler (). scheduleDelayedTask (delay,
  83. ChkForAuxSDPLine, this );
  84. }
  85. }
  86. Protected:
  87. Virtual const char * getAuxSDPLine (RTPSink * sink, FramedSource * source)
  88. {
  89. Fprintf (stderr, "[% d] % s... calling \ n", gettid (), _ func __);
  90. If (mp_sdp_line) return mp_sdp_line;
  91. Mp_dummy_rtpsink = sink;
  92. Mp_dummy_rtpsink-> startPlaying (* source, 0, 0 );
  93. // Mp_dummy_rtpsink-> startPlaying (* source, afterPlayingDummy, this );
  94. ChkForAuxSDPLine (this );
  95. M_done = 0;
  96. Envir (). taskScheduler (). doEventLoop (& m_done );
  97. Mp_sdp_line = strdup (mp_dummy_rtpsink-> auxSDPLine ());
  98. Mp_dummy_rtpsink-> stopPlaying ();
  99. Return mp_sdp_line;
  100. }
  101. Virtual RTPSink * createNewRTPSink (Groupsock * rtpsock, unsigned char type, FramedSource * source)
  102. {
  103. Fprintf (stderr, "[% d] % s... calling \ n", gettid (), _ func __);
  104. Return hsf-videortpsink: createNew (envir (), rtpsock, type );
  105. }
  106. Virtual FramedSource * createNewStreamSource (unsigned sid, unsigned & bitrate)
  107. {
  108. Fprintf (stderr, "[% d] % s... calling \ n", gettid (), _ func __);
  109. Bitrate = 500;
  110. Return hsf-videostreamframer: createNew (envir (), new WebcamFrameSource (envir ()));
  111. }
  112. Private:
  113. FramedSource * mp_source; // corresponding to WebcamFrameSource
  114. Char * mp_sdp_line;
  115. RTPSink * mp_dummy_rtpsink;
  116. Char m_done;
  117. };
  118. Static void test_task (void * ptr)
  119. {
  120. Fprintf (stderr, "test: task... \ n ");
  121. _ Env-> taskScheduler (). scheduleDelayedTask (100000, test_task, 0 );
  122. }
  123. Static void test (UsageEnvironment & env)
  124. {
  125. Fprintf (stderr, "test: begin... \ n ");
  126. Char done = 0;
  127. Int delay = 100*1000;
  128. Env. taskScheduler (). scheduleDelayedTask (delay, test_task, 0 );
  129. Env. taskScheduler (). doEventLoop (& done );
  130. Fprintf (stderr, "test: end... \ n ");
  131. }
  132. Int main (int argc, char ** argv)
  133. {
  134. // Env
  135. TaskScheduler * schedew = basictaskschedew: createNew ();
  136. _ Env = BasicUsageEnvironment: createNew (* schedew );
  137. // Test
  138. // Test (* _ env );
  139. // Rtsp server
  140. RTSPServer * rtspServer = RTSPServer: createNew (* _ env, 8554 );
  141. If (! RtspServer ){
  142. Fprintf (stderr, "ERR: create RTSPServer err \ n ");
  143. : Exit (-1 );
  144. }
  145. // Add live stream
  146. Do {
  147. WebcamFrameSource * webcam_source = 0;
  148. ServerMediaSession * sms = ServerMediaSession: createNew (* _ env, "webcam", 0, "Session from/dev/video0 ");
  149. Sms-> addSubsession (WebcamOndemandMediaSubsession: createNew (* _ env, webcam_source ));
  150. RtspServer-> addServerMediaSession (sms );
  151. Char * url = rtspServer-> rtspURL (sms );
  152. * _ Env <"using url \" "<url <" \ "\ n ";
  153. Delete [] url;
  154. } While (0 );
  155. // Run loop
  156. _ Env-> taskScheduler (). doEventLoop ();
  157. Return 1;
  158. }


Live555 + libavcodec + libswscale + libx264 is required. The client uses vlc, mplayer, quicktime ,.....

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.