本文来自:
http://blog.chinaunix.net/uid-23093301-id-86409.html
#include "SDL.h" /* All SDL App's need this */
#include
#include
#include
using namespace std;
#include
#include "decoder.h"
#include "encoder.h"
#include "log.h"
#include "rtp_receive.h"
#include "singleton.h"
int base_port = 5000;
const string dest_host = "192.168.1.6";
const int dest_port = 6000;
SDL_Surface *screen;
SDL_Overlay *overlay;
SDL_Event event;
SDL_Rect rect;
const int WIDTH = 640;
const int HEIGHT = 480;
static int XDIM=640,YDIM=480;
int SHXDIM =640;//display size
int SHYDIM =480;
int paused=0;
int resized=0;
AVFrame pict;
//AVPicture pict;
CDecoder aDecoder;
CEncoder aEncoder("target.mp4",WIDTH,HEIGHT);
CEncoder aRawEncoder("target.avi",WIDTH,HEIGHT);
int ret;
AVFrame* mainFrame;
AVFrame* rawFrame;
FILE* ftrRawDta;
void show_rtp_pict()
{
string rtp_data;
SDL_LockSurface(screen);
SDL_LockYUVOverlay(overlay);
pict.data[0] = overlay->pixels[0];
pict.data[1] = overlay->pixels[2];
pict.data[2] = overlay->pixels[1];
pict.linesize[0] = overlay->pitches[0];
pict.linesize[1] = overlay->pitches[2];
pict.linesize[2] = overlay->pitches[1];
//cout << "begin to read...
";
rtp_data = singleton::instance().pop_frame();
fwrite(rtp_data.data(),rtp_data.size(),1,ftrRawDta);
if(rtp_data.size()<6000)
{
cout << "begin to read size="<goto end;
}
aDecoder.push_frame((void*)rtp_data.data(),rtp_data.size());
//cin >> cmd;
ret = aDecoder.try_show(&pict,640,480,mainFrame,rawFrame);
if(ret<0) goto end;
//ret = aDecoder.try_show(mainFrame,640,480);
//if(ret<0) goto end;
//cin >> cmd;
//if(num!=0)continue;
aEncoder.try_encode(mainFrame);
aRawEncoder.try_encode(rawFrame);
end:
SDL_UnlockYUVOverlay(overlay);
SDL_UnlockSurface(screen);
SDL_DisplayYUVOverlay(overlay, &rect);
}
int main(int argc, char *argv[]) {
if(argc>1)
base_port = atoi(argv[1]);
cout <<"RTP info:
"
<<" RTP base port:"<<<" RTP dest host:"<<<" RTP dest port:"<<<"
";
cout <<"SDL info:
"
<<" SDL window width:640
"
<<" SDL windor height:480
"
<<"
";
cout <<"FFMPEG info:
"
<<" output filename:target.mp4
"
<<" encoder:H264
"
<<"
";
cout <<"main begin base port="<singleton::instance().start(base_port,dest_host,dest_port);
mainFrame = aDecoder.do_alloc_picture(PIX_FMT_YUV420P,WIDTH,HEIGHT);
rawFrame = aDecoder.do_alloc_picture(PIX_FMT_YUV420P,WIDTH,HEIGHT);
const char* rawdata_filename = "rawdata.mpeg";
ftrRawDta = fopen(rawdata_filename,"wb");
if(ftrRawDta == NULL)
{
cout <<"main con't open="<exit(1);
}
sleep(1);
printf("Initializing SDL.
");
/* Initialize defaults, Video and Audio */
if((SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO| SDL_INIT_TIMER)==-1)) {
printf("Could not initialize SDL: %s.
", SDL_GetError());
exit(-1);
}
atexit (SDL_Quit);
printf("SDL initialized.
");
screen = SDL_SetVideoMode (WIDTH, HEIGHT, 0, SDL_HWSURFACE
| SDL_DOUBLEBUF
| SDL_ANYFORMAT
| SDL_RESIZABLE);
if (screen == NULL)
{
fprintf(stderr, "SDL_SetVideoMode ==>> %s
", SDL_GetError());
goto fatal;
}
if (0 == (screen->flags & SDL_HWSURFACE))
{
fprintf(stderr,"Can't get hardware surface
");
}
SDL_WM_SetCaption ("USB Camera By Breeze", NULL);
overlay = SDL_CreateYUVOverlay(XDIM, YDIM, SDL_YV12_OVERLAY, screen);
if (!overlay)
{
fprintf(stderr, "Couldn't create overlay: %s
", SDL_GetError());
exit(4);
}
printf("SDL_CreateYUVOverlay info: %dx%dx%d %s %s overlay
",overlay->w,overlay->h,overlay->planes,
overlay->hw_overlay?"hardware":"software",
overlay->format==SDL_YV12_OVERLAY?"YV12":
overlay->format==SDL_IYUV_OVERLAY?"IYUV":
overlay->format==SDL_YUY2_OVERLAY?"YUY2":
overlay->format==SDL_UYVY_OVERLAY?"UYVY":
overlay->format==SDL_YVYU_OVERLAY?"YVYU":
"Unknown");
rect.x=0;
rect.y=0;
rect.w=SHXDIM;
rect.h=SHYDIM;
do{
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_VIDEORESIZE:
{
screen=SDL_SetVideoMode(event.resize.w, event.resize.h, 0, SDL_RESIZABLE | SDL_SWSURFACE);
rect.w=event.resize.w;
rect.h=event.resize.h;
if (paused)
{
resized=1;
}
}break;
case SDL_QUIT:
{
aEncoder.finish_coder();
fclose(ftrRawDta);
goto release_all;
}break;
}//! end switch
}//! end while (SDL_PollEvent(&event))
show_rtp_pict();
SDL_Delay(10);//! delay 1 ms
//!printf("Wvent Poll.
");
}while(1);
//cin >>cmd;
printf("Quiting SDL.
");
release_all:
printf("Quiting....
");
exit(0);
fatal:
printf("fatal!!,exit
");
return -1;;
}