avformat_open_input using custom AVDictionary to set parameter

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);





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值