#include #include #include #include #include #include #include "frame.c" #include "picinfo.h" #include "decoder.h" #include "global.h" #include "video_common.h" #include "rtp.h" Decoder::Decoder():Thread() { n_xn = n_xmcn1 = n_xpn1 = 0; p = 0; picformat = NULL_FORMAT; } Decoder::~Decoder() { fprintf(stderr, "n_xn %x xmcn1 %x npn1 %x\n", n_xn, n_xmcn1, n_xpn1); // delete n_xn; delete n_xmcn1; delete n_xpn1;// delete p; // Base class destructor is automatically called } void Decoder::init_decoder(frformat_t &format, int sockfd, Widget toplevel, Widget picW) { if( memcmp(&picformat, &format,sizeof(picformat))) { fprintf(stderr, "initing decoder\n"); delete n_xn; delete n_xmcn1; delete n_xpn1; delete p; picformat = format; n_xn = new Frame(picformat.rows, picformat.cols); n_xmcn1 = new Frame(picformat.rows, picformat.cols); n_xpn1 = new Frame(picformat.rows, picformat.cols); p = new PicInfo( picformat ); } fprintf(stderr, "n_xn %x xmcn1 %x npn1 %x\n", n_xn, n_xmcn1, n_xpn1); rx_fd = sockfd; init_display(toplevel, picW, picformat.cols, picformat.rows); } void Decoder::cleanup(void) { finish_display(); } #define RCVBUF_SZ 8192 static u_char recv_buf[RCVBUF_SZ]; void Decoder::Run(void) { int i = 0; int hdrlen = sizeof(rtp_hdr_t) + sizeof(h261_hdr_t); int sbits = 0, ebits = 0; int rc = 0; rtp_hdr_t rtphdr; h261_hdr_t h261hdr; u_short curr_seqno = 0; while(1) { int startgb =0, startmb = 0; tryagain: rc = recv(rx_fd, recv_buf, RCVBUF_SZ, 0); if(rc < 0) { perror("recv "); return; } /* Check sequence number Check for old frames do new startmb and startgb if lost packets are found */ get_rtphdr(recv_buf, &rtphdr); get_h261hdr(recv_buf + H261HDR_OFFSET, &h261hdr); sbits = h261hdr.sbit; ebits = h261hdr.ebit; if(curr_seqno+1 != rtphdr.seq) { fprintf(stderr, "Missing seq %d %d\n", curr_seqno, rtphdr.seq); /* Do error recovery */ /* Find gob and mb */ if(h261hdr.i) startmb = 0; else startmb = h261hdr.mbap + 1; startgb = h261hdr.gobn; } curr_seqno = rtphdr.seq; p->input.attach_rbuf(recv_buf + hdrlen, (rc-hdrlen) * 8 - ebits ); for(int k=0; k < sbits; k++) p->input.read_bit(); try { read_picture(p, n_xn, n_xpn1, n_xmcn1, startgb, startmb); } catch (PicException_t X) { if(X.type == END_OF_PKT) { startmb = X.mbnum; startgb = X.gbnum; if(p->frameformat.type == QCIF_TYPE) startgb = startgb / 2; if(startgb < p->frameformat.numgbs) goto tryagain; } else { fprintf(stderr, "%s ***** rcvd exception %d\n", __PRETTY_FUNCTION__, X.type); return; } } render_image(n_xn->Getydata(), n_xn->Getudata(), n_xn->Getvdata(), n_xn->GetCols(), n_xn->GetRows()); write(1, ".", 1); display_image(False); i++; } }