środa, 3 czerwca 2009

Edycja video w CImg i ffmpeg

Próba edycji pliku wideo z poziomu C++ może okazać się kłopotliwa jeśli nie korzystamy z dodatkowych bibliotek. Jak wiadomo standardów zapisu / kompresji multimediów jest naprawdę sporo i jeśli poradzilibyśmy sobie z jednym formatem to taką samą pracę należało by wykonać dla pozostałych. W Linuksie może nas w tym wyręczyć narzędzie ffmpeg i zbiór bibliotek, które są w nim zawarte (więcej można przeczytać na Wikipedii).

Aby napisać prosty przykład korzystający z ffmpeg trzeba poznać podstawy API bibliotek libavcodec oraz libavformat. Dla początkującego użytkownika może okazać się problematyczna analiza techniczna dokumentacji i niuansów związanych z kodekami video. Dlatego skorzystamy z innej biblioteki, która zawiera wsparcie dla ffmpeg, a mianowicie CImg (ta mała biblioteka nie przestaje mnie zaskakiwać swoimi możliwościami).

Na początek musimy się upewnić, że mamy zainstalowany pakiet ffmpeg. Możemy wydać polecenie instalacji i jeśli go nie będzie zostanie pobrany i zainstalowany:
sudo apt-get install ffmpeg

Oczywiście będzie również potrzebny testowy film, który będziemy modyfikować. Ja korzystałem z Pixar "Yeti Dance" (Pixar-Yeti_Dance.mpeg).

Następnie przygotowujemy kod programu:
#include <iostream>
#include <ostream>
#include "../CImg.h"

using namespace std;
using namespace cimg_library;

void process_frame(CImg<unsigned char> &frame)
{
  //negatyw obrazu
  cimg_forXYV(frame,x,y,v) { frame(x,y,v) = 255 - frame(x,y,v); }
}

int main()
{
  CImgList<unsigned char> film;
  film.load_ffmpeg("Pixar-Yeti_Dance.mpeg"); //odczyt z pliku

  CImgDisplay disp_film1, disp_film2;

  cimglist_for(film,index) {
    film[index].display(disp_film1);  //wyświetl oryginalną klatkę
    process_frame( film[index] );     //nakładanie filtru
    film[index].display(disp_film2);  //wyświetl zmodyfikowaną klatkę
  }
  while (!disp_film1.is_closed) disp_film1.wait();

  film.save_ffmpeg("Pixar-Yeti_Dance-invert.mpeg"); //zapis
  return 0;
}

Kompilacja za pomocą pomocą polecenia:
g++ -o ffmpeg_test ffmpeg_test.cpp -lX11 -lpthread

Po uruchomieniu programu zobaczymy na ekranie zarówno obraz oryginalny, jak i zmodyfikowany:

Omówiony przykład jest bardzo prosty i nie pokazuje pełnych możliwości ffmpeg. Jednak na etapie projektowania algorytmu wykorzystanie biblioteki CImg może znacznie ułatwić przygotowanie działającego prototypu.

0 komentarze:

Prześlij komentarz