lutza

Untitled

Nov 8th, 2011
126
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #include <stdio.h>
  2.  
  3. #include <libavformat/avformat.h>
  4. #include <libavcodec/avcodec.h>
  5. #include <libavutil/opt.h>
  6. #include <libswscale/swscale.h>
  7.  
  8. int main (int argc, char **argv)
  9. {
  10.     if (argc !=3)
  11.     {
  12.         fprintf(stderr, "Error: invalid arguments\n");
  13.         fprintf(stderr, "\tCorrect usage: %s <input-filename> <output-filename>\n", argv[0]);
  14.         exit(1);
  15.     }
  16.  
  17.     // initialize all formats and codecs
  18.     av_register_all();
  19.  
  20.     /// Set up input
  21.     const char *input_filename = argv[1];
  22.     // must be initialized to NULL or otherwise avformat_open_input() will segfault
  23.     AVFormatContext *input_context = NULL;
  24.  
  25.     // Get input file context
  26.     if ( avformat_open_input(&input_context, input_filename, NULL, NULL) != 0 )
  27.     {
  28.         fprintf(stderr, "Error: Couldn't open input file.\n");
  29.         exit(1);
  30.     }
  31.  
  32.     // Get streams information
  33.     if( avformat_find_stream_info(input_context, NULL) < 0 )
  34.     {
  35.         fprintf(stderr, "Error: Couldn't find stream information.\n");
  36.         exit(1);
  37.     }
  38.  
  39.     // debug: dump informations about input to stdout
  40.     av_dump_format(input_context, 0, input_filename, 0);
  41.  
  42.  
  43.     // Find the first video stream
  44.     int i, video_stream;
  45.     video_stream=-1;
  46.  
  47.     for(i=0; i<input_context->nb_streams; i++)
  48.     {
  49.         if(input_context->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO)
  50.         {
  51.             video_stream=i;
  52.             break;
  53.         }
  54.     }
  55.     if(video_stream==-1)
  56.     {
  57.         fprintf(stderr, "Error: Couldn't find a video stream.\n");
  58.         exit(1);
  59.     }
  60.  
  61.     // Get codec context for selected stream
  62.     AVCodecContext *iv_codec_ctx = input_context->streams[video_stream]->codec;
  63.     // Find the decoder for the video stream
  64.     AVCodec *v_decoder  = avcodec_find_decoder ( iv_codec_ctx->codec_id );
  65.     if(v_decoder==NULL)
  66.     {
  67.         fprintf(stderr, "Error: Video decoder not found.\n");
  68.         exit(1);
  69.     }
  70.  
  71.     // Inform the codec that we can handle truncated bitstreams -- i.e.,
  72.     // bitstreams where frame boundaries can fall in the middle of packets
  73.     if(v_decoder->capabilities & CODEC_CAP_TRUNCATED)
  74.         iv_codec_ctx->flags|=CODEC_FLAG_TRUNCATED;
  75.  
  76.     // Open decoder with desired setup
  77.     if ( avcodec_open(iv_codec_ctx, v_decoder) < 0 )
  78.     {
  79.         fprintf(stderr, "Error: Couldn't open video decoder.\n");
  80.         exit(1);
  81.     }
  82.  
  83.     /// Set up output
  84.     const char *output_filename = argv[2];
  85.     AVFormatContext *output_context;
  86.  
  87.     // Alloc and create output file context
  88.     //   tell avcodec that it will contain h264 video stream
  89.     avformat_alloc_output_context2(&output_context, NULL, "h264", NULL);
  90.     if (!output_context)
  91.     {
  92.         fprintf(stderr, "Error: Couldn't create context for output file.\n");
  93.         exit(1);
  94.     }
  95.  
  96.     //open output file
  97.     if ( avio_open(&output_context->pb, output_filename, AVIO_FLAG_WRITE) < 0 )
  98.     {
  99.         fprintf(stderr, "Error: Could not open '%s'\n", output_filename);
  100.         exit(1);
  101.     }
  102.  
  103.     // find coder for h264
  104.     AVCodec *v_coder = avcodec_find_encoder(CODEC_ID_H264);
  105.     if (!v_coder)
  106.     {
  107.         fprintf(stderr, "Error: Could not found h264 codec.\n");
  108.         exit(1);
  109.     }
  110.  
  111.     // add new stream encoded by this coder to ouput context
  112.     AVStream *ov_stream = avformat_new_stream(output_context, v_coder);
  113.     if (!ov_stream)
  114.     {
  115.         fprintf(stderr, "Error: Could not alloc stream.\n");
  116.         exit(1);
  117.     }
  118.  
  119.     // set up encoding parameters (codec context)
  120.     AVCodecContext *ov_codec_ctx = ov_stream->codec;
  121.     ov_codec_ctx->codec_id = CODEC_ID_H264;
  122.     ov_codec_ctx->codec_type = AVMEDIA_TYPE_VIDEO;
  123.     /* put sample parameters */
  124.     ov_codec_ctx->bit_rate = 400000;
  125.     /* resolution must be a multiple of two */
  126.     ov_codec_ctx->width = 352;
  127.     ov_codec_ctx->height = 288;
  128.     /* frames per second */
  129.     ov_codec_ctx->time_base= //(AVRational){1,25};
  130.         iv_codec_ctx->time_base;
  131.     ov_codec_ctx->gop_size = 10; /* emit one intra frame every ten frames */
  132.     ov_codec_ctx->max_b_frames=2;
  133.     ov_codec_ctx->pix_fmt = PIX_FMT_YUV420P;
  134.  
  135.     // set h264 preset
  136.     if ( av_opt_set(ov_codec_ctx->priv_data, "preset", "slow", 0) )
  137.     {
  138.         fprintf(stderr, "Error: Could not set h264 preset.\n");
  139.         exit(1);
  140.     }
  141.  
  142.     // debug: dump informations about output to stdout
  143.     av_dump_format(output_context, 0, output_filename, 1);
  144.  
  145.     // open h264 codec
  146.     if (avcodec_open(ov_codec_ctx, v_coder) < 0)
  147.     {
  148.         fprintf(stderr, "Error: Could not open h264 codec.\n");
  149.         exit(1);
  150.     }
  151.  
  152.     // create output buffer for video
  153.     int video_outbuf_size = 200000;
  154.     uint8_t *video_outbuf = av_malloc(video_outbuf_size);
  155.  
  156.     // allocate output picture
  157.     AVFrame *output_picture = avcodec_alloc_frame();
  158.     int size = avpicture_get_size(ov_codec_ctx->pix_fmt, ov_codec_ctx->width, ov_codec_ctx->height);
  159.     uint8_t * output_picture_buf = av_malloc(size);
  160.     if (!output_picture || !output_picture_buf)
  161.     {
  162.         fprintf(stderr, "Error: Could not allocate output picture.\n");
  163.         exit(1);
  164.     }
  165.     avpicture_fill((AVPicture *)output_picture, output_picture_buf,
  166.                    ov_codec_ctx->pix_fmt, ov_codec_ctx->width, ov_codec_ctx->height);
  167.  
  168.     // create picture conversion context
  169.     struct SwsContext *img_convert_ctx =
  170.             sws_getContext( iv_codec_ctx->width, iv_codec_ctx->height, iv_codec_ctx->pix_fmt,
  171.                             ov_codec_ctx->width, ov_codec_ctx->height, ov_codec_ctx->pix_fmt,
  172.                             SWS_BICUBIC, NULL, NULL, NULL);
  173.  
  174.  
  175.  
  176.     AVFrame *input_picture = avcodec_alloc_frame();
  177.     int got_picture;
  178.     int len, out_size;
  179.     int picture_counter = 0;
  180.     AVPacket packet;
  181.     AVPacket output_packet;
  182.     //av_init_packet(&packet);
  183.     uint8_t * packet_start;
  184.  
  185.  
  186.     /* write the output stream header, if any */
  187.     av_write_header(output_context);
  188.  
  189.     while ( av_read_frame(input_context, &packet) >= 0 )
  190.     // grab packet from input file
  191.     {
  192.         if ( packet.stream_index == video_stream )
  193.         // care only for packets from desired video stream
  194.         {
  195.             // store ptr to packet data start
  196.             packet_start = packet.data;
  197.             while (packet.size > 0)
  198.             // decode data from packet
  199.             {
  200.                 len = avcodec_decode_video2( iv_codec_ctx, input_picture, &got_picture, &packet);
  201.                 //printf("[video packet]%d bytes decoded from packet, got_picture = %d\n", len, got_picture);
  202.                 if (len<0)
  203.                 {
  204.                     fprintf(stderr, "Error: While decoding picture.\n");
  205.                     exit(1);
  206.                 }
  207.                 if (got_picture)
  208.                 {
  209.                     // handle picture
  210.                     picture_counter++;
  211.                     // convert img to output img format
  212.                     sws_scale(img_convert_ctx, &input_picture->data, input_picture->linesize,
  213.                         0, ov_codec_ctx->height, &output_picture->data, output_picture->linesize);
  214.  
  215.                     // send image for encoding
  216.                     out_size = avcodec_encode_video(ov_codec_ctx, video_outbuf, video_outbuf_size, output_picture);
  217.                     printf("encoding frame %3d (size=%5d)\n", picture_counter, out_size);
  218.                     // encoder returned some data, lets write them into output file
  219.                     if (out_size>0)
  220.                     {
  221.                         av_init_packet(&output_packet);
  222.                         // todo: co je tohle ??
  223.                         if (ov_codec_ctx->coded_frame->pts != AV_NOPTS_VALUE)
  224.                             output_packet.pts=
  225.                                 av_rescale_q(ov_codec_ctx->coded_frame->pts, ov_codec_ctx->time_base, ov_stream->time_base);
  226.                         printf("pts = %lf,   ", (double)ov_stream->pts.val * ov_stream->time_base.num / ov_stream->time_base.den);
  227.                         printf("%d %d %d\n", ov_codec_ctx->coded_frame->pts, ov_codec_ctx->time_base, ov_stream->time_base);
  228.                         //output_packet.dts = AV_NOPTS_VALUE;
  229.                         if(ov_codec_ctx->coded_frame->key_frame)
  230.                             output_packet.flags |= AV_PKT_FLAG_KEY;
  231.                         output_packet.stream_index = ov_stream->index;
  232.                         output_packet.data = video_outbuf;
  233.                         output_packet.size = out_size;
  234.  
  235.                         /* write the compressed frame in the media file */
  236.                         if ( av_interleaved_write_frame(output_context, &output_packet)!= 0 )
  237.                         {
  238.                             fprintf(stderr, "Error: while writing video frame.\n");
  239.                             exit(1);
  240.                         }
  241.  
  242.                     }
  243.                 }
  244.                 packet.size -= len;
  245.                 packet.data += len;
  246.             }
  247.             // restore ptr to packet data start so it can get released correctly by AV
  248.             packet.data = packet_start;
  249.         }
  250.         av_free_packet(&packet);    // free packet
  251.     }
  252.  
  253.     printf("video frames grabbed = %d \n", picture_counter);
  254.  
  255.     // write output trailer if any
  256.     av_write_trailer(output_context);
  257.  
  258.     // clean resources
  259.  
  260.     // free output
  261.     avcodec_close(ov_stream->codec);
  262.     av_free(output_picture);
  263.     av_free(output_picture->data[0]);
  264.     av_free(video_outbuf);
  265.  
  266.     for(i = 0; i < output_context->nb_streams; i++) {
  267.         av_freep(&output_context->streams[i]->codec);
  268.         av_freep(&output_context->streams[i]);
  269.     }
  270.     av_free(output_context);
  271.  
  272.     // free input
  273.     avcodec_close(iv_codec_ctx);
  274.     av_close_input_file(input_context);
  275.     av_free(input_picture);
  276.  
  277.     return 0;
  278. }
  279.  
  280.  
RAW Paste Data

Adblocker detected! Please consider disabling it...

We've detected AdBlock Plus or some other adblocking software preventing Pastebin.com from fully loading.

We don't have any obnoxious sound, or popup ads, we actively block these annoying types of ads!

Please add Pastebin.com to your ad blocker whitelist or disable your adblocking software.

×