Как декодировать кадр H.264 на iOS с помощью аппаратного декодирования?

Я использовал ffmpeg для декодирования каждого кадра, который я получил с моей IP-камеры. Краткий код выглядит так:

-(void) decodeFrame:(unsigned char *)frameData frameSize:(int)frameSize{
   AVFrame frame;
   AVPicture picture;
   AVPacket pkt;
   AVCodecContext *context;
   pkt.data = frameData;
   pat.size = frameSize;
   avcodec_get_frame_defaults(&frame);
   avpicture_alloc(&picture, PIX_FMT_RGB24, targetWidth, targetHeight);
   avcodec_decode_video2(&context, &frame, &got_picture, &pkt);
}

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


person ChihHao    schedule 08.08.2014    source источник


Ответы (2)


iOS не предоставляет открытого доступа непосредственно к механизму аппаратного декодирования, поскольку аппаратное обеспечение всегда используется для декодирования видео H.264 на iOS.

Таким образом, сеанс 513 содержит всю информацию, необходимую для разрешения покадрового декодирования на iOS. . Короче говоря, за этот сеанс:

  • Создайте отдельные единицы уровня сетевой абстракции (NALU) из вашего элементарного потока H.264. В сети много информации о том, как это делается. NALU VCL (IDR и не-IDR) содержат ваши видеоданные и должны быть переданы в декодер.
  • Переупакуйте эти NALU в соответствии с форматом «AVCC», удалив стартовые коды NALU и заменив их 4-байтовым заголовком длины NALU.
  • Создайте CMVideoFormatDescriptionRef из ваших NALU SPS и PPS через CMVideoFormatDescriptionCreateFromH264ParameterSets()
  • Упаковать кадры NALU как CMSampleBuffers за сеанс 513.
  • Create a VTDecompressionSessionRef, and feed VTDecompressionSessionDecodeFrame() with the sample buffers
    • Alternatively, use AVSampleBufferDisplayLayer, whose -enqueueSampleBuffer: method obviates the need to create your own decoder.
person rpj    schedule 27.10.2014
comment
Это работает, начиная с iOS 8. Обратите внимание, что 4-байтовый заголовок длины NALU имеет формат с обратным порядком байтов, поэтому, если у вас есть значение UInt32, перед копированием в CMBlockBuffer необходимо поменять местами байты (используйте CFSwapInt32). - person 12on; 12.12.2014
comment
Спасибо, 12on, я долго ломал голову над ошибками декодирования, пока не попробовал поменять местами байты, как вы сказали. - person Greg; 28.02.2015
comment
@rpj - можете ли вы объяснить третий шаг (упаковка)? Сколько кадров NALU я должен упаковать (например, все с одинаковым номером кадра)? - person Tomasz Wójcik; 07.05.2015
comment
Эта ссылка содержит более подробное объяснение того, как шаг за шагом декодировать h.264: stackoverflow.com/a/29525001/3156169 - person ChihHao; 22.05.2015
comment
Одна раздражающая вещь: этот отличный ответ, разговор 513 и знаменитый связанный ответ прекрасно объясняют, как перейти от элементарного потока через NALU к VTDecompressionSession. Тем не мение! Очень сложно найти какие-либо примеры или обсуждение того, как достичь того, чтобы ваш поток 264 был готов к этому! Работы может быть много.......... - person Fattie; 16.12.2018