Advertisement
Guest User

AR.Drone 2, video decode frame only

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