Welcome to Doom9's Forum, THE in-place to be for everyone interested in DVD conversion. Before you start posting please read the forum rules. By posting to this forum you agree to abide by the rules. |
![]() |
#1 | Link |
Registered User
Join Date: Oct 2004
Location: lubbock, tx, usa
Posts: 33
|
what is the difference between these two h.264 mp4s?
hi all.
i wrote a qt c++ program that uses the ffmpeg api to transcode video to h.264 mp4. i know, i know - don't use the ffmpeg api to control x264. but it was working fine until i upgraded ffmpeg and x264 to the latest versions. last release build used ffmpeg from git from around last summer (N-54452-g621ab4e). x264 was "core 135 r2 f0c1c53". i updated ffmpeg to 2.2.1 and x264 to "core 142 r2 956c8d8". i encoded the same test video before and after updating the libraries. you can find them here: http://nate.quandra.org/kowz_good.mp4 http://nate.quandra.org/kowz_bad.mp4 both play fine in good players, but in the bad player (quicktime pre 7.7) i get this: ![]() so updating ffmpeg and/or x264 broke playback in old quicktime. it's pretty bizarre because the same settings are being passed to x264. also x264 commandline and ffmpeg commandline do not create video with the problem. i have already tried mediainfo and ffprobe -show_streams and i cannot find any difference between the files. it's a mystery to me. to be honest, i don't even care about old quicktime, but like they say: "where there's smoke ..." if anyone loves a mystery, please help me out. my ffmpeg code: Code:
filename_string = temp_out_file.fileName()+"v.mp4"; QByteArray filename_ba = filename_string.toLocal8Bit(); char *filename_pointer = filename_ba.data(); avformat_alloc_output_context2(&oc, NULL, NULL, filename_pointer); Q_ASSERT(oc); codec = avcodec_find_encoder(AV_CODEC_ID_H264); if (!codec) { fprintf(stderr, "Codec not found\n"); exit(1); } //add to output stream context st = avformat_new_stream(oc, codec); if (!st) { fprintf(stderr, "Could not allocate stream\n"); exit(1); } st->id = oc->nb_streams-1; //c = avcodec_alloc_context3(codec); c = st->codec; if (!c) { fprintf(stderr, "Could not allocate video codec context\n"); exit(1); } /* Some formats want stream headers to be separate. */ if (oc->oformat->flags & AVFMT_GLOBALHEADER) { c->flags |= CODEC_FLAG_GLOBAL_HEADER; } AVDictionary *opts = NULL; av_dict_set(&opts, "preset", "veryslow", 0); //http://mewiki.project357.com/wiki/X264_Encoding_Suggestions#QuickTime_Player_X_compatibility //this doesn't work because we set the profile and/or level for every quality below (20130330) av_dict_set(&opts, "refs", "4", 0); av_dict_set(&opts, "qpmin", "4", 0); av_dict_set(&opts, "profile", "high", 0); av_dict_set(&opts, "level", "4.1", 0); //bluray compatibility level c->pix_fmt = (AVPixelFormat)video_information.colorspace; QString stat_file_name = temp_out_file.fileName()+".stats"; stat_file_name_ba = stat_file_name.toLocal8Bit(); char *stat_file_name_pointer = stat_file_name_ba.data(); av_dict_set(&opts, "stats", stat_file_name_pointer, 0); if (pass == 1) { av_dict_set(&opts, "crf", "17", 0); av_dict_set(&opts, "fastfirstpass", "0", 0); c->flags |= CODEC_FLAG_PASS1; } else if (pass == 2) { c->bit_rate = video_information.bitrate_kbit * 1000; c->flags |= CODEC_FLAG_PASS2; } c->thread_count = 0; c->width = video_information.width_after_cropping; c->height = video_information.height_after_cropping; c->sample_aspect_ratio.num = st->sample_aspect_ratio.num = aspect_ratio_num * video_information.height; c->sample_aspect_ratio.den = st->sample_aspect_ratio.den = aspect_ratio_den * video_information.width; c->time_base.num = timebase_num; c->time_base.den = timebase_den; if (mutex) mutex->lock(); int ret = avcodec_open2(c, codec, &opts); if (mutex) mutex->unlock(); if (ret < 0) { qDebug() << "Could not open video codec"; exit(1); } /* open the output file, if needed */ if (avio_open(&oc->pb, filename_pointer, AVIO_FLAG_WRITE) < 0) { fprintf(stderr, "Error occurred when opening video output file\n"); return; } /* Write the stream header, if any. */ if (avformat_write_header(oc, NULL) < 0) { fprintf(stderr, "Error occurred when writing video header\n"); return; } |
![]() |
![]() |
![]() |
#3 | Link |
Registered User
Join Date: Oct 2004
Location: lubbock, tx, usa
Posts: 33
|
ok, that is kind of what i suspected ... is there something wrong with how i am writing to the mp4 output? see my code below. in particular, using the ffmpeg commandline program built with the new libraries doesn't exhibit this problem ... so i doubt it is a problem with ffmpeg. rather how i am using the library is incorrect.
Code:
//after avcodec_encode_video2() if (c->coded_frame->key_frame) pkt.flags |= AV_PKT_FLAG_KEY; pkt.stream_index = st->index; av_interleaved_write_frame(oc, &pkt); //when it's time to finish the file av_write_trailer(oc); if (mutex) mutex->lock(); avcodec_close(st->codec); if (mutex) mutex->unlock(); /* Free the streams. */ for (uint i = 0; i < oc->nb_streams; i++) { av_freep(&oc->streams[i]->codec); av_freep(&oc->streams[i]); } avio_close(oc->pb); /* free the stream */ av_free(oc); |
![]() |
![]() |
![]() |
#4 | Link |
Registered User
Join Date: Oct 2004
Location: lubbock, tx, usa
Posts: 33
|
for reference, this was the problem (after calling avcodec_encode_video2()):
Code:
if (c->coded_frame->key_frame) { pkt.flags |= AV_PKT_FLAG_KEY; } |
![]() |
![]() |
![]() |
Tags |
ffmpeg x264 mp4 quicktime |
Thread Tools | Search this Thread |
Display Modes | |
|
|