[Libav-user] c++ API h264 encoded video does not play on all platforms

Drabner drabner at zoobe.com
Wed Jul 18 11:20:16 CEST 2012


This is a copy of my question on stackoverflow (thought it would be a good
idea to post it here, too):
http://stackoverflow.com/questions/11537830/ffmpeg-api-h264-encoded-video-does-not-play-on-all-platforms

I am using the C++ API to create a mp4 video in C++.

I want the resulting video to be of the profile "Constrained Baseline", so
that the resulting video can be played on as much platforms as possible,
especially mobile, but I get "Main" profile every time, even though I hard
coded the codec profile to be *FF_PROFILE_H264_CONSTRAINED_BASELINE*. As a
result, the video does not play on all our testing platforms.

This is what "ffprobe video.mp4 -show_streams" tells about my video streams:
//---------------------------------------------------------
      Metadata:
    major_brand     : isom
    minor_version   : 512
    compatible_brands: isomiso2avc1mp41
    creation_time   : 1970-01-01 00:00:00
    encoder         : Lavf53.5.0
      Duration: 00:00:13.20, start: 0.000000, bitrate: 553 kb/s
    Stream #0:0(und): Video: h264 (Main) (avc1 / 0x31637661), yuv420p,
320x180,
    424 kb/s, 15 fps, 15 tbr, 15 tbn, 30 tbc
    Metadata:
      creation_time   : 1970-01-01 00:00:00
      handler_name    : VideoHandler
    Stream #0:1(und): Audio: aac (mp4a / 0x6134706D), 44100 Hz, stereo, s16,
12
    kb/s
    Metadata:
      creation_time   : 1970-01-01 00:00:00
      handler_name    : SoundHandler
    -------VIDEO STREAM--------
    [STREAM] 
    index=0
    codec_name=h264
    codec_long_name=H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10

    profile=Main <-- This should be "Constrained Baseline"

    codec_type=video
    codec_time_base=1/30
    codec_tag_string=avc1
    codec_tag=0x31637661
    width=320
    height=180
    has_b_frames=0
    sample_aspect_ratio=N/A
    display_aspect_ratio=N/A
    pix_fmt=yuv420p
    level=30
    timecode=N/A
    is_avc=1
    nal_length_size=4
    id=N/A
    r_frame_rate=15/1
    avg_frame_rate=15/1
    time_base=1/15
    start_time=0.000000
    duration=13.200000
    bit_rate=424252
    nb_frames=198
    nb_read_frames=N/A
    nb_read_packets=N/A
    TAG:creation_time=1970-01-01 00:00:00
    TAG:language=und
    TAG:handler_name=VideoHandler
    [/STREAM]
    -------AUDIO STREAM--------
    [STREAM]
    index=1
    codec_name=aac
    codec_long_name=Advanced Audio Coding
    profile=unknown
    codec_type=audio
    codec_time_base=1/44100
    codec_tag_string=mp4a
    codec_tag=0x6134706d
    sample_fmt=s16
    sample_rate=44100
    channels=2
    bits_per_sample=0
    id=N/A
    r_frame_rate=0/0
    avg_frame_rate=0/0
    time_base=1/44100
    start_time=0.000000
    duration=13.165714
    bit_rate=125301
    nb_frames=567
    nb_read_frames=N/A
    nb_read_packets=N/A
    TAG:creation_time=1970-01-01 00:00:00
    TAG:language=und
    TAG:handler_name=SoundHandler
    [/STREAM]
//---------------------------------------------------------

This is the function I use to add a video stream. All the values that come
from ptr-> are defined from outside, do those values have to be specific
values to get the correct profile?:
//---------------------------------------------------------
    static AVStream *add_video_stream( Cffmpeg_dll * ptr, AVFormatContext
*oc, enum   CodecID codec_id )
    {
	AVCodecContext *c;
	AVStream *st;                 

	st = av_new_stream(oc, 0);
	if (!st) {
		av_log(NULL, AV_LOG_ERROR, "%s","Could not alloc stream\n");
		exit(1);
	}

	c = st->codec;
	c->codec_id = CODEC_ID_H264;
	c->codec_type = AVMEDIA_TYPE_VIDEO;

	/* put parameters */
	c->bit_rate = ptr->video_bit_rate;

        c->qmin = ptr->qmin;
        c->qmax = ptr->qmax;
        c->me_method = ptr->me_method;
        c->me_subpel_quality = ptr->me_subpel_quality;
        c->i_quant_factor = ptr->i_quant_factor;
        c->qcompress = ptr->qcompress;
        c->max_qdiff = ptr->max_qdiff;

        c->level = 30;
	    c->profile = FF_PROFILE_H264_CONSTRAINED_BASELINE;

	c->width = ptr->dstWidth; 
	c->height = ptr->dstHeight; 

	c->time_base.den = ptr->fps;
	c->time_base.num = 1;
	c->gop_size = 30; 
	c->pix_fmt = PIX_FMT_YUV420P;

	if(oc->oformat->flags & AVFMT_GLOBALHEADER)
		c->flags |= CODEC_FLAG_GLOBAL_HEADER;

	return st;
    }
//---------------------------------------------------------

*Additional info:*

As a reference video, I use the gizmo.mp4 that Mozilla serves as an example
that plays on every platform/browser. It definitely has the "Constrained
Baseline" profile, and definitely works on all our testing smartphones. You
can download it here: http://www.808.dk/pics/video/gizmo.mp4 Our
self-created video doesn't work on all platforms and I'm convinced this is
because of the profile.

I am also using *qt-faststart.exe* to move the headers to the start of the
file after creating the mp4, as this cannot be done in a good way in C++
directly. Could that be the problem?

Obviously, I am doing /something/ wrong, but I don't know what it could be.
I'd be thankful for every hint ;)


--
View this message in context: http://libav-users.943685.n4.nabble.com/c-API-h264-encoded-video-does-not-play-on-all-platforms-tp4655422.html
Sent from the libav-users mailing list archive at Nabble.com.


More information about the Libav-user mailing list