[c++] FFMPEG으로 동영상 재생하기

이 블로그 포스트에서는 FFMPEG 라이브러리를 사용하여 C++에서 동영상을 재생하는 방법에 대해 다루겠습니다.

필요한 라이브러리 설치

먼저, FFMPEG 라이브러리를 설치해야 합니다. 다음은 Linux 운영 체제 환경에서의 설치 방법입니다.

sudo apt-get install libavformat-dev libavcodec-dev libavutil-dev libswscale-dev

동영상 재생 코드 작성

이제 동영상을 재생하는 C++ 코드를 작성해보겠습니다. 아래는 간단한 예제 코드입니다.

extern "C" {
#include <libavformat/avformat.h>
#include <libavutil/imgutils.h>
#include <libavutil/opt.h>
#include <libswscale/swscale.h>
#include <libavutil/time.h>
}

int main() {
    av_register_all();

    AVFormatContext *pFormatContext = avformat_alloc_context();
    if (avformat_open_input(&pFormatContext, "video.mp4", NULL, NULL) != 0) {
        return -1;
    }

    avformat_find_stream_info(pFormatContext, NULL);

    av_dump_format(pFormatContext, 0, "video.mp4", 0);

    int videoStream = -1;
    for (unsigned int i = 0; i < pFormatContext->nb_streams; i++) {
        if (pFormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStream = i;
            break;
        }
    }

    if (videoStream == -1) {
        return -1;
    }

    AVCodecParameters *pCodecParameters = pFormatContext->streams[videoStream]->codecpar;
    AVCodec *pCodec = avcodec_find_decoder(pCodecParameters->codec_id);
    AVCodecContext *pCodecContext = avcodec_alloc_context3(pCodec);

    avcodec_parameters_to_context(pCodecContext, pCodecParameters);
    avcodec_open2(pCodecContext, pCodec, NULL);

    AVFrame *pFrame = av_frame_alloc();
    AVFrame *pFrameRGB = av_frame_alloc();

    int numBytes = av_image_get_buffer_size(
        AV_PIX_FMT_RGB24, pCodecContext->width, pCodecContext->height, 1);
    uint8_t *buffer = (uint8_t *)av_malloc(numBytes * sizeof(uint8_t));

    av_image_fill_arrays(
        pFrameRGB->data, pFrameRGB->linesize, buffer, 
        AV_PIX_FMT_RGB24, pCodecContext->width, pCodecContext->height, 1);

    struct SwsContext *swsContext = sws_getContext(
        pCodecContext->width, pCodecContext->height, pCodecContext->pix_fmt,
        pCodecContext->width, pCodecContext->height, AV_PIX_FMT_RGB24,
        SWS_BILINEAR, NULL, NULL, NULL);

    AVPacket packet;
    while (av_read_frame(pFormatContext, &packet) >= 0) {
        if (packet.stream_index == videoStream) {
            avcodec_send_packet(pCodecContext, &packet);
            avcodec_receive_frame(pCodecContext, pFrame);
            sws_scale(
                swsContext, (uint8_t const * const *)pFrame->data, 
                pFrame->linesize, 0, pCodecContext->height, 
                pFrameRGB->data, pFrameRGB->linesize);

            // pFrameRGB의 이미지를 화면에 표시하는 코드 작성
        }
        av_packet_unref(&packet);
    }

    // 종료 작업 수행
    av_frame_free(&pFrameRGB);
    av_frame_free(&pFrame);
    avcodec_close(pCodecContext);
    avcodec_free_context(&pCodecContext);
    avformat_close_input(&pFormatContext);
    avformat_free_context(pFormatContext);

    return 0;
}

위 코드는 주어진 동영상 파일을 열고 해당 동영상의 프레임을 디코딩하고 RGB 형식으로 변환한 다음 이를 화면에 표시하는 단순한 예제입니다. 화면에 표시하는 부분은 각자의 환경에 맞게 구현하여 사용할 수 있습니다.

마치며

이렇게 FFMPEG을 사용하여 C++에서 동영상을 재생하는 방법에 대해 간단하게 소개해보았습니다. FFMPEG은 매우 강력하고 유연한 멀티미디어 처리 라이브러리이며, 다양한 멀티미디어 관련 작업을 할 때 유용하게 활용될 수 있습니다.

더 많은 기능과 옵션들을 살펴보려면 FFMPEG의 공식 문서를 참고하시기 바랍니다.

참고 자료: