Advertisement
Guest User

FFmpegTut1

a guest
Jan 6th, 2017
121
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.95 KB | None | 0 0
  1. extern "C"
  2. {
  3. #include <libavcodec/avcodec.h>
  4. #include <libavformat/avformat.h>
  5. #include <libswscale/swscale.h>
  6. #include <libavutil/imgutils.h>
  7. }
  8. #include <stdio.h>
  9. #include <iostream>
  10.  
  11. // compatibility with newer API
  12. #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,1)
  13. #define av_frame_alloc avcodec_alloc_frame
  14. #define av_frame_free avcodec_free_frame
  15. #endif
  16.  
  17. void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {
  18.     FILE *pFile;
  19.     char szFilename[32];
  20.     int  y;
  21.  
  22.     // Open file
  23.     sprintf(szFilename, "frame%d.ppm", iFrame);
  24.     pFile = fopen(szFilename, "wb");
  25.     if (pFile == NULL)
  26.         return;
  27.  
  28.     // Write header
  29.     fprintf(pFile, "P6\n%d %d\n255\n", width, height);
  30.  
  31.     // Write pixel data
  32.     for (y = 0; y < height; y++)
  33.         fwrite(pFrame->data[0] + y*pFrame->linesize[0], 1, width * 3, pFile);
  34.  
  35.     // Close file
  36.     fclose(pFile);
  37. }
  38.  
  39. int main(int argc, char *argv[]) {
  40.     // Initalizing these to NULL prevents segfaults!
  41.     AVFormatContext   *pFormatCtx = NULL;
  42.     int               i, videoStream;
  43.     AVCodecContext    *pCodecCtxOrig = NULL;
  44.     AVCodecContext    *pCodecCtx = NULL;
  45.     AVCodecParameters *pCodecParams = NULL;
  46.     AVCodec           *pCodec = NULL;
  47.     AVFrame           *pFrame = NULL;
  48.     AVFrame           *pFrameRGB = NULL;
  49.     AVPacket          packet;
  50.     int               frameFinished;
  51.     int               numBytes;
  52.     uint8_t           *buffer = NULL;
  53.     struct SwsContext *sws_ctx = NULL;
  54.     AVPixelFormat     pxFormat = AV_PIX_FMT_YUV420P;
  55.  
  56.     if (argc < 2) {
  57.         printf("Please provide a movie file\n");
  58.         return -1;
  59.     }
  60.     // Register all formats and codecs
  61.     av_register_all();
  62.  
  63.     // Open video file
  64.     if (avformat_open_input(&pFormatCtx, argv[1], NULL, NULL) != 0)
  65.         return -1; // Couldn't open file
  66.  
  67.                    // Retrieve stream information
  68.     if (avformat_find_stream_info(pFormatCtx, NULL) < 0)
  69.         return -1; // Couldn't find stream information
  70.  
  71.                    // Dump information about file onto standard error
  72.     av_dump_format(pFormatCtx, 0, argv[1], 0);
  73.  
  74.     // Find the first video stream
  75.     videoStream = -1;
  76.     for (i = 0; i < pFormatCtx->nb_streams; i++)
  77.         if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
  78.             videoStream = i;
  79.             break;
  80.         }
  81.     if (videoStream == -1)
  82.         return -1; // Didn't find a video stream
  83.  
  84.                    // Get a pointer to the codec context for the video stream
  85.     // Find the decoder for the video stream
  86.     pCodec = avcodec_find_decoder(pFormatCtx->streams[videoStream]->codecpar->codec_id);
  87.     std::cout << pCodec->pix_fmts;
  88.     if (pCodec == NULL) {
  89.         fprintf(stderr, "Unsupported codec!\n");
  90.         return -1; // Codec not found
  91.     }
  92.  
  93.  
  94.     pCodecCtx = avcodec_alloc_context3(pCodec);
  95.  
  96.  
  97.     //Copy context
  98.  
  99.     if (avcodec_parameters_to_context(pCodecCtx, pFormatCtx->streams[videoStream]->codecpar) != 0) {
  100.         fprintf(stderr, "Couldn't copy codec context");
  101.         return -1; // Error copying codec context
  102.     }
  103.  
  104.     // Open codec
  105.  
  106.     if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0)
  107.         return -1; // Could not open codec
  108.  
  109.                    // Allocate video frame
  110.     pFrame = av_frame_alloc();
  111.  
  112.     // Allocate an AVFrame structure
  113.     pFrameRGB = av_frame_alloc();
  114.     if (pFrameRGB == NULL)
  115.         return -1;
  116.  
  117.     // Determine required buffer size and allocate buffer
  118.     numBytes = av_image_get_buffer_size(pxFormat, pCodecCtx->width, pCodecCtx->height, 32);
  119.     buffer = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t));
  120.  
  121.     // Assign appropriate parts of buffer to image planes in pFrameRGB
  122.     // Note that pFrameRGB is an AVFrame, but AVFrame is a superset
  123.     // of AVPicture
  124.     av_image_fill_arrays(pFrameRGB->data, pFrameRGB->linesize, buffer, pxFormat, pCodecCtx->width, pCodecCtx->height, 32);
  125.  
  126.     // initialize SWS context for software scaling
  127.     sws_ctx = sws_getContext(pCodecCtx->width,
  128.         pCodecCtx->height,
  129.         pCodecCtx->pix_fmt,
  130.         pCodecCtx->width,
  131.         pCodecCtx->height,
  132.         pxFormat,
  133.         SWS_BILINEAR,
  134.         NULL,
  135.         NULL,
  136.         NULL
  137.     );
  138.  
  139.     // Read frames and save first five frames to disk
  140.     i = 0;
  141.     while (av_read_frame(pFormatCtx, &packet) >= 0) {
  142.         // Is this a packet from the video stream?
  143.         if (packet.stream_index == videoStream) {
  144.             // Decode video frame
  145.             frameFinished = avcodec_receive_frame(pCodecCtx, pFrame);
  146.  
  147.             // Did we get a video frame?
  148.             if (frameFinished) {
  149.                 // Convert the image from its native format to RGB
  150.                 std::cout << "Frame finished";
  151.                 sws_scale(sws_ctx, (uint8_t const * const *)pFrame->data,
  152.                     pFrame->linesize, 0, pCodecCtx->height,
  153.                     pFrameRGB->data, pFrameRGB->linesize);
  154.  
  155.                 // Save the frame to disk
  156.                 //if (++i <= 5)
  157.                     //SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height,
  158.                         //i);
  159.             }
  160.         }
  161.  
  162.         // Free the packet that was allocated by av_read_frame
  163.         av_packet_unref(&packet);
  164.     }
  165.  
  166.     // Free the RGB image
  167.     av_free(buffer);
  168.     av_frame_free(&pFrameRGB);
  169.  
  170.     // Free the YUV frame
  171.     av_frame_free(&pFrame);
  172.  
  173.     // Close the codecs
  174.     avcodec_parameters_free(&pCodecParams);
  175.     avcodec_close(pCodecCtx);
  176.     avcodec_close(pCodecCtxOrig);
  177.  
  178.     // Close the video file
  179.     avformat_close_input(&pFormatCtx);
  180.  
  181.     return 0;
  182. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement