Guest User

stream my life

a guest
Mar 29th, 2015
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.31 KB | None | 0 0
  1. #include <libavcodec/avcodec.h>
  2. #include <libavformat/avformat.h>
  3. #include <libswscale/swscale.h>
  4. #include <libavdevice/avdevice.h>
  5. #include <libavutil/opt.h>
  6. #include <stdio.h>
  7. #include <stdint.h>
  8. #include <unistd.h>
  9.  
  10. /*
  11. Run using gcc -g -o stream test.c -lavformat -lavutil -lavcodec -lavdevice -lswscale
  12. */
  13.  
  14. // void show_av_device() {
  15.  
  16. //    inFmt->get_device_list(inFmtCtx, device_list);
  17. //    printf("Device Info=============\n");
  18. //    //avformat_open_input(&inFmtCtx,"video=Capture screen 0",inFmt,&inOptions);
  19. //    printf("===============================\n");
  20. // }
  21.  
  22. void registerLibs() {
  23.     av_register_all();
  24.     avdevice_register_all();
  25.     avformat_network_init();
  26.     avcodec_register_all();
  27. }
  28.  
  29. int main(int argc, char *argv[]) {
  30.    
  31.     //conversion variables
  32.     struct SwsContext *swsCtx = NULL;
  33.     //input stream variables
  34.     AVFormatContext   *inFmtCtx = NULL;
  35.     AVCodecContext    *inCodecCtx = NULL;
  36.     AVCodec           *inCodec = NULL;
  37.     AVInputFormat     *inFmt = NULL;
  38.     AVFrame           *inFrame = NULL;
  39.     AVDictionary      *inOptions = NULL;
  40.     const char *streamURL = "http://localhost:8090/test.flv";
  41.     const char *name = "avfoundation";
  42.    
  43. //    AVFrame           *inFrameYUV = NULL;
  44.     AVPacket          inPacket;
  45.    
  46.    
  47.     //output stream variables
  48.     AVCodecContext    *outCodecCtx = NULL;
  49.     AVCodec           *outCodec;
  50.     AVFormatContext   *outFmtCtx = NULL;
  51.     AVOutputFormat    *outFmt = NULL;
  52.     AVFrame           *outFrameYUV = NULL;
  53.     AVStream          *stream = NULL;
  54.    
  55.     int               i, videostream, ret;
  56.     int               numBytes, frameFinished;
  57.    
  58.     registerLibs();
  59.     inFmtCtx = avformat_alloc_context(); //alloc input context
  60.     av_dict_set(&inOptions, "pixel_format", "uyvy422", 0);
  61.     av_dict_set(&inOptions, "probesize", "7000000", 0);
  62.    
  63.     inFmt = av_find_input_format(name);
  64.     ret = avformat_open_input(&inFmtCtx, "Capture screen 0:", inFmt, &inOptions);
  65.     if (ret < 0) {
  66.         printf("Could not load the context for the input device\n");
  67.         return -1;
  68.     }
  69.     if (avformat_find_stream_info(inFmtCtx, NULL) < 0) {
  70.         printf("Could not find stream info for screen\n");
  71.         return -1;
  72.     }
  73.     av_dump_format(inFmtCtx, 0, "Capture screen 0", 0);
  74.     // inFmtCtx->streams is an array of pointers of size inFmtCtx->nb_stream
  75.    
  76.     videostream = av_find_best_stream(inFmtCtx, AVMEDIA_TYPE_VIDEO, -1, -1, &inCodec, 0);
  77.     if (videostream == -1) {
  78.         printf("no video stream found\n");
  79.         return -1;
  80.     } else {
  81.         printf("%s is inCodec\n", inCodec->long_name);
  82.     }
  83.     inCodecCtx = inFmtCtx->streams[videostream]->codec;
  84.     // open codec
  85.     if (avcodec_open2(inCodecCtx, inCodec, NULL) > 0) {
  86.         printf("Couldn't open codec");
  87.         return -1;  // couldn't open codec
  88.     }
  89.  
  90.    
  91.         //setup output params
  92.     outFmt = av_guess_format(NULL, streamURL, NULL);
  93.     if(outFmt == NULL) {
  94.         printf("output format was not guessed properly");
  95.         return -1;
  96.     }
  97.    
  98.     if((outFmtCtx = avformat_alloc_context()) < 0) {
  99.         printf("output context not allocated. ERROR");
  100.         return -1;
  101.     }
  102.    
  103.     printf("%s", outFmt->long_name);
  104.    
  105.     outFmtCtx->oformat = outFmt;
  106.    
  107.     snprintf(outFmtCtx->filename, sizeof(outFmtCtx->filename), streamURL);
  108.     printf("%s\n", outFmtCtx->filename);
  109.  
  110.     outCodec = avcodec_find_encoder(AV_CODEC_ID_H264);
  111.     if(!outCodec) {
  112.         printf("could not find encoder for H264 \n" );
  113.         return -1;
  114.     }
  115.    
  116.     stream = avformat_new_stream(outFmtCtx, outCodec);
  117.     outCodecCtx = stream->codec;
  118.     avcodec_get_context_defaults3(outCodecCtx, outCodec);
  119.    
  120.     outCodecCtx->codec_id = AV_CODEC_ID_H264;
  121.     outCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
  122.     outCodecCtx->flags = CODEC_FLAG_GLOBAL_HEADER;
  123.     outCodecCtx->width = inCodecCtx->width;
  124.     outCodecCtx->height = inCodecCtx->height;
  125.     outCodecCtx->time_base.den = 25;
  126.     outCodecCtx->time_base.num = 1;
  127.     outCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
  128.     outCodecCtx->gop_size = 50;
  129.     outCodecCtx->bit_rate = 400000;
  130.  
  131.     //setup output encoders etc
  132.     if(stream) {
  133.         ret = avcodec_open2(outCodecCtx, outCodec, NULL);
  134.         if (ret < 0) {
  135.             printf("Could not open output encoder");
  136.             return -1;
  137.         }
  138.     }
  139.    
  140.     if (avio_open(&outFmtCtx->pb, outFmtCtx->filename, AVIO_FLAG_READ_WRITE ) < 0) {
  141.         perror("url_fopen failed");
  142.     }
  143.    
  144.     avio_open_dyn_buf(&outFmtCtx->pb);
  145.     ret = avformat_write_header(outFmtCtx, NULL);
  146.     if (ret != 0) {
  147.         printf("was not able to write header to output format");
  148.         return -1;
  149.     }
  150.     unsigned char *pb_buffer;
  151.     int len = avio_close_dyn_buf(outFmtCtx->pb, (unsigned char **)(&pb_buffer));
  152.     avio_write(outFmtCtx->pb, (unsigned char *)pb_buffer, len);
  153.    
  154.    
  155.     numBytes = avpicture_get_size(PIX_FMT_UYVY422, inCodecCtx->width, inCodecCtx->height);
  156.     // Allocate video frame
  157.     inFrame = av_frame_alloc();
  158.  
  159.     swsCtx = sws_getContext(inCodecCtx->width, inCodecCtx->height, inCodecCtx->pix_fmt, inCodecCtx->width,
  160.                             inCodecCtx->height, PIX_FMT_YUV420P, SWS_BILINEAR, NULL, NULL, NULL);
  161.     int frame_count = 0;
  162.     while(av_read_frame(inFmtCtx, &inPacket) >= 0) {
  163.         if(inPacket.stream_index == videostream) {
  164.             avcodec_decode_video2(inCodecCtx, inFrame, &frameFinished, &inPacket);
  165.             // 1 Frame might need more than 1 packet to be filled
  166.             if(frameFinished) {
  167.                 outFrameYUV = av_frame_alloc();
  168.                
  169.                 uint8_t *buffer = (uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
  170.                
  171.                 int ret = avpicture_fill((AVPicture *)outFrameYUV, buffer, PIX_FMT_YUV420P,
  172.                                          inCodecCtx->width, inCodecCtx->height);
  173.                 if(ret < 0){
  174.                     printf("%d is return val for fill\n", ret);
  175.                     return -1;
  176.                 }
  177.                 //convert image to YUV
  178.                 sws_scale(swsCtx, (uint8_t const * const* )inFrame->data,
  179.                           inFrame->linesize, 0, inCodecCtx->height,
  180.                           outFrameYUV->data, outFrameYUV->linesize);
  181.                 //outFrameYUV now holds the YUV scaled frame/picture
  182.                 outFrameYUV->format = outCodecCtx->pix_fmt;
  183.                 outFrameYUV->width = outCodecCtx->width;
  184.                 outFrameYUV->height = outCodecCtx->height;
  185.                
  186.                
  187.                 AVPacket pkt;
  188.                 int got_output;
  189.                 av_init_packet(&pkt);
  190.                 pkt.data = NULL;
  191.                 pkt.size = 0;
  192.  
  193.                 outFrameYUV->pts = frame_count;
  194.                
  195.                 ret = avcodec_encode_video2(outFmtCtx->streams[0]->codec, &pkt, outFrameYUV, &got_output);
  196.                 if (ret < 0) {
  197.                     fprintf(stderr, "Error encoding video frame: %s\n", av_err2str(ret));
  198.                     return -1;
  199.                 }
  200.                
  201.                 if(got_output) {
  202.                     if(stream->codec->coded_frame->key_frame) {
  203.                         pkt.flags |= AV_PKT_FLAG_KEY;
  204.                     }
  205.                     pkt.stream_index = stream->index;
  206.                     if(pkt.pts != AV_NOPTS_VALUE)
  207.                         pkt.pts = av_rescale_q(pkt.pts, stream->codec->time_base, stream->time_base);
  208.                     if(pkt.dts != AV_NOPTS_VALUE)
  209.                         pkt.dts = av_rescale_q(pkt.dts, stream->codec->time_base, stream->time_base);
  210.                     if(avio_open_dyn_buf(&outFmtCtx->pb)!= 0) {
  211.                         printf("ERROR: Unable to open dynamic buffer\n");
  212.                     }
  213.                     ret = av_interleaved_write_frame(outFmtCtx, &pkt);
  214.                     unsigned char *pb_buffer;
  215.                     int len = avio_close_dyn_buf(outFmtCtx->pb, (unsigned char **)&pb_buffer);
  216.                     avio_write(outFmtCtx->pb, (unsigned char *)pb_buffer, len);
  217.  
  218.                 } else {
  219.                     ret = 0;
  220.                 }
  221.                 if(ret != 0) {
  222.                     fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret));
  223.                     exit(1);
  224.                 }
  225.                
  226.                 fprintf(stderr, "encoded frame #%d\n", frame_count);
  227.                 frame_count++;
  228.                
  229.                 av_free_packet(&pkt);
  230.                 av_free(outFrameYUV);
  231.                
  232.             }
  233.         }
  234.         av_free_packet(&inPacket);
  235.     }
  236.     av_write_trailer(outFmtCtx);
  237.    
  238.     //close video stream
  239.     if(stream) {
  240.         avcodec_close(outCodecCtx);
  241.     }
  242.     for (i = 0; i < outFmtCtx->nb_streams; i++) {
  243.         av_freep(&outFmtCtx->streams[i]->codec);
  244.         av_freep(&outFmtCtx->streams[i]);
  245.     }
  246.     if (!(outFmt->flags & AVFMT_NOFILE))
  247.     /* Close the output file. */
  248.         avio_close(outFmtCtx->pb);
  249.     /* free the output format context */
  250.     avformat_free_context(outFmtCtx);
  251.    
  252.     // Free the YUV frame populated by the decoder
  253.     av_free(inFrame);
  254.    
  255.     // Close the video codec (decoder)
  256.     avcodec_close(inCodecCtx);
  257.    
  258.     // Close the input video file
  259.     avformat_close_input(&inFmtCtx);
  260.  
  261.     return 1;
  262.  
  263. }
Add Comment
Please, Sign In to add comment