c++ - ffmpeg yadif deinterlacing - c++

I'm trying deinterlacing video with ffmpeg in my C++ program.
First of all, i used avpicture_deinterlacebut is deprecated.
Looking for more information, I've tried avfilter_get_by_name("yadif")after avfilter_register_all()but always return NULL. I've tried the next code too, but still not working. I've tried different parameters in avfilter_init_strfunction buterris always less than 0, that means there is an error.
int err;
// Register all built-in filters
avfilter_register_all();
// Find the yadif filter
AVFilter *yadif_filter = avfilter_get_by_name("buffer");
AVFilterContext *filter_ctx;
// Create the filter context with yadif filter
avfilter_open(&filter_ctx, yadif_filter, NULL);
// Init the yadif context with "1:-1" option
err = avfilter_init_str(filter_ctx, "\"yadif=1:-1\"");
I know filtering_video.c file is a good start point to understand how to build a filter but I don't want to build one, I only need to use the yadif deinterlacing filter. I have the AVFramebut I don't know how to apply de yadif filter to it.
Any help could be welcome.

In older FFmpeg releases, yadif was only compiled if --enable-gpl configure option was used. You probably need to update to a later release or re-compile the old release with --enable-gpl.

Related

Setting a WinRt AdvertisementFilter() to a substring of LocalName

C++, WinRT, VS2017, Win10
I create a watcher to look for my Bluetooth LE device with
BluetoothLEAdvertisementWatcher watcher;
Now I want to set a filter for for the device that I am specifically looking for. Let's say that the LocalName for the device is "MyDevice_ABC1234". I can do this with
watcher.AdvertisementFilter().Advertisement().LocalName().c_str() == L"MyDevice_ABC1234";
But what I really want to do is set the filter to the manufacture's name and not the specific model number. I want to filter for "MyDevice" being in the LocalName. This would be easy enough given the luxury of a few lines of code but how would it be done in the context of
watcher.AdvertisementFilter().Advertisement().LocalName()
LocalName() has an operator for basic_string_view which has a find() method but for the life of me I can't get that to work properly. The find() is supposed to return the npos so I tried:
watcher.AdvertisementFilter().Advertisement().LocalName().operator std::basic_string_view<wchar_t, std::char_traits<wchar_t>>.find("MyDevice") == 8;
I actually tried this as simple code so I could debug the results with
hstring hstrLocalName = L"MyDevice_aBC1234";
bool bFind = hstrLocalName.operator std::basic_string_view<wchar_t, std::char_traits<wchar_t>>.find("MyDevice", 0) == 8;
and also
int iFind = hstrLocalName.operator std::basic_string_view<wchar_t, std::char_traits<wchar_t>>.find("MyDevice", 0);
But neither of these worked. They compiled but just never executed. Is there a way to get the basic_string_view.find() to work or would there be a better way to do this?
I see now, that when I do use the method mentioned above from StackOverflow here, it does filter for the LocalName that I set. However, and I remember this warning from the docs somewhere, that some advertisement packets come with the local name but not Uuids and visa versa. As it happenes, that is why I thought the filter was catching nothing. I was ignoring any packets that did not have services and these were the ones with the LocalName. Catch22.
For what it is worth, here is the method for setting a filter mentioned in the link above that also worked for me (with caveats)
auto filter = BluetoothLEAdvertisementFilter();
auto advert = BluetoothLEAdvertisement();
advert.LocalName(L"MyDevice_ABC1234");
filter.Advertisement(advert);
watcher.AdvertisementFilter(filter);

Apply MFPKEY_ASFMEDIASINK_AUTOADJUST_BITRATE to IMFSinkWriter

Currently I'm creating WMV file with Windows Media Foundation SDK using the method (Transcode API) in following article: https://learn.microsoft.com/en-us/windows/desktop/medfound/tutorial--using-the-sink-writer-to-encode-video
What I noticed is if I don't set MFPKEY_ASFMEDIASINK_AUTOADJUST_BITRATE, output WMV file may be corrupted (show up as terrible artifacts during playback) when coded WMV file over the specified bitrate.
According to following article, the flag needs to set to IMFASFContentInfo:
https://learn.microsoft.com/en-us/windows/desktop/medfound/mfpkey-asfmediasink-autoadjust-bitrate-property
So I tried following way:
IMFSinkWriter* pSinkWriter = NULL;
//initialize sink writer with MFCreateSinkWriterFromURL
...
IMFASFContentInfo* pContentInfo = NULL;
pSinkWriter->GetServiceForStream((DWORD)MF_SINK_WRITER_MEDIASINK, GUID_NULL, __uuidof(IMFASFContentInfo), (LPVOID*)&pContentInfo);
IPropertyStore* pPropStore = NULL;
pContentInfo->GetEncodingConfigurationPropertyStore(0, &pPropStore);
PROPVARIANT var;
PropVariantInit(&var);
var.vt = VT_BOOL;
var.boolVal = VARIANT_TRUE;
pPropStore->SetValue(MFPKEY_ASFMEDIASINK_AUTOADJUST_BITRATE, var);
PropVariantClear(&var);
//Add Video stream and BeginWriting, then start passing samples
...
But, the settings does not seem to be applied to muxer, and I still see obvious artifacts of corrupted stream.
What I guess is since MFCreateSinkWriterFromURL will create MediaSink and underlying IMFASFMultiplexer internally, however MFASF_MULTIPLEXER_AUTOADJUST_BITRATE needs to be set during creating IMFASFMultiplexer, so settings the flag after SinkWriter is created is too late.
If I don't use Transcode API, and create IMFASFWriter by myself, I think I can set MFASF_MULTIPLEXER_AUTOADJUST_BITRATE during creating IMFASFWriter manually but since I already have a working code besides settings this flag by using Transcode API, if possible I want to keep current way.
If anybody has any clue/solution/workaround, please let me know.
You should be able to query for IPropertyStore of to the ASF File Sink from the Sink Writer directly using GetServiceForStream and specifying MF_SINK_WRITER_MEDIASINK like this:
pSinkWriter->GetServiceForStream(MF_SINK_WRITER_MEDIASINK, GUID_NULL, IID_PPV_ARGS(&pPropertyStore));
where pPropertyStore points to an IPropertyStore.
After that you should set the MFPKEY_ASFMEDIASINK_AUTOADJUST_BITRATE property as explained here

Loading OpenGL > 1.1 functions Windows

I'm having trouble setting up OpenGL with MSVS 2013. I'm aware that the opengl32.dll on my Windows
platform located at C:\Windows\System32 is an implementation of OpenGL 1.1.
What I'm trying to do is to load the newer OpenGL > 1.1 functions such as glBindBuffer and glBufferData. I have read that it's possible getting a pointer to the function using wglGetProcAddress. When using this function the returned pointer is always null, all the original functions in the dll using GetProcAddress(OpenGL32DLL, "...") work perfectly except the newer functions don't seem to load.
I'm hoping anybody here can help me go through my setup and point out what I did wrong or if I have missed something.
So here we go:
I have downloaded OpenGL Extensions Viewer 4.4 which points out I'm able to perfectly run upto OpenGL 2.1 which
should be more than enough to use or load glBindBuffer and glBufferData.
I downloaded Microsoft SDKs/v7.1 which includes the headers: gl/glu.h and gl/gl.h; I also downloaded the GLEXT extensions API
from here and linked the glext.lib + included the headers.
Files in the Linker:
C:\Program Files\Microsoft SDKs\Windows\v7.1\Lib\OpenGL32.Lib
C:\Program Files\Microsoft SDKs\Windows\v7.1\Lib\GlU32.Lib
C:\Users\user\Desktop\glext\lib\glext.lib
The CPP files included:
C:\Program Files\Microsoft SDKs\Windows\v7.1\Include -> GL.h, GLU.h
C:\Users\user\Desktop\glext\include -> glcorearb.h, glext.h, wglext.h
Instead of handling all these details yourself, I suggest you just grab yourself a copy of GLEW ( http://glew.sourceforge.net/ ) which handles all of this for you in a standard way. I currently use it on several published products without issues.
In your example, you'd be able to do the following:
if (GL_ARB_multi_bind) {
//glBindBuffer is available.
}
(Of course, after a call to glewInit(), possibly with glewExperimental = TRUE; - see documentation for details.)
When using this function the returned pointer is always null, all the original functions in the dll using GetProcAddress(OpenGL32DLL, "...") work perfectly except the newer functions don't seem to load.
Do you have a valid OpenGL context created and made current on the calling thread? In Windows extension functions are technically per-context, i.e. you have to get the pointers to the functions for each OpenGL context you create and make sure to use the right function pointers with the right context.
This of course also means that you must have a OpenGL context to begin with. The usual sequence of setting up an OpenGL context in Windows is:
pseudocode
struct glctx {
HGLRC rc
// dictionary for explanation purposes
// one would normally just have a bunch of
// structure elements here
functionpointer[string:name] extensionfunction
}
if not window_with_desired_pixelformat_exists: {
wnd := create_a_window
pixelformat := select_pixelformat
wnd→set_pixelformat pixelformat
}
dc := wnd→getDC
glctx ctx
ctx→rc := wglCreateContext(dc)
wglMakeCurrent(dc, ctx→rc);
foreach(fname in extensionfunctions_names): {
ctx→extensionfunction[name] = wglGetProcAddress(name)
}
I think that the problem is that there is no current context while calling wglGetProcAddress.
Function pointers can be specific for a precise pixel format, determined by tge context creation procedure.

Boost.Log: how to filter by current thread id

I'm using Boost.Log, which is a part of Boost v1.54. I have a sink, which I want to only accept log messages from the current thread. How can I achieve that?
BOOST_LOG_ATTRIBUTE_KEYWORD(thread_id, "ThreadID", logging::attributes::current_thread_id::value_type)
std::stringstream stream;
logging::add_common_attributes();
boost::shared_ptr<text_sink> sink = boost::make_shared<text_sink>();
sink->locked_backend()->add_stream(stream);
logging::core::get()->add_sink(sink);
boost::thread::id currentThreadId = boost::this_thread::get_id();
// At this line compiler complains about the '==' operator.
sink->set_filter(thread_id == currentThreadId);
Without the last line everything works fine, and when I configure sink formatter, it outputs the calling thread ID. What is the proper way to compare thread_id attribute with the currentThreadId?
I know I can use some custom attribute to tag messages with the current thread ID, and then filter them by that attribute, but what about the default boost's current_thread_id attribute? Is it usable for such a purpose?
Well, after spending half the night digging around I came across the (undocumented?) boost::log::aux namespace, where I found boost::log::aux::this_thread::get_id() function. It returns an object of the proper type which I am now able to compare with the thread_id keyword.
Now I wonder if the boost::log::aux namespace is meant for boost internal use only? Some time ago I used to utilize some internal features of boost mutexes/locks, and after the next library update they changed everything and I couldn't even compile my code against that new version of the library. So now I don't want to repeat my past mistakes :)

FMOD_CHANNEL_FREE undefined, different version of fmod?

I'm trying to add sound to an app of mine using FMOD, visual studio 2012, and c++. I got the latest version (1.02) and installed it. Everything seems to work fine but (varibles?) like FMOD_CHANNEL_FREE and FMOD_CHANNEL_REUSE are undefined. Everyone I talked to had this problem and never solved it, and everyone online doesn't seem to have this issue.Another thing I noticed is that the parameters for playSound have switched.
For me:
system->playSound(sound->second, FMOD_CHANNEL_FREE, false, 0);
Everywhere else
system->playSound( FMOD_CHANNEL_FREE, sound->second, false, 0);
I followed the installed instructions, included fmod.hpp and fmod_errors.h, uninstalled, re-installed, and google has failed me. If it helps the parameter needed in channel_free spot is a FMOD::ChannelGroup
Any ideas? If you need more code, put a comment (not answer) and I'll comply.
With the change from FMOD Ex to FMOD Studio some of the APIs have been revised, this is one such case. The first parameter from the FMOD Ex version of System::playSound has been removed, the default behavior is always FMOD_CHANNEL_FREE now.
The new second parameter is for specifying the FMOD::ChannelGroup to play this channel in. You are not required to set this, specify NULL if you want the FMOD Ex behavior of playing the sound in the master channel group.
Correct usage for FMOD Studio would be:
FMOD::System *system = NULL; // create and init not shown
FMOD::Sound *sound = NULL; // create not shown
FMOD::Channel *channel = NULL;
FMOD_RESULT result = system->playSound(sound, NULL, false, &channel);
they are not switched, did you look at the headerfile? The second parameter is a pointer to a channelgroup, and you're trying to pass an integer to it?
Regardless, the free/reuse flags are gone, just delete them. Internally channels are always 'free'.