[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