2015-06-11 1 views
3

Я пытаюсь инициализировать контекст кодека FFMPEG H264 заполнения ExtraData поле с рамкой SPS, как это:Как получить ширину и высоту от H264 SPS с помощью FFmpeg

#include <libavcodec/avcodec.h> 
#include <libavformat/avformat.h> 

int main() 
{ 
    const char sps[] = {0x00, 0x00, 0x00, 0x01, 0x67, 0x42, 0x00, 0x0a, 0xf8, 0x41, 0xa2}; 
    av_register_all(); 
    av_log_set_level(AV_LOG_DEBUG); 

    AVCodec *const codec = avcodec_find_decoder(CODEC_ID_H264); 
    if (codec != NULL) 
    {    
     AVCodecContext* ctx = avcodec_alloc_context3(codec); 
     ctx->debug = ~0; 
     ctx->extradata = (uint8_t *)av_malloc(sizeof(sps) + FF_INPUT_BUFFER_PADDING_SIZE); 
     ctx->extradata_size = sizeof(sps); 
     memcpy(ctx->extradata,sps,sizeof(sps)); 
     memset(&ctx->extradata[ctx->extradata_size], 0, FF_INPUT_BUFFER_PADDING_SIZE); 

     if (avcodec_open2(ctx, codec, NULL) < 0) 
     { 
      fprintf(stderr, "Failed to open codec\n"); 
     } 
     else 
     { 
      char buf[1024]; 
      avcodec_string(buf,sizeof(buf),ctx,1); 
      fprintf(stderr, "%s\n", buf); 
     } 
     avcodec_close(ctx); 
     av_free(ctx); 
    } 
} 

Выход программы:

[H264 @ 0xc74010] NAL 7/3 на 4/11 длины 6
[H264 @ 0xc74010] СФС: 0 профиль: 66/10 PoC: 0 ссылок: 0 8х6 КАДР культур: 0/0/0/0 420 0/0 b8 reo: -1
Видео: h264, 1 контрольная рамка, нет (слева), q = 2-31, 200 kb/s

Выходной сигнал показывает, что СФС был расшифрован с необходимой информацией для вычисления ширины и высоты от h264_ps.c (mb_width = 8, mb_height = 6, crop_left = crop_right = crop_top = crop_bottom = 0).

Тогда я ожидал получить ширину и высоту, вызывающую avcodec_string.
Есть ли способ сделать это без декодирования кадров?

+0

Привет человек , смогли ли вы это решить? – Teamol

ответ

0

Кормление декодера с фиктивным буфером позволяет получить размер закодированный в SPS.
Использование нулевой PPS и пустой не-IDR SLICE:

int got_frame = 0; 
AVPacket pkt; 
av_init_packet(&pkt); 
char buffer[] = {0x00, 0x00, 0x00, 0x01, 0x68, 0xff, 0x00, 0x00, 0x00, 0x01, 0x21}; 
pkt.data = buffer; 
pkt.size = sizeof(buffer); 
AVFrame* frame = av_frame_alloc(); 
avcodec_decode_video2(ctx, frame, &got_frame, &pkt);  
av_frame_free(&frame); 
fprintf(stderr, "size: %dx%d\n", ctx->width, ctx->height);  

Запуск этой ошибки код печати, но позволяют извлекать ширину и высоту от SPS:

[h264 @ 0xd0d040] Missing reference picture, default is 0 
[h264 @ 0xd0d040] decode_slice_header error 
size: 128x96 
1

Его доступный в AVCodecContext.width и AVCodecContext.height после avcodec_open2(), если вы правильно отформатируете extradata.

Этот пост расскажет вам, как это должно быть отформатировано Possible Locations for Sequence/Picture Parameter Set(s) for H.264 Stream

+0

Я полагаю, вы ошибаетесь, это причина этого вопроса, я следую коду ffmpeg и 'init_dimensions' из [h264_slice.c] (https://github.com/FFmpeg/FFmpeg/blob/master/libavcodec/ h264_slice.c) не вызывается перед декодированием первого фрагмента. Если что-то не так в форматировании 'extradata', пожалуйста, укажите это. – mpromonet

+0

Экстрадата - это не только SPS, но и не в приложении B. это полный формат, который включает дополнительную информацию. Если вы прочтете ссылку, которую я разместил, она объясняет это. Или вы можете просто разобрать SPS самостоятельно. h264_bitstream сделает это. – szatmary

+0

h264_bitstream может быть способом, но использование ffmpeg должно дать возможность управлять другими форматами. – mpromonet

Смежные вопросы