Reputation: 1058
I am using libav to parsing a MJPEG Stream to get the packet data for resending it over an websocket, now I am facing the issue that ffmpeg use only 25 FPS. I know the Stream has 60FPS for 100%
These are the values after open and read the stream Informations:
avg_frame_rate = 0, r_frame_rate = 25/1, time_base = 1/25
I tried to set all of them to a setting for 60FPS, but this looks has no effect. I have set time_base to 1/60 and also frame rates to 60 but none of them are making any difference.
Because its an MJPEG Stream libav needs to guess the framerate, but I don't know why setting time_base or framerate does not have any effect.
Maybe someone could help me how I could force 60 FPS for parsing an MJEPG Stream, this would be great.
Thank u
This is just an Illustration of my code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <libavutil/avutil.h>
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
int main(int argc, char *argv[]) {
AVFormatContext *fmt_ctx = NULL;
AVCodecContext *codec_ctx = NULL;
AVCodec *codec = NULL;
AVPacket pkt;
if (argc < 2) {
fprintf(stderr, "Usage: %s <mjpeg-stream-url>\n", argv[0]);
exit(1);
}
av_register_all();
if (avformat_open_input(&fmt_ctx, argv[1], NULL, NULL) < 0) {
fprintf(stderr, "Could not open stream '%s'\n", argv[1]);
exit(1);
}
if (avformat_find_stream_info(fmt_ctx, NULL) < 0) {
fprintf(stderr, "Could not find stream information\n");
exit(1);
}
int video_stream_index = av_find_best_stream(fmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &codec, 0);
if (video_stream_index < 0) {
fprintf(stderr, "Could not find video stream\n");
exit(1);
}
AVStream *video_stream = fmt_ctx->streams[video_stream_index];
stream->time_base = (AVRational) { 1, 60};
stream->avg_frame_rate = (AVRational) { 60, 1 };
stream->r_frame_rate = (AVRational) { 60, 1 };
av_init_packet(&pkt);
while (av_read_frame(fmt_ctx, &pkt) >= 0) {
if (pkt.stream_index == video_stream_index) {
// Sending it to an websocket ....
}
av_packet_unref(&pkt);
}
avformat_close_input(&fmt_ctx);
avformat_free_context(fmt_ctx);
return 0;
}
Upvotes: 0
Views: 538
Reputation: 111
The AVDictionary
sets additional/specific parameters to endpoints and if you call it while opening the endpoint, it uses these specific parameters to open the endpoint.
It could take multiple key - value
pairs and applies all of them to the endpoint.
I suppose creating an AVDictionay
and passing a "framerate", "60"
or may be "framerate" "60000/1000"
parameter could solve your problem. Or if your source supports format_code then you could also use the format code something like "format_code", "Hp60"
in the AVDictionary
.
AVDictionary *options{nullptr};
// You should find the right parameter name
// like "frame_rate", "format_code", "sample_rate" etc.
// You can also set multiple options there!
// you may put all the possibilities once!
if(av_dict_set(&options, "framerate", "60", 0) < 0) {
fprintf(stderr, "Could not set the option!\n");
exit(1);
}
if (avformat_open_input(&fmt_ctx, argv[1], NULL, &options) < 0) {
fprintf(stderr, "Could not open stream '%s'\n", argv[1]);
exit(1);
}
Upvotes: 0