q1: set video size
I'm producing MPEGTS streams (h264/aac) using ffmpeg, so I know exactly how they are coded, and I could modify that if needed.Now, when I receive them in my own code, I always have to run them through avformat_open_input and avformat_find_stream_info to get the settings into the codec context.Because udp mpegts streams have no header, both avformat_open_input and avformat_find_stream_info sometimes have problems to get all settings correctly.However, all settings are known, and so I try to inform avformat_open_input and avformat_find_stream_info about them, using a AVDictionary.However, despite setting the video_size to 720x576, I often get "unspecified size". Other AVDictionary options such as "probesize" are honored though.Ideally I want to skip the avformat_find_stream_info step completely and preset all settings. But how to do that correctly?Also sometimes avformat_open_input does not get it correctly that there is a video and an audio stream. I'm reading the stream though a memory buffer, and not directly from a file or url. This is what I tried:====== av_dict_set(&format_opts, "video_size", "720x576", 0); <<== seems to be ignored // av_dict_set(&format_opts, "pixel_format", av_get_pix_fmt_name(ffmpeg::PIX_FMT_YUV420P), 0); av_dict_set(&format_opts, "pixel_format", "yuv420p", 0); av_dict_set(&format_opts, "sample_format", "fltp", 0); av_dict_set(&format_opts, "analyzeduration", "8000000", 0); <<== honored av_dict_set(&format_opts, "probesize", "8000000", 0); <<== honored av_dict_set(&format_opts, "channels", "2", 0); av_dict_set(&format_opts, "sample_rate", "48000", 0); av_dict_set(&format_opts, "seekable", "0", 0); ... err = avformat_open_input(&pFormatCtx, "", inputFmt, &format_opts); => sometimes sees one stream only av_dict_set(&format_opts, "video_size", "720x576", 0); <<== seems to be ignored ... err = avformat_find_stream_info(pFormatCtx, &format_opts); av_dump_format(pFormatCtx, 0, "Memory Buffer", false); => often says "unspecified size"======I'm using the very latest ffmpeg 1.0.3 from 2 days ago.My Questions are:
How do I pass the video size to avformat_open_input and avformat_find_stream_info so that it is taken?
Which settings do i have to set to set (and how) to avoid the need for avformat_find_stream_info?
How do i tell avformat_open_input that there is a video stream and an audio stream, or help it to find them (possible a change in the encoding parameters)?
Thanks for any hints or help!
Regards,
Kalileo
q2:set frame rate
I'm writing an application, remuxing streams.
It has the raw motion jpeg as an input and saves it to .avi files.
My problem is that motion jpeg has a frame rate of 2fps, but the resulting files have 25fps.
I know the accurate frame rate value, because all my input frames have timetamps, stored separately.
I have the following code snippet:
in_ioc = avio_alloc_context(< custom IO context routines, input is not a file>);
in_ioc->is_streamed = 1;
input = avformat_alloc_context();
input->pb = in_ioc;
input->iformat = av_find_input_format("mjpeg");
input->flags |= AVFMT_NOFILE | AVFMT_FLAG_IGNIDX;
input->max_analyze->duration = 2 * AV_TIME_BASE;
AVDictionary *options = NULL;
av_dict_set(&options, "s", "704x576", 0);
av_dict_set(&options, "pix_fmt", "yuv420p", 0);
av_dict_set(&options, "r", "2", 0);
avformat_open_input(&input, "input", input->iformat, &options);
av_dict_set(&options, "r", "2", 0);
avformat_find_stream_info(input, &options);
av_dict_free(&options);
av_dump_format(input, 0, "input", 0);
However, av_dump_format anyway writes:
Input #0, mjpeg, from 'input':
Duration: N/A, bitrate: N/A
Stream #0.0: Video: mjpeg, yuvj422p, 704x576, 25 fps, 1200k tbn, 25 tbc
That is, setting framerate to 2 fps had no effect.
However, I've managed to do the same using ffmpeg command line utility.
It writes 2pfs, 2tbr, 1200k tbn, 2 tbc and the resulting videos have correct frame rate.
Here is the full output:
C:\>ffmpeg -y -r 2 -f mjpeg -i "http://192.168.24.62:15555/copy.cgi?tid=10&mts=1317540591000" -vcodec copy cam2.avi
ffmpeg version N-32962-gcbf914c, Copyright (c) 2000-2011 the FFmpeg developers
built on Sep 25 2011 21:37:29 with gcc 4.6.1
configuration: --disable-static --enable-shared --enable-gpl --enable-version3 --enable-runtime-cpudetect --enabl
synth --enable-bzlib --enable-frei0r --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libfreetype --e
-libgsm --enable-libmp3lame --enable-libopenjpeg --enable-librtmp --enable-libschroedinger --enable-libspeex --enab
btheora --enable-libvo-aacenc --enable-libvo-amrwbenc --enable-libvorbis --enable-libvpx --enable-libx264 --enable-
vs --enable-libxvid --enable-zlib
libavutil 51. 17. 0 / 51. 17. 0
libavcodec 53. 17. 0 / 53. 17. 0
libavformat 53. 13. 0 / 53. 13. 0
libavdevice 53. 4. 0 / 53. 4. 0
libavfilter 2. 43. 5 / 2. 43. 5
libswscale 2. 1. 0 / 2. 1. 0
libpostproc 51. 2. 0 / 51. 2. 0
[mjpeg @ 003EA040] max_analyze_duration 5000000 reached at 5000000
[mjpeg @ 003EA040] Estimating duration from bitrate, this may be inaccurate
Input #0, mjpeg, from 'http://192.168.24.62:15555/copy.cgi?tid=10&mts=1317540591000':
Duration: N/A, bitrate: N/A
Stream #0:0: Video: mjpeg, yuvj422p, 704x576, 2 fps, 2 tbr, 1200k tbn, 2 tbc
Output #0, avi, to 'cam2.avi':
Metadata:
ISFT : Lavf53.13.0
Stream #0:0: Video: mjpeg (MJPG / 0x47504A4D), yuvj422p, 704x576, q=2-31, 4 tbn, 4 tbc
Stream mapping:
Stream #0.0 -> #0.0 (copy)
Press [q] to stop, [?] for help
frame= 596 fps=164 q=-1.0 Lsize= 19148kB time=00:04:57.75 bitrate= 526.8kbits/s
video:19115kB audio:0kB global headers:0kB muxing overhead 0.176567%
q3 set rtsp
I'm trying to stream from an Axis ip camera which uses RTSP over HTTP. I can get the normal RTSP stream to work, but I can't find any information or documentation on how to actually set the tunneling mode for the stream. It is supported in the source code by setting the control_transport to RTSP_MODE_TUNNEL . My question is simple how do I do this with the following code?
int ret = avformat_open_input(&pFormatCtx, [@"rtsp://ip/axis-media/media.amp" UTF8String], NULL, NULL);
I tried the following:
pFormatCtx = avformat_alloc_context();
pFormatCtx->priv_data = malloc(sizeof(RTSPState));
RTSPState *rt = pFormatCtx->priv_data;
rt->control_transport = RTSP_MODE_TUNNEL;
int ret = avformat_open_input(&pFormatCtx, [@"rtsp://ip/axis-media/media.amp" UTF8String], NULL, NULL);
But it simply ignores it for me (It still keeps using RTP). I tried this aswell
int ret = avformat_open_input(&pFormatCtx, [@"rtsp://ip/axis-media/media.amp" UTF8String], NULL, NULL);
RTSPState *rt = pFormatCtx->priv_data;
rt->control_transport = RTSP_MODE_TUNNEL;
How would I solve this? I'm thinking it's something really simple since the ENUM is there.
Working solution is
AVDictionary *opts = 0;
int ret = av_dict_set(&opts, "rtsp_transport", "http", 0);
ret = avformat_open_input(&pFormatCtx, [@"rtsp://ip:80/axis-media/media.amp" UTF8String], NULL, &opts);
av_dict_free(&opts);