Archiv verlassen und diese Seite im Standarddesign anzeigen : Windows AVI 24bit unkomprimiert einlesen?
Hi Leute,
ich will ein Video im Format Windows AVI 24bit unkomprimiert, Auflösung 352x288, 25fps einlesen, um es als Bytebuffer Bild für Bild an eine Funktion übergeben zu können. Da gibt es doch mit Sicherheit schon irgendwelche Sourcen für, irgendwo. Kann mir jemand sagen, was man da am besten für nimmt?
Danke
Gruß,
Hendrik
Anders gefragt: hat schonmal jemand mit ffmpeg gearbeitet hier? libavformat, libavcodec?
quinte17
26-01-2006, 09:25
weder noch, aber ein avi ist ja nur ein RIFF container, diese sind auf msdn recht gut dokumentiert..
habe mit kumpel an so einem tool schon ein wenig rumgewurschtelt...
bluebox-effect
lichtschwert
überblenden
farbmanipulation
uvm...
source kann ich dir leider nicht geben
greetz
Also um das mal zu erklären... es geht darum, ein AVI File Bild für Bild in einen H.263 codierten RTP Stream zu encodieren. Dieser RTP Stream soll dann Paket für Paket statt auf das Netzwerk erstmal in einer sogenannten IRF Datei abgelegt werden. Darin enthalten sind im Prinzip nur aneinandergereiht die Payloads der generierten RTP-Pakete; ach ja, und umgekehrt - also aus einer IRF Datei ein AVI zu machen.
Soviel zur Theorie. Das ganze muss jetzt in die Praxis umgesetzt werden. Die ganzen Funktionen zum Encodieren der Bilder existieren schon. Es geht jetzt nur noch darum, den Funktionen einzeln die Bilder als Byte-Buffer samt Größe zu übergeben. Ich muss also nur wissen, wie man mit libavformat und libavcodec (hier in der Version 0.4.6) ein Windows AVI 24bit Video bildweise einliest.
Harr, da hab ich euch wieder ein Thema aufgedrückt, was?! :) Schon Scheiße, wenn man sich mit solch... seltenen Themen rumärgern muss, bei denen einem fast keiner helfen kann.
Kannst du dir nicht einfach anschauen, wie das ffmpeg (das ist doch libavcodec, oder) Eingabeplugin von transcode die Bilder einliest?
transcode macht ja im Grunde genommen das, was du auch machen musst; AVIs umkomprimieren.
Shit is das kompliziert... Vorher überhaupt mal 'ne Frage: woher weiß ich denn, daß das, was bei mir jetzt am Ende heraus kommt (ja, einlesen klappt wohl, umkodieren auch... jedenfalls theoretisch), tatsächlich RTP-Payloads mit H.263 encodierten AVI Frames sind, und nicht irgendein undefinierbarer Byte-Salat? Gibt es Tools, mit denen man sich sowas anschauen kann?
Also okay... Encodierung scheint zu funktionieren. MPlayer kann den daraus resultierenden H.263 RTP-Stream abspielen. Jetzt muss ich diesen Raw-RTP Stream wieder in ein unkomprimiertes 24bit AVI Format verwandeln.
Sind jetzt runtergegangen auf QCIF (176x144). Vorher hatten wir CIF (352x288). Jetzt tritt aber irgendwie ein Problem auf, wo ich nicht ganz weiß, wie ich da ansetzen soll. Wenn ich das resultierende RTP File abspiele, fehlt am Ende ein ganzes Stück des Videos gegenüber dem Original. Mein Programm sagt mir aber, es habe alle Frames encodiert. Wie kann sowas zustande kommen?
Vielleicht fehlt tatsächlich nichts, nur die Datei selbst hat an der Stelle ein falsches Format und der Player bricht dann ab?
Der MPlayer sagt mir an der Stelle dann "End of File reached (EOF)". Die komplette Ausgabe des MPlayers bei Wiedergabe des im Anhang befindlichen (als zip gepackten) Files:
MPlayer dev-CVS-050928-16:38-3.4.2 (C) 2000-2005 MPlayer Team
CPU: Intel (Family: 8, Stepping: 3)
Detected cache-line size is 64 bytes
CPUflags: MMX: 1 MMX2: 1 3DNow: 0 3DNow2: 0 SSE: 0 SSE2: 0
Compiled with runtime CPU detection - WARNING - this is not optimal!
To get best performance, recompile MPlayer with --disable-runtime-cpudetection.
CommandLine: 'src10.rtp' '-v'
init_freetype
font: can't open file: c:/windows/fonts/arial.ttf
Cannot load font: c:/windows/fonts/arial.ttf
Using MMX (with tiny bit MMX2) Optimized OnScreenDisplay
Using Windows native timing
get_path('input.conf') -> 'D:/My/ISTS/H263/MPlayer/mplayer/mplayer/input.conf'
Parsing input config file D:/My/ISTS/H263/MPlayer/mplayer/mplayer/input.conf
Input config file D:/My/ISTS/H263/MPlayer/mplayer/mplayer/input.conf parsed: 53
binds
get_path('src10.rtp.conf') -> 'D:/My/ISTS/H263/MPlayer/mplayer/mplayer/src10.rtp
.conf'
Playing src10.rtp.
WINSOCK2 init: 0
[file] File size is 91645 bytes
STREAM: [file] src10.rtp
STREAM: Description: File
STREAM: Author: Albeu
STREAM: Comment: based on the code from ??? (probably Arpi)
Checking for YUV4MPEG2
ASF_check: not ASF guid!
Checking for NuppelVideo
Checking for REAL
Checking for SMJPEG
Searching demuxer type for filename src10.rtp ext: .rtp
Checking for Nullsoft Streaming Video
Checking for MOV
Checking for VIVO
header block 1 size: 0
AVS: avs_check_file - attempting to open file src10.rtp
AVS: File is too big, aborting...
Checking for PVA
Checking for MPEG-TS...
TRIED UP TO POSITION 68718, FOUND 0, packet_size= 71, SEEMS A TS? 0
Checking for LMLM4 Stream Format
Invalid packet in LMLM4 stream: ch=0 size=481067768
LMLM4 Stream Format not found
MPEG Stream reached EOF
ds_fill_buffer: EOF reached (stream: video)
MPEG packet stats: p100: 0 p101: 0 p1B6: 0 p12x: 0 sli: 0 a: 0 b: 0 c: 0 idr: 0
sps: 0 pps: 0 PES: 0 MP3: 64, synced: 0
Not MPEG System Stream format... (maybe Transport Stream?)
MPEG Stream reached EOF
ds_fill_buffer: EOF reached (stream: video)
MPEG packet stats: p100: 0 p101: 0 p1B6: 0 p12x: 0 sli: 0 a: 0 b: 0 c: 0 idr: 0
sps: 0 pps: 0 PES: 0 MP3: 64, synced: 3
Not MPEG System Stream format... (maybe Transport Stream?)
ds_fill_buffer: EOF reached (stream: video)
LAVF_check: raw h263
libavformat file format detected.
==> Found video stream: 0
======= VIDEO Format ======
biSize 40
biWidth 176
biHeight 144
biPlanes 0
biBitCount 0
biCompression 859189832='H263'
biSizeImage 0
===========================
LAVF: 0 audio and 1 video streams found
LAVF: build 3211520
VIDEO: [H263] 176x144 0bpp 25.000 fps 0.0 kbps ( 0.0 kbyte/s)
[V] filefmt:35 fourcc:0x33363248 size:176x144 fps:25.00 ftime:=0.0400
get_path('sub/') -> 'D:/My/ISTS/H263/MPlayer/mplayer/mplayer/sub/'
get_path('default.sub') -> 'D:/My/ISTS/H263/MPlayer/mplayer/mplayer/default.sub'
<vo_directx><INFO>checking primary surface
<vo_directx><FORMAT PRIMARY>14 BGR32 supported
<vo_directx><INFO>testing supported overlay pixelformats
<vo_directx><FORMAT OVERLAY>0 YV12 supported
<vo_directx><FORMAT OVERLAY>1 I420 supported
<vo_directx><FORMAT OVERLAY>2 IYUV supported
<vo_directx><FORMAT OVERLAY>3 YVU9 supported
<vo_directx><FORMAT OVERLAY>4 YUY2 supported
<vo_directx><FORMAT OVERLAY>5 UYVY supported
<vo_directx><FORMAT OVERLAY>6 BGR8 not supported
<vo_directx><FORMAT OVERLAY>7 RGB15 not supported
<vo_directx><FORMAT OVERLAY>8 BGR15 not supported
<vo_directx><FORMAT OVERLAY>9 RGB16 not supported
<vo_directx><FORMAT OVERLAY>10 BGR16 not supported
<vo_directx><FORMAT OVERLAY>11 RGB24 not supported
<vo_directx><FORMAT OVERLAY>12 BGR24 not supported
<vo_directx><FORMAT OVERLAY>13 RGB32 not supported
<vo_directx><FORMAT OVERLAY>14 BGR32 not supported
<vo_directx><INFO>Your card supports 6 of 15 overlayformats
<vo_directx><INFO>can mirror left right
<vo_directx><INFO>can mirror up down
<vo_directx><INFO>hardware supports overlay
================================================== ========================
Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family
INFO: libavcodec init OK!
Selected video codec: [ffh263] vfm:ffmpeg (FFmpeg H.263+ decoder)
================================================== ========================
Audio: no sound
Freeing 0 unused audio chunks.
Starting playback...
[ffmpeg] aspect_ratio: 1.333333
VDec: vo config request - 176 x 144 (preferred csp: Planar YV12)
Trying filter chain: vo
VDec: using Planar YV12 as output csp (no 0)
Movie-Aspect is 1.33:1 - prescaling to correct movie aspect.
VO Config (176x144->192x144,flags=0,'MPlayer',0x32315659)
VO: [directx] 176x144 => 192x144 Planar YV12
VO: Description: Directx DDraw YUV/RGB/BGR renderer
VO: Author: Sascha Sommer <saschasommer@freenet.de>
<vo_directx><INFO>overlay with format YV12 created
*** [vo] Allocating (slices) mp_image_t, 176x144x12bpp YUV planar, 38016 bytes
get_path('subfont.ttf') -> 'D:/My/ISTS/H263/MPlayer/mplayer/mplayer/subfont.ttf'
New_Face failed. Maybe the font path is wrong.
Please supply the text font file (~/.mplayer/subfont.ttf).
subtitle font: load_sub_face failed.
*** [vo] Allocating (slices) mp_image_t, 176x144x12bpp YUV planar, 38016 bytes
ds_fill_buffer: EOF reached (stream: video)
EOF code: 1
uninit video: ffmpeg
WINSOCK2 uninit
Exiting... (End of file)
Ich weiß, meine Fragen sind momentan alle noch etwas schwammig formuliert, aber mein Wissen über diese Thematik ist eben leider noch sehr lückenhaft.
Edit: ich würde das Original auch gern hier hochladen. Es ist allerdings dank fehlender Komprimierung knapp 17 MB groß...
Edit2: wenn du dir die Sourcen meines Programms mal anschauen willst, dann zieh sie dir dort:
http://7eq.ath.cx/repos/H263TEST/
Ich hab das ganze jetzt mal unter Windows zu kompilieren versucht. FFMPeg 0.4.9 lässt sich im MinGW nach start der vcvars32.bat sauber übersetzen. Configure:
./configure --enable-shared --enable-memalign-hack
Danach make klappt wunderbar. Er legt mir die notwendigen .lib und .dll Dateien an. Alles fein.
Mein Programm übersetzt auch sauber, linkt auch, startet auch. Aber... der Funktionsaufruf
AVCodec *pCodec;
pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
liefert unter Windoof pCodec = NULL; zurück. Unter Linux funktioniert das einwandfrei. Was kann da falsch gelaufen sein?
EDIT: aha, avcodec_register_all() nirgendwo vorher aufgerufen *kopf->tisch*
Hmm... jetzt bekomme ich seit neuestem den Fehler AVERROR_IO von av_open_input_file zurück (immer noch unter Windows)... Die Datei existiert aber, ist auch nicht von irgendeinem anderen Programm geöffnet. Sehr eigenartig. Jemand 'ne Idee?
edit: hmm, das Problem hat sich auch erledigt... man sollte auch av_register_all() vorher aufrufen. Nicht nur avcodec_register_all().
Wie dem auch sei... Irgendwie hab ich immer noch das Problem, daß das Video nach der Encodierung absolut scheiße aussieht. Also man erkennt gar nix mehr, alles ist verzerrt, die Farben sind falsch, nix geht mehr...
Also irgendwas muss da beim Übersetzen der FFMPEG Libs schiefgehen. Jedenfalls hab ich das jetzt alles runtergebrochen auf ein Level, wo Windows und Linux exakt das selbe tun. Unter Linux sind die RTP Payloads bei jedem Aufruf mit einer Beispielsequenz gleich groß. Beispielsweise ist Frame #140 immer 1204 Bytes lang. Der Logik nach zu urteilen ist das auch korrekt. Die Eingabe-Daten ändern sich ja auch nicht.
So... unter Windows sind trotz der selben Eingabe-Sequenz die RTP Payloads bei jedem Aufruf unterschiedlich groß! Beispielsweise ist Payload #140 beim 1. Aufruf 2156 Bytes (!) lang, beim nächsten Aufruf mit der selben Datei nur noch 2128 Bytes. Beim 3. Aufruf dann 2153 Bytes... also immer unterschiedlich. Was läuft da schief???
Zur Info
Windows:
ffmpeg Version: ffmpeg-0.4.9
Übersetzungsumgebung u. Windows: MinGW
Compiler-Version: gcc-3.4.2
Configure-Aufruf v. ffmpeg: ./configure --enable-shared --enable-gpl --disable-mmx
Linux:
ffmpeg Version: ffmpeg-0.4.9
Compiler-Version: 3.3.3
Configure-Aufruf v. ffmpeg: ./configure --enable-shared --prefix=/ffmpeg-0.4.9
Edit:
Habe mir mal die ersten 10 Bytes jedes einzelnen von avcodec_encode_video zurückgelieferten Frames angeschaut (Buffer output).
Linux:
First 10 Bytes of Payload #140: 0x0 0x0 0x82 0x2e 0x1c 0xac 0x83 0x4 0x92 0x0
First 10 Bytes of Payload #141: 0x0 0x0 0x82 0x32 0x1c 0xac 0x83 0x0 0x12 0x0
First 10 Bytes of Payload #142: 0x0 0x0 0x82 0x36 0x1c 0xac 0x83 0x4 0x92 0x0
First 10 Bytes of Payload #143: 0x0 0x0 0x82 0x3a 0x1c 0xac 0x83 0x4 0x12 0x0
First 10 Bytes of Payload #144: 0x0 0x0 0x82 0x3e 0x1c 0xac 0x83 0x4 0x92 0x0
First 10 Bytes of Payload #145: 0x0 0x0 0x82 0x42 0x1c 0xac 0x83 0x4 0x12 0x0
First 10 Bytes of Payload #146: 0x0 0x0 0x82 0x46 0x1c 0xac 0x83 0x4 0x92 0x0
First 10 Bytes of Payload #147: 0x0 0x0 0x82 0x4a 0x1c 0xac 0x83 0x4 0x12 0x0
First 10 Bytes of Payload #148: 0x0 0x0 0x82 0x4e 0x1c 0xac 0x83 0x4 0x92 0x0
First 10 Bytes of Payload #149: 0x0 0x0 0x82 0x52 0x1c 0xac 0x83 0x4 0x12 0x0
Windows:
First 10 Bytes of Payload #140: 0x0 0x0 0x82 0x2e 0x1c 0xac 0x83 0x4 0x93 0x0
First 10 Bytes of Payload #141: 0x0 0x0 0x82 0x32 0x1c 0xac 0x83 0x0 0x13 0x0
First 10 Bytes of Payload #142: 0x0 0x0 0x82 0x36 0x1c 0xac 0x83 0x4 0x93 0x0
First 10 Bytes of Payload #143: 0x0 0x0 0x82 0x3a 0x1c 0xac 0x83 0x4 0x13 0x0
First 10 Bytes of Payload #144: 0x0 0x0 0x82 0x3e 0x1c 0xac 0x83 0x4 0x93 0x0
First 10 Bytes of Payload #145: 0x0 0x0 0x82 0x42 0x1c 0xac 0x83 0x4 0x13 0x0
First 10 Bytes of Payload #146: 0x0 0x0 0x82 0x46 0x1c 0xac 0x83 0x4 0x93 0x0
First 10 Bytes of Payload #147: 0x0 0x0 0x82 0x4a 0x1c 0xac 0x83 0x4 0x13 0x0
First 10 Bytes of Payload #148: 0x0 0x0 0x82 0x4e 0x1c 0xac 0x83 0x4 0x93 0x0
First 10 Bytes of Payload #149: 0x0 0x0 0x82 0x52 0x1c 0xac 0x83 0x4 0x13 0x0
Kann mir mal jemand erklären, wieso bei identischem Code, identischen Versionsnummern der Software (inzwischen auch unter Linux getestet mit GCC 3.4.1 mit dem selben Effekt) etc. das 9. Byte unter Linux jeweils 1 niedriger ist, als unter Windows??? Es sind die selben Quell-Video-Sequenzen, die selben Code-Dateien... FFMPEG liegt auf beiden Systemen in der Version 0.4.9 vor. Einzig die Compiler-Umgebung und das Betriebssystem unterscheiden sich.
Ich versteh das nicht! Kann mir das einer erklären???
Hab Änderungen an meinem letzten Posting vorgenommen...
Kann es einfach sein, dass das Komprimierungsverfahren nicht nur lossy, sondern auch nicht-deterministisch ist? Das also verschiedene Durchläufe andere Ergebnisse liefern, da andere Zufallszahlen genommen werden?
Ich denke übrigens, das man dir in der ffmpeg-user Mailingliste besser helfen können wird.
Hmm, könnte sein. Das weiß ich nicht. Kenn mich da leider noch nicht so aus. Aber danke für den Hinweis mit der Mailing List... hätt ich ja beinahe selber drauf kommen können. :D
Hehe... Jaja, der Wald und die Bäume! ;)
Hmm... also viel Wald ist da nicht... irgendwie herrscht dort in der Mailinglist momentan der Leitsatz mit dem Schweigen und dem Edelmetall vor... :confused:
Achso, und zu deiner These in Sachen nicht-deterministisch... dann ist es jedoch eigenartig, daß unter Linux das Ergebnis immer bit-identisch ist, unter Windows jedoch nicht. Nutzt FFMPEG denn unter Linux nicht die gleichen (eigenen) Codec-Algorithmen, wie unter Windows? Oder nutzt FFMPEG die vom Betriebssystem bereitgestellten Codecs? Letzteres kann bei näherer Betrachtung eigentlich nicht möglich sein, denn ich habe in mein Linux keine extra Codecs integriert.
In der FFMPEG Mailinglist tobt echt der Bär... NICHT! Hmm... Also wir haben jetzt den Windows Part erstmal ad akta gelegt. Jetzt geht's darum, den Linux Part der Software fit zu machen. Der lustige Effekt dabei ist, daß das Bild des resultierenden RTP Files beim Abspielen einige Pixel nach rechts verschoben ist und einige Frames am Ende fehlen.
Ist hier eventuell jemand, der solch ein generiertes RTP Payload File analysieren kann, um sagen zu können, was da verkehrt läuft? Ich kann hier mal die Einstellungen zum entsprechenden Encoder Context aufführen:
context->width=176;
context->height=144;
context->frame_rate=25;
context->frame_rate_base=1;
context->frame_number=0;
context->gop_size = 10;
context->max_b_frames=0;//B-Frames werden nicht unterstützt!!!
context->bit_rate=3;
context->bit_rate_tolerance=1;
context->flags|=CODEC_FLAG_H263P_AIC; //Advanced Intra Coding Mode
context->flags|=CODEC_FLAG_H263P_UMV; //Unlimited Motion Vector Mode
context->rtp_mode=1;
context->rtp_payload_size= 20000;
context->rtp_callback=&h263_rtp_callback;
context->workaround_bugs=FF_BUG_AUTODETECT;
context->pix_fmt=PIX_FMT_YUV420P;
context->time_base.den = 25;
context->time_base.num = 1;
context->flags|=CODEC_FLAG_PSNR;
Vielleicht hilft das bei der Analyse des Problems. Das ist der CodecContext, der beim Aufruf von avcodec_encode_video verwendet wird, welches dann per Callback die RTP Payloads als Puffer an eine andere Funktion übergibt.
Im Anhang jetzt mal das RTP Payload File mit dem merkwürdigen Verschiebungseffekt.
oracle2025
16-02-2006, 11:32
Hi,
also es gibt ein oder zwei Tutorials wie man mit ffmpeg Dateien auslesen kann, hab die Links grad nicht parat, aber müsste eigentlich zu finden sein.
Abgesehen davon finde ich das API von ffmpeg nicht besonders End-Benutzer freundlich. Ich benutze immer libquicktime (http://libquicktime.sf.net/), das hat wesentlich freundlichere APIs. Allerdings ist es nicht wirklich Windows geeignet, aber evtl. kann man mit cygwin was machen.
Die Tutorials kenne ich bereits. Aber die sagen nichts über Schwierigkeiten beim Encodieren. Außerdem geht's da nur um das Auslesen, nicht jedoch um das erstellen einer AVI Datei, was bei uns im zweiten Step erfolgen soll. Aber das ist noch nicht akut.
Powered by vBulletin® Version 4.2.5 Copyright ©2024 Adduco Digital e.K. und vBulletin Solutions, Inc. Alle Rechte vorbehalten.