?? client.cpp
字號:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pthread.h>
#include <SDL/SDL.h>
#include <SDL/SDL_thread.h>
#include <SDL/SDL_timer.h>
#include <linux/videodev.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <fcntl.h>
#include "tcp.h"
#include "rtpsession.h"
#include "rtppacket.h"
#include "rtpudpv4transmitter.h"
#include "rtpipv4address.h"
#include "rtpsessionparams.h"
#include "rtperrors.h"
#include "rtpsourcedata.h"
#include <iostream>
#include <string.h>
#include <stdint.h>
#include <xvid.h>
#include "dxvid.h"
#define BUFFER_SIZE (2*1024*1024)
SDL_Overlay *overlay;
SDL_Rect rect;
int SHXDIM =320;//display size
int SHYDIM =240;
SDL_Surface *screen;
char receivebuffer[1000000];
char *receivepointer = receivebuffer;
bool visiflag = false;
int receivepayloadlength = 0;
int headreceiveflag=0;
RTPUDPv4TransmissionParams transparams;
RTPSessionParams sessparams;
void
checkerror (int rtperr)
{
if (rtperr < 0)
{
std::cout << "ERROR: " << RTPGetErrorString (rtperr) << std::endl;
exit (-1);
}
}
class MyRTPSession:public RTPSession
{
protected:
void OnPollThreadStep ();
int ProcessRTPPacket (const RTPSourceData & srcdat,
const RTPPacket & rtppack);
};
MyRTPSession sess;
void
MyRTPSession::OnPollThreadStep ()
{
BeginDataAccess ();
// check incoming packets
if (GotoFirstSourceWithData ())
{
do
{
RTPPacket *pack;
RTPSourceData *srcdat;
srcdat = GetCurrentSourceInfo ();
while ((pack = GetNextPacket ()) != NULL&&visiflag==false)
{
ProcessRTPPacket (*srcdat, *pack);
delete pack;
}
}
while (GotoNextSourceWithData ());
}
if (visiflag==false) printf(" \n %d",receivepayloadlength);
EndDataAccess ();
}
int
MyRTPSession::ProcessRTPPacket (const RTPSourceData & srcdat,
const RTPPacket & rtppack)
{
int i;
char * payloadpointer = (char *)rtppack.GetPayloadData ();
// You can inspect the packet and the source's info here
std::cout << "Got packet " << rtppack.
GetExtendedSequenceNumber () << " from SSRC " << srcdat.
GetSSRC () << std::endl;
bool packermarker = rtppack.HasMarker ();
if (headreceiveflag==0)
{ if(rtppack.GetPayloadLength ()==50) headreceiveflag=1;
else {printf("error");
return (-1);}
}
if (!packermarker)
{ memcpy(receivepointer,payloadpointer,rtppack.GetPayloadLength ());
//for (i = 0; i < rtppack.GetPayloadLength (); i++)
//*(receivepointer++) = *(payloadpointer++);
receivepointer+=rtppack.GetPayloadLength ();
receivepayloadlength += rtppack.GetPayloadLength ();
visiflag = false;
}
else
{memcpy(receivepointer,payloadpointer,rtppack.GetPayloadLength ());
// for (i = 0; i < rtppack.GetPayloadLength (); i++)
//*(receivepointer++) = *(payloadpointer++);
receivepointer+=rtppack.GetPayloadLength ();
receivepayloadlength += rtppack.GetPayloadLength ();
visiflag = true;headreceiveflag=0;
}
}
struct frame_t{
char header[5];
int nbframe;
double seqtimes;
int deltatimes;
int w;
int h;
int size;
int format;
unsigned short bright;
unsigned short contrast;
unsigned short colors;
unsigned short exposure;
unsigned char wakeup;
int acknowledge;
} __attribute__ ((packed));
int readm4v(int sock, unsigned char **buf,struct frame_t *headerframe,int statOn);
int Client (char *Ip, short port,int owidth, int oheight, int statOn);
static int videoOk = 0;
void init_SDL();
int main(int argc, char *argv[])
{
int statOn = 0;
int owidth = 0;
int oheight = 0;
int i;
uint16_t portbase, destport;
uint32_t destip;
std::string ipstr;
int status;
sessparams.SetOwnTimestampUnit (1.0/90000);
/*********************************/
char *AdIpPort;
char AdIp[]= "000.000.000.000";
unsigned short ports = 0;
/*********************************/
std::cout << "Enter local portbase:" << std::endl;
std::cin >> portbase;
std::cout << std::endl;
transparams.SetPortbase (portbase);
status = sess.Create (sessparams, &transparams);
checkerror (status);
for (i = 1; i < argc; i++) {
/* skip bad arguments */
if (argv[i] == NULL || *argv[i] == 0 || *argv[i] != '-') {
continue;
}
if (strcmp (argv[i], "-w") == 0) {
if (i + 1 >= argc) {
printf ("No parameter specified with -w, aborting.\n");
exit (1);
}
AdIpPort = strdup (argv[i + 1]);
if(reportip(AdIpPort,AdIp,&ports) < 0)
printf("error in port convertion \n");
printf ("using Server %s Port %d \n",AdIp,ports);
}
}
Client(AdIp,ports,owidth,oheight, statOn);
}
int Client (char *Ip, short port,int owidth, int oheight, int statOn)
{
struct frame_t *headerframe;
//struct client_t *messcallback;
unsigned char *buf = NULL;
int width,height;
int jpegsize;
int sock_client;
int run = 1;
int quit =1;
int keypressed =0;
int bpp = 3;
struct tm *tdate;
time_t curdate;
char titre[21];
size_t outbytes;
SDL_Event event;
int fps = 25;
FILE *out;
int used_bytes;
int status;
unsigned char *out_buffer=NULL;
xvid_dec_stats_t xvid_dec_stats;
int bufframenum;
unsigned char *mp4_buffer;
unsigned char *mp4_ptr;
int useful_bytes;
useful_bytes=0;
int i;
int fpsdelay;
uint32_t lastftick;
int paused=0;
int resized=0;
int y;
uint8_t *outy,*outu,*outv,*op[3];
mp4_buffer = (unsigned char *) malloc(BUFFER_SIZE);
if (!mp4_buffer)
goto free_all_memory;
out_buffer = (unsigned char *)malloc(XDIM*YDIM*3/2);
if (!out_buffer)
goto free_all_memory;
init_SDL();
sock_client = open_clientsock(Ip,port);
headerframe=(struct frame_t*)malloc(sizeof(struct frame_t));
status = dec_init(1, 0);
if (status) {
fprintf(stderr,
"Decore INIT problem, return value %d\n", status);
goto release_all;
}
/* set the start frame */
i=0;
fpsdelay=1000/fps;
lastftick=SDL_GetTicks();
do
{
if((useful_bytes = readm4v(sock_client,&buf,headerframe,statOn)) < 0){
printf(" No size !!! exit fatal \n");
goto error;}
mp4_ptr=buf;
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_KEYDOWN:
if (event.key.keysym.sym == SDLK_SPACE)
{
paused=!paused;
break;
}
if (event.key.keysym.sym != SDLK_ESCAPE)
{
goto release_all;
}
case SDL_QUIT:
goto release_all;
}
}
if ((!paused)||(resized))
{
if (((SDL_GetTicks()-lastftick)>fpsdelay)||(resized))
{
lastftick=SDL_GetTicks();
/* This loop is needed to handle VOL/NVOP reading */
do{
/* Decode frame */
used_bytes = dec_main(mp4_ptr, out_buffer, useful_bytes, &xvid_dec_stats);
printf ("the usedbytes is %d\n",used_bytes);
if(xvid_dec_stats.type==XVID_TYPE_VOL
&& (xvid_dec_stats.data.vol.width != XDIM
||xvid_dec_stats.data.vol.height != YDIM))
{printf("panduan\n");
//reallocate bigger out frame
free(out_buffer);
XDIM = xvid_dec_stats.data.vol.width;
YDIM = xvid_dec_stats.data.vol.height;
out_buffer = (unsigned char *) malloc(XDIM*YDIM*3/2);
if (!out_buffer)
goto free_all_memory;
//reallocate bigger yuv overlay
SDL_FreeYUVOverlay(overlay);
overlay = SDL_CreateYUVOverlay(XDIM, YDIM, SDL_YV12_OVERLAY, screen);
if (!overlay)
{
fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError());
exit(4);
}
}
if(used_bytes > 0) {
mp4_ptr += used_bytes;
useful_bytes -= used_bytes;
}
}while (xvid_dec_stats.type <= 0 && useful_bytes > 0);
SDL_LockSurface(screen);
SDL_LockYUVOverlay(overlay);
outy = out_buffer;
outu = out_buffer+XDIM*YDIM;
outv = out_buffer+XDIM*YDIM*5/4;
for(y=0;y<screen->h && y<overlay->h;y++)
{
op[0]=overlay->pixels[0]+overlay->pitches[0]*y;
op[1]=overlay->pixels[1]+overlay->pitches[1]*(y/2);
op[2]=overlay->pixels[2]+overlay->pitches[2]*(y/2);
memcpy(op[0],outy+y*XDIM,XDIM);
if(y%2 == 0)
{
memcpy(op[1],outu+XDIM/2*y/2,XDIM/2);
memcpy(op[2],outv+XDIM/2*y/2,XDIM/2);
}
}
SDL_UnlockYUVOverlay(overlay);
SDL_UnlockSurface(screen);
SDL_DisplayYUVOverlay(overlay, &rect);
if (resized)
resized = 0;
}
}
SDL_Delay(10);
} while (1 );
useful_bytes = 0; /* Empty buffer */
release_all:
if (dec_handle) {
status = dec_stop();
if (status)
fprintf(stderr, "decore RELEASE problem return value %d\n", status);
}
error:
close_sock(sock_client);
free(buf);
free(headerframe);
SDL_Quit ();
free_all_memory:
free(out_buffer);
free(mp4_buffer);
return 0;
}
int readm4v(int sock, unsigned char **buf,struct frame_t *headerframe,int statOn)
{
int byteread,bytewrite;
while (1){
if (visiflag==true ) break;
usleep(10);
}
memcpy(headerframe,receivebuffer,sizeof(struct frame_t));
if(statOn)
printf (" key %s nb %d width %d height %d times %dms size %d \n",headerframe->header,
headerframe->nbframe,headerframe->w,headerframe->h,headerframe->deltatimes,headerframe->size);
if(headerframe->size && !headerframe->wakeup){
//if(headerframe->size){
*buf=(unsigned char*) realloc(*buf,headerframe->size);
memcpy(*buf,receivebuffer+sizeof(struct frame_t),headerframe->size);
/*if((byteread = read_sock(sock,*buf,headerframe->size)) < 0){
printf("Seem server is gone !! try later \n");
goto error;}
*/}
//printf("buf read %d \n",byteread);
if(headerframe->acknowledge)
usleep(5000);
printf("h");
receivepayloadlength = 0;
receivepointer = receivebuffer;
visiflag=false;
return ((headerframe->wakeup)?0:(headerframe->size));
//return (headerframe->size);
error:
return -1;
}
void init_SDL()
{
if (SDL_Init (SDL_INIT_VIDEO) < 0)
{ videoOk=0;
fprintf (stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
exit (1);
}
videoOk=1;
atexit (SDL_Quit);
screen = SDL_SetVideoMode (320, 240, 0, SDL_HWSURFACE
| SDL_DOUBLEBUF
| SDL_ANYFORMAT
| SDL_RESIZABLE);
if (screen == NULL)
{
fprintf(stderr, "Couldn't set video mode: %s\n", SDL_GetError());
exit(2);
}
if (0 == screen->flags & SDL_HWSURFACE)
{
fprintf(stderr,"Can't get hardware surface\n");
exit(3);
}
SDL_WM_SetCaption ("SDL MultiMedia Application", NULL);
overlay = SDL_CreateYUVOverlay(XDIM, YDIM, SDL_YV12_OVERLAY, screen);
if (!overlay)
{
fprintf(stderr, "Couldn't create overlay: %s\n", SDL_GetError());
exit(4);
}
//show the overlay status
printf("Created %dx%dx%d %s %s overlay\n",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;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -