liveMedia/H263plusVideoRTPSink.cpp

Go to the documentation of this file.
00001 /**********
00002 This library is free software; you can redistribute it and/or modify it under
00003 the terms of the GNU Lesser General Public License as published by the
00004 Free Software Foundation; either version 2.1 of the License, or (at your
00005 option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
00006 
00007 This library is distributed in the hope that it will be useful, but WITHOUT
00008 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00009 FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
00010 more details.
00011 
00012 You should have received a copy of the GNU Lesser General Public License
00013 along with this library; if not, write to the Free Software Foundation, Inc.,
00014 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
00015 **********/
00016 // "liveMedia"
00017 // Copyright (c) 1996-2013 Live Networks, Inc.  All rights reserved.
00018 // RTP sink for H.263+ video (RFC 4629)
00019 // Implementation
00020 
00021 #include "H263plusVideoRTPSink.hh"
00022 
00023 H263plusVideoRTPSink
00024 ::H263plusVideoRTPSink(UsageEnvironment& env, Groupsock* RTPgs,
00025                        unsigned char rtpPayloadFormat,
00026                        u_int32_t rtpTimestampFrequency)
00027   : VideoRTPSink(env, RTPgs, rtpPayloadFormat, rtpTimestampFrequency, "H263-1998") {
00028 }
00029 
00030 H263plusVideoRTPSink::~H263plusVideoRTPSink() {
00031 }
00032 
00033 H263plusVideoRTPSink*
00034 H263plusVideoRTPSink::createNew(UsageEnvironment& env, Groupsock* RTPgs,
00035                                 unsigned char rtpPayloadFormat,
00036                                 u_int32_t rtpTimestampFrequency) {
00037   return new H263plusVideoRTPSink(env, RTPgs, rtpPayloadFormat, rtpTimestampFrequency);
00038 }
00039 
00040 Boolean H263plusVideoRTPSink
00041 ::frameCanAppearAfterPacketStart(unsigned char const* /*frameStart*/,
00042                                  unsigned /*numBytesInFrame*/) const {
00043   // A packet can contain only one frame
00044   return False;
00045 }
00046 
00047 void H263plusVideoRTPSink
00048 ::doSpecialFrameHandling(unsigned fragmentationOffset,
00049                          unsigned char* frameStart,
00050                          unsigned numBytesInFrame,
00051                          struct timeval framePresentationTime,
00052                          unsigned numRemainingBytes) {
00053   if (fragmentationOffset == 0) {
00054     // This packet contains the first (or only) fragment of the frame.
00055     // Set the 'P' bit in the special header:
00056     unsigned short specialHeader = 0x0400;
00057 
00058     // Also, reuse the first two bytes of the payload for this special
00059     // header.  (They should both have been zero.)
00060     if (numBytesInFrame < 2) {
00061       envir() << "H263plusVideoRTPSink::doSpecialFrameHandling(): bad frame size "
00062               << numBytesInFrame << "\n";
00063       return;
00064     }
00065     if (frameStart[0] != 0 || frameStart[1] != 0) {
00066       envir() << "H263plusVideoRTPSink::doSpecialFrameHandling(): unexpected non-zero first two bytes: "
00067               << (void*)(frameStart[0]) << "," << (void*)(frameStart[1]) << "\n";
00068     }
00069     frameStart[0] = specialHeader>>8;
00070     frameStart[1] = (unsigned char)specialHeader;
00071   } else {
00072     unsigned short specialHeader = 0;
00073     setSpecialHeaderBytes((unsigned char*)&specialHeader, 2);
00074   }
00075 
00076   if (numRemainingBytes == 0) {
00077     // This packet contains the last (or only) fragment of the frame.
00078     // Set the RTP 'M' ('marker') bit:
00079     setMarkerBit();
00080   }
00081 
00082   // Also set the RTP timestamp:
00083   setTimestamp(framePresentationTime);
00084 }
00085 
00086 
00087 unsigned H263plusVideoRTPSink::specialHeaderSize() const {
00088   // There's a 2-byte special video header.  However, if we're the first
00089   // (or only) fragment of a frame, then we reuse the first 2 bytes of
00090   // the payload instead.
00091   return (curFragmentationOffset() == 0) ? 0 : 2;
00092 }

Generated on Mon Apr 29 13:28:01 2013 for live by  doxygen 1.5.2