Nevcairiel / LAVFilters

LAV Filters - Open-Source DirectShow Media Splitter and Decoders
GNU General Public License v2.0
7.36k stars 789 forks source link

~CC Output pin format #428

Closed gizmocuz closed 3 years ago

gizmocuz commented 3 years ago

Would it be possible to support

MajorType = MEDIATYPE_AUXLine21Data

This way we can connect it to the default Line 21 Decoder that already exists on the system

I tried connecting a sample grabber to the current output pin/format (MEDIATYPE_DTVCCData/IID_MediaSideDataEIA608CC), but I don't receive any data.

Maybe someone could explain how this pin can be used ? Ideally it would output all CC data received in the PES frame at once (not pushing 100 times a 2 byte pair)

Thank you in advance!

Nevcairiel commented 3 years ago

The Line 21 Decoder is extremely limited, and not something I aim at supporting.

The data is currently provided as a set of 3 byte CC data packets (control + cc1/cc2), with multiple CC data packets in the delivered packet (as can be determined by the size of the delivered buffer), as the bitstream provides.

The CC Output Pin also needs to be programatically enabled, and is only supported on mpeg2 and h264, but if you are seeing it and can connect something to it, I suppose you figured that part out already.

gizmocuz commented 3 years ago

@Nevcairiel , thank you for your feedback and time. Yes I enabled it, and connected a sample grabber to it

Configured the sample grabber with:

AM_MEDIA_TYPE mt;
ZeroMemory(&mt, sizeof(AM_MEDIA_TYPE));
mt.majortype = MEDIATYPE_DTVCCData;
mt.subtype = IID_MediaSideDataEIA608CC;
m_pSampleGrabber->SetMediaType(&mt);
m_pSampleGrabber->SetCallback(m_pCCDecoder, 0);
m_pSampleGrabber->SetBufferSamples(FALSE);
m_pSampleGrabber->SetOneShot(FALSE);

Unfortunally the callback is not being called. (It is when connecting it to other Pins, other decoders (different major/sub types of course)

Actually what you are sending to it (3 bytes) is almost the same as using the regular major/subtype, but instead of pushing 100 pairs, the complete buffer is send. Which (in my opinion) takes less performance of course... and MEDIATYPE_AUXLine21Data MEDIASUBTYPELine21_BytePair or MEDIASUBTYPE_Line21_GOPPacket or any other existing sub types could make it more universal to let it connect to any upstream filter)

But... I would be happy with receiving the 3 byte CC data packets.... Do I need to connect the output of the sample grabber to something to get it working ? I tried connecting it to a null filter, but I do not receive any data Maybe I configured the sample grabber wrong ?

(I am 1000% sure the my source has CC data as I am able to extract this myself low-level directly from the PES packets)

Nevcairiel commented 3 years ago

The decoder outputs CC data that is embedded in the video stream, eg. in user data for mpeg2 or in SEI data for h264. If the CC data is actually in a PES stream in the mpeg ts, then the video decoder is not going to be involved with dealing with it.

gizmocuz commented 3 years ago

Correct, but I connected the sample grabber to CC Output pin so I would expected the data being pushed to this. But the callback is not being called, did I setup this correctly above ?

I tested with both MPEG2 and H264, the sample grabber callback is not being called.

The CC data is available in the user data (MPEG2) and in the user_data of the SEI (in case of a H264 stream)

The sample grabber is called when using another filter instead of the LAV Video Decoder

All of the below calls return S_OK

m_pSampleGrabber->SetMediaType(&mt);
m_pSampleGrabber->SetCallback(m_pCCDecoder, 0);
m_pSampleGrabber->SetBufferSamples(FALSE);
m_pSampleGrabber->SetOneShot(FALSE)

image

Nevcairiel commented 3 years ago

Just to be safe, for this to work you must not be using CUVID or QuickSync, CC export is not supported with those - among one of the reasons why they are both deprecated.

Otherwise, I really can't help you. I know it works because I use it, but I have never used the sample grabber for anything, I just connect a filter to actually consume and process the CC data.

gizmocuz commented 3 years ago

Thank you for your answer/time again. Is it possible to tell a bit more how you connect to the CC pin or what upstream filter you use to decode the CC?

Edit: Hmmm currently debugging the LAVVideo filter and the breakpoints in CCCOutputPin::DeliverCCData are being called and 'Deliver' returns S_OK... Still the samplegrabber callback is not called.

I made a filter inside a test application (IBaseFilter) and added this to the graph instead of the sample grabber... And.... I receive data ! Very happy with this, but still strange it does not seem to work with a SampleGrabber

I am closing this issue as this is working for me!

gizmocuz commented 3 years ago

@Nevcairiel , You are right about CUVID/QuickSync... GA94 user_data can be retrieved from the PES/ES payload without having a decoder involved, would be great if this was supported for whatever HWACC is selected

To support output pin type/subtype MEDIATYPE_AUXLine21Data/MEDIASUBTYPE_Line21_GOPPacket, only the GA94 header has to be put in front. When this is supported, the systems default Line 21 filter can be used (for 608)

Would this be something to add ? I think I can make a PR for this if that is OK ?

Nevcairiel commented 3 years ago

LAV does not use ffmpeg for CUVID or QuickSync. And the "solution" is to independently parse the bitstream all over again. Hence, its not supported, and any way to make it work is an ugly work-around, which is pointless since those decoders are no longer supported in LAV.