3
votes

I am writing a small tool, which converts a video into a raw h264 file. These files shall be played later by a SIP phone. I have the following code:

  eccx->pix_fmt = PIX_FMT_YUV420P;
  eccx->width = VIDEO_FRAME_WIDTH;
  eccx->height = VIDEO_FRAME_HEIGHT;
  eccx->time_base.num = 1;
  eccx->time_base.den = VIDEO_FRAMES_PER_SEC;
  eccx->max_b_frames = 0;

  eccx->rtp_payload_size = VIDEO_RTP_PAYLOAD_SIZE;

  eccx->bit_rate = VIDEO_BIT_RATE;
  eccx->rc_max_rate = VIDEO_BIT_RATE;
  eccx->rc_buffer_size = VIDEO_BIT_RATE * 2;

  eccx->flags |= CODEC_FLAG_QP_RD;
  eccx->flags |= CODEC_FLAG_LOW_DELAY;
  eccx->flags |= CODEC_FLAG_QSCALE;
  eccx->flags |= CODEC_FLAG_EMU_EDGE;

  eccx->mb_decision = FF_MB_DECISION_SIMPLE;

  switch(video){
  case H263:
    break;
  case H263P:
    eccx->flags |= CODEC_FLAG_H263P_SLICE_STRUCT;
    break;
  case H264:
    av_dict_set(&options, "vprofile", "baseline", 0);
    eccx->flags2 = CODEC_FLAG2_FASTPSKIP;
    eccx->profile = FF_PROFILE_H264_BASELINE;
    eccx->level = 13;
    break;
  }

When I execute this program I got the following output from libx264:

[libx264 @ 0x10fad60] using cpu capabilities: MMX2 SSE2Fast SSSE3 FastShuffle SSE4.1 Cache64
[libx264 @ 0x10fad60] profile Main, level 1.3

Why is this still Main profile, though I have set it explicitly to baseline?

Additionally, I would be really cool, if someone could add some notes which kind of h264 settings are useful for SIP phone calls. Thank you very much!

2
What is the VIDEO_FRAME_WIDTH and VIDEO_FRAME_HEIGHT? is it possible that these resolutions are too high?Dundar
The profile is independent from the level. The level restricts the frame size. Level 1.3 allows frames up to CIF (en.wikipedia.org/wiki/H264#Levels). The input video stream has CIF. The input video might contain B-frames, which aren't allowed in Baseline, but how do I convince libav to convert them into I- or P- frames?Denis Loh

2 Answers

5
votes

You should set options on the private part of the codec context:

av_opt_set(eccx->priv_data, "profile", "baseline", 0);

of course assuming that eccx is an AVCodecContext instance. Then open the codec with

avcodec_open2(eccx, codec, NULL);

where codec is your AVCodec instance which you should already have gotten with something similar to this:

AVCodec *codec = avcodec_find_encoder(AV_CODEC_ID_H264);

You can check that this works by giving an invalid profile name, then the library will tell you the valid profile names on standard error.

1
votes

vprofile is an avconv option (and an undocumented/deprecated/not recommended for usage anyway, use -profile:v instead). avconv parses it and the option name that actually gets sent to libavcodec is just profile. So that is what you should use.