[FFmpeg-devel] probable dshow bug or strangeness
Don Moir
donmoir at comcast.net
Mon Mar 17 20:08:27 CET 2014
----- Original Message -----
From: "Roger Pack" <rogerdpack2 at gmail.com>
To: "FFmpeg development discussions and patches" <ffmpeg-devel at ffmpeg.org>
Sent: Monday, March 17, 2014 2:41 PM
Subject: Re: [FFmpeg-devel] probable dshow bug or strangeness
> On 3/16/14, Don Moir <donmoir at comcast.net> wrote:
>>> ----- Original Message -----
>>> From: "Roger Pack" <rogerdpack2 at gmail.com>
>>> To: "FFmpeg development discussions and patches"
>>> <ffmpeg-devel at ffmpeg.org>
>>> Sent: Thursday, March 13, 2014 12:38 PM
>>> Subject: Re: [FFmpeg-devel] probable dshow bug or strangeness
>>>
>>>
>>>> On 3/12/14, Don Moir <donmoir at comcast.net> wrote:
>>>>>
>>>>> ----- Original Message -----
>>>>> From: "Roger Pack" <rogerdpack2 at gmail.com>
>>>>> To: "FFmpeg development discussions and patches"
>>>>> <ffmpeg-devel at ffmpeg.org>
>>>>> Sent: Wednesday, March 12, 2014 4:40 PM
>>>>> Subject: Re: [FFmpeg-devel] probable dshow bug or strangeness
>>>>>
>>>>>
>>>>>> On 3/11/14, Don Moir <donmoir at comcast.net> wrote:
>>>>>>>
>>>>>>> ----- Original Message -----
>>>>>>> From: "Don Moir" <donmoir at comcast.net>
>>>>>>> To: "FFmpeg development discussions and patches"
>>>>>>> <ffmpeg-devel at ffmpeg.org>
>>>>>>> Sent: Monday, March 10, 2014 5:27 PM
>>>>>>> Subject: Re: [FFmpeg-devel] probable dshow bug or strangeness
>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>> On 3/7/14, Don Moir <donmoir at comcast.net> wrote:
>>>>>>>>>> I am posting here since not quite sure and need some advice.
>>>>>>>>>>
>>>>>>>>>> I got word that some captures devices were not working. Everything
>>>>>>>>>> enumerated and went thru but no display.
>>>>>>>>>>
>>>>>>>>>> You get packets with zero size and then no decode success.
>>>>>>>>>>
>>>>>>>>>> I traced this into dshow_pin.c and function
>>>>>>>>>> libAVMemInputPin_Receive.
>>>>>>>>>> In
>>>>>>>>>> this function there is:
>>>>>>>>>>
>>>>>>>>>> buf_size = IMediaSample_GetActualDataLength(sample);
>>>>>>>>>>
>>>>>>>>>> In this case, buf_size is always zero. I think it is supposed to
>>>>>>>>>> be
>>>>>>>>>> set
>>>>>>>>>> somewhere with IMediaSample_SetActualDataLength and could be a
>>>>>>>>>> coding
>>>>>>>>>> issue
>>>>>>>>>> with driver.
>>>>>>>>>>
>>>>>>>>>> This apparently happens enough where I can't just blame the driver
>>>>>>>>>> if
>>>>>>>>>> thats
>>>>>>>>>> where it lies. Maybe it is supposed to be set in dshow_pin.c
>>>>>>>>>> somewhere
>>>>>>>>>> but
>>>>>>>>>> don't know.
>>>>>>>>>>
>>>>>>>>>> When this happens (buf_size == 0), the real data length appears to
>>>>>>>>>> be
>>>>>>>>>> returned by IMediaSample_GetSize(sample); This is supposed to be
>>>>>>>>>> the
>>>>>>>>>> actual
>>>>>>>>>> buffer length and not necessarily the data length. When I change
>>>>>>>>>> it
>>>>>>>>>> to
>>>>>>>>>> use
>>>>>>>>>> IMediaSample_GetSize it works perfect.
>>>>>>>>>
>>>>>>>>> Are you sure it's not just re-using the previous frame's worth of
>>>>>>>>> data?
>>>>>>>>
>>>>>>>> I think I am sure about that. It plays normal if I use GetSize and
>>>>>>>> nothing
>>>>>>>> with GetActualDataLength.
>>>>>>>>
>>>>>>>>> Maybe you should just ignore frames with size 0?
>>>>>>>>> Just wondering.
>>>>>>>>
>>>>>>>> GetActualDataLength is always zero in this case. I think yes you
>>>>>>>> should
>>>>>>>> ignore it but as a quick fix I used:
>>>>>>>>
>>>>>>>> buf_size = GetActualDataLength(sample);
>>>>>>>> if (!buf_size)
>>>>>>>> buf_size = GetSize(sample);
>>>>>>>>
>>>>>>>> If you completely ignore nothing will display and basically same
>>>>>>>> thing.
>>>>>>>>
>>>>>>>> The above is not correct and something else is going on. Still
>>>>>>>> looking
>>>>>>>> into it but have to do some other things first. If you have
>>>>>>>> any ideas let me know.
>>>>>>>
>>>>>>> Using above quick fix only allows for some display. It is not correct
>>>>>>> though
>>>>>>> (display is a bit weird) and that does not overcome the
>>>>>>> real problem which is still unknown.
>>>>>>>
>>>>>>> The thing about GetSize in this case is it always returns the
>>>>>>> expected
>>>>>>> frame
>>>>>>> size. Be it RGB, YUV, etc, the size returned by GetSize
>>>>>>> is the expected frame size.
>>>>>>>
>>>>>>> I have about 3 or 4 normal USB cameras and they all work correctly
>>>>>>> with
>>>>>>> GetActualDataLength etc. Just some assortment of capture
>>>>>>> devices are not working and this information came to me from end
>>>>>>> users.
>>>>>>>
>>>>>>> The problem as reported to me was: Everything list ok but you get no
>>>>>>> display. So I had to find some software capture device that
>>>>>>> reproduced the problem.
>>>>>>>
>>>>>>> I came across MediaLooks capture device and it seems to indicate the
>>>>>>> problems reported by users. List ok but no display.
>>>>>>>
>>>>>>> Roger if you or anyone else wants to take a look, you can download
>>>>>>> the
>>>>>>> MediaLooks dshow filter here. It's free (ignore buy button)
>>>>>>> and easy. Download, Install, no BS.
>>>>>>>
>>>>>>> http://www.medialooks.com/screen_capture/
>>>>>>>
>>>>>>> You can use ffplay or other code using ffmpeg to reproduce the
>>>>>>> problem.
>>>>>>> I
>>>>>>> can't say right now if this particular device accounts for
>>>>>>> all devices reported by users but it's a good start and these
>>>>>>> reported
>>>>>>> problems all had the same indication of: (list ok but no
>>>>>>> display).
>>>>>>>
>>>>>>> Works fine in VLC. I should be able to get back to it in a couple
>>>>>>> days,
>>>>>>> but
>>>>>>> if anyone has a suggestion I will look at that right
>>>>>>> away.
>>>>>>
>>>>>> I am able to see the issue with the medialooks capture.
>>>>>> I wonder if VLC gets the same values back for GetActualDataLength or
>>>>>> not.
>>>>>> Also it appears VLC is receiving it at I420 by default, not bgra?
>>>>>> hmm...
>>>>>> -roger-
>>>>>
>>>>> I don't think it matters about the color format. Checked several things
>>>>> going back and forth and don't recall that making any
>>>>> difference.
>>>>
>>>> I also wonder what this "i420" mentioned by VLC even is, maybe our
>>>> list_options output here is not verbose enough?
>>>>
>>>> C:\installs\ffmpeg-20140307-git-64e4bd7-win32-static\bin\ffmpeg.exe -f
>>>> dshow -list_options true -i video="MediaLooks Screen Capture" yo.mpg
>>>> ffmpeg version N-61143-g64e4bd7 Copyright (c) 2000-2014 the FFmpeg
>>>> developers
>>>> built on Mar 7 2014 00:01:08 with gcc 4.8.2 (GCC)
>>>> configuration: --enable-gpl --enable-version3 --disable-w32threads
>>>> --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r
>>>> --enable-gnutls --enable-iconv --enable-libass --enable-libbluray
>>>> --enable-libcaca --enable-libfreetype --enable-libgsm --enable-libilbc
>>>> --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb
>>>> --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus
>>>> --enable-librtmp --enable-libschroedinger --enable-libsoxr
>>>> --enable-libspeex --enable-libtheora --enable-libtwolame
>>>> --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc
>>>> --enable-libvorbis --enable-libvpx --enable-libwavpack
>>>> --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid
>>>> --enable-zlib
>>>> libavutil 52. 66.101 / 52. 66.101
>>>> libavcodec 55. 52.102 / 55. 52.102
>>>> libavformat 55. 33.101 / 55. 33.101
>>>> libavdevice 55. 11.100 / 55. 11.100
>>>> libavfilter 4. 3.100 / 4. 3.100
>>>> libswscale 2. 5.101 / 2. 5.101
>>>> libswresample 0. 18.100 / 0. 18.100
>>>> libpostproc 52. 3.100 / 52. 3.100
>>>> [dshow @ 02903300] DirectShow video device options
>>>> [dshow @ 02903300] Pin "Video 0"
>>>> [dshow @ 02903300] pixel_format=yuyv422 min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=yuyv422 min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=uyvy422 min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=uyvy422 min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=yuv420p min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=yuv420p min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=yuyv422 min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=yuyv422 min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=yuv420p min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=yuv420p min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=bgra min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=bgra min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=bgra min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=bgra min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=bgr24 min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=bgr24 min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=uyvy422 min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> [dshow @ 02903300] pixel_format=uyvy422 min s=128x96 fps=1 max
>>>> s=2048x2048 fps=59.9999
>>>> video=MediaLooks Screen Capture: Immediate exit requested
>>>>
>>>> I still wonder what values VLC is getting back from
>>>> GetActualDataLength...or if it has a work around :)
>>>
>>> I had to started to look at the VLC code and then something else came up I
>>> had to work on.. The relevant VLC files are dshow.cpp,
>>> filter.cpp, and bdagraph.cpp. It does things a bit different in Receive
>>> etc, queueing up samples etc. With the time I had spent on
>>> it, I did not see anything earth shaking so just need to get back to it.
>>>
>>> It appears in the in the VLC code, GetActualDataLength returns a proper
>>> value. A zero value is an indication of an error and
>>> should not happen. In other words, Receive being called with zero data
>>> length is not really defined. This kind of winds it way
>>> thru in the VLC code, and about as far as I got with it at the time. In
>>> VLC filter.cpp and in CapturePin::Receive, the sample is
>>> queued up and did not go much beyond that, although, there is an AddRef on
>>> the sample.
>>>
>>> A guess is, something upstream from Receive is not being done correctly.
>>> Also AddRef could play a role here but I tested it with
>>> no luck. If a reference value is not correct, a fliter is suppose to
>>> return zero I believe, but that's as far as I got with it.
>>> Some other things might be setting the time stamp correctly etc, but no
>>> real clue on that.
>>>
>>> Should be able to get back on it tomorrow but thanks for helping and keep
>>> digging. I may go ahead and verify that this is the same
>>> problem with other devices that have this same indication as well. Using
>>> the quick but broken fix is enough to at least get a
>>> display and enough to verify problem with other devices.
>>
>> So started looking at this again. The code I used to use for dshow 'works'
>> and so I have that code base to compare with. Now though,
>> I am wondering what 'works' means for this device :) In 3 of the different
>> unrelated programs I tested with, I get this sort of
>> nested display when the main window has the focus. When main window does not
>> have the focus I get a normal looking display. In VLC,
>> you seem to get this normal looking display even when the main window has
>> the focus.
>>
>> When I apply the quick fix stated above, I also get a nested display and
>> same as the unrelated programs I tested with. Even when
>> GetActualDataLength returns a proper value I am seeing this nested display
>> so that is something else a little odd about this. Could
>> be some simple explanation for this though and just not concerned with this
>> at the moment. Could be something like DirectX usage of
>> window versus normal windows usage of window or similiar.
>
> Nested when viewed how here?
You can view it using ffplay but you have to make this change first in dshow_pin.c / libAVMemInputPin_Recieve
buf_size = IMediaSample_GertActualDataLength(sample);
if (!buf_size)
buf_size = IMediaSample_GetSize(sample);
After that you should get a display and it should be nested so you can see what I am talking about. I seem to get this nested
display in everything except VLC. Not sure what kind of problem or if it is a problem at the moment.
> I'll admit it would be nice to hammer out the bugs in avdevice so the
> rest of us can benefit...
Yes, I don't sleep well unless I know the answer even if I end up leaving it. Already mentioned I would try to resolve it. The
problem with this is that there are many nuances with dshow and just takes one thing to be out of order somewhere or not quite
right. so even if you have similiar code, you still have to hunt and peck since there is a trail of dependencies that may be
different.
>I wonder if converting things to cpp would
> work, but that might be tricky...
The other dshow code I am using to test that 'works' is cpp and so trying to match that with the ffmpeg code. It's has a different
pipeline to the end result so breaking that down.
More information about the ffmpeg-devel
mailing list