Advertisement
Guest User

New_version

a guest
Sep 22nd, 2017
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.46 KB | None | 0 0
  1. extern "C"
  2. {
  3.     #include <libavcodec/avcodec.h>
  4.     #include <libavformat/avformat.h>
  5.     #include <libswscale/swscale.h>
  6.  
  7.     #include <libavutil/opt.h>
  8.     #include <libavutil/channel_layout.h>
  9.     #include <libavutil/common.h>
  10.     #include <libavutil/imgutils.h>
  11.     #include <libavutil/mathematics.h>
  12.     #include <libavutil/samplefmt.h>
  13. }
  14. #include <iostream>
  15. #include <unistd.h>
  16. #include <stdio.h>
  17.  
  18. //Mainly based on https://stackoverflow.com/questions/40825300/ffmpeg-create-rtp-stream
  19. int main()
  20. {
  21.     //Init ffmpeg
  22.     avcodec_register_all();
  23.     av_register_all();
  24.     avformat_network_init();
  25.  
  26.     //Init the codec used to encode our given image
  27.     AVCodecID codecID = AV_CODEC_ID_H264;
  28.     AVCodec* codec;
  29.     AVCodecContext* codecCtx;
  30.  
  31.     codec    = avcodec_find_encoder(codecID);
  32.     codecCtx = avcodec_alloc_context3(codec);
  33.  
  34.     codecCtx->bit_rate      = 400000;
  35.     codecCtx->width         = 352;
  36.     codecCtx->height        = 288;
  37.  
  38.     codecCtx->time_base.num = 1;
  39.     codecCtx->time_base.den = 25;
  40.     codecCtx->gop_size      = 25;
  41.     codecCtx->max_b_frames  = 1;
  42.     codecCtx->pix_fmt       = AV_PIX_FMT_YUV420P;
  43.     codecCtx->codec_type    = AVMEDIA_TYPE_VIDEO;
  44.  
  45.     if (codecID == AV_CODEC_ID_H264)
  46.     {
  47.         av_opt_set(codecCtx->priv_data, "preset", "ultrafast", 0);
  48.         av_opt_set(codecCtx->priv_data, "tune", "zerolatency", 0);
  49.     }
  50.  
  51.     avcodec_open2(codecCtx, codec, NULL);
  52.  
  53.     //Init the Frame containing our raw data
  54.     AVFrame* frame;
  55.  
  56.     frame         = av_frame_alloc();
  57.     frame->format = codecCtx->pix_fmt;
  58.     frame->width  = codecCtx->width;
  59.     frame->height = codecCtx->height;
  60.  
  61.     av_image_alloc(frame->data, frame->linesize, frame->width, frame->height, codecCtx->pix_fmt, 32);
  62.  
  63.     //Init the format context
  64.     AVFormatContext* fmtCtx  = avformat_alloc_context();
  65.     AVOutputFormat*  format  = av_guess_format("rtp", NULL, NULL);
  66.     avformat_alloc_output_context2(&fmtCtx, format, format->name, "rtp://127.0.0.1:49990");
  67.  
  68.     avio_open(&fmtCtx->pb, fmtCtx->filename, AVIO_FLAG_WRITE);
  69.  
  70.     //Configure the AVStream for the output format context
  71.     struct AVStream* stream      = avformat_new_stream(fmtCtx, codec);
  72.    
  73.     avcodec_parameters_from_context(stream->codecpar, codecCtx);
  74.     stream->time_base.num        = 1;
  75.     stream->time_base.den        = 25;
  76.  
  77.     /* Rewrite the header */
  78.     avformat_write_header(fmtCtx, NULL);
  79.  
  80.     /* Write a file for VLC */
  81.     char buf[200000];
  82.     AVFormatContext *ac[] = { fmtCtx };
  83.     av_sdp_create(ac, 1, buf, 20000);
  84.     printf("sdp:\n%s\n", buf);
  85.     FILE* fsdp = fopen("test.sdp", "w");
  86.     fprintf(fsdp, "%s", buf);
  87.     fclose(fsdp);
  88.  
  89.     AVPacket pkt;
  90.     for(int i = 0; i < 1000; i++)
  91.     {
  92.         fflush(stdout);
  93.         av_init_packet(&pkt);
  94.         pkt.data = NULL;    // packet data will be allocated by the encoder
  95.         pkt.size = 0;
  96.  
  97.         int R, G, B;
  98.         R = G = B = i % 255;
  99.  
  100.         int Y =  0.257 * R + 0.504 * G + 0.098 * B +  16;
  101.         int U = -0.148 * R - 0.291 * G + 0.439 * B + 128;
  102.         int V =  0.439 * R - 0.368 * G - 0.071 * B + 128;
  103.  
  104.         /* prepare a dummy image */
  105.         /* Y */
  106.         for (int y = 0; y < codecCtx->height; y++)
  107.             for (int x = 0; x < codecCtx->width; x++)
  108.                 frame->data[0][y * codecCtx->width + x] = Y;
  109.  
  110.         for (int y = 0; y < codecCtx->height/2; y++)
  111.             for (int x=0; x < codecCtx->width / 2; x++)
  112.             {
  113.                 frame->data[1][y * frame->linesize[1] + x] = U;
  114.                 frame->data[2][y * frame->linesize[2] + x] = V;
  115.             }
  116.  
  117.         /* Which frame is it ? */
  118.         frame->pts = i;
  119.  
  120.         /* Send the frame to the codec */
  121.         if(avcodec_send_frame(codecCtx, frame) < 0)
  122.             std::cerr << "error at sending the frame \n" << std::endl;
  123.  
  124.         /* Use the data in the codec to the AVPacket */
  125.         switch(avcodec_receive_packet(codecCtx, &pkt))
  126.         {
  127.             case AVERROR_EOF:
  128.                 printf("Stream EOF\n");
  129.                 break;
  130.  
  131.             case AVERROR(EAGAIN):
  132.                 printf("Stream EAGAIN\n");
  133.                 break;
  134.  
  135.             default:
  136.                 printf("Write frame %3d (size=%5d)\n", i, pkt.size);
  137.  
  138.                 /* Write the data on the packet to the output format  */
  139.                 av_interleaved_write_frame(fmtCtx, &pkt);
  140.  
  141.                 /* Reset the packet */
  142.                 av_packet_unref(&pkt);
  143.                 break;
  144.         }
  145.  
  146.         av_packet_unref(&pkt);
  147.         usleep(1e6/27);
  148.     }
  149.  
  150.     // end
  151.     avcodec_send_frame(codecCtx, NULL);
  152.  
  153.     //Free everything
  154.     av_free(codecCtx);
  155.     av_free(fmtCtx);
  156.  
  157.     return 0;
  158. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement