MPEG Encodr

0

Witam i proszę o pomoc.
Napisałem aplikację w Javie, która ma służyć tworzeniu prostych reklam na podstawie szablonów. Aplikacja działa bez zarzutu, problem pojawia się z plikiem końcowym. Docelowo plik takiej reklamy ma być avi'kiem z kompresją MPEG4 (lub MPEG2, ale ze względu na rozdzielczości "720x576" wolałbym MPEG4). I tu pojawia się problem gdyż Java nie mam możliwości wygenerowania pliku z tą kompresją.

Puenta:

  1. Mój program generuje plik .avi (nieskompresowany) który trzeba skompresować do .avi (z kompresją MPEG4).
  2. Nie może to być graficzny program zewnętrzny.

Sugestie:

  1. Myślałem o napisaniu małego programu w C który pobierałby plik źródłowy (nieskompresowany) i generował docelowy (skompresowany) z wykorzystaniem jakiejś biblioteki (tylko nie mogę znaleźć żadnej biblioteki którą mógłbym się posłużyć). Następnie taki program skomunikować z aplikacją główną na gniazdach.
0

Nie napisales jaki system ? (java niby wieloplatformowa ale tu chcesz w c)
W windows mozna
http://msdn2.microsoft.com/en-us/library/ms712636.aspx
(funkcje AVI*) i ustawienie kompresji na MPEG-4 (zakladajac, ze jest kodek)

0

Platforma Windows. Nie zależy mi na między-platformowej wersji.

0

zatem szukaj o AVIFileOpen od tego poczatek ....

  1. otwieramy AVI (1) i tworzymy AVI(2): AVIFileOpen, AVIFileCreateStream
  2. Ustawiamy kodek dla (2) i formaty: AVISaveOptions, AVIMakeCompressedStream, AVIStreamSetFormat
  3. czytamy ramke (1) : AVIStreamRead
  4. zapisujemy ramke (2): AVIStreamWrite
    ..... do konca pliku 3) i 4)
  5. zamykamy (1) i (2): AVIStreamRelease, AVIStreamRelease, AVIFileRelease, AVIFileExit

np:
hep.fuw.edu.pl/u/wrochna/files/avi_doc.pdf

0

Wielkie dzięki dla Ciebie za tego posta.
Zabieram się do pisania.
Jak coś wykombinuję, dam znać.
Pozdrawiam Krzysiek

0

Witam ponownie.
Siedziałem wczoraj chwilę nad tym kodem i napisałem taki prosty program. Oto kod:

#include <stdio.h>
#include "headers\vfw.h"

void checkRetCode(int retCode);

int main(int argc, char *argv[]){
printf("Encoder MPEG4 plikow .avi\n");
int retCode;

AVIFileInit();
PAVIFILE *aviSourceFile = new PAVIFILE();
if((retCode =AVIFileOpen(aviSourceFile, "c:\\POLIBUDA\\ppp.avi", OF_READ, NULL)) == 0)
	printf("PLIK movie.avi otwarty do odczytu\n");
else{
	checkRetCode(retCode);
	AVIFileExit();
	return -1;
}

AVIFILEINFO *aviFileInfo;
if(AVIFileInfo(*aviSourceFile, aviFileInfo, sizeof(AVIFILEINFO)) == 0){
	printf("szerokosc w pikselach: %u\n",aviFileInfo->dwWidth);
	printf("wysokosc w pikselach: %u\n",aviFileInfo->dwHeight);
}else{
	printf("blad odczytu informacji o pliku\n");
	AVIFileRelease(*aviSourceFile);
	AVIFileExit();
	return -2;
}

PAVISTREAM *aviSourceStream = new PAVISTREAM();
if(AVIFileGetStream(*aviSourceFile, aviSourceStream, streamtypeVIDEO , 0) == AVIERR_OK){
	printf("otwarto strumien do odczytu\n");
}else{
	printf("blad otwarcia strumienia\n");
	AVIFileRelease(*aviSourceFile);
	AVIFileExit();
	return -3;
}

AVISTREAMINFO aviStreamInfo;
ZeroMemory(&aviStreamInfo,sizeof(AVISTREAMINFO));
AVIStreamInfo(*aviSourceStream, &aviStreamInfo, sizeof(AVISTREAMINFO));
AVIStreamRelease(*aviSourceStream);
AVIFileRelease(*aviSourceFile);
AVIFileExit();
return 0;

}

Funkcja checkRetCode(retCode); wyświetla tylko informacje o rodzaju błędu. Program się kompiluje i uruchamia. Problem w tym że po chwili przerywa działanie (dokładnie po wyświetleniu
"Encoder MPEG4 plikow .avi"
"PLIK movie.avi otwarty do odczytu") i pojawia się błąd Windows ("AviConverter.exe has encountered a problem and needs to close. We are sorry for the inconvenience."). Wiem że otwarcie pliku i strumienia działa poprawnie natomiast problem jest ze strukturą AVISTREAMINFO. Jeśli ktoś ma chwilkę żeby na to rzucić okiem to byłbym wdzięczny.
Używam MinGW Studio, do projektu linkuję bibliotekę libvfw32.a.

0

Poczytaj wiecej o wskaznikach, referencjach

        AVIFILEINFO aviFileInfo;
        if(AVIFileInfo(*aviSourceFile, &aviFileInfo, sizeof(AVIFILEINFO)) == 0){
                printf("szerokosc w pikselach: %u\n",aviFileInfo.dwWidth);
                printf("wysokosc w pikselach: %u\n",aviFileInfo.dwHeight);

jest w devie debuger, a jak stosujesz printf to tez dodaj fflush bo moze Cie oszukac.

0

Po co Od razu w C pisać?
http://www.alphaworks.ibm.com/tech/tk4mpeg4

IBM Alphaworks więc jakość niezła...

0

che che tak myslalem, z Java jestem na bakier wiec nie orientuje sie dokladnie co jest (jakos nigdy nie polubilem ... ani programowac (wlasciwie to programowac chyba lubilem duzo sie nie rozni od innych) ani uzywac aplikacji pisanych w javie).

0

Koziołek dzięki za zainteresowanie. Mam tylko pytanie: czy Ty kiedykolwiek tego używałeś do zapisywania. Bo jak na pierwszy rzut oka to przy pomocy tego narzędzia da się tylko wyświetlać tzn. dekodować ale nie da się enkodować . Jeśli się mylę to proszę o jakieś wskazówki.

Reichel. Ten kod wysypuje się nie na inicjowaniu ścieżki tylko na inicjowaniu AVISTREAMINFO. Bez tych trzech linii wszystko działa dlatego zachodzę w głowę co może być nie tak.

    AVISTREAMINFO aviStreamInfo;
    ZeroMemory(&aviStreamInfo,sizeof(AVISTREAMINFO));
    AVIStreamInfo(*aviSourceStream, &aviStreamInfo, sizeof(AVISTREAMINFO));
0

Ten kod u mnie dziala:

#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <vfw.h>

//using namespace std;

//void checkRetCode(int retCode);

int main(int argc, char *argv[])
{

        printf("Encoder MPEG4 plikow .avi\n");
        int retCode;

        AVIFileInit();
        PAVIFILE *aviSourceFile= new PAVIFILE();
        if((retCode =AVIFileOpen(aviSourceFile, "c:\\big.avi", OF_READ, NULL)) == 0)
        {
                printf("PLIK movie.avi otwarty do odczytu\n");
                fflush(stdout);
            }
        else{
              //  checkRetCode(retCode);
                AVIFileExit();
                return -1;
        }

        AVIFILEINFO aviFileInfo;
        if(AVIFileInfo(*aviSourceFile, &aviFileInfo, sizeof(AVIFILEINFO)) == 0){
                printf("szerokosc w pikselach: %u\n",aviFileInfo.dwWidth);
                printf("wysokosc w pikselach: %u\n",aviFileInfo.dwHeight);
        }else{
                printf("blad odczytu informacji o pliku\n");
                AVIFileRelease(*aviSourceFile);
                AVIFileExit();
                return -2;
        }

        PAVISTREAM *aviSourceStream = new PAVISTREAM();
        if(AVIFileGetStream(*aviSourceFile, aviSourceStream, streamtypeVIDEO , 0) == AVIERR_OK){
                printf("otwarto strumien do odczytu\n");
        }else{
                printf("blad otwarcia strumienia\n");
                AVIFileRelease(*aviSourceFile);
                AVIFileExit();
                return -3;
        }

        AVISTREAMINFO aviStreamInfo;
        ZeroMemory(&aviStreamInfo,sizeof(AVISTREAMINFO));
        AVIStreamInfo(*aviSourceStream, &aviStreamInfo, sizeof(AVISTREAMINFO));
        AVIStreamRelease(*aviSourceStream);
        AVIFileRelease(*aviSourceFile);
        AVIFileExit();



    system("PAUSE");
    return EXIT_SUCCESS;
}
Encoder MPEG4 plikow .avi
PLIK movie.avi otwarty do odczytu
szerokosc w pikselach: 1000
wysokosc w pikselach: 1000
otwarto strumien do odczytu
Press any key to continue . . .

i zgadza sie rozmiar

0

@KrzysiekP, powiem szczerze, że nie. Jednak zadałem jeszcze jedno pytanie i:
http://jmencode.sourceforge.net/index.html

encoding z GUI, ale nas będą interesować tylko fragmenty związane z kompresją. Machnij majla do autora niech podzieli się wiedzą. Projekt jest OpenSource więc można wziąć źródła bez problemu.

ps. z javą jest tak, że trzeba dobrze googlować i zadawać pytania w różny sposób. Dużo rzeczy już jest i nie warto się użerać z ich pisaniem od nowa

0

Reichel wielkie dzięki, po prostu dawno w C nic nie pisałem i troche musze się przyznać zginąłem tym bardziej podziękowania dla Ciebie.

Tobie też koziołek dzięki za inicjatywę, zaraz zapytam o o kod ale nie jestem pewien czy się przyda ponieważ muszę to musiałby być format DivX. Wiem że niby to to samo co XVid (a o tym formacie pisze autor), ale nie wiem czy tak do końca będę mógł go wykorzystać.

Póki co wielkie dzięki i pozdrawiam.

0

Znów mały kłopot .... chyba jednak będę troszke musiał podszkolić to C jeśli chce to napisać. Napisałem tak program (specjalnie pominąłem sprawdzenie kodów błędu w początkowych funkcjach bo wiem na pewno że działają OK a nie chce gmatwać kodu) i niestety cały czas dostaję błąd z funkcji zapisu strumienia "AVIStreamWrite(...)". Możecie coś podpowiedzieć ? Może źle ustawiam strukturę "AVICOMPRESSOPTIONS" albo coś nie tak z "AVIStreamSetFormat" ? Poniżej wklejam kod:

#include <stdio.h>
#include "headers\vfw.h"

int main(int argc, char *argv[]){
printf("Encoder MPEG4 plikow .avi\n");

int retCode;
AVIFileInit();

PAVIFILE *aviSourceFile = new PAVIFILE();
retCode = AVIFileOpen(aviSourceFile, "c:\\POLIBUDA\\movie.avi", OF_READ, NULL);

AVIFILEINFO aviFileInfo;
AVIFileInfo(*aviSourceFile, &aviFileInfo, sizeof(AVIFILEINFO));

PAVISTREAM *aviSourceStream = new PAVISTREAM();
AVIFileGetStream(*aviSourceFile, aviSourceStream, streamtypeVIDEO , 0); 

AVISTREAMINFO aviStreamInfo;
ZeroMemory(&aviStreamInfo,sizeof(aviStreamInfo));
AVIStreamInfo(*aviSourceStream, &aviStreamInfo, sizeof(AVISTREAMINFO));

PAVIFILE *aviDesFile = new PAVIFILE();
AVIFileOpen(aviDesFile, "c:\\POLIBUDA\\movie2.avi", OF_CREATE | OF_WRITE, NULL);

//tworzenie skompresowanego strumienia do zapisu;
PAVISTREAM *aviDesStream= new PAVISTREAM();
AVICOMPRESSOPTIONS aviCompressOptions;
ZeroMemory(&aviCompressOptions,sizeof(AVICOMPRESSOPTIONS));
aviCompressOptions.fccType = streamtypeVIDEO;
//aviCompressOptions.fccHandler=mmioFOURCC('d','i','v','x');
aviCompressOptions.fccHandler = aviStreamInfo.fccHandler; // narazie taki który wiem napewno że zadziała
aviCompressOptions.dwQuality = aviStreamInfo.dwQuality;
aviCompressOptions.dwFlags = AVICOMPRESSF_VALID;
if(AVIMakeCompressedStream(aviDesStream, *aviSourceStream, &aviCompressOptions, NULL) == AVIERR_OK)
	printf("utworzono strumien do zapisu\n");

long lSize = 0;
AVIStreamReadFormat(*aviSourceStream, 0, NULL, &lSize);
char format[(int)lSize];
AVIStreamReadFormat(*aviSourceStream, 0,format, &lSize);
AVIStreamSetFormat(*aviDesStream, 0,format, lSize);
AVIMakeFileFromStreams(aviDesFile, 1, aviDesStream);

int i = 0;
char buffer[720*576*3]; // bo filmik jest w rozdzielczości 720x576
while((retCode = AVIStreamRead(*aviSourceStream, i, 1, &buffer, sizeof(buffer), NULL, NULL)) == 0){
	printf("odczyt ze strumienia\n");
	if((retCode = AVIStreamWrite(*aviDesStream, i, 1, &buffer, sizeof(buffer), AVIIF_KEYFRAME, NULL, NULL))==0)
		printf("zapis do strumienia\n");
	else{
		printf("blad zapisu do strumienia\n");
	}
	i++;
}

AVIStreamRelease(*aviDesStream);
AVIFileRelease(*aviDesFile);
AVIStreamRelease(*aviSourceStream);
AVIFileRelease(*aviSourceFile);
AVIFileExit();
return 0;

}

0

Dodam jeszcze że plik "movie.avi" jest oczywiście nieskompresowany.

0

Ok problem rozwiązany :-)
Połapałem się w końcu.
Jeśli ktoś chciałby kod to na maila (syzrkMAŁPAo2.pl).
Jeszcze raz wielkie dzięki dzięki dla Ciebie reichel.
Nie wiem czy dałbym rade bez twoich wskazówek.
Pozdrawiam

1 użytkowników online, w tym zalogowanych: 0, gości: 1