Advertisement
Guest User

drone video, stack smash version

a guest
Mar 12th, 2014
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 9.39 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdint.h>
  3.  
  4. #include <sys/socket.h>
  5. #include <sys/time.h>
  6. #include <netinet/in.h>
  7. #include <netdb.h>
  8. #include <arpa/inet.h>
  9. #include <fcntl.h>
  10.  
  11. #define DRONE_IP_ADDR "192.168.1.1"
  12. #define DRONE_VID_STREAM_PORT "5555"
  13.  
  14. extern "C" {
  15. #include <libavcodec/avcodec.h>
  16. #include <libswscale/swscale.h>
  17. #include <libavformat/avformat.h>
  18. }
  19.  
  20. #define VIDEO_BUFFER_SIZE 40000
  21. #define PaVE_HEADER_LENGTH 68
  22.  
  23. typedef struct { //PaVE
  24. uint8_t signature[4]; /* "PaVE" - used to identify the start of
  25.  frame */
  26. uint8_t version; /* Version code */
  27. uint8_t video_codec; /* Codec of the following frame */
  28. uint16_t header_size; /* Size of the parrot_video_encapsulation_t */
  29. uint32_t payload_size; /* Amount of data following this PaVE */
  30. uint16_t encoded_stream_width; /* ex: 640 */
  31. uint16_t encoded_stream_height; /* ex: 368 */
  32. uint16_t display_width; /* ex: 640 */
  33. uint16_t display_height; /* ex: 360 */
  34. uint32_t frame_number; /* Frame position inside the current stream
  35.  */
  36. uint32_t timestamp; /* In milliseconds */
  37. uint8_t total_chuncks; /* Number of UDP packets containing the
  38.  current decodable payload - currently unused */
  39. uint8_t chunck_index; /* Position of the packet - first chunk is #0
  40.  - currenty unused*/
  41. uint8_t frame_type; /* I-frame, P-frame -
  42.  parrot_video_encapsulation_frametypes_t */
  43. uint8_t control; /* Special commands like end
  44.     -of-stream or
  45.     advertised frames */
  46.     uint32_t stream_byte_position_lw; /* Byte position of the current payload in
  47.      the encoded stream - lower 32-bit word */
  48.     uint32_t stream_byte_position_uw; /* Byte position of the current payload in
  49.      the encoded stream - upper 32-bit word */
  50.     uint16_t stream_id; /* This ID indentifies packets that should be
  51.      recorded together */
  52.     uint8_t total_slices; /* number of slices composing the current
  53.      frame */
  54.     uint8_t slice_index; /* position of the current slice in the frame
  55.      */
  56.     uint8_t header1_size; /* H.264 only : size of SPS inside payload -
  57.      no SPS present if value is zero */
  58.     uint8_t header2_size; /* H.264 only : size of PPS inside payload -
  59.      no PPS present if value is zero */
  60.     uint8_t reserved2[2]; /* Padding to align on 48 bytes */
  61.     uint32_t advertised_size; /* Size of frames announced as advertised
  62.      frames */
  63.     uint8_t reserved3[12]; /* Padding to align on 64 bytes */
  64.     //uint8_t reserved4[4]; // padding -- added b/c it was in the KIPR library code
  65. }__attribute__ ((packed)) parrot_video_encapsulation_t;
  66.  
  67. typedef enum { //PaVE codec IDs
  68.     CODEC_UNKNNOWN = 0,
  69.     CODEC_VLIB,
  70.     CODEC_P264,
  71.     CODEC_MPEG4_VISUAL,
  72.     CODEC_MPEG4_AVC
  73. } parrot_video_encapsulation_codecs_t;
  74.  
  75. typedef enum { //PaVE frame types
  76.     FRAME_TYPE_UNKNNOWN = 0, FRAME_TYPE_IDR_FRAME, /* headers followed by I-frame */
  77.     FRAME_TYPE_I_FRAME, FRAME_TYPE_P_FRAME, FRAME_TYPE_HEADERS
  78. } parrot_video_encapsulation_frametypes_t;
  79.  
  80. void printPaVE(parrot_video_encapsulation_t PaVE) {
  81.     printf("\n---------------------------\n");
  82.  
  83.     printf("Codec : %s\n",
  84.             (PaVE.video_codec == CODEC_MPEG4_VISUAL) ?
  85.                     "MP4" :
  86.                     ((PaVE.video_codec == CODEC_MPEG4_AVC) ? "H264" : "Unknown"));
  87.  
  88.     printf("StreamID : %d \n", PaVE.stream_id);
  89.     printf("Timestamp : %d ms\n", PaVE.timestamp);
  90.     printf("Encoded dims : %d x %d\n", PaVE.encoded_stream_width,
  91.             PaVE.encoded_stream_height);
  92.     printf("Display dims : %d x %d\n", PaVE.display_width, PaVE.display_height);
  93.     ////printf ("Header size  : %d (PaVE size : %d)\n", PaVE.header_size, sizeof (parrot_video_encapsulation_t));
  94.     printf("Header size : %d\n", PaVE.header_size);
  95.     printf("Payload size : %d\n", PaVE.payload_size);
  96.     printf("Size of SPS inside payload : %d\n", PaVE.header1_size);
  97.     printf("Size of PPS inside payload : %d\n", PaVE.header2_size);
  98.     printf("Slices in the frame : %d\n", PaVE.total_slices);
  99.     printf("Frame Type / Number : %s : %d : slide %d/%d\n",
  100.             (PaVE.frame_type == FRAME_TYPE_P_FRAME) ?
  101.                     "P-Frame" :
  102.                     ((PaVE.frame_type == FRAME_TYPE_I_FRAME) ?
  103.                             "I-Frame" : "IDR-Frame"), PaVE.frame_number,
  104.             PaVE.slice_index + 1, PaVE.total_slices);
  105.  
  106.     printf("---------------------------\n\n");
  107. }
  108.  
  109. int receive(int socketNumber, unsigned char *buffer, int requestSize) {
  110.     int lengthReceived = -1;
  111.     //lengthReceived = recv(socketNumber,buffer,requestSize,MSG_WAITALL);
  112.     lengthReceived = recv(socketNumber, buffer, requestSize, 0);
  113.     if (lengthReceived < 0) {
  114.         printf("failed to receive assumed PaVE packet\n");
  115.     } else {
  116.         printf("asked for %i bytes, received packet of %i bytes\n", requestSize,
  117.                 lengthReceived);
  118.     }
  119.     return lengthReceived;
  120. }
  121.  
  122. void fetch_and_decode(int socketNumber,AVCodecContext *codecContext, AVFrame *picture) {
  123.     parrot_video_encapsulation_t PaVE;
  124.     unsigned char part[VIDEO_BUFFER_SIZE];
  125.     int partLength = -1;
  126.     partLength = receive(socketNumber, part, VIDEO_BUFFER_SIZE);
  127.     if (partLength < 0) {
  128.         printf("did not receive video data\n");
  129.         return;
  130.     }
  131.     //memcpy(&PaVE, part, sizeof(parrot_video_encapsulation_t));
  132.     memcpy(&PaVE, part, 76);
  133.     if (strncmp((const char*) PaVE.signature, "PaVE", 4) != 0) {
  134.         printf("PaVE not synchronized, skipping iteration\n");
  135.         return;
  136.     } else {
  137.         printf("PaVE synchronized. YIPEEEEEEEEEEEEEEEEEEEEEEEE\n");
  138.         printPaVE(PaVE);
  139.     }
  140.  
  141.     uint32_t read = 0;
  142.     unsigned char payload[VIDEO_BUFFER_SIZE];
  143.  
  144.     memcpy(payload, part + PaVE.header_size, partLength - PaVE.header_size);
  145.     read += partLength - PaVE.header_size;
  146.  
  147.     double lastTime = clock();
  148.  
  149.     while (read < PaVE.payload_size && (clock() - lastTime) < 0.1) {
  150.         int payloadLength = -1;
  151.         printf("gathering payload...\n");
  152.         payloadLength = receive(socketNumber, payload + read,
  153.                 PaVE.payload_size - read);
  154.         read += payloadLength;
  155.         lastTime = clock();
  156.     }
  157.  
  158.     printf("payload complete, attempting to decode frame\n");
  159.  
  160.     AVPacket avPkt;
  161.     av_init_packet(&avPkt);
  162.     avPkt.data = NULL;
  163.     avPkt.size = 0;
  164.  
  165.     avPkt.data = payload;
  166.     avPkt.size = PaVE.payload_size;
  167.  
  168.     printf("avPkt.size = %d\n",avPkt.size);
  169.  
  170.     int done = 0;
  171.     int ret = -1;
  172.     ret = avcodec_decode_video2(codecContext, picture, &done, &avPkt);
  173.     if (done == 0 || ret < 0) {
  174.         printf("could not decode frame\n");
  175.         return;
  176.     }
  177.     else {
  178.         printf("\"done\" integer = %d\n",done);
  179.         printf("avcodec_decode_video2 returned %d\n",ret);
  180.     }
  181.  
  182.     avPkt.data = NULL;
  183.     avPkt.size = 0;
  184.     av_free_packet(&avPkt);
  185. }
  186.  
  187. ///////////////////////////////////////////////////////////////////////
  188. ///////////////////////////////////////////////////////////////////////
  189. ///////////////////////////////////////////////////////////////////////
  190.  
  191. int main() {
  192.  
  193.     printf("\n\n*********************** START ***********************\n\n");
  194.  
  195.     //printf("size of PaVE = %d\n",sizeof(parrot_video_encapsulation_t));
  196.  
  197.     int socketNumber;
  198.     sockaddr_in myAddr;
  199.     sockaddr_in droneAddr;
  200.  
  201.     // my sockaddr_in
  202.     myAddr.sin_family = AF_INET;
  203.     myAddr.sin_addr.s_addr = INADDR_ANY; // my IP address
  204.     myAddr.sin_port = htons(atoi(DRONE_VID_STREAM_PORT));
  205.  
  206.     // the drone's sockaddr_in
  207.     droneAddr.sin_family = AF_INET;
  208.     droneAddr.sin_addr.s_addr = inet_addr(DRONE_IP_ADDR);
  209.     droneAddr.sin_port = htons(atoi(DRONE_VID_STREAM_PORT));
  210.  
  211.     socketNumber = socket(AF_INET, SOCK_STREAM, 0);
  212.  
  213.     // bind the socket
  214.     if (bind(socketNumber, (sockaddr*) &myAddr, sizeof(sockaddr_in)) < 0) {
  215.         printf("failed to bind socket\n");
  216.     }
  217.  
  218.     int result = -1;
  219.     result = connect(socketNumber, (sockaddr*) &droneAddr, sizeof(sockaddr_in));
  220.     if (result != 0) {
  221.         printf("connection NOT established\n");
  222.     }
  223.  
  224.     printf("booting...\n");
  225.     // send one packet of "some bytes" to drone
  226.     uint8_t gateKeyPkt[4] = { 0x01, 0x00, 0x00, 0x00 };
  227.     int badCheck = -1;
  228.     badCheck = sendto(socketNumber, (void*) gateKeyPkt, 4, 0,
  229.             (sockaddr*) &droneAddr, sizeof(sockaddr_in));
  230.  
  231.     if (badCheck < 0) {
  232.         printf("Failed to send basic packet\n");
  233.     }
  234.  
  235.     AVCodec *codec = NULL;
  236.     AVCodecContext *codecContext = NULL;
  237.     AVFrame *picture = NULL;
  238.     AVFrame *pictureBGR = NULL;
  239.     SwsContext *convertContext = NULL;
  240.  
  241.     uint8_t *buffer = NULL;
  242.  
  243.     // set up codec
  244.     avcodec_register_all();
  245.     av_register_all();
  246.     av_log_set_level(AV_LOG_DEBUG);
  247.     codec = avcodec_find_decoder(CODEC_ID_H264);
  248.     codec->id = CODEC_ID_H264;
  249.  
  250.     codecContext = avcodec_alloc_context3(codec);
  251.     avcodec_open2(codecContext, codec, 0);
  252.     codecContext->width = 640;
  253.     codecContext->height = 360;
  254.     codecContext->pix_fmt = PIX_FMT_YUV420P;
  255.     codecContext->skip_frame = AVDISCARD_DEFAULT;
  256.     codecContext->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK;
  257.     codecContext->skip_loop_filter = AVDISCARD_DEFAULT;
  258.     codecContext->workaround_bugs = FF_BUG_AUTODETECT;
  259.     codecContext->debug = true;
  260.  
  261.     // allocate video frames and buffer
  262.     picture = avcodec_alloc_frame();
  263.     pictureBGR = avcodec_alloc_frame();
  264.     buffer = (uint8_t*) av_mallocz(
  265.             avpicture_get_size(PIX_FMT_BGR24, codecContext->width,
  266.                     codecContext->height) * sizeof(uint8_t));
  267.  
  268.     // assign parts of buffer to image planes in BGR frame
  269.     avpicture_fill((AVPicture*) pictureBGR, buffer, PIX_FMT_BGR24,
  270.             codecContext->width, codecContext->height);
  271.  
  272.     // convert context
  273.     convertContext = sws_getContext(codecContext->width, codecContext->height,
  274.             codecContext->pix_fmt, codecContext->width, codecContext->height,
  275.             PIX_FMT_BGR24, SWS_SPLINE, 0, 0, 0);
  276.  
  277.     for (int j = 0; j < 100; j++) {
  278.         fetch_and_decode(socketNumber, codecContext, picture);
  279.         printf("I escaped from the dreaded fetch_and_decode monster!\n");
  280.     }
  281.  
  282.     avcodec_close(codecContext);
  283.     av_free(codecContext);
  284.     av_free(picture);
  285.     av_free(pictureBGR);
  286.  
  287.     return 1;
  288. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement