Advertisement
Guest User

libavfilter trying to apply some filters

a guest
Jun 14th, 2012
139
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 8.57 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <libavformat/avformat.h>
  4. #include <libavcodec/avcodec.h>
  5. #include <libavdevice/avdevice.h>
  6. #include <libswscale/swscale.h>
  7.  
  8. // filters
  9. #include <libavfilter/avfilter.h>
  10. #include <libavfilter/avfiltergraph.h>
  11. #include <libavfilter/buffersink.h>
  12. #include <libavfilter/avcodec.h>
  13.  
  14. int main(int argc, char **argv)
  15. {
  16.   if (argc < 3) {
  17.     fprintf(stderr,"usage: %s input-file format\n",argv[0]);
  18.     exit(1);
  19.   }
  20.  
  21.   // Prepare ffmpeg library
  22.   av_register_all();
  23.   avdevice_register_all();
  24.   avfilter_register_all();
  25.   avformat_network_init();
  26.  
  27.   // Open video stream
  28.   AVInputFormat *pIFormat = av_find_input_format(argv[2]);
  29.  
  30.   AVDictionary *params = NULL;
  31.  
  32.   if (strcmp(argv[2],"video4linux") == 0) {
  33.     av_dict_set(&params,"video_size","640x240",0);
  34.     av_dict_set(&params,"standard","ntsc",0);
  35.   }
  36.  
  37.   AVFormatContext *pIFormatCtx = NULL;
  38.  
  39.   int bRet = avformat_open_input(&pIFormatCtx, argv[1], pIFormat, &params);
  40.  
  41.   if (bRet != 0) {
  42.       fprintf(stderr, "Could not open file\n");
  43.       return 1;
  44.   }
  45.  
  46.   /* Retrieve stream information */
  47.   if (avformat_find_stream_info(pIFormatCtx,NULL) < 0) {
  48.       fprintf(stderr, "No stream info\n");
  49.       return 1;
  50.   }
  51.  
  52.   /* Find the first video stream */
  53.   int ixInputStream = -1;
  54.   int ix;
  55.   for (ix = 0; ix < pIFormatCtx->nb_streams; ix++) {
  56.       if (pIFormatCtx->streams[ix]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
  57.           ixInputStream = ix;
  58.           break;
  59.       }
  60.   }
  61.   if (ixInputStream == -1) {
  62.       fprintf(stderr, "No video stream in file\n");
  63.       return 1;
  64.   }
  65.  
  66.   /* Get a pointer to the codec pICodecCtx for the video stream */
  67.   AVCodecContext *pICodecCtx = pIFormatCtx->streams[ixInputStream]->codec;
  68.  
  69.   /* Find the decoder for the video stream */
  70.   AVCodec *pICodec = avcodec_find_decoder(pICodecCtx->codec_id);
  71.   if (!pICodec) {
  72.       fprintf(stderr, "Codec not found\n");
  73.       return 1;
  74.   }
  75.  
  76.   /* Open input codec */
  77.   if (avcodec_open2(pICodecCtx, pICodec,NULL) < 0) {
  78.       fprintf(stderr, "Could not open codec\n");
  79.       return 1;
  80.   }
  81.  
  82.   AVPacket inputPacket;
  83.  
  84.   /* Get 1 frame from input */
  85.   av_init_packet(&inputPacket);
  86.  
  87.   bRet = av_read_frame(pIFormatCtx, &inputPacket);
  88.  
  89.   if (bRet < 0) {
  90.     fprintf(stderr, "Could not read frame\n");
  91.     return 1;
  92.   }
  93.  
  94.   if (inputPacket.stream_index != ixInputStream) {
  95.     fprintf(stderr, "Packet is not for our stream\n");
  96.     return 1;
  97.   }
  98.  
  99.   /* Allocate video frame */
  100.   AVFrame *pFrame = avcodec_alloc_frame();
  101.  
  102.   /* Determine required buffer size and allocate buffer */
  103.   int szBuffer = avpicture_get_size(pICodecCtx->pix_fmt, pICodecCtx->width, pICodecCtx->height);
  104.   uint8_t *pBuffer = av_mallocz(szBuffer);
  105.  
  106.   /* Decode video frame */
  107.   int got_frame = 0;
  108.   int e = avcodec_decode_video2(pICodecCtx, pFrame, &got_frame,&inputPacket);
  109.  
  110.   av_free_packet(&inputPacket);
  111.  
  112.   if (!got_frame) {
  113.     fprintf(stderr, "Error reading frame\n");
  114.     return 1;
  115.   }
  116.  
  117.   pFrame->pts = 1;
  118.  
  119.   /* ------------------------------------------------------------------------------------ */
  120.  
  121.   // description of the filter
  122.   // TODO: write here the filter description
  123.   const char *filter_desc = "drawbox=20:20:20:20:red,format=rgb24";
  124.  
  125.   /* ---------------------------------------------------------------------------- */
  126.   /* Init the filter */
  127.   AVFilterGraph *filter_graph = avfilter_graph_alloc();
  128.   AVFilterContext *buffersink_ctx = NULL;
  129.   AVFilterContext *buffersrc_ctx = NULL;
  130.   {
  131.     char args[512];
  132.    
  133.     AVFilterInOut *outputs = avfilter_inout_alloc();
  134.     AVFilterInOut *inputs  = avfilter_inout_alloc();
  135.    
  136.     enum PixelFormat pix_fmts[] = { pICodecCtx->pix_fmt, PIX_FMT_NONE };
  137.    
  138.     /* buffer video source: the decoded frames from the decoder will be inserted here. */
  139.     snprintf(args, sizeof(args), "%d:%d:%d:%d:%d:%d:%d:flags=%d",
  140.               pICodecCtx->width, pICodecCtx->height, pICodecCtx->pix_fmt,
  141.               pICodecCtx->time_base.num, pICodecCtx->time_base.den,
  142.               pICodecCtx->sample_aspect_ratio.num, pICodecCtx->sample_aspect_ratio.den,
  143.               SWS_BILINEAR
  144.             );
  145.    
  146.     int ret = avfilter_graph_create_filter(&buffersrc_ctx, avfilter_get_by_name("buffer"), "in",
  147.                                         args, NULL, filter_graph);
  148.     if (ret < 0) {
  149.         av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
  150.         return ret;
  151.     }
  152.  
  153.     /* buffer video sink: to terminate the filter chain. */
  154.     ret = avfilter_graph_create_filter(&buffersink_ctx, avfilter_get_by_name("buffersink"), "out",
  155.                                         NULL, pix_fmts, filter_graph);
  156.     if (ret < 0) {
  157.         av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
  158.         return ret;
  159.     }
  160.  
  161.     /* Endpoints for the filter graph. */
  162.     outputs->name       = av_strdup("in");
  163.     outputs->filter_ctx = buffersrc_ctx;
  164.     outputs->pad_idx    = 0;
  165.     outputs->next       = NULL;
  166.  
  167.     inputs->name       = av_strdup("out");
  168.     inputs->filter_ctx = buffersink_ctx;
  169.     inputs->pad_idx    = 0;
  170.     inputs->next       = NULL;
  171.  
  172.     if (avfilter_graph_parse(filter_graph, filter_desc,&inputs, &outputs, NULL) < 0) {
  173.      fprintf(stderr, "Could init filters\n");
  174.      return 1;                                    
  175.     }
  176.        
  177.  
  178.     if (avfilter_graph_config(filter_graph, NULL) < 0) {
  179.       fprintf(stderr, "Could init filters\n");
  180.       return 1;    
  181.     }
  182.   }
  183.  
  184.   /* ---------------------------------------------------------------------------- */
  185.  
  186.   // Apply the filter in one frame
  187.   if (av_vsrc_buffer_add_frame(buffersrc_ctx,pFrame,0) < 0) {
  188.     fprintf(stderr, "Error reading frame II\n");
  189.     return 1;      
  190.   }
  191.  
  192.   AVFilterBufferRef *picref = NULL;
  193.  
  194.   if (avfilter_poll_frame(buffersink_ctx->inputs[0])<0) {
  195.     fprintf(stderr, "Error applying filter frame\n");
  196.     return 1;
  197.   }
  198.  
  199.   if (av_buffersink_get_buffer_ref(buffersink_ctx,&picref,0) > 0 || !picref) {
  200.     fprintf(stderr, "Error applying filter frame II\n");
  201.     return 1;
  202.   }
  203.  
  204.   /* ----------------------------------------------------------------------------------- */
  205.  
  206.   // prepare the output
  207.   AVCodec *pOCodec = avcodec_find_encoder(CODEC_ID_PNG);
  208.  
  209.   /* Allocate Output Codec */
  210.   AVCodecContext *pOCodecCtx = avcodec_alloc_context3(pOCodec);
  211.   if (!pOCodecCtx) {
  212.       fprintf(stderr, "Could not allocate codec\n");
  213.       return 1;
  214.   }
  215.  
  216.   /* Initialize picture size and other format parameters */
  217.   pOCodecCtx->width = pICodecCtx->width;
  218.   pOCodecCtx->height = pICodecCtx->height;
  219.   pOCodecCtx->pix_fmt = PIX_FMT_RGB24;
  220.   pOCodecCtx->time_base.num = 1;
  221.   pOCodecCtx->time_base.den = 1;
  222.   pOCodecCtx->thread_count = 2;
  223.  
  224.   if (avcodec_open2(pOCodecCtx, pOCodec,NULL) < 0) {
  225.       fprintf(stderr, "Could not open final codec\n");
  226.       return 1;
  227.   }
  228.  
  229.   /* -------------------------------------------------------------------------------------- */
  230.  
  231.   // frame in jpeg
  232.   AVFrame *finalFrame = avcodec_alloc_frame();
  233.  
  234.   // copy the filtered picture to the final frame
  235.   bRet = avfilter_fill_frame_from_video_buffer_ref(finalFrame,picref);
  236.  
  237.   if (bRet) {
  238.     fprintf(stderr, "Error copyng filter to frame\n");
  239.     return 1;
  240.   }
  241.  
  242.   finalFrame->pts = 1;
  243.  
  244.   /* -------------------------------------------------------------------------------------- */
  245.  
  246.   // where the encoded frame will be stored
  247.   AVPacket packet;
  248.   av_init_packet(&packet);
  249.   packet.size = szBuffer;
  250.   packet.data = pBuffer;
  251.  
  252.   int gotPacket = 0;
  253.  
  254.   int szBufferActual = avcodec_encode_video2(pOCodecCtx, &packet,pFrame,&gotPacket);
  255.  
  256.   if (!szBufferActual && gotPacket && pOCodecCtx->coded_frame) {
  257.       pOCodecCtx->coded_frame->pts       = packet.pts;
  258.       pOCodecCtx->coded_frame->key_frame = !!(packet.flags & AV_PKT_FLAG_KEY);
  259.   }  
  260.  
  261.   /* Write frame to file */
  262.   FILE *file = fopen("test.png", "wb");
  263.   bRet = fwrite(pBuffer, sizeof(uint8_t), packet.size, file);
  264.   fclose(file);
  265.   if (bRet != packet.size) {
  266.       fprintf(stderr, "Error writing jpeg file\n");
  267.       return 1;
  268.   }
  269.  
  270.   avfilter_unref_buffer(picref);
  271.  
  272.   /* Cleanup */
  273.   if (pBuffer) {
  274.       av_freep(&pBuffer);
  275.       pBuffer = NULL;
  276.       szBuffer = 0;
  277.   }
  278.  
  279.   if (pFrame) {
  280.       av_freep(&pFrame);
  281.       pFrame = NULL;
  282.   }
  283.  
  284.   if (pICodecCtx) {
  285.       avcodec_close(pICodecCtx);
  286.       pICodecCtx = NULL;
  287.   }
  288.  
  289.   if (pOCodecCtx) {
  290.       avcodec_close(pOCodecCtx);
  291.       pOCodecCtx = NULL;
  292.   }
  293.  
  294.   if (pIFormatCtx) {
  295.       avformat_close_input(&pIFormatCtx);
  296.       pIFormatCtx = NULL;
  297.   }
  298.  
  299.   return 0;
  300. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement