[Libav-user] FFMPEG RTSP streaming in C
Xiemin Chen
chenxiemin at gmail.com
Wed Jul 30 05:45:53 CEST 2014
I think you could refer to the following tutorial1 with ffmpeg 2.2.1.
Thanks.
https://github.com/chelyaev/ffmpeg-tutorial
2014-07-30 9:48 GMT+08:00 Neerav Patel <neeravpatel at hotmail.com>:
> Hi
>
> I am attempting to stream my webcam via rtsp to VLC on another PC, I know
> it is possible with ffmpeg, but there is no documentation etc. that I could
> find to help with this.
>
> Any help would be greatly appreciated!
>
> Neerav
>
> I am trying to do the following:
>
> AVFormatContext *oc;
> const char *filename = "rtsp://127.0.0.1:8554/test";
>
> avformat_alloc_output_context2(&oc, NULL, "rtsp", NULL);
>
> if (!oc) {
> printf("Could not deduce output format from file extension: using
> MPEG.\n");
> avformat_alloc_output_context2(&oc, NULL, "mpeg", filename);
> }
>
> AVOutputFormat *fmt;
> AVStream *video_st;
> AVCodec *video_codec;
> fmt = oc->oformat;
>
> int out_codec = fmt->video_codec;
> video_st = add_stream(oc, &video_codec, fmt->video_codec);
>
> open_video(oc, video_codec, video_st);
>
> char errorBuff[80];
>
> if (!(fmt->flags & AVFMT_NOFILE)) {
> <------------------------------------ IT NEVER GOES INTO THIS DUE TO THIS
> CONDITION FAILING
> int ret = avio_open(&oc->pb, filename, AVIO_FLAG_WRITE);
> if (ret < 0) {
> fprintf(stderr, "Could not open outfile '%s':
> %s",filename,av_make_error_string(errorBuff,80,ret));
> return 1;
> }
> }
>
>
> // -------------------------------------------
>
> add_stream and open_video functions
>
> static AVStream *add_stream(AVFormatContext *oc, AVCodec **codec,
> enum AVCodecID codec_id)
> {
> AVCodecContext *c;
> AVStream *st;
>
> /* find the encoder */
> *codec = avcodec_find_encoder(codec_id);
> if (!(*codec)) {
> fprintf(stderr, "Could not find encoder for '%s'\n",
> avcodec_get_name(codec_id));
> exit(1);
> }
>
> st = avformat_new_stream(oc, *codec);
> if (!st) {
> fprintf(stderr, "Could not allocate stream\n");
> exit(1);
> }
> st->id = oc->nb_streams-1;
> c = st->codec;
>
> switch ((*codec)->type) {
> case AVMEDIA_TYPE_AUDIO:
> c->sample_fmt = (*codec)->sample_fmts ?
> (*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
> c->bit_rate = 64000;
> c->sample_rate = 44100;
> c->channels = 2;
> break;
>
> case AVMEDIA_TYPE_VIDEO:
> c->codec_id = codec_id;
> if(codec_id == CODEC_ID_H264)
> printf("Codec ID %x", (AVCodecID)codec_id);
> c->bit_rate = 400000;
> /* Resolution must be a multiple of two. */
> c->width = 320*5;
> c->height = 720;
> /* timebase: This is the fundamental unit of time (in seconds) in
> terms
> * of which frame timestamps are represented. For fixed-fps
> content,
> * timebase should be 1/framerate and timestamp increments should
> be
> * identical to 1. */
> c->time_base.den = 25;
> c->time_base.num = 1;
> c->gop_size = 12; /* emit one intra frame every twelve frames
> at most */
> c->pix_fmt = AV_PIX_FMT_YUV420P;
> if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
> /* just for testing, we also add B frames */
> c->max_b_frames = 2;
> }
> if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
> /* Needed to avoid using macroblocks in which some coeffs
> overflow.
> * This does not happen with normal video, it just happens
> here as
> * the motion of the chroma plane does not match the luma
> plane. */
> c->mb_decision = 2;
> }
> break;
>
> default:
> break;
> }
>
> /* Some formats want stream headers to be separate. */
> if (oc->oformat->flags & AVFMT_GLOBALHEADER)
> c->flags |= CODEC_FLAG_GLOBAL_HEADER;
>
> return st;
> }
>
> static AVFrame *frame;
> static AVPicture src_picture, dst_picture;
>
> static void open_video(AVFormatContext *oc, AVCodec *codec, AVStream *st)
> {
> int ret;
> AVCodecContext *c = st->codec;
>
> /* open the codec */
> ret = avcodec_open2(c, codec, NULL);
> if (ret < 0) {
> fprintf(stderr, "Could not open video codec: ");
> exit(1);
> }
>
> /* allocate and init a re-usable frame */
> frame = av_frame_alloc();
> if (!frame) {
> fprintf(stderr, "Could not allocate video frame\n");
> exit(1);
> }
> frame->format = c->pix_fmt;
> frame->width = c->width;
> frame->height = c->height;
>
> /* Allocate the encoded raw picture. */
> ret = avpicture_alloc(&dst_picture, c->pix_fmt, c->width, c->height);
> if (ret < 0) {
> fprintf(stderr, "Could not allocate picture: ");
> exit(1);
> }
>
> /* If the output format is not YUV420P, then a temporary YUV420P
> * picture is needed too. It is then converted to the required
> * output format. */
> if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
> ret = avpicture_alloc(&src_picture, AV_PIX_FMT_YUV420P, c->width,
> c->height);
> if (ret < 0) {
> fprintf(stderr, "Could not allocate temporary picture:");
> exit(1);
> }
> }
>
> /* copy data and linesize picture pointers to frame */
> *((AVPicture *)frame) = dst_picture;
> }
>
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/libav-user
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20140730/00db5ef3/attachment.html>
More information about the Libav-user
mailing list