DavidNorgren

Untitled

Jul 25th, 2014
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.76 KB | None | 0 0
  1. #define __STDC_CONSTANT_MACROS
  2. #include <iostream>
  3.  
  4. #define WIDTH 100
  5. #define HEIGHT 100
  6.  
  7. extern "C" {
  8.     #include <libavdevice/avdevice.h>
  9.     #include <libavformat/avformat.h>
  10.     #include <libavutil/imgutils.h>
  11.     #include <libavutil/pixfmt.h>
  12. }
  13.  
  14. using namespace std;
  15.  
  16. void OpenImage(const char* imageFileName, AVFrame* pFrame) {
  17.     AVFormatContext *pFormatCtx = avformat_alloc_context();
  18.  
  19.     if (avformat_open_input(&pFormatCtx, imageFileName, NULL, NULL)!=0) {
  20.         printf("Can't open image file '%s'\n", imageFileName);
  21.         return;
  22.     }
  23.  
  24.     AVCodecContext *pCodecCtx;
  25.  
  26.     pCodecCtx = pFormatCtx->streams[0]->codec;
  27.     pCodecCtx->width = WIDTH;
  28.     pCodecCtx->height = HEIGHT;
  29.     pCodecCtx->pix_fmt = PIX_FMT_RGB32;
  30.  
  31.     // Find the decoder for the video stream
  32.     AVCodec *pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
  33.     if (!pCodec) {
  34.         printf("Codec not found\n");
  35.         return;
  36.     }
  37.  
  38.     // Open codec
  39.     if(avcodec_open(pCodecCtx, pCodec)<0) {
  40.         printf("Could not open codec\n");
  41.         return ;
  42.     }
  43.  
  44.     if (!pFrame) {
  45.         printf("Can't allocate memory for AVFrame\n");
  46.         return ;
  47.     }
  48.  
  49.     int frameFinished;
  50.     int numBytes;
  51.  
  52.     // Determine required buffer size and allocate buffer
  53.     numBytes = avpicture_get_size(PIX_FMT_RGB32, pCodecCtx->width, pCodecCtx->height);
  54.     uint8_t *buffer = (uint8_t *) av_malloc(numBytes * sizeof(uint8_t));
  55.  
  56.     avpicture_fill((AVPicture *) pFrame, buffer, PIX_FMT_RGB32, pCodecCtx->width, pCodecCtx->height);
  57.  
  58.     // Read frame
  59.  
  60.     AVPacket packet;
  61.  
  62.     int framesNumber = 0;
  63.     while (av_read_frame(pFormatCtx, &packet) >= 0) {
  64.         if(packet.stream_index != 0)
  65.             continue;
  66.  
  67.         int ret = avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet);
  68.         if (ret > 0) {
  69.             printf("Frame is decoded, size %d\n", ret);
  70.             pFrame->quality = 4;
  71.         } else printf("Error [%d] while decoding frame: %s\n", ret, strerror(AVERROR(ret)));
  72.     }
  73. }
  74.  
  75. int main() {
  76.     av_register_all();
  77.  
  78.     char* filename = "out.mpg";
  79.  
  80.     // Find the video encoder
  81.     AVCodec* codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
  82.     if (!codec)
  83.     {
  84.         printf("Codec not found\n");
  85.         return -1;
  86.     }
  87.  
  88.     // Initialize codec.
  89.     AVCodecContext* codecContext = avcodec_alloc_context3(codec);
  90.  
  91.     codecContext->width = WIDTH;
  92.     codecContext->height = HEIGHT;
  93.     codecContext->bit_rate = 400000;
  94.     codecContext->time_base.num = 1;
  95.     codecContext->time_base.den = 25;
  96.     codecContext->gop_size = 10;
  97.     codecContext->max_b_frames=1;
  98.     codecContext->pix_fmt = PIX_FMT_YUV420P;
  99.     codecContext->codec_id = CODEC_ID_MPEG1VIDEO;
  100.  
  101.     // Open the codec.
  102.     if (avcodec_open2(codecContext, codec, NULL) < 0) {
  103.         printf("could not open codec\n");
  104.         return -2;
  105.     }
  106.  
  107.     // Open the output file
  108.     FILE* outputFile = fopen(filename, "wb");
  109.     if (!outputFile) {
  110.         printf("could not open %s\n", filename);
  111.         return -3;
  112.     }
  113.  
  114.     // Create buffer.
  115.     int outbuf_size = WIDTH * HEIGHT;
  116.     int actualSize = (( ( outbuf_size * 3 ) / 2 ) + 100) * sizeof(uint8_t);
  117.  
  118.     AVPacket packet;
  119.     bool first = true;
  120.     int out_size, got_output;
  121.  
  122.     AVFrame *frame = avcodec_alloc_frame();
  123.  
  124.     if (!frame) {
  125.         printf("Can't allocate memory for AVFrame\n");
  126.         return -4;
  127.     }
  128.  
  129.     int i;
  130.     int frames=25;
  131.     for (i = 0; i < frames; i++) {
  132.         av_init_packet(&packet);
  133.         packet.data = NULL;
  134.         packet.size = 0;
  135.         fflush(stdout);
  136.  
  137.         OpenImage("test.png", frame);
  138.  
  139.         frame->pts = i;
  140.         out_size = avcodec_encode_video2(codecContext, &packet, frame, &got_output);
  141.         if (out_size < 0) {
  142.             return -5;
  143.         }
  144.         if (got_output && got_output > 0) {
  145.             printf("Write frame %3d (size=%5d)\n", i, packet.size);
  146.             fwrite(packet.data, 1, packet.size, outputFile);
  147.             av_free_packet(&packet);
  148.         }
  149.     }
  150.  
  151.     // Get the delayed frames
  152.     for (got_output = 1; got_output; i++) {
  153.         fflush(stdout);
  154.         out_size = avcodec_encode_video2(codecContext, &packet, NULL, &got_output);
  155.         if (out_size < 0) {
  156.             return -6;
  157.         }
  158.         if (got_output) {
  159.             printf("Write frame %3d (size=%5d)\n", i, packet.size);
  160.             fwrite(packet.data, 1, packet.size, outputFile);
  161.             av_free_packet(&packet);
  162.         }
  163.     }
  164.  
  165.     // add sequence end code to have a real mpeg file
  166.     uint8_t endcode[] = { 0, 0, 1, 0xb7 };
  167.     fwrite(endcode, 1, sizeof(endcode), outputFile);
  168.     fclose(outputFile);
  169.     avcodec_close(codecContext);
  170.     av_free(codecContext);
  171.     av_freep(&frame->data[0]);
  172.     return 0;
  173. }
Advertisement
Add Comment
Please, Sign In to add comment