c ++ - Videooptagelse hænger på IMFSinkWriter-> Afslut

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har implementeret brugerdefineret IMFMediaSink til brug med sink skribent. Fungerer OK, modtager h264 videosampler. Jeg har ingen container, jeg bruger rå h264 video prøver. Jeg har ikke implementeret brugerdefineret skribent, jeg bruger mFCreateSinkWriterFromMediaSink API til at pakke min brugerdefinerede medievask til en rammeforfatter. [12]


Jeg kan ikke gennemføre yndefulde nedlukning, IMFSinkWriter::Finalize() vender aldrig tilbage. Da jeg implementerede IMFSinkWriterCallback, IMFSinkWriter::Finalize() vender tilbage straks, men min IMFSinkWriterCallback::OnFinalize blev aldrig kaldt.


Problemet gengives i 100\% test med både nvenc og MS software encoder.


Writer attributter:


MF\_LOW\_LATENCY = TRUE
MF\_READWRITE\_ENABLE\_HARDWARE\_TRANSFORMS = TRUE (1)
MF\_READWRITE\_DISABLE\_CONVERTERS = FALSE (2)
MF\_SINK\_WRITER\_DISABLE\_THROTTLING = TRUE
MF\_SINK\_WRITER\_D3D\_MANAGER
MF\_SINK\_WRITER\_ASYNC\_CALLBACK


(1) Prøvet begge, samme resultat


(2) Brug konverterne, fordi nvenc kun understøtter YUV, og jeg har RGB-teksturer på input.


Output media type (den er fast, jeg bruger den indbyggede handler skabt af MFCreateSimpleTypeHandler API).


MF\_MT\_MAJOR\_TYPE = MFMediaType\_Video
MF\_MT\_SUBTYPE = MFVideoFormat\_H264
MF\_MT\_INTERLACE\_MODE = MFVideoInterlace\_Progressive
MF\_MT\_AVG\_BITRATE = 40*1000*1000
MF\_MT\_FRAME\_SIZE = { 3840, 2160 }
MF\_MT\_FRAME\_RATE = { 60, 1 }
MF\_MT\_PIXEL\_ASPECT\_RATIO = { 1, 1 }


Input media type:


MF\_MT\_MAJOR\_TYPE = MFMediaType\_Video
MF\_MT\_SUBTYPE = MFVideoFormat\_RGB32
MF\_MT\_INTERLACE\_MODE = MFVideoInterlace\_Progressive
MF\_MT\_FRAME\_SIZE = { 3840, 2160 }
MF\_MT\_FRAME\_RATE = { 60, 1 }
MF\_MT\_PIXEL\_ASPECT\_RATIO = { 1, 1 }


Når du ikke bruger IMFSinkWriterCallback, er der en call stack på tidspunktet for hænge:


ntdll.dll!\_NtWaitForSingleObject@12 ()
KernelBase.dll!WaitForSingleObjectEx()
mfreadwrite.dll!CMFSinkWriter::InternalFinalize(void)
mfreadwrite.dll!CMFSinkWriter::Finalize(void)


MFTrace har ikke noget i forbindelse med at afslutte selv med -k All:


13700,3C60 19:01:25.79566 CMFTransformDetours::ProcessOutput @02EA6E3C failed hr=0xC00D6D72 MF\_E\_TRANSFORM\_NEED\_MORE\_INPUT
13700,2A98 19:01:25.80250 CMFTransformDetours::ProcessOutput @1A6CEF38 Stream ID 0, Sample @1C244F30, Time 1216ms, Duration 16ms, Buffers 1, Size 12441600B, MFSampleExtension\_CleanPoint=1;MFSampleExtension\_Interlaced=0
13700,2098 19:01:25.80254 CMFTransformDetours::ProcessInput @02EA6E3C Stream ID 0, Sample @1C244F30, Time 1216ms, Duration 16ms, Buffers 1, Size 12441600B, MFSampleExtension\_CleanPoint=1;MFSampleExtension\_Interlaced=0
13700,2A98 19:01:25.80256 CMFTransformDetours::ProcessOutput @1A6CEF38 failed hr=0xC00D6D72 MF\_E\_TRANSFORM\_NEED\_MORE\_INPUT
13700,2A98 19:01:25.80266 CMFTransformDetours::ProcessMessage @1A6CEF38 Message type=0x00000001 MFT\_MESSAGE\_COMMAND\_DRAIN, param=00000000
13700,2A98 19:01:25.80267 CMFTransformDetours::ProcessOutput @1A6CEF38 failed hr=0xC00D6D72 MF\_E\_TRANSFORM\_NEED\_MORE\_INPUT
13700,2098 19:01:25.81669 CMFTransformDetours::ProcessOutput @02EA6E3C Stream ID 0, Sample @1FB68CF8, Time 1216ms, Duration 16ms, Buffers 1, Size 680B, {2B5D5457-5547-4F07-B8C8-B4A3A9A1DAAC}=1;{73A954D4-09E2-4861-BEFC-94BD97C08E6E}=12166667 (0,12166667);{9154733F-E1BD-41BF-81D3-FCD918F71332}=65535;{973704E6-CD14-483C-8F20-C9FC0928BAD5}=1;MFSampleExtension\_CleanPoint=0;{B2EFE478-F979-4C66-B95E-EE2B82C82F36}=16 (0,16)
13700,82C 19:01:25.81674 CMFTransformDetours::ProcessOutput @02EA6E3C failed hr=0xC00D6D72 MF\_E\_TRANSFORM\_NEED\_MORE\_INPUT
13700,82C 19:01:25.81674 CMFTransformDetours::ProcessMessage @02EA6E3C Message type=0x00000001 MFT\_MESSAGE\_COMMAND\_DRAIN, param=00000000
13700,82C 19:01:25.81674 CMFTransformDetours::ProcessOutput @02EA6E3C failed hr=0xC00D6D72 MF\_E\_TRANSFORM\_NEED\_MORE\_INPUT
13700,1F54 19:01:27.24237 CKernel32ExportDetours::OutputDebugStringA @ D3D11 WARNING: Process is terminating. Using simple reporting. Please call ReportLiveObjects() at runtime for standard reporting. [ STATE\_CREATION WARNING #0: UNKNOWN] 
13700,1F54 19:01:27.24255 CKernel32ExportDetours::OutputDebugStringA @ D3D11 WARNING: Live Producer at 0x0311D91C, Refcount: 13. [ STATE\_CREATION WARNING #0: UNKNOWN] 


Advarsler om levende D3D-ressourcer forventes, da jeg afsluttede processen efter hængslen.


Eventuelle ideer, hvad sker der? Jeg tror, ​​at forfatteren formentlig venter på at disse SPS/PPS magiske blobs kommer frem, men det sker aldrig. Er der en måde at instruere h264-encoderen på at sende SPS/PPS et sted?

Bedste reference


Du har implementeret brugerdefinerede IMFMediaSink, så jeg formoder, at du også har implementeret IMFStreamSink.


Hvis du gør dette på den sædvanlige måde med Mediafoundation, har du en cirkulær COM-reference mellem IMFMediaSink og IMFStreamSink. Det er derfor, at Shutdown-metoden fra IMFMediaSink-grænsefladen eksisterer.


Hvis et program, der bruger din brugerdefinerede MediaSink, ikke kalder Shutdown på det rigtige sted, vil der være hukommelselækager.


Fra dit IMFSinkWriterCallback-problem har vi ikke nok information til at finde ud af, hvor problemet er.


Det er heller ikke klart om 'brugerdefinerede IMFMediaSink' og 'IMFSinkWriter'. Implementerer du også en IMFSinkWriter ...


Edit1


Bare to ting:


MFCreateSinkWriterFromMediaSink [13]


Ring til CoInitialize (Ex) og MFStartup, før du ringer til denne funktion.


Når du er færdig med at bruge medievasken, skal du ringe til medievasken 's IMFMediaSink :: Afslutningsmetode. (Vaskeskriveren lukker ikke medievasken.) Løsn vaskeforfatteren, før du ringer Afbrydelse på medievasken.


frigiver du grænseflader korrekt?


IMFSinkWriter :: Afslut [14]


Internt kalder denne metode IMFStreamSink :: PlaceMarker for at placere slutmarkeringsmarkører for hver strøm på media-sinken.


Håndterer du denne meddelelse (MFSTREAMSINK\_MARKER\_ENDOFSEGMENT)?


Vi ved ikke, hvordan du håndterer CriticalSection/Event/CircularReference, så det er svært at finde problemet.


Edit2



  Er der en måde at instruere h264-encoderen på at sende SPS/PPS et sted?



Normalt for h264-videoformat skal du få attributterne MF\_MT\_MPEG\_SEQUENCE\_HEADER (BLOB-type), når SetCurrentMediaType hedder din IMFStreamSink (forudsat at du implementerer IMFMediaTypeHandler).


EDIT3


Kunne du give den rigtige (sådan tror jeg, at appen skal være):


topologi og dataflow [15]


Jeg kan ikke huske, om din tilpassede sink skaber en mp4-fil. Hvis det er, i IMFSinkWriter :: Finalize, skal du generere ftpy/moov atom.


EDIT4


Du kan også læse dette: Videooptagelse hænger på IMFSinkWriter-> Afslut ();



Uden kildekode er dette det eneste svar, jeg kan give.