Advertisement
Guest User

Send TS packets over UDP

a guest
May 23rd, 2012
3,291
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.28 KB | None | 0 0
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdbool.h>
  5. #include <string.h>
  6. #include <math.h>
  7.  
  8. #include <libavcodec/avcodec.h>
  9. #include <libavformat/avformat.h>
  10. #include <libswscale/swscale.h>
  11.  
  12. // for cross compatibility
  13. typedef unsigned int IN_PORT;
  14. typedef unsigned short IN_FAMILY;
  15. typedef unsigned long IN_ADDR_T;
  16.  
  17. #ifdef WIN32
  18.  
  19. #include <winsock2.h>
  20. #include <stdint.h>
  21.  
  22. #elif defined (linux)
  23.  
  24. // the goal of these definitions is to use the same names both in Windows and Linux
  25. #include <sys/types.h>
  26. #include <sys/socket.h>
  27. #include <netinet/in.h>
  28. #include <arpa/inet.h>
  29. #include <unistd.h> /* close */
  30. #include <netdb.h> /* gethostbyname */
  31. #define INVALID_SOCKET -1
  32. #define SOCKET_ERROR -1
  33. // here we are defining a macro in order to invoke the function to close a socket with the same name
  34. #define closesocket(s) close(s)   //In windows closesocket(Socket) and linux it is close(Socket)
  35. typedef int SOCKET;
  36. typedef struct sockaddr_in SOCKADDR_IN;
  37.  
  38. typedef struct sockaddr SOCKADDR;
  39.  
  40. /*
  41.   struct sockaddr {
  42.     unsigned short    sa_family;    // address family, AF_xxx
  43.     char              sa_data[14];  // 14 bytes of protocol address
  44. };
  45.  
  46. */
  47. typedef struct in_addr IN_ADDR;
  48.  
  49. #else
  50.  
  51. #error not defined for this platform
  52.  
  53. #endif
  54.  
  55. static void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame);
  56.  
  57. static void fillPacket(AVPacket *streamPacket, uint8_t *packet, size_t size);
  58.  
  59. static void SendFrame(uint8_t *packet, size_t size);
  60.  
  61. int main (int argc, const char * argv[])
  62. {
  63.     AVFormatContext *pFormatCtx;
  64.     int             i, videoStream, audioStream, iaudio, ivideo, videoFrames;
  65.     AVCodecContext  *pCodecCtx, *audioCodecCtx;
  66.     AVCodec         *pCodec, *audioCodec;
  67.     AVFrame         *pFrame;
  68.     AVFrame         *pFrameRGB;
  69.     AVPacket        packet;
  70.     int             frameFinished;
  71.     int             numBytes;
  72.     uint8_t         *buffer;
  73.     uint8_t         *packet_buffer;
  74.     uint8_t         *outbuf;
  75.     size_t          packet_size;
  76.  
  77.     // Register all formats and codecs
  78.     av_register_all();
  79.  
  80.     // Open video file
  81.     if(av_open_input_file(&pFormatCtx, argv[1], NULL, 0, NULL)!=0)
  82.         return -1; // Couldn't open file
  83.  
  84.     // Retrieve stream information
  85.     if(av_find_stream_info(pFormatCtx)<0)
  86.         return -1; // Couldn't find stream information
  87.  
  88.     // Dump information about file onto standard error
  89.     dump_format(pFormatCtx, 0, argv[1], false);
  90.  
  91.     // Find the first video stream and the first audio stream
  92.     videoStream = audioStream = -1;
  93.     for(i=0; i<pFormatCtx->nb_streams; i++) {
  94.         if(pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO)
  95.         {
  96.             videoStream = i;
  97.             //break;
  98.         } else if (pFormatCtx->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO) {
  99.             audioStream = i;
  100.         }
  101.     }
  102.     if(videoStream==-1)
  103.         return -1; // Didn't find a video stream
  104.     if(audioStream==-1)
  105.             return -1; // Didn't find a video stream
  106.  
  107.     // Get a pointer to the codec context for the video stream
  108.     pCodecCtx=pFormatCtx->streams[videoStream]->codec;
  109.     // Get a pointer to the codec context for the audio stream
  110.     audioCodecCtx=pFormatCtx->streams[audioStream]->codec;
  111.  
  112.     // Find the decoder for the video stream
  113.     pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
  114.     if(pCodec==NULL)
  115.         return -1; // Codec not found
  116.     // Find the decoder for the audio stream
  117.     audioCodec=avcodec_find_decoder(audioCodecCtx->codec_id);
  118.     if(audioCodec==NULL)
  119.         return -1; // Codec not found
  120.  
  121.     // Open codec for the video stream
  122.     if(avcodec_open(pCodecCtx, pCodec)<0)
  123.         return -1; // Could not open codec
  124.     // Open codec for the audio stream
  125.     if(avcodec_open(audioCodecCtx, audioCodec)<0)
  126.         return -1; // Could not open codec
  127.  
  128.     // Hack to correct wrong frame rates that seem to be generated by some codecs
  129.     if(pCodecCtx->time_base.num>1000 && pCodecCtx->time_base.den==1)
  130.         pCodecCtx->time_base.den=1000;
  131.  
  132.     // Allocate video/audio frame
  133.     pFrame=avcodec_alloc_frame();
  134.  
  135.     //outbuf = malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
  136.  
  137.     // Allocate an AVFrame structure
  138.     pFrameRGB=avcodec_alloc_frame();
  139.     if(pFrameRGB==NULL)
  140.         return -1;
  141.  
  142.     printf("%d pFrame Size = %d pFrameRGB size = %d\n", sizeof(AVFrame), sizeof(*pFrame), sizeof(*pFrameRGB));
  143.  
  144.     // Determine required buffer size and allocate buffer
  145.     numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
  146.         pCodecCtx->height);
  147.  
  148.     buffer=malloc(numBytes);
  149.  
  150.     packet_buffer = NULL;
  151.  
  152.     // Assign appropriate parts of buffer to image planes in pFrameRGB
  153.     avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
  154.         pCodecCtx->width, pCodecCtx->height);
  155.  
  156.     // Read frames and save first five frames to disk
  157.     i = iaudio = ivideo = packet_size = videoFrames = 0;
  158.     while(av_read_frame(pFormatCtx, &packet)>=0)
  159.     {
  160.  
  161.         // Is this a packet from the video stream?
  162.         if(packet.stream_index==videoStream)
  163.         {
  164.  
  165.             printf("#%d Video packet found: size is %d\n", i, packet.size);
  166.  
  167.             // Decode video frame
  168.             /*avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
  169.                 packet.data, packet.size);
  170.  
  171.             // Did we get a video frame?
  172.             if(frameFinished)
  173.             {
  174.  
  175.                 static struct SwsContext *img_convert_ctx;
  176.  
  177.                 // Convert the image into YUV format that SDL uses
  178.                 if(img_convert_ctx == NULL) {
  179.                     int w = pCodecCtx->width;
  180.                     int h = pCodecCtx->height;
  181.  
  182.                     img_convert_ctx = sws_getContext(w, h,
  183.                                     pCodecCtx->pix_fmt,
  184.                                     w, h, PIX_FMT_RGB24, SWS_BICUBIC,
  185.                                     NULL, NULL, NULL);
  186.  
  187.                     if(img_convert_ctx == NULL) {
  188.                         fprintf(stderr, "Cannot initialize the conversion context!\n");
  189.                         exit(1);
  190.                     }
  191.                 }
  192.                 int ret = sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0,
  193.                           pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);
  194.  
  195.                 }*/
  196.  
  197.             i++;
  198.             ivideo++;
  199.             videoFrames++;
  200.  
  201.         } else {
  202.             printf("#%d Audio packet found: size is %d\n", i, packet.size);
  203.  
  204.             // Decode audio frame
  205.             /*int outsize = AVCODEC_MAX_AUDIO_FRAME_SIZE;
  206.             avcodec_decode_audio2(audioCodecCtx, (short *)outbuf, &outsize, packet.data, packet.size);*/
  207.  
  208.             i++;
  209.             iaudio++;
  210.         }
  211.  
  212.         //if (packet.stream_index==videoStream) {
  213.  
  214.             packet_size += packet.size;
  215.  
  216.             printf("i modulo 7 is %d size of packet is %d packet_size is %d\n", i%7, packet.size, packet_size);
  217.  
  218.             if (packet_buffer != NULL) {
  219.                 packet_buffer = realloc(packet_buffer, packet_size);
  220.             } else {
  221.                 packet_buffer = malloc(packet_size);
  222.             }
  223.  
  224.             //printf("DONE\n");
  225.  
  226.             fillPacket(&packet, packet_buffer, packet_size);
  227.  
  228.             if (i % 7 == 0) {
  229.                 printf("%d Sending a UDP packet\n", (int)(i/7));
  230.                 SendFrame(packet_buffer, packet_size);
  231.                 usleep(40000*videoFrames);
  232.                 //free(packet_buffer);
  233.                 packet_size = 0;
  234.                 videoFrames = 0;
  235.             }
  236.         //}
  237.  
  238.         // Free the packet that was allocated by av_read_frame
  239.         av_free_packet(&packet);
  240.     }
  241.  
  242.     printf("%d packets: %d video %d audio\n", i, ivideo, iaudio);
  243.  
  244.     //free(outbuf);
  245.  
  246.     // Free the RGB image
  247.     free(buffer);
  248.     av_free(pFrameRGB);
  249.  
  250.     // Free the YUV frame
  251.     av_free(pFrame);
  252.  
  253.     // Close the codec
  254.     avcodec_close(pCodecCtx);
  255.  
  256.     // Close the video file
  257.     av_close_input_file(pFormatCtx);
  258.  
  259.     return 0;
  260. }
  261.  
  262. void fillPacket(AVPacket *streamPacket, uint8_t *packet, size_t size)
  263. {
  264.     memcpy(packet+size-streamPacket->size, streamPacket->data, streamPacket->size);
  265. }
  266.  
  267. void SendFrame (uint8_t *packet, size_t size)
  268. {
  269.     // socket creation
  270.     SOCKET sock = socket(AF_INET, SOCK_DGRAM, 0);
  271.     SOCKADDR_IN sin;
  272.  
  273.     char address[10] = "127.0.0.1";
  274.  
  275.     struct hostent *hostinfo;
  276.     if(sock == INVALID_SOCKET)
  277.     {
  278.         perror("socket()");
  279.         exit(errno);
  280.     }
  281.     hostinfo = gethostbyname(address);
  282.     if (hostinfo == NULL)
  283.     {
  284.         fprintf (stderr, "Unknown host %s.\n", address);
  285.         exit(EXIT_FAILURE);
  286.     }
  287.     sin.sin_addr = *(IN_ADDR *) hostinfo->h_addr;
  288.     sin.sin_port = htons(2500);
  289.     sin.sin_family = AF_INET;
  290.  
  291.     sendto(sock, packet, size, 0, (SOCKADDR *) &sin, sizeof(sin));
  292.  
  293.     closesocket(sock);
  294.  
  295.     /*FILE *pFile;
  296.         char szFilename[32];
  297.         int  y;
  298.  
  299.         // Open file
  300.         sprintf(szFilename, "prova.ts");
  301.         pFile=fopen(szFilename, "wb");
  302.         if(pFile==NULL)
  303.             return;
  304.  
  305.         // Write header
  306.         //fprintf(pFile, "P6\n%d %d\n255\n", width, height);
  307.  
  308.         // Write pixel data
  309.         //for(y=0; y<height; y++)
  310.             //fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);
  311.         fwrite(packet->data, packet->size, 1, pFile);
  312.  
  313.         // Close file
  314.         fclose(pFile);*/
  315. }
  316.  
  317. static void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame)
  318. {
  319.     /*FILE *pFile;
  320.     char szFilename[32];
  321.     int  y;
  322.  
  323.     // Open file
  324.     sprintf(szFilename, "video/frames/frame%d.ppm", iFrame);
  325.     pFile=fopen(szFilename, "wb");
  326.     if(pFile==NULL)
  327.         return;
  328.  
  329.     // Write header
  330.     fprintf(pFile, "P6\n%d %d\n255\n", width, height);
  331.  
  332.     // Write pixel data
  333.     for(y=0; y<height; y++)
  334.         fwrite(pFrame->data[0]+y*pFrame->linesize[0], 1, width*3, pFile);
  335.  
  336.     // Close file
  337.     fclose(pFile);*/
  338.  
  339. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement