3

Ideally the solution would be in python and cross platform, but that's probably not too likely, so all I require is it work in linux, and I can use a c extension to interface w/python if necessary. I see there is a python binding for ffmpeg which I was thinking about using, however I can't figure out how to determine the profile and level as it is, with fmmpeg or anything else, much less do it pragmatically. Google is not much help on the matter either.

I've been able to determine what features I'd be looking for if I needed to determine the profile and levels manually then I can do that, but then that leads to the question, can ffmpeg then determine if the video was encoded with that feature set? I guess what I'm wondering to that effect is, is it perhaps not possible to fully determine the level and specific profile after encoding? I would think you'd have to know in order to decode it, but maybe not; that would explain why I can't find any information on it. I've been toying with this on and off for awhile, but recently decided to consider a project I'd been thinking about, but this is one of this big things holding me back.

kryptobs2000
  • 3,289
  • 3
  • 27
  • 30

2 Answers2

3

Here is a small program I wrote. It prints the profile and level of MP4 files that use h264 as the video codec. You can compile it with the following command line:

gcc -std=c99 printProfileAndLevel.c -o printProfileAndLevel

Here is the C source :

#include <stdio.h>
#include <stdlib.h>

void printProfile(int profile_idc, int profile_iop, int level_idc) {
  switch(profile_idc) {
    case 0x42: printf("Baseline Profile"); break;
    case 0x4D: printf("Main Profile"); break;
    case 0x58: printf("Extended Profile"); break;
    case 0x64: printf("High Profile"); break;
    default:   printf("Unknown profile (%x)", profile_idc);
  }

  switch(level_idc) {
    case 0x15: printf(" @ Level 2.1\n"); break;
    case 0x1F: printf(" @ Level 3.1\n"); break;
    case 0x29: printf(" @ Level 4.1\n"); break;
    case 0x33: printf(" @ Level 5.1\n"); break;
    default:   printf(" @ unknown level (%x)", level_idc);
  }
}

int main(int argc, char* argv[])
{
  if(argc < 2) {
    printf("syntax: %s <files>\n", argv[0]);
    exit(-1);
  }

  int buffsize = 1024;
  char *buffer = malloc(buffsize + 1);

  for(int nArg = 1; nArg < argc; nArg++) {
    printf("File %s:\n", argv[nArg]);
    FILE *file = fopen(argv[nArg], "r+");
    if(file == NULL) {
      printf("Cannot open input file %s\n", argv[nArg]);
      continue;
    }

    int nRead = 0;
    nRead = fread(buffer, 1, buffsize, file);

    for(int i = 0; i < nRead - 7; i++) {
      if(buffer[i] == 0x61 && buffer[i+1] == 0x76 && buffer[i+2] == 0x63 && buffer[i+3] == 0x43) {
        printProfile(buffer[i+5], buffer[i+6], buffer[i+7]);
      }
    }
    fclose(file);
  }
  free(buffer);
  return 0;
}
Teraokay
  • 120
  • 6
2

Basically you need to identify SPS (Sequence Parameter Set) in the bitstream and decode a couple of its leading bytes.

See H.264 stream header and links there.

Community
  • 1
  • 1
Roman R.
  • 68,205
  • 6
  • 94
  • 158