Попытка определить профиль и уровень h.264 прагматично - PullRequest
3 голосов
/ 09 ноября 2011

В идеале решение должно быть на python и кроссплатформенности, но это, вероятно, не слишком вероятно, поэтому все, что мне нужно, это работать в linux, и я могу использовать расширение c для взаимодействия с python, если это необходимо. Я вижу, что для ffmpeg есть привязка к python, о которой я думал, однако я не могу понять, как определить профиль и уровень как есть, с помощью fmmpeg или чего-то еще, тем более делать это прагматично. Google не сильно помогает в этом вопросе.

Я смог определить, какие функции я бы искал, если бы мне нужно было определить профиль и уровни вручную, тогда я могу это сделать, но тогда возникает вопрос, может ли ffmpeg определить, было ли видео закодированы с этим набором функций? Я думаю, что мне интересно на этот счет, возможно ли невозможно полностью определить уровень и конкретный профиль после кодирования? Я думаю, вы должны знать, чтобы расшифровать его, но, возможно, нет; это объяснило бы, почему я не могу найти информацию об этом. Я какое-то время играл и выключал это, но недавно решил рассмотреть проект, о котором я думал, но это одна из тех больших вещей, которые меня сдерживают.

Ответы [ 2 ]

2 голосов
/ 23 июня 2012

Вот небольшая программа, которую я написал. Он печатает профиль и уровень файлов MP4, которые используют h264 в качестве видеокодека. Вы можете скомпилировать его с помощью следующей командной строки:

gcc -std=c99 printProfileAndLevel.c -o printProfileAndLevel

Вот источник C:

#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;
}
2 голосов
/ 09 ноября 2011

В основном вам нужно идентифицировать SPS (набор параметров последовательности) в битовом потоке и декодировать пару его старших байтов.

См. Заголовок потока H.264 и ссылки там.

...