问题
I am trying to initialize an FFMPEG H264 codec context filling the extradata field with the SPS frame like this :
#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);
}
}
The output of the program is :
[h264 @ 0xc74010] NAL 7/3 at 4/11 length 6
[h264 @ 0xc74010] sps:0 profile:66/10 poc:0 ref:0 8x6 FRM crop:0/0/0/0 420 0/0 b8 reo:-1
Video: h264, 1 reference frame, none(left), q=2-31, 200 kb/s
The output show that sps was decoded with the needed information to compute width and height by h264_ps.c (mb_width=8, mb_height=6, crop_left=crop_right=crop_top=crop_bottom=0).
Then I was expecting to get the width and the height calling avcodec_string.
Is there a way to do this without decoding frames ?
回答1:
Its available in AVCodecContext.width, and AVCodecContext.height after avcodec_open2(), if you format your extradata correctly.
This post will tell you how it should be formated Possible Locations for Sequence/Picture Parameter Set(s) for H.264 Stream
回答2:
Feeding the decoder with a dummy buffer make possible to get the size encoded in the SPS.
Using a null PPS and an empty non-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);
Running this code print errors but it allow to extract width and height from the SPS :
[h264 @ 0xd0d040] Missing reference picture, default is 0 [h264 @ 0xd0d040] decode_slice_header error size: 128x96
来源:https://stackoverflow.com/questions/30787875/how-to-get-width-and-height-from-the-h264-sps-using-ffmpeg