Not able to change H264 profile to High from Main using FFMPEG API - c++

I am using QtFFMPEG wrapper(https://code.google.com/p/qtffmpegwrapper/) with Qt 5.4 and MSCV 2012. I want to encode a mp4 video from image files at 25 fps and high profile.
I used the createFile() and encodeImage() functions from here
I am using the below parameters:
pCodecCtx=pVideoStream->codec;
pCodecCtx->codec_id = pOutputFormat->video_codec;
pCodecCtx->codec_type = ffmpeg::AVMEDIA_TYPE_VIDEO;
pCodecCtx->profile=FF_PROFILE_H264_HIGH;
pCodecCtx->bit_rate = Bitrate;
pCodecCtx->width = getWidth();
pCodecCtx->height = getHeight();
pCodecCtx->time_base.den = fps;
pCodecCtx->time_base.num = 1;
pCodecCtx->gop_size = 10;
pCodecCtx->pix_fmt = ffmpeg::PIX_FMT_YUV420P;
pCodecCtx->qmin = 10;
pCodecCtx->qmax = 51;
The FFMPEG variables are:
License: %s
GPL version 3 or later
AVCodec version %d
3476480
AVFormat configuration: %s
--disable-static --enable-shared --enable-gpl --enable-version3 --enable-runtime-cpudetect --enable-avisynth --enable-bzlib --enable-frei0r --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libfreetype --enable-libgsm --enable-libmp3lame --enable-libopenjpeg --enable-librtmp --enable-libschroedinger --enable-libspeex --enable-libtheora --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-libxavs --enable-libxvid --enable-zlib
Now I currently get a video with below properties:
ID : 1
Format : AVC
Format/Info : Advanced Video Codec
Format profile : Main#L3.2
Format settings, CABAC : No
Format settings, ReFrames : 1 frame
Format settings, GOP : M=1, N=10
Codec ID : avc1
Codec ID/Info : Advanced Video Coding
Duration : 4s 320ms
I want the profile to be "High" and the CABAC to be yes with 3 ReFrames. How do I achieve that? I tried setting the profile, coder_type and max_b_frames but did not help. At times the generated file did not even play. Can anyone help please. Thanks.
I also tried using the av_opt_set() way but could not find that function. Only function I have is av_opt_set_dict(), am I missing something - outdated FFMPEG or missing #include.
Tried this too, didnt help-
ffmpeg::AVDictionary *opt = NULL;
int iRes = av_dict_set(&opt, "profile", "high", 0);
av_opt_set_dict(pFormatCtx->priv_data, &opt);
av_opt_set_dict(pFormatCtx, &opt);
Please help.
EDIT:
I got a high quality mp4 by changing the qmin and qmax values and then reencoding the big sized output via command line. I will try to upgrade the FFMPEG as suggested by Ronald below. Please consider the question closed for now.

AVCodec version %d
3476480
That version (libavcodec 53.12.0) is from October 2011, please update to something newer. As you can see from the H264 encoding wiki docs, your settings will work with recent versions of ffmpeg. (Also please share the rest of your code, you're just showing the code that sets your settings, but not any other part of your code, so I can't reproduce anything.)

Related

Google Speech to Text: InvalidArgument: 400 Must use single channel (mono) audio, but WAV header indicates 1 channels

I am using the Google Cloud Platform to convert some audio into text files through the Google Speech-to-Text API. I keep getting the error: google.api_core.exceptions.InvalidArgument: 400 Must use single channel (mono) audio, but WAV header indicates 1 channels.
Here is my code:
config_wave_enhanced = speech.types.RecognitionConfig(
#sample_rate_hertz=44100,
encoding = 'LINEAR16',
enable_automatic_punctuation=True,
language_code='en-US',
#use_enhanched=True,
model='video',
enable_separate_recognition_per_channel = True,
audio_channel_count = 2
)
operation = speech_client.long_running_recognize(
config=config_wave_enhanced,
audio=long_audi_wave
)
response = str(operation.result(timeout=90))
Can anyone help me solve this error? I'm going crazy here.
Setting audio_channel_count = 1 might help.
Convert your audio to 1-channel. You can do this using command line ffmpeg -i stereo.wav -ac 1 mono.wav. Also set audio_channel_count = 1 as Christian Adib mentioned.

AWS Lambda - ffmpeg erroneously outputs distorted/clipped mp3

How do I get an mp3 output without any distortion using ffmpeg?
I am utilizing ffmpeg on AWS Lambda linux using the static build provided by https://www.johnvansickle.com/ffmpeg/ (x86_64 build).
After running the following command, the mp3 output has terrible clipping/distortion.
ffmpeg -loglevel verbose -ss 0 -t 30 -y -i /tmp/ick_20180323005225.wav -codec:a libmp3lame -qscale:a 7 /tmp/ick_20180323005225-opa.mp3
Edit: here is the sample file that I used:
http://www.brainybetty.com/FacebookFans/Feb112010/strings.wav
Here is the log coming from Lambda:
Executing command '/tmp/ffmpeg -loglevel verbose -ss 0 -t 30 -y -i /tmp/ick_20180323005225.wav -codec:a libmp3lame -qscale:a 7 /tmp/ick_20180323005225-opa.mp3' ...
STDERR:
ffmpeg version 3.4.2-static https://johnvansickle.com/ffmpeg/ Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 6.3.0 (Debian 6.3.0-18) 20170516
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc-6 --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gray --enable-libfribidi --enable-libass --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enab
libavutil 55. 78.100 / 55. 78.100
libavcodec 57.107.100 / 57.107.100
libavformat 57. 83.100 / 57. 83.100
libavdevice 57. 10.100 / 57. 10.100
libavfilter 6.107.100 / 6.107.100
libswscale 4. 8.100 / 4. 8.100
libswresample 2. 9.100 / 2. 9.100
libpostproc 54. 7.100 / 54. 7.100
[wav # 0x4bbdf40] parser not found for codec pcm_s16le, packets or times may be invalid.
Guessed Channel Layout for Input Stream #0.0 : stereo
Input #0, wav, from '/tmp/ick_20180323005225.wav':
Duration: 00:00:05.00, bitrate: 1411 kb/s
Stream #0:0: Audio: pcm_s16le ([1][0][0][0] / 0x0001), 44100 Hz, stereo, s16, 1411 kb/s
Stream mapping:
Stream #0:0 -> #0:0 (pcm_s16le (native) -> mp3 (libmp3lame))
Press [q] to stop, [?] for help
[graph_0_in_0_0 # 0x4bc64e0] tb:1/44100 samplefmt:s16 samplerate:44100 chlayout:0x3
[format_out_0_0 # 0x4bc6360] auto-inserting filter 'auto_resampler_0' between the filter 'Parsed_anull_0' and the filter 'format_out_0_0'
[auto_resampler_0 # 0x4bd2ee0] ch:2 chl:stereo fmt:s16 r:44100Hz -> ch:2 chl:stereo fmt:s16p r:44100Hz
Output #0, mp3, to '/tmp/ick_20180323005225-opa.mp3':
Metadata:
TSSE : Lavf57.83.100
Stream #0:0: Audio: mp3 (libmp3lame), 44100 Hz, stereo, s16p, delay 1105
Metadata:
encoder : Lavc57.107.100 libmp3lame
size= 11kB time=00:00:00.73 bitrate= 119.5kbits/s speed=1.41x
size= 23kB time=00:00:01.67 bitrate= 114.5kbits/s speed=1.61x
size= 36kB time=00:00:02.61 bitrate= 113.4kbits/s speed=1.65x
size= 48kB time=00:00:03.55 bitrate= 111.0kbits/s speed=1.69x
size= 60kB time=00:00:04.46 bitrate= 109.6kbits/s speed=1.71x
No more output streams to write to, finishing.
size= 67kB time=00:00:05.01 bitrate= 108.9kbits/s speed=1.75x
video:0kB audio:66kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.371917%
Input file #0 (/tmp/ick_20180323005225.wav):
Input stream #0:0 (audio): 216 packets read (881988 bytes); 216 frames decoded (220497 samples);
Total: 216 packets (881988 bytes) demuxed
Output file #0 (/tmp/ick_20180323005225-opa.mp3):
Output stream #0:0 (audio): 192 frames encoded (220497 samples); 193 packets muxed (68026 bytes);
Total: 193 packets (68026 bytes) muxed
Executed command '/tmp/ffmpeg -loglevel verbose -ss 0 -t 30 -y -i /tmp/ick_20180323005225.wav -codec:a libmp3lame -qscale:a 7 /tmp/ick_20180323005225-opa.mp3' with code: 0.

Metadata is not showing ffmpeg C++

I am muxing h264 encoded video data and PCM g711 encoded audio data into a .mov media container. I am trying to write metadata on header but the metadata is not showing when I go to file->right click->properties->details on windows and likewise in Ubuntu. This is my code -
// Instead of creating new AVDictionary object, I also tried following way
// stated here: http://stackoverflow.com/questions/17024192/how-to-set-header-metadata-to-encoded-video
// but no luck
AVDictionary* pMetaData = m_pFormatCtx->metadata;
av_dict_set(&pMetaData, "title", "Cloud Recording", 0);
av_dict_set(&pMetaData, "artist", "Foobar", 0);
av_dict_set(&pMetaData, "copyright", "Foobar", 0);
av_dict_set(&pMetaData, "filename", m_sFilename.c_str(), 0);
time_t now = time(0);
struct tm tStruct = *localtime(&now);
char date[100];
strftime(date, sizeof(date), "%c", &tStruct); // i.e. Thu Aug 23 14:55:02 2001
av_dict_set(&pMetaData, "date", date, 0);
av_dict_set(&pMetaData, "creation_time", date, 0);
av_dict_set(&pMetaData, "comment", "This video has been created using Eyeball MSDK", 0);
// ....................
// .................
/* write the stream header, if any */
int ret = avformat_write_header(m_pFormatCtx, &pMetaData);
I also tried to see if the file contains any metadata using mediainfo and exiftools in linux. Also I tried ffmpeg -i output.mov but no metadata is shown.
Whats the problem? Is the flags value 0 in av_dict_set okay? DO I need to set different flags for different platform (windows/linux) ?
I saw this link and it stated that for windows, I have to use id3v2_version 3 and -write_id3v1 1 to make metadata working. If so, how can I do this in C++?
I have something similar to your code, but I'm adding the AVDictionary to my AVFormatContext metadata parameter and it works for me that way. Here's a snippet based on your code.
AVDictionary *pMetaData = NULL;
av_dict_set(&pMetaData, "title", "Cloud Recording", 0);
m_pFormatCtx->metadata = pMetaData;
avformat_write_header(m_pFormatCtx, NULL);

ffmpeg starts too slow when using ip camera (the same as using OpenCV)

Here is my code:
ffmpeg -i http://192.168.0.101:8889/video?dummy=param.mjpeg out.mjpg
When I run this command, it will immediately print below:
ffmpeg version N-70223-g7296716 Copyright (c) 2000-2015 the FFmpeg developers
built with gcc 4.9.2 (GCC)
configuration: --enable-gpl --enable-version3 --disable-w32threads --enable-avisynth --enable-bzlib --enable-fontconfig --enable-frei0r --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libbs2b --enable-libcaca --enable-libfreetype --enable-libgme --enable-libgsm --enable-libilbc --enable-libmodplug --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-librtmp --enable-libschroedinger --enable-libsoxr --enable-libspeex --enable-libtheora --enable-libtwolame --enable-libvidstab --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxavs --enable-libxvid --enable-lzma --enable-decklink --enable-zlib
libavutil 54. 19.100 / 54. 19.100
libavcodec 56. 26.100 / 56. 26.100
libavformat 56. 23.105 / 56. 23.105
libavdevice 56. 4.100 / 56. 4.100
libavfilter 5. 11.101 / 5. 11.101
libswscale 3. 1.101 / 3. 1.101
libswresample 1. 1.100 / 1. 1.100
libpostproc 53. 3.100 / 53. 3.100
However, it takes almost twenty seconds before showing next line, and it prints this warning:
[mjpeg # 0000000002c4fec0] Format mjpeg detected only with low score of 25, misdetection possible!
Then it prints this:
Input #0, mjpeg, from 'http://192.168.0.101:8889/video?dummy=param.mjpeg':
Duration: N/A, bitrate: N/A
Stream #0:0: Video: mjpeg, yuvj420p(pc, bt470bg/unknown/unknown), 640x480 [SAR 1:1 DAR 4:3], 25 tbr, 1200k tbn, 25 tbc
Output #0, mjpeg, to 'a.mjpg':
Metadata:
encoder : Lavf56.23.105
Stream #0:0: Video: mjpeg, yuvj420p(pc), 640x480 [SAR 1:1 DAR 4:3], q=2-31,
200 kb/s, 25 fps, 25 tbn, 25 tbc
Metadata:
encoder : Lavc56.26.100 mjpeg
Stream mapping:
Stream #0:0 -> #0:0 (mjpeg (native) -> mjpeg (native))
Press [q] to stop, [?] for help
frame= 195 fps=0.0 q=24.8 size= 1022kB time=00:00:07.80 bitrate=1073.6kbits/
frame= 199 fps=185 q=24.8 size= 1043kB time=00:00:07.96 bitrate=1073.6kbits/
frame= 203 fps=125 q=24.8 size= 1064kB time=00:00:08.12 bitrate=1073.6kbits/
What's worse, when I am using OpenCV, the open of the VideoCapture also takes the same long time!
#include "opencv2/opencv.hpp"
#include <iostream>
using namespace std;
using namespace cv;
int main(){
cout<<"Start"<<endl;
VideoCapture cap("http://192.168.0.101:8889/video?dummy=param.mjpg");
cout<<"End"<<endl;
return 0;
}
20s after printing "start", it prints "end".
I am using ffmpeg on win7 64 bit downloaded from here.
Any idea will be appreciated!
Try with:
ffmpeg -f mjpeg -i http://192.168.0.101:8889/video?dummy=param.mjpeg out.mjpg
Other options if that doesn't work:
It may take too long because MJPEG streams don't include timestamps,
and by default they are generated by ffmpeg like there's 25 FPS.
Try ffmpeg -use_wallclock_as_timestamps 1 -i ​http://...
Try ffmpeg -f mjpeg -use_wallclock_as_timestamps 1 -i ​http://...
Try ffmpeg -f mjpeg -i ​http://...
Try also -probesize 32 -analyzeduration 0
or something like that to reduce probing period.
Source: http://trac.ffmpeg.org/ticket/2343

django-videothumbs and "list index out of range" error

Im using django-videothumbs
Video field is:
video = videothumbs.VideoThumbField(upload_to='videos', sizes=((125,125),(300,200),))
In uploading, video uploads but in thumbnail creation I have this error:
Exception Value: list index out of range
Exception Location:/library/videothumbs.py in generate_thumb, line 51
And line 51:
for c in range(len(histogram[0])):
ac = 0.0
for i in range(n):
ac = ac + (float(histogram[i][c])/n)
avg.append(ac)
What is wrong about video filed?
Edit:
with print histogram I have:
sh: ffmpeg: command not found
But in terminal:
FFmpeg version CVS, Copyright (c) 2000-2004 Fabrice Bellard
Mac OSX universal build for ffmpegX
configuration: --enable-memalign-hack --enable-mp3lame --enable-gpl --disable-vhook -- disable-ffplay --disable-ffserver --enable-a52 --enable-xvid --enable-faac --enable-faad --enable-amr_nb --enable-amr_wb --enable-pthreads --enable-x264
libavutil version: 49.0.0
libavcodec version: 51.9.0
libavformat version: 50.4.0
built on Apr 15 2006 04:58:19, gcc: 4.0.1 (Apple Computer, Inc. build 5250)
usage: ffmpeg [[infile options] -i infile]... {[outfile options] outfile}...
Hyper fast Audio and Video encoder
Thanks in advance
Have you checked the value of histogram[0]? Most probably histogram doesn't have any elements.
I would change the code in:
if len(histogram) > 0:
for c in range(len(histogram[0])):
ac = 0.0
for i in range(n):
ac = ac + (float(histogram[i][c])/n)
avg.append(ac)