Ok folgendes habe ich jetzt:
Ich habe aus einem RTMP Stream, der Mikrofondaten im Nellymoser Format mit 44,1kHz übeträgt, genau die Audiodaten extrahiert (ohne den RTMP header). Waren jeweils Chunks von 513 Byte (seltsamerweise 513...aber ok)
Dann wollte ich das mit FFMpeg decodieren lassen. Also alles in eine Datei geschrieben, und folgende Funktion geschrieben, woran ich das übergebe:
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50:
| procedure convert(const sFile,sOutFile:string); var pCodec:PAVCodec; pCodecCtx:PAVCodecContext; outBuf:Array[0..AVCODEC_MAX_AUDIO_FRAME_SIZE-1] of Byte; inBuf:Array[0..FF_INPUT_BUFFER_PADDING_SIZE+InBuf_Size-1] of Byte; stIn,stOut:TStream; size,len,outSize:Integer; pInBuf:PByte; begin pCodec:=avcodec_find_decoder(CODEC_ID_NELLYMOSER); if(pCodec=nil) then begin showmessage('no codec'); exit; end; pCodecCtx:=avcodec_alloc_context(); if(pCodecCtx=nil) then begin showmessage('no codecCtx'); exit; end; if(avcodec_open(pCodecCtx,pCodec)<0) then begin showmessage('Error open codec'); exit; end; stIn:=TFileStream.Create(sFile,fmOpenRead); stIn.Position:=0; stOut:=TFileStream.Create(sOutFile,fmCreate); try while(stIn.Position<stIn.Size) do begin size:=stIn.Read(inBuf[0],InBuf_Size); pInBuf:=@inBuf[0]; while(size>0) do begin outSize:=Length(outBuf); len:=avcodec_decode_audio2(pCodecCtx,@outBuf[0],@outSize,pInBuf,size); if(len<=0) then begin showmessage('Error decoding'); exit; end; if(outSize>0) then begin stOut.Write(outBuf[0],outSize); end; Dec(size,len); Inc(pInBuf,len); end; end; finally stIn.Free; stOut.Free; avcodec_close(pCodecCtx); end; end; |
Mit nem InBuf_Size von 513 (oder vielfache davon) läuft der durch (len=513). Sonst gibts Fehler oder Zugriffsverletzungen in der DLL. Das Problem: outSize ist immer 0. D.h. er gibt mir keine Ausgabe.
Weiß da jemand was?
Edit: Anscheinend werden die Daten gepuffert.
Hab beim testweise encode festgestellt, dass erstmal viele Daten in den Encoder reingehn und erst nach ein paar Sample-folgen AusgabeDaten kommen. Kann man den zwingen, auszugeben, was er bisher hat?
Edit2: Doch nicht (lt Source code) zumindest nicht beim decode.
Er braucht 512 Bytes sonst steigt er vorher aus.
Die AV kommt aus der DLL. s:
ffmpeg.arrozcru.org/...mp;t=1603&p=5442