This article uses the compiled library file from the previous section http://www.cnblogs.com/wenjingu/p/3977015.html to get the h464 bare stream on the network and save it to the MP4 file via RTSP.
1, VS2010 set up VC + + Win32 Console Project
2, in the project directory to establish the Lib directory and include directory, will have been compiled Lib torture lib, include copy to include, DLL copied to the debug directory
3, Project Properties--Configuration Properties--vc++ Directory--Include directory, add ffmpeg header file directory and other third party header files directory
Linker--general--Attach library directory, add Lib directory
Linker--input--additional dependencies, adding individual lib names
4, Design and implementation:
4.1 Design ideas:
Components and network initialization--open network flow--Get network flow information--Initialize output stream information based on network flow information--Create and open MP4 file--write MP4 file header
--Loop through the input stream and write to the MP4 file--Write a file--close the stream, close the file
4.2 Key Data Structures:
Avformatcontext,avstream,avcodeccontext,avpacket,avframe and so on, their relationship is explained as follows:
A avformatcontext contains multiple avstream, each containing AVCODEC and avcodeccontext,avpicture as a subset of Avframe,
They are all the data streams used to hold data caches in the image, the data read from the data stream is first stored in the Avpacket, or can be understood as a avpacket a maximum of only one avframe,
And a avframe may contain several avpacket,avpacket that are the concept of data flow subcontracting.
4.3 Key functions:
int Avformat_open_input (Avformatcontext **ps, const char *filename, Avinputformat *fmt, avdictionary **options); Open a network stream or file stream
int Avformat_write_header (Avformatcontext *s, avdictionary **options);//write the file header in the appropriate format according to the suffix of the file name
int Av_read_frame (Avformatcontext *s, Avpacket *pkt);//Read a sub-package from the input stream
int Av_interleaved_write_frame (Avformatcontext *s, Avpacket *pkt);//write a sub-package to the output stream
int Av_write_trailer (Avformatcontext *s);//write output stream (file) end of file
4.4 Code:
View Sourceprint?
001. #include "stdafx.h"
002.
003. #ifdef __cplusplus
004.extern "C" {
005. #endif
006.
007. #include <libavcodec/avcodec.h>
008. #include <libavdevice/avdevice.h>
009. #include <libavformat/avformat.h>
010. #include <libavfilter/avfilter.h>
011. #include <libavutil/avutil.h>
012. #include <libswscale/swscale.h>
013.
014. #include <stdlib.h>
015. #include <stdio.h>
016. #include <string.h>
017. #include <math.h>
018.
019. #ifdef __cplusplus
020.}
021. #endif
022.
023.AVFormatContext *i_fmt_ctx;
024.AVStream *i_video_stream;
025.
026.AVFormatContext *o_fmt_ctx;
027.AVStream *o_video_stream;
028.
029.int _tmain (int argc, char **argv)
030.{
031.avcodec_register_all ();
032.av_register_all ();
033.avformat_network_init ();
034.
035./* should set to NULL so that avformat_open_input () allocate a new one */
036.i_fmt_ctx = NULL;
037.char rtspurl[] = "Rtsp://admin:[email protected]:554";
038.const char *filename = "1.mp4";
039.if (Avformat_open_input (&i_fmt_ctx, rtspurl, NULL, NULL)!=0)
040.{
041.fprintf (stderr, "could not open input file\n");
042.return-1;
043.}
044.
045.if (Avformat_find_stream_info (I_fmt_ctx, NULL) <0)
046.{
047.fprintf (stderr, "could not find stream info\n");
048.return-1;
049.}
050.
051.//av_dump_format (i_fmt_ctx, 0, argv[1], 0);
052.
053./* Find First Video stream */
054.for (unsigned i=0; i<i_fmt_ctx->nb_streams; i++)
055.{
056.if (I_fmt_ctx->streams[i]->codec->codec_type = = Avmedia_type_video)
057.{
058.i_video_stream = i_fmt_ctx->streams[i];
059.break;
060.}
061.}
062.if (I_video_stream = = NULL)
063.{
064.fprintf (stderr, "didn ' t find any video stream\n");
065.return-1;
066.}
067.
068.AVFORMAT_ALLOC_OUTPUT_CONTEXT2 (&O_FMT_CTX, NULL, NULL, filename);
069.
070./*
071.* since all input files is supposed to be identical (framerate, dimension, color format, ...)
072.* we can safely set output codec values from first input file
073.*/
074.o_video_stream = Avformat_new_stream (O_fmt_ctx, NULL);
075.{
076.AVCodecContext *c;
077.C = o_video_stream->codec;
078.c->bit_rate = 400000;
079.c->codec_id = i_video_stream->codec->codec_id;
080.c->codec_type = i_video_stream->codec->codec_type;
081.c->time_base.num = i_video_stream->time_base.num;
082.c->time_base.den = i_video_stream->time_base.den;
083.fprintf (stderr, "time_base.num =%d Time_base.den =%d\n", C->time_base.num, C->time_base.den);
084.c->width = i_video_stream->codec->width;
085.c->height = i_video_stream->codec->height;
086.C->PIX_FMT = i_video_stream->codec->pix_fmt;
087.printf ("%d%d%d", C->width, C->height, c->pix_fmt);
088.c->flags = i_video_stream->codec->flags;
089.c->flags |= Codec_flag_global_header;
090.c->me_range = i_video_stream->codec->me_range;
091.c->max_qdiff = i_video_stream->codec->max_qdiff;
092.
093.c->qmin = i_video_stream->codec->qmin;
094.c->qmax = i_video_stream->codec->qmax;
095.
096.c->qcompress = i_video_stream->codec->qcompress;
097.}
098.
099.avio_open (&O_FMT_CTX->PB, filename, avio_flag_write);
100.
101.avformat_write_header (O_fmt_ctx, NULL);
102.
103.int last_pts = 0;
104.int Last_dts = 0;
105.
106.int64_t pts, DTS;
107.while (1)
108.{
109.AVPacket i_pkt;
110.av_init_packet (&I_PKT);
111.i_pkt.size = 0;
112.i_pkt.data = NULL;
113.if (Av_read_frame (I_fmt_ctx, &I_PKT) <0)
114.break;
115./*
116.* pts and DTS should increase monotonically
117.* pts should be >= DTS
118.*/
119.i_pkt.flags |= Av_pkt_flag_key;
120.pts = i_pkt.pts;
121.i_pkt.pts + = last_pts;
122.dts = I_pkt.dts;
123.i_pkt.dts + = Last_dts;
124.i_pkt.stream_index = 0;
125.
126.//printf ("%lld%lld\n", i_pkt.pts, I_pkt.dts);
127.static int num = 1;
128.printf ("Frame%d\n", num++);
129.av_interleaved_write_frame (O_fmt_ctx, &I_PKT);
130.//av_free_packet (&I_PKT);
131.//av_init_packet (&I_PKT);
132.}
133.last_dts + = DTS;
134.last_pts + = pts;
135.
136.avformat_close_input (&I_FMT_CTX);
137.
138.av_write_trailer (O_FMT_CTX);
139.
140.avcodec_close (O_FMT_CTX->STREAMS[0]->CODEC);
141.av_freep (&O_FMT_CTX->STREAMS[0]->CODEC);
142.av_freep (&o_fmt_ctx->streams[0]);
143.
144.avio_close (O_FMT_CTX->PB);
145.av_free (O_FMT_CTX);
146.
147.return 0;
148.}
5. Testing
such as the printed result of the program in the stored procedure. The generated MP4 file can be played with any player that supports that format.
Go: FFmpeg Learning (ii) get H264 bare stream through RTSP and save to MP4 file