H264: декодировать ряд наль единиц с помощью ffmpeg - PullRequest
3 голосов
/ 20 июля 2010

Я попытался декодировать серию nal-блоков с помощью ffmpeg (libavcodec), но получаю ошибку «без кадра». Я создал целые единицы измерения с указанием Как можно кодировать серию изображений в H264 с помощью x264 C API? . Я попробовал следующую стратегию для декодирования:

avcodec_init();  
avcodec_register_all();  
AVCodec* pCodec;  
pCodec=lpavcodec_find_decoder(CODEC_ID_H264);  
AVCodecContext* pCodecContext;  
pCodecContext=lpavcodec_alloc_context();  
avcodec_open(pCodecContext,pCodec);  
AVFrame *pFrame;  
pFrame=avcodec_alloc_frame();
//for every nal unit:    
    int frameFinished=0;  
    //nalData2 is nalData without the first 4 bytes
    avcodec_decode_video(pCodecContext,pFrame,&frameFinished,(uint8_t*) nalData2,nalLength);

Я передал все единицы измерения, полученные в этом коде, но frameFinished остался 0. Я думаю, что-то не так с настройкой pCodecContext. Может кто-нибудь прислать мне рабочий пример?

Спасибо

Ответы [ 2 ]

4 голосов
/ 20 июля 2010

Проверьте этот урок.Он должен иметь возможность декодировать любой тип видео, включая H.264:

http://dranger.com/ffmpeg/

Я не знаю точно, что вызывает проблему, но я подозреваю, что это как-то связано стот факт, что вы не используете av_read_frame из libavformat для анализа данных за один раз.H.264 имеет возможность разбивать кадр на несколько фрагментов и, следовательно, несколько блоков NAL.

Я уверен, что кодер x264 не делает этого по умолчанию и выдает один блок NAL на кадр.Однако существуют блоки NAL с другой информацией о потоке, которые необходимо подавать в декодер.Я экспериментировал с этим в прошлом, и когда av_read_frame анализирует фреймы данных, он иногда содержит несколько блоков NAL.Я бы посоветовал внимательно изучить руководство и посмотреть, работает ли он.

Другое дело, что я думаю, что вам нужно передать первые 4 байта блока NAL в avcodec_decode_video, если вы используете этот стартовый кодговорить о (0x00000001).Изучив выходные данные из av_read_frame, стартовые коды все еще находятся в данных при передаче в декодер.

0 голосов
/ 01 августа 2013

Попробуйте это после кода экземпляра контекста кодека:

  if(pCodec->capabilities & CODEC_CAP_TRUNCATED)
      pCodecContext->flags |= CODEC_FLAG_TRUNCATED; /* We may send incomplete frames */
  if(pCodec->capabilities & CODEC_FLAG2_CHUNKS)
      pCodecContext->flags2 |= CODEC_FLAG2_CHUNKS;
...