How to get a string representation of an audio AVStream in ffmpeg? - c

I'm using ffmpeg. Consider the following piece of code:
for(i=0; i<pFormatCtx->nb_streams; i++) {
if (pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO) {
//how do I get the language of the stream?
}
}
I found out that there is a LangEntry struct in libavformat (avlanguage file), there's also a table containing languages and their codes, seems it's just what I need. But I don't know how to use it. I couldn't find any examples of its usage. There are no reference to the LangEntry neither in AVStream, nor in AVCodecContext.

The LangEntry has nothing to do with your objective of detecting the language.
In fact, LangEntry table is to do with List of ISO 639-2 codes
Language code gets encoded as metadata, so you should be trying as below to identify the language
AVDictionaryEntry *lang;
for(i=0; i<pFormatCtx->nb_streams; i++)
{
if (pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO)
{
lang = av_dict_get(pFormatCtx->streams[i]->metadata, "language", NULL,0);
// Check lang->value, it should give 3-letter word matching to one of the LangEntry Table
}
}

Related

Can memmove accessing the contents of a FILE* and delete information?

Does memmove work on file pointer data?
I am trying to remove a line from a C file. I am trying to use memmove to make this more efficient than the internet's recommendation to create a duplicate file and overwrite it. I have debugged and I can't figure out why this code isn't working. I am asking for input. The logic is a for loop. Inside the loop, I have logic to do a memmove but it doesn't seem effective.
nt RemoveRow(int iRowNum)
{
char sReplaceLineStart[m_MaxSizeRow]={0};
char sTemp[m_MaxSizeRow] ={0};
size_t RemovalLength = 0;
GoToBeginningOfFile();
for(int i =0;i<m_iNumberOfRows;i++)
{
if(i == iRowNum)
{
// Line to remove
fgets(m_sRemovalRow,m_MaxSizeRow,pFile);
}
if(m_sRemovalRow == NULL)
{
// Were removing the last line
// just make it null
memset(m_sRemovalRow,0,sizeof(m_MaxSizeRow));
}
}
else if(i==iRowNum+1)
{
// replace removal line with this.
RemovalLength+=strlen(sTemp);
fgets(sReplaceLineStart, m_MaxSizeRow, pFile);
}
else if(i>iRowNum) {
// start line to replace with
RemovalLength+=strlen(sTemp);
fgets(sTemp, m_MaxSizeRow, pFile);
}
else
{
// were trying to get to the removal line
fgets(m_sCurrentRow, m_MaxSizeRow, pFile);
printf("(not at del row yet)iRow(%d)<iRowNum(%d) %s\n",
i,
m_iNumberOfRows,
m_sCurrentRow);
}
}
{
memmove(m_sRemovalRow,
sReplaceLineStart,
RemovalLength);
}
return 1;
}
FILE is a so-called opaque type, meaning that the application programmer is purposely locked out of its internals as per design - private encapsulation.
Generally one would create an opaque type using the concept of forward declaration, like this:
// stdio.h
typedef struct FILE FILE;
And then inside the private library:
// stdio.c - not accessible by the application programmer
struct FILE
{
// internals
};
Since FILE was forward declared and we only have access to the header, FILE is now an incomplete type, meaning we can't declare an instance of that type, access its members nor pass it to sizeof etc. We can only access it through the API which does know the internals. Since C allows us to declare a pointer to an incomplete type, the API will use FILE* like fopen does.
However, the implementation of the standard library isn't required to implement FILE like this - the option is simply there. So depending on the implementation of the standard library, we may or may not be able to create an instance of a FILE objet and perhaps even access its internals. But that's all in the realm of non-standard language extensions and such code would be non-portable.

Using strtok to tokenize html

I'm looking to extract text found exactly within an < and >, while also extracting things found between > and <.
For instance:
<html> would just return <html>
<title>This is a title</title> would return <title>, This is a title, </title>
This is a title would return This is a title
And finally <title>This is a weird use of < bracket</title> should return <title>, This is a weird use of < bracket, </title>. My current version recognises it as <title>, This is a weird use of, < bracket, </title>
I'd appreciate any snippets of code, or directions to head in to get to a solution.
tldr, grab substrings with <...> and >...< seperately without being stumped by a floating ...>... or ...<....
Edit: not using strtok anymore, would appreciate any other help or similiar problems you may know about. Any thing to read also would be greatly beneficial. Note: we aren't trying to parse, simply lex the input string
Can only use standard libraries for c.
Just trying to build a basic validator for a subset of valid HTML.
You can't, not even a basic one. You will have too many false positives and negatives. Here's a simple example.
<tag attribute=">" />
HTML has many features which do not allow simple parsing. It is...
Balanced, like <tag></tag> and also "quotes".
Nested, like <tag><tag></tag></tag>.
Escaped, like "escaped\"quote".
Has other languages embedded in it, like Javascript and CSS.
If this is an exercise in tokenization, you could define a very specific subset, but I'd suggest something simpler like JSON which has a well defined grammar. Those are typically parsed using a lexer and parser, but JSON is small enough to be written by hand.
My own solution has been thus so far,
as suggested by #chqrlie...
void tokenize(char* stringPtr)
{
char *flag;
strcpy(flag, " ");
/*We build this up as we iterate the string.
Strtok was not suitable, build up tokens char by char */
char tempToken[tokenLength];
strcpy(tempToken, ""); // Init current token
// Traverse string catching stuff between <...> and >...< seperately.
for(int i =0; i<strlen(stringPtr);i++)
{
if (stringPtr[i]=='<' )
{
if (strcmp(flag, " ")==0)
{
putToken(tempToken);
strcpy(tempToken,""); // Tag starting, everything before it is a token.
strcpy(flag,"<");
strcat(tempToken, flag);
}
else // Catches <...<
{
presentError(stringPtr);
}
}
else if (stringPtr[i]=='>')
{
if (strcmp(flag,"<")==0)
{
strcat(tempToken, ">");
strcpy(flag," ");
putToken(tempToken);
strcpy(tempToken,"");
}
else // Cant have a > unless we saw < already
{
presentError(stringPtr);
}
}
else // Manage non angle brackets
{
strncat(tempToken, &stringPtr[i],1 );
}
}
putToken(tempToken); // Catches a line ending in a value, not a tag
/* Notes
Floating <'s and >'s will be errored up
- Special case ....<...>..., which is incorrect
will cause floating tokens, can be identified
Unclosed tags i.e. </p will be tokenized verbatim,
thus can identify this mistake
Unopened tags i.e. p> will be errored
*/
}
Assume that presentError() terminates lexing.
Some improvements can be made, I'm open to suggestions however this is a first working draft.

How do I calculate FPS from data in a .mov file?

I've been writing a program in C# that reads a .mov file. I'm able to parse through the entire thing, ignoring chunks I don't understand, and grabbing relevant info from chunks that I do.
What I'm trying to do is get the FPS from the file, but getting it hasn't been straightforward. I assume because the format can store many movies at different rates.
If someone could point me in the right direction, like which chunks (atoms) should I be looking at? I thought it was stts, but not all .mov files contain that chunk!
I was mistaken. The stts atom is always there, and that is where you get the information to calculate the FPS. The following code hasn't be thoroughly tested, but it did work with all the .mov files I have.
void ReadSTTS(BinaryReader reader)
{
int versionAndFlags = reader.ReadInt32(true);
int nEntries = reader.ReadInt32(true);
int sampleCount = 0;
int sampleDuration = 0;
for (int i = 0; i < nEntries; i++)
{
sampleCount += reader.ReadInt32(true);
sampleDuration += reader.ReadInt32(true);
}
FPS = (float)Math.Round((float)mediaTimeScale / ((float)mediaDuration / (float)sampleCount), 2);
}
mediaTimeScale and mediaDuration both come from the mvhd atom. ReadInt32(true) is an extension that changes the endianness, since I'm reading the .mov on a windows machine.

Parse JSON message manually in C

I need to parse manually, without external libraries, a JSON message coming from a server, in C language.
The message coming from server would be like:
{[CR+LF]
"Tmg": "R",[CR+LF]
"STP": 72[CR+LF]
}[CR+LF]
or
{[CR+LF]
"Tmg": "R",[CR+LF]
"STP": 150[CR+LF]
}[CR+LF]
I need the number after STP:. The number is different in each message structure, so I need to get that number from the JSON structure. I can't use external libraries because this code is in an embedded system and exernal code is not allowed.
I tried this following:
int main (){
const char response_message[35] = "{\r\n\"Tmg\":\"R\",\r\n\"STP\":72,\r\n}";
const char needle[8] = "P\":";
char *ret;
ret = strstr(response_message, needle);
printf("The number is: %s\n", ret);
return 0;
}
But obviously, I am getting this result:
The number is: P":72,
}
So I need to only get the number, how can I get this?
Thanks
You can use a hacked solution. Use strstr () to find "STP": then find the following , or } and extract the digits in between.
And that's a hack. Not guaranteed to work. For something that's guaranteed to work, you use a JSON parser.

Dynamic FileFormat conversion - C Programming

I'm a beginner in "C" programming.
I'm planning to convert the input file into a different format / output file using some kind of static configuration file.
For e.g:
Input File content:
HDRUS15Jan2014153600MY22Jan2014000000KUL
DTLUSANZABC Private Company, Arizona 53213.
DTLMYKULJS Sdn Bhd, Kuala Lumpur 49000 .
Output File content:
ANZ15Jan2014153600
ABC Private Company, Arizona 53213.
KUL22Jan2014000000
JS Sdn Bhd, Kuala Lumpur 49000 .
Hints:
The input file format is fixed length and HDR & DTL keywords are the line identifiers.
I wanted to avoid implementing the hardcoding of extracting the content, instead i wanted to have a kind of configuration file...based on the configuration file the input file content will be extracted and construct the output files.
This concept will allow me to produce additional information in the output file in future without modifying the source code.
I will be just changing the configuration file...
any thoughts will be appreciated.
why you don't use any well known data representaion format like json or xml for your input? by using this kinds of formats you will have no problems with future changes
json will be a good choice and there are implememtaions for c (libjansson etc.)
EDIT
ok, then store your configuration data in file, use some format (i prefer json...)
you will need offset and len infomration:
[
{
offset: 0,
len: 10
}
{
offset: 10,
len: 10
}
]
then you can read this file in your programm and use the information to parse your input:
int offset = getOffset(0);
int len; = getLen(0);
int i;
for(i = offset; i<len; i++)
{
doSomething(input[i]);
}

Resources