ffmpeg code (API) - api

I started to deal with ffmpeg API ( not the command prompt ) to build a movie editor, and I'm trying to find a good tutorial about how to extract keyframes from video, but I didn't find it.
Someone did it before and can write the code here?
Someone has a good tutorial about ffmpeg API?
Thank you!

In your demuxing loop, check for the AV_PKT_FLAG_KEY flag in AVPacket::flags after calling av_read_frame() with your AVFormatContext and confirming the read packet is from the correct stream of the input. Example:
AVPacket packet;
if (av_read_frame(pFormatCtx, &packet) < 0) {
break;
}
if (videoStream/* e.g. 0 or 1 */ == packet.stream_index) {
if (packet.flags & AV_PKT_FLAG_KEY) { //do something
Note that, in my experience, you sometimes need to decode up to 2 keyframes before the desired frame in order to produce a good picture.
See the doc/examples directory in the ffmpeg distribution for some API usage examples, e.g. demuxing_decoding.c. You can also reference ffmpeg.c (the source of the famous CLI) if you are brave and/or have a good IDE.

Related

Set OCR whitelist in the TextRecognizer

I'm analysing the ocr-reader sample project: https://github.com/googlesamples/android-vision/tree/master/visionSamples/ocr-reader
The goal would be to replace my custom "text to image" implementation for Android (with OpenCV and Tesseract) with Android Vision.
I could not find any way to apply advanced configuration for the OCR processor. For example, in my application, only a predefined set of symbols is allowed. For that, I'm using the following code in my App:
api.SetVariable("tessedit_char_whitelist", "ABJOKEA1234");
This helps to avoid the confusion between 0 and O for example.
Is there a way to do this with android-vision? I don't see any options while building the TextRecognizer:
TextRecognizer textRecognizer = new TextRecognizer.Builder(context).build();
In a general matter, does Google plan to extend the configurability of the library? For example:
Cropping of the source image
Providing a custom OCR training file
Or is it supposed to remain a straightforward library, with just common features?
Thanks for your help!
I am also working on that, i am trying to make a business card reader with mobile vision, so far when the text is detected i am using checks with if conditions using strings which are generated in real time..
if (mText == null) {
return;
}
if(mText.getValue().contains("#") && mText.getValue().contains(".") && !mText.getValue().equals(mText.getValue().toUpperCase())){
Log.e("mTextemail",mText.getValue());
email=mText.getValue();
}
if (mText.getValue().startsWith("+")|| mText.getValue().startsWith("0")&& mText.getValue().contains("+-0123456789/-#")&& !mText.getValue().contains("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")){
Log.e("mTextphone",mText.getValue());
phone=mText.getValue();
}
if (!mText.getValue().contains("ABCDEFGHIJKLMNOPQRSTUVWXYZ")&& !mText.getValue().contains("0123456789-/#") && !mText.getValue().contains("abcdefghijklmnopqrstuvwxyz")){
Log.e("mTextcompanyName",mText.getValue());
companyName=mText.getValue();
}if(mText.getValue().startsWith("ABCDEFGHIJKLMNOPQRSTUVWXYZ" )&& mText.getValue().endsWith("abcdefghijklmnopqrstuvwxyz")){
name=mText.getValue();
}
if(name ==null){
name="Was not specified";
}
if(email ==null){
email="Was not specified";
}
if(phone ==null){
phone="Was not specified";
}
if(companyName ==null){
companyName="Was not specified";
}
it prints the logs with 70% accuracy, may be we can help each other and also i want these correct logs to be displayed in an activity i have used interfaces but its not working.
If you have any tips or trick that you have discovered please do share.

How to get author of a pdf document with mupdf

how can I get metadata of a pdf document(e.g. title, author, creation date etc) by using mupdf library? There is not enough documentation to find out this functionality. Comments are not sufficient, too. Most probably, there is a functionality for this purpose but it is hard to find under these circumstances. The following code is what I have so far.
char info[64];
globals *glo = get_globals(env, thiz);
fz_meta(glo->doc, FZ_META_INFO, info, sizeof(info));
I have used FZ_META_INFO tag, but it doesn't work. I didn't get any info, just empty. I have checked that it has metadata. Any help is appreciated.
EDIT:
Target Android sdk:20
Min Android sdk:15
Mupdf version: 1.6
ndk: r10c
Development OS: Ubuntu 12.04
In what sense 'doesn't work' ? Throws an error ? Crashes ? Are you certain the PDF file you are using has any 'Info' metadata ?
What is the version of MuPDF ? What platform are you using ?
You need to set the relevant key in the buffer you pass to fz_meta before you call fz_mets, I notice you aren't doing that.
See win_main.c at around line 487, after you get past the macro this resolves to
char info[256]
sprintf(info, "Title");
fz_meta(doc, FZ_META_INFO, info, 256);
On return 'info' will contain the metadata associated with the Title key in the dictionary.
When in doubt, build the sample app and follow it in a debugger......
If the proper casting allow to send the key,
this casting is NOT correct to receive back a char*.
Exemple;
Proper casting to send a request
char buff[2048];
strcpy(buff,"CreationDate")
if (fz_meta(ctx,doc,FZ_META_INFO,&buff,2048)) {
buff[0] = 0;
}
Will:
find the key,
convert utf8
then will crash when copyback of the result
Proper casting to receive a request
char buff[2048];
strcpy(buff,"CreationDate")
if (fz_meta(ctx,doc,FZ_META_INFO,buff,2048)) {
buff[0] = 0;
}
Will crash during dict scanning.
looks really like a bug!
I confirm that modifying original source
info = pdf_dict_gets(ctx, info, (char *)ptr);
is the way to go. (even if strange that nobody else find it while writing code, because Meta are useful features frequently used

Get USB disk drive letter by device path or handle

My goal is to write a c-dll (compiled with MinGW) that is able to search for certain models of USB sticks connected to the computer and deliver the serial number, the vendor ID, the product ID and the drive letter.
I have searched on the internet for several hours know but could not find an approach that works for me.
I am using the Setup Api to get a list of all connected USB devices. For each USB device I get a path that looks like this:
\?\usb#vid_048d&pid_1172#00000020370220#{a5dcbf10-6530-11d2-901f-00c04fb951ed}
From that string I can get the vendor ID, product ID and the serial number I am looking for.
My problem is now to determine the drive letter of the USB drive that is related to this device path.
During my internet research I found the following approach multiple times (for example here http://oroboro.com/usb-serial-number/):
Once the device path is found, the USB drive must be opened by CreateFile. The handle returned by that function can be used to get the device number by function DeviceIOControl with IOCTL_STORAGE_GET_DEVICE_NUMBER.
After that, the CreateFile function could be used to open each drive letter (starting from a:) and try to get the device number the same way like described above. Once the same device number is found again, the relation between device path and drive letter is made.
My Problem is that the IOCTL_STORAGE_GET_DEVICE_NUMBER call is not working. The DeviceIOControl function returns error code 50 which means "The request is not supported".
I am not able to create a link between the device path of a USB stick and the drive letter. I have tried several IOCTL_STORAGE and IOCTL_VOLUME calls but none worked for the USB sticks I tried.
I also read in another Forum that people had problems with the results of the DeviceIOControl function. It was returning the desired result on some PCs while it was making trouble on others.
Is there another way of achieving my goal?
I already had a look into the registry where I can also find the desired data. But again I had the problem to create the connection between device path and drive letter.
I would not like to use the WMI. I have read that it is still not really supported by MinGW.
I have a implementaion for all this with C# where it is really easy to get the desired information, but now I also need one that is created with unmanaged code and can be used to replace a c-dll also included in Delphi projects.
I would appreciate any suggestions for a solution to my problem.
Best regards,
Florian
And here the code if someone is interested. The position with this comment "//HERE IS WHERE I WOULD LIKE TO GET THE DEVICE NUMBER!!!" is where the request of the device number would be used if it would work.
typedef struct ty_TUSB_Device
{
PSP_DEVICE_INTERFACE_DETAIL_DATA deviceDetailData;
char devicePath[300];
}TUSB_Device;
int
GetUSBDevices (TUSB_Device *devList[], int size)
{
HANDLE hHCDev;
HDEVINFO deviceInfo;
SP_DEVICE_INTERFACE_DATA deviceInfoData;
ULONG index;
ULONG requiredLength;
int devCount = 0;
//SP_DEVINFO_DATA DevInfoData;
// Now iterate over host controllers using the new GUID based interface
//
deviceInfo = SetupDiGetClassDevs((LPGUID)&GUID_DEVINTERFACE_USB_DEVICE,
NULL,
NULL,
(DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));
if (deviceInfo != INVALID_HANDLE_VALUE)
{
deviceInfoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);
for (index=0;
SetupDiEnumDeviceInterfaces(deviceInfo,
0,
(LPGUID)&GUID_DEVINTERFACE_USB_DEVICE,
index,
&deviceInfoData);
index++)
{
SetupDiGetDeviceInterfaceDetail(deviceInfo,
&deviceInfoData,
NULL,
0,
&requiredLength,
NULL);
//allocate memory for pointer to TUSB_Device structure
devList[devCount] = malloc(sizeof(TUSB_Device));
devList[devCount]->deviceDetailData = GlobalAlloc(GPTR, requiredLength);
devList[devCount]->deviceDetailData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);
SetupDiGetDeviceInterfaceDetail(deviceInfo,
&deviceInfoData,
devList[devCount]->deviceDetailData,
requiredLength,
&requiredLength,
NULL);
//open the usb device
hHCDev = CreateFile(devList[devCount]->deviceDetailData->DevicePath,
GENERIC_WRITE,
FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
0,
NULL);
// If the handle is valid, then we've successfully found a usb device
//
if (hHCDev != INVALID_HANDLE_VALUE)
{
strncpy(devList[devCount]->devicePath, devList[devCount]->deviceDetailData->DevicePath, sizeof(devList[devCount]->devicePath));
//HERE IS WHERE I WOULD LIKE TO GET THE DEVICE NUMBER!!!
CloseHandle(hHCDev);
devCount++;
}
//GlobalFree(devList[devCount]->deviceDetailData);
}
SetupDiDestroyDeviceInfoList(deviceInfo);
}
return devCount;
}
I found out what my problem was. From what I read on the internet it seems there where other people having the same problems like me, so I will post my solution.
The whole point is that there are obviously different path values one can obtain for a USB device using the SetupApi. All path values can be used to get a handle to that device, but there are obviously differences about what can be done with the handle.
My failure was to use GUID_DEVINTERFACE_USB_DEVICE to list the devices. I found out that when I use GUID_DEVINTERFACE_DISK, I get a different path value that lets me request the device number. That way I am able to get the link to the drive letter.
That path value obtained with GUID_DEVINTERFACE_DISK also contains the serial number but not the vendor and product IDs. But since both path values do contain the serial, it is no problem to get them both and build the relation.
I tested the code with Windows XP, 7 and 8 and it works fine. Only the FileCreate code of the code sample above must be adjusted (replace GENERIC_WRITE by 0). Otherwise Administrator rights or compatibility mode are required.
I did not try to find out what these different GUID values really stand for. Someone with a deeper knowledge in this area could probably provide a better explanation.
Best regards,
Florian

How to clear the console/trace?

The following JavaScript code writes a line to the console when using ADL:
air.trace("Hello world!");
But the console can soon fill up when tracing a lot of data.
How can I clear the console?
I've tried Googling with no luck!
This is what I've ended up doing:
function clearDebug()
{
for(var i = 0; i < 56; i++)
air.trace();
}
If anyone has a "standard" way of doing this, feel free to post an answer and I'll accept it!
Failing that though, this works (though you may have to edit 56 to a number of console lines suitable to your screen resolution).

Save to buffer instead of file when recording aac with Audio Queue Services

My goal is to record audio in AAC format and send it over a network connection as a stream.
I'm using Audio Queue Services and have based my code on the SpeakHere example. I know that for writing to a file it uses the AudioFileWritePackets() function.
Here's the callback function:
void MyInputBufferHandler(void* inUserData,
AudioQueueRef inAQ,
AudioQueueBufferRef inBuffer,
const AudioTimeStamp * inStartTime,
UInt32 inNumPackets,
const AudioStreamPacketDescription* inPacketDesc) {
Recorder *aqr = (Recorder *)inUserData;
if (inNumPackets > 0) {
// write packets to file
AudioFileWritePackets(aqr->mRecordFile, FALSE,
inBuffer->mAudioDataByteSize,
inPacketDesc, aqr->mRecordPacket,
&inNumPackets, inBuffer->mAudioData);
aqr->mRecordPacket += inNumPackets;
}
// if we're not stopping, re-enqueue the buffe so that it gets filled again
if ([aqr IsRunning])
AudioQueueEnqueueBuffer(inAQ, inBuffer, 0, NULL);
}
At first I thought AudioFileWritePackets works by directly writing the content of inBuffer->mAudioData. However when I manually write just the contents of mAudioData to a file the decoding doesn't seem to work.
On examining and comparing the raw data of what AudioFileWritePackets writes to a file and of me just writing mAudioData to a file, they seem to have attached a header to it.
As I can't find out how AudioFileWritePackets() works inside, my question is, how can I write the recorded audio to a buffer (or stream, if you prefer to call it this way) instead of a file, so that I can later send it over a network connection?
Again, in short here's what I need: record audio in aac format and stream the audio over network connection.
Thanks! I've been searching my head blue...
P.S: please if you point me to existing projects, make sure they are what I need. I really feel like I've been looking for all possible projects out there >.<
This should help.
Check the "HandleInputBuffer" method in "SpeechToTextModule.m".