How to retrieve codec information using libvlc? - c

I need to get codec information when using libvlc to play remote media. Since the VLC player can achieve this(see the screenshot below), libvlc may well be able to do it too.
Also, I find that libvlc_media_tracks_get can return a related struct as follows:
typedef struct libvlc_media_track_t
{
/* Codec fourcc */
uint32_t i_codec;
uint32_t i_original_fourcc;
int i_id;
libvlc_track_type_t i_type;
/* Codec specific */
int i_profile;
int i_level;
union {
libvlc_audio_track_t *audio;
libvlc_video_track_t *video;
libvlc_subtitle_track_t *subtitle;
};
unsigned int i_bitrate;
char *psz_language;
char *psz_description;
} libvlc_media_track_t;
Maybe the member i_codec stores such information, but it's not human-readable and I don't know the meaning of a specific value. Probably there is a map between them and I haven't found it yet.

The third line already tells you that i_codec should be interpreted as fourcc.
fourcc is a sequence of four ASCII character codes, which are actually human readable, just not as an integer. A list of these codes is available here.
libvlc declares vlc_fourcc_GetDescription in vlc_fourcc.h, which can be used to get a description string.

Related

Accessing structure in structure through pointer

Brief description:
I write something to structure through pointer but something else gets written. I work in atollic true studio 8.1, programming an STM32F415RG MCU.
The strangest thing is that even if I look in variables and expression window, I can see the same structure with different values.
Same variable in two windows with different values
Now to elaborate a bit (I am going to simplify a lot of stuff to make it more readable).
I have my protocol handle type defined:
typedef struct
{
RS485DriverHandle master_rs485;
} EscomProtocolHandle;
My RS485 driver handle is defined as follows:
typedef struct
{
UART_HandleTypeDef* uart_handle;
TransceiverState transceiver_state;
GPIO_TypeDef* dir_gpio;
uint16_t dir_pin;
} RS485DriverHandle;
I have created my protocol handle as a global variable:
static EscomProtocolHandle hprot1;
I pass it to my protocol init function which takes a pointer to handle as an argument:
Escom_Protocol_Init(&hprot1);
Init function passes it to RS485 driver init function which takes pointer to RS485 handle as an argument (this call is simplified a lot):
void Escom_Protocol_Init(EscomProtocolHandle* protocol_handle)
{
RS485_Init(&protocol_handle->master_rs485)
}
RS485 init function sets default values:
void RS485_Init(RS485DriverHandle* rs485_handle, UART_HandleTypeDef* uart_handle,
GPIO_TypeDef* dir_gpio, uint16_t dir_pin)
{
/* default = listening */
rs485_handle->uart_handle = uart_handle;
rs485_handle->dir_gpio = dir_gpio;
rs485_handle->dir_pin = dir_pin;
ReceiverOutputEnable(rs485_handle);
rs485_handle->transceiver_state = kReceiving;
}
Now if I look at the local variable rs485_handle, the values are set correctly. But If I look at my handle hprot1, the values don't match. Even though rs485_handle's address matches the address of master_rs485 member of the hprot1 handle.
P.S.: I have not messed with the packing (#pragma pack) of any of the above mentioned structures, so that should not be an issue.
Got it!
There was a seemingly unrelated header file that had a structure prototype in it which was packed(1) and there was no #pragma pack() after the structre prototype to restore the packing to default state. Thus RS485DriverHandle was packed differently in different places. In both Escom_Protocol_Init and RS485_Init the address of the handle structure was the same, but the packing was different so for example the address of GPIO_TypeDef* dir_gpio member was 0x200000D6 in Escom_Protocol_Init but was 0x200000D9 in RS485_Init.

keyboard interrupt handler giving null value

I am learning Linux Kernel Module programming(Interrupt Handler) and using the tutorial (http://tldp.org/LDP/lkmpg/2.6/html/) exact module link(http://tldp.org/LDP/lkmpg/2.6/html/x1256.html).
In the tutorial I am getting error when I used
INIT_WORK(&task, got_char, &scancode);
The error was "error: macro "INIT_WORK" passed 3 arguments, but takes just 2"
So I found one solution and use the below line
INIT_WORK(&task, got_char);
It's working fine but the output I am getting is null. I am expecting the key number from the keyboard.
Any body have any idea ?
If it is not clear please let me know I will try to interpret more.
Thanks
Add a structure like follows,
struct getchar_info {
/* Other info ... */
struct work_struct work;
unsigned int scancode;
/* Other info ... */
};
static struct getchar_info gci; /* Statically declare or use kmalloc() */
Change got_char() to,
static void got_char(struct work_struct *work)
{
struct getchar_info *info = container_of(work, struct getchar_info, work);
info->scancode = my_val;
/* ... */
Initialize it like INIT_WORK(&gci.work, got_char);
This is a common Linux kernel paradigm or design pattern. The work queue code needs to manage this structure pointer so it is easy to provide to your got_char routine. Your driver must allocate it as part of a larger structure (it is inheritence in OO terms; it looks like composition as 'C' only supports that). The container_of is like a C++ dynamic_cast<> (with single inheritance in case any C++ gurus are looking). It lets you get the composed structure from the sub-structure.

How to get metadata from Libextractor into a struct

I want to use Libextractor to get keywords/metadata for files.
The basic example for it is -
struct EXTRACTOR_PluginList *plugins
= EXTRACTOR_plugin_add_defaults (EXTRACTOR_OPTION_DEFAULT_POLICY);
EXTRACTOR_extract (plugins, argv[1],
NULL, 0,
&EXTRACTOR_meta_data_print, stdout);
EXTRACTOR_plugin_remove_all (plugins);
However, this calls the function EXTRACTOR_meta_data_print which "prints" it to "stdout"
I'm looking at a way to get this information to another function - i.e. pass or store this in memory for further working. The documentation was not clear to me. Any help or experience regarding this?
I've tried to install libextractor and failed to get it working (it always returns a NULL plugin pointer upon call to EXTRACTOR_plugin_add_defaults()), so what I will write next is NOT TESTED:
from : http://www.gnu.org/software/libextractor/manual/libextractor.html#Extracting
Function Pointer: int
(*EXTRACTOR_MetaDataProcessor)(void *cls,
const char *plugin_name,
enum EXTRACTOR_MetaType type,
enum EXTRACTOR_MetaFormat format,
const char *data_mime_type,
const char *data,
size_t data_len)
and
Type of a function that libextractor calls for each meta data item found.
cls
closure (user-defined)
plugin_name
name of the plugin that produced this value;
special values can be used (i.e. '<zlib>' for
zlib being used in the main libextractor library
and yielding meta data);
type
libextractor-type describing the meta data;
format basic
format information about data
data_mime_type
mime-type of data (not of the original file);
can be NULL (if mime-type is not known);
data
actual meta-data found
data_len
number of bytes in data
Return 0 to continue extracting, 1 to abort.
So you would just have to write your own function called whatever you want, and have this declaration be like:
int whateveryouwant(void *cls,
const char *plugin_name,
enum EXTRACTOR_MetaType type,
enum EXTRACTOR_MetaFormat format,
const char *data_mime_type,
const char *data,
size_t data_len)
{
// Do your stuff here
if(stop)
return 1; // Stops
else
return 0; // Continues
}
and call it via:
EXTRACTOR_extract (plugins, argv[1],
NULL, 0,
&whateveryouwant,
NULL/* here be dragons */);
Like described in http://www.gnu.org/software/libextractor/manual/libextractor.html#Generalities "3.3 Introduction to the libextractor library"
[here be dragons]: That is a parameter left for the user's use (even if it's redundant to say so). As defined in the doc: "For each meta data item found, GNU libextractor will call the ‘proc’ function, passing ‘proc_cls’ as the first argument to ‘proc’."
Where "the proc function" being the function you added (whateveryouwant() here) and proc_cls being an arbitrary pointer (can be anything) for you to pass data to the function. Like a pointer to stdout in the example, in order to print to stdout. That being said, I suspect that the function writes to a FILE* and not inevitably to stdout; so if you open a file for writing, and pass its "file decriptor" as last EXTRACTOR_extract()'s parameter you would probably end with a file filled with the information you can currently read on your screen. That wouldn't be a proper way to access the information, but if you're looking into a quick and dirty way to test some behavior or some feature; that could do it, until you write a proper function.
Good luck with your code!

store and restore struct in file in C

I need to store a struct in a file and read it back to return it then.
I would try to write it to the file like this:
void lld_tpWriteCalibration(struct cal cal) {
FIL fdst; /* file objects */
UINT bw; /* File write count */
/* Create destination file on the drive 0 */
wf_open(&fdst, "0:calibration.txt", FA_CREATE_ALWAYS | FA_WRITE);
wf_write(&fdst, cal, sizeof(cal), &bw);
wf_close(&fdst);
}
Would that work?
And how can I read it back and return it from this function?
struct cal lld_tpReadCalibration(void) {
}
The struct is:
struct cal {
float xm;
float ym;
float xn;
float yn;
};
Thanks for your help.
You can retrieve your structure the same way you stored it.
read(&fdst, &cal, sizeof(cal));
But you got to be careful, you won't be able to do this on every architecture because of endianess problem.
You'll be OK with that structure and that writing/reading technique if you only try to read the file on the same type of machine as you write it on. The data written like that is not reliably portable across different types of machines.

Raw input winapi in c, can't get device info

I'm messing around with a USB RFID scanner and trying to read input with raw input, so far I have this
#define _WIN32_WINNT 0x0601
#include <windows.h>
#include <stdio.h>
int main(void)
{
PRAWINPUTDEVICELIST pRawInputDeviceList;
PUINT puiNumDevices, pcbSize;
UINT cbSize = sizeof(RAWINPUTDEVICELIST);
char *pData[1000];
GetRawInputDeviceList(NULL, puiNumDevices, cbSize);
pRawInputDeviceList = malloc(cbSize * *puiNumDevices);
GetRawInputDeviceList(pRawInputDeviceList, puiNumDevices, cbSize);
// gives a correct RIM_TYPE for all devices 0-7 (GetRawInputDeviceList returns 8 devices for me)
printf("%I32u\n", pRawInputDeviceList[0].dwType);
GetRawInputDeviceInfo(pRawInputDeviceList[1].hDevice, RIDI_DEVICENAME, pData, pcbSize);
// gives a huge number (garbage?), should be the length of the name
printf("%u\n", pcbSize);
// "E" in my case
printf("%s\n", pData);
// error 87, apparently ERROR_INVALID_PARAMETER
printf("%I32u\n", GetLastError());
return 0;
}
When you call GetRawInputDeviceInfo, it expects pcbSize to be a pointer. You have it as a pointer, but its not pointing to anything. Try this:
Get rid of pcbSize (everywhere).
Create a variable UINT cbDataSize = 1000. This is the size of your pData array.
For the last argument of GetRawInputDeviceInfo, use &cbDataSize. This takes the address of cbDataSize, the address is a pointer.
Change printf("%u\n", pcbSize); to printf("%u\n", cbDataSize);.
See how that works for you.
[edit]
Also, you should do the same thing for puiNumDevices. Instead, create a UINT called uiNumDevices. Use &uiNumDevices where the functions expect pointers.
I am going to go out on a limb here and guess that this thing may actually be a HID device. Do you know if it is?
HID Devices are actually pretty easy to talk to; you connect to them via CreateFile() -- the same way that you would open a COM port -- and then just ReadFile() to get data.
Most of the problem is figuring out the correct path to connect to. It's actually a value called DevicePath that you get from SetupDiGetDeviceInterfaceDetail().
A rough map of it looks like this:
HidD_GetHidGuid() to get the HID guid
SetupDiGetClassDevs() to get the list of dev
Looping through devs, until you find yours:
SetupDiEnumDeviceInterfaces() to enum the device interfaces
SetupDiGetDeviceInterfaceDetail() to get the detail
CreateFile() to open the device with the DevicePath from the detail.
HidD_GetAttributes to get the vendorid and productid to see if it's your device.
If it is, remember it, and use ReadFile() to get data.

Resources