stagefright里发送264+AMR的完整代码-2-01

stagefright里发送264+AMR的完整代码-1
stagefright里发送264+AMR的完整代码-2-1   这里补充  RFC3984Writer.cpp 的源码

#define LOG_TAG "RFC3984Writer"
#include

#include

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define PT         96
#define PT_STR   "96"
#define PT_AMR 97
#define PT_AMR_STR "97"
#define NAL_START_CODE_SIZE 4
static const size_t kMaxPacketSize = 1500;
static const uint32_t kRTP_SSRC = 21239876;
namespace android {

class RFC3984Writer::Track {
public:
      Track(RFC3984Writer *owner, const sp &source, size_t trackId);

      ~Track();

      status_t start(MetaData *params);
      status_t stop();
      status_t pause();
      bool reachedEOS();

      int64_t getDurationUs() const;
      bool isAvc() const { return mIsAvc; }
      bool isAudio() const { return mIsAudio; }
      int32_t getTrackId() const { return mTrackId; }
    
private:
      RFC3984Writer *mOwner;
      sp mMeta;
      sp mSource;
      volatile bool mDone;
      volatile bool mPaused;
      volatile bool mResumed;
      volatile bool mStarted;
      bool mIsAvc;
      bool mIsAudio;
      int32_t mTrackId;
      int64_t mTrackDurationUs;

      pthread_t mThread;

int64_t mStartTimestampUs;
      int64_t mStartTimeRealUs;
int mSampleRate;
int mChannelCount;
      int mNumRTPSent;
uint32_t mRTPTimeBase;
uint32_t m_nPort;
Rfc3984Context *m_packer;
SessionSet *m_pSessionSet;
RtpSession *m_Session;
MSQueue m_RFC3984queue;
unsigned int m_nUser_Timestamp;
    
     bool mReachedEOS;

        enum {
            INVALID,
            H264,
            H263,
            AMR_NB,
            AMR_WB,
AAC_RAW, //not LATM,ADTS
      } mMode;
      enum {
            kAdtsHeaderLength = 7,       // # of bytes for the adts header
            kSamplesPerFrame   = 1024,   // # of samples in a frame
};
      static void *ThreadWrapper(void *me);
      status_t threadEntry();

void sendAVCData(MediaBuffer *mediaBuf,const sp &meta_data);
void sendAMRData(MediaBuffer *mediaBuf,const sp &meta_data) ;
void sendAACData(MediaBuffer *mediaBuf,const sp &meta_data) ;
status_t writeAdtsHeader(uint32_t frameLength,uint8_t header[7]);
      Track(const Track &);
      Track &operator=(const Track &);
};

RFC3984Writer::Track::Track(
            RFC3984Writer *owner, const sp &source, size_t trackId)
      : mOwner(owner),
         mMeta(source->getFormat()),
         mSource(source),
         mDone(false),
         mPaused(false),
         mResumed(false),
         mStarted(false),
         mTrackId(trackId),
  mRTPTimeBase(0),
  mNumRTPSent(0),
  m_nPort(1234),
  m_nUser_Timestamp(0),
  mSampleRate(44100),
  mChannelCount(2),
         mReachedEOS(false){
      
      const char *mime;
LOGD("RFC3984Writer::Track::Track +++");
      mMeta->findCString(kKeyMIMEType, &mime);
      mIsAvc = !strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC);
      mIsAudio = !strncasecmp(mime, "audio/", 6);
if( mIsAudio )
{
CHECK(mMeta->findInt32(kKeyChannelCount, &mChannelCount));
CHECK(mMeta->findInt32(kKeySampleRate, &mSampleRate));

}
LOGD("RFC3984Writer::Track::Track ---");
}

RFC3984Writer::Track::~Track() {
LOGD("RFC3984Writer::Track::~Track +++");
      stop();
LOGD("RFC3984Writer::Track::~Track ---");
}

status_t RFC3984Writer::Track::start(MetaData *params) {
      if (!mDone && mPaused) {
            mPaused = false;
            mResumed = true;
            return OK;
      }

      int64_t startTimeUs;
      if (params == NULL || !params->findInt64(kKeyTime, &startTimeUs)) {
            startTimeUs = 0;
      }
      mStartTimeRealUs = startTimeUs;
LOGD("RFC3984Writer::Track::start +++");
      LOGD("RFC3984Writer::Track::start %s track", mIsAvc? "Video":"Audio");

const char *mime;
      CHECK(mSource->getFormat()->findCString(kKeyMIMEType, &mime));

      
      status_t err = mSource->start();
      if (err != OK) {
            mDone = mReachedEOS = true;
LOGD("RFC3984Writer::Track::start 001 ---");
            return err;
      }

if( mIsAvc )
{
//rfc3984 init +++
m_packer=rfc3984_new();
rfc3984_set_mode(m_packer,1); //mode 1
rfc3984_enable_stap_a(m_packer,FALSE);
}
//rfc3984 init ---

LOGD("==> Scheduler initialized\n");
if( mIsAvc )
{
rtp_profile_set_payload(&av_profile,96,&payload_type_h264); //set 264 playload type 
m_nPort = 1234;
}
else
{//AMR
if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_NB)) 
{
rtp_profile_set_payload(&av_profile,PT_AMR,&payload_type_amr); //set amr type
mMode = AMR_NB;
else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AMR_WB)) 
{
rtp_profile_set_payload(&av_profile,PT_AMR,&payload_type_amrwb);
mMode = AMR_WB;
else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) 
{
//rtp_profile_set_payload(&av_profile,PT_AMR,&payload_type_amrwb);
mMode = AAC_RAW;
m_nPort = 1236;
}
m_Session = rtp_session_new(RTP_SESSION_SENDONLY);
rtp_session_set_scheduling_mode(m_Session,1);
rtp_session_set_blocking_mode(m_Session,0);
rtp_session_set_remote_addr(m_Session,"192.168.1.5", m_nPort);
//rtp_session_set_remote_addr(m_Session,"255.255.255.255", m_nPort);
if( mIsAvc )
{
rtp_session_set_send_payload_type(m_Session,96); //96 is h.264
rtp_session_enable_rtcp(m_Session,true);
}
else
{
rtp_session_set_send_payload_type(m_Session,PT_AMR); //97 is amr
rtp_session_enable_rtcp(m_Session,true);
}
//rtp_session_set_ssrc(m_Session,kRTP_SSRC);
m_pSessionSet = session_set_new();
session_set_set(m_pSessionSet,m_Session);
if( mIsAvc )
{
ms_queue_init(&m_RFC3984queue);
}
      pthread_attr_t attr;
      pthread_attr_init(&attr);
      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);

      mDone = false;
      mStarted = true;
      mTrackDurationUs = 0;
      mReachedEOS = false;
      
      pthread_create(&mThread, &attr, ThreadWrapper, this);
      pthread_attr_destroy(&attr);

LOGD("RFC3984Writer::Track::start ---");
      return OK;
}

status_t RFC3984Writer::Track::pause() {
LOGD("RFC3984Writer::Track::pause +++");
      mPaused = true;
LOGD("RFC3984Writer::Track::pause ---");
      return OK;
}

status_t RFC3984Writer::Track::stop() {
      LOGD("Stopping %s track", mIsAudio? "Audio": "Video");
      if (!mStarted) {
            LOGE("Stop() called but track is not started");
            return ERROR_END_OF_STREAM;
      }
LOGD("RFC3984Writer::Track::stop +++");
      if (mDone) {
LOGD("RFC3984Writer::Track::stop 001 ---");
            return OK;
      }
      mDone = true;

      void *dummy;
      pthread_join(mThread, &dummy);

      status_t err = (status_t) dummy;

      LOGD("Stopping %s track source", mIsAudio? "Audio": "Video");
      {
            status_t status = mSource->stop();
            if (err == OK && status != OK && status != ERROR_END_OF_STREAM) {
                  err = status;
            }
      }
LOGD("RFC3984Writer::Track::stop   ---");
      LOGD("%s track stopped", mIsAudio? "Audio": "Video");
      return err;
}

bool RFC3984Writer::Track::reachedEOS() {
LOGD("RFC3984Writer::Track::reachedEOS");
      return mReachedEOS;
}

void *RFC3984Writer::Track::ThreadWrapper(void *me) {
      Track *track = static_cast(me);
LOGD("RFC3984Writer::Track::ThreadWrapper");
      status_t err = track->threadEntry();
      return (void *) err;
}
static void savetofuse(const char *filename,const uint8_t *data ,int len)
{
int fd = 0;
fd = open(filename,O_RDWR);
if( fd )
{
write(fd,data,len);
close(fd);
}
}
status_t RFC3984Writer::Track::threadEntry() {
      int32_t count = 0;
    
      bool hasBFrames = false;
int nZeroLengthFrames = 0;
LOGD("RFC3984Writer::Track::threadEntry +++");
#if 1
      // XXX: Samsung's video encoder's output buffer timestamp
      // is not correct. see bug 4724339
      char value[PROPERTY_VALUE_MAX];
      if (property_get("rw.media.record.hasb", value, NULL) &&
            (!strcasecmp(value, "true") || !strcasecmp(value, "1"))) {
            hasBFrames = true;
      }
#endif
      if (mIsAudio) {
            prctl(PR_SET_NAME, (unsigned long)"AudioTrackEncoding", 0, 0, 0);
      } else {
            prctl(PR_SET_NAME, (unsigned long)"VideoTrackEncoding", 0, 0, 0);
      }
      androidSetThreadPriority (0, ANDROID_PRIORITY_AUDIO);

      sp meta_data;

     // mNumSamples = 0;
      status_t err = OK;
      MediaBuffer *buffer;
      while (!mDone && (err = mSource->read(&buffer)) == OK) {
            if (buffer->range_length() == 0) {
                  buffer->release();
                  buffer = NULL;
                  ++nZeroLengthFrames;
LOGD("[RFC3984Writer::Track::threadEntry] nZeroLengthFrames=%d",nZeroLengthFrames);
                  continue;
            }

            // If the codec specific data has not been received yet, delay pause.
            // After the codec specific data is received, discard what we received
            // when the track is to be paused.
            if (mPaused && !mResumed) {
                  buffer->release();
                  buffer = NULL;
                  continue;
            }

            ++count;

            // Make a deep copy of the MediaBuffer and Metadata and release
            // the original as soon as we can
            MediaBuffer *copy = new MediaBuffer(buffer->range_length());
            memcpy(copy->data(), (uint8_t *)buffer->data() + buffer->range_offset(),
                        buffer->range_length());
            copy->set_range(0, buffer->range_length());
            meta_data = new MetaData(*buffer->meta_data().get());
            buffer->release();
            buffer = NULL;

            //session_set_select(NULL,m_pSessionSet,NULL);
            size_t sampleSize = copy->range_length();
            if (mIsAvc) {
                 sendAVCData(copy,meta_data);
}
else
{//audio
sendAMRData(copy,meta_data);
}
copy->release();
copy = NULL;

      }


      mReachedEOS = true;

      if (err == ERROR_END_OF_STREAM) {
            return OK;
      }
      return err;
}
static size_t getFrameSize(bool isWide, unsigned FT) {
      static const size_t kFrameSizeNB[8] = {
            95, 103, 118, 134, 148, 159, 204, 244
      };
      static const size_t kFrameSizeWB[9] = {
            132, 177, 253, 285, 317, 365, 397, 461, 477
      };

      size_t frameSize = isWide ? kFrameSizeWB[FT] : kFrameSizeNB[FT];

      // Round up bits to bytes and add 1 for the header byte.
      frameSize = (frameSize + 7) / 8 + 1;

      return frameSize;
}
static void x264_buf_to_msgb(const uint8_t *buf, int bufsize, MSQueue * nalus)
{
//int i,kkk,size;
mblk_t *m;

m=allocb(bufsize+14,0);
memcpy(m->b_wptr,buf,bufsize);
m->b_wptr+=bufsize;
ms_queue_put(nalus,m);
}

void RFC3984Writer::Track::sendAVCData(MediaBuffer *mediaBuf,const sp &meta_data) {
      // 12 bytes RTP header + 2 bytes for the FU-indicator and FU-header.
      //CHECK_GE(kMaxPacketSize, 12u + 2u);

      int64_t timeUs;
      CHECK(meta_data->findInt64(kKeyTime, &timeUs));

      uint32_t rtpTime = mRTPTimeBase + (timeUs * 9 / 100ll);
// uint32_t rtpTime = m_nUser_Timestamp;
      const uint8_t *pnal =
            (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset();
int nallen = mediaBuf->range_length();
savetofuse("/mnt/sdcard/fuse/w264.264",pnal,nallen);
MSQueue nalus;
ms_queue_init(&nalus);
int i=0,sps_size,pps_size;
int sps_idx,pps_idx,frame_idx;
for(i = 0;i < nallen-4 && (pnal[4]==0x67);i++ )
{
if(pnal[i]==0x00 && pnal[i+1]==0x00 && pnal[i+2]==0x00 &&pnal[i+3]==0x01)
{
if(pnal[i+4]==0x67)
{
sps_idx = i+4;
LOGD("found sps");
}
else if(pnal[i+4]==0x68)
{
pps_idx = i+4;  
LOGD("found sps+pps");
}
else if(pnal[i+4]==0x65 || pnal[i+4]==0x41) 
{
LOGD("found sps+pps+frame");
frame_idx = i+4;
x264_buf_to_msgb(&pnal[sps_idx],pps_idx-sps_idx-NAL_START_CODE_SIZE,&nalus); 
x264_buf_to_msgb(&pnal[pps_idx],frame_idx-pps_idx-NAL_START_CODE_SIZE,&nalus); 
x264_buf_to_msgb(&pnal[frame_idx],nallen-frame_idx,&nalus); 
LOGD("RFC3984Writer::Track::sendAVCData ");
break;
}
else
{
LOGE(" %s   %d say : Invaild encoded data!!",__FUNCTION__,__LINE__);
break;
}
}
}
if((pnal[0]==0x00 && pnal[1]==0x00 && pnal[2]==0x00 && pnal[3]==0x01) && (pnal[4]==0x65 || pnal[4]==0x41))
{
if(pnal[4]==0x65)
{
x264_buf_to_msgb(&pnal[NAL_START_CODE_SIZE],nallen-NAL_START_CODE_SIZE,&nalus);
LOGD("found I frame");
}
if(pnal[4]==0x41)
{
LOGD("found P frame");
x264_buf_to_msgb(&pnal[NAL_START_CODE_SIZE],nallen-NAL_START_CODE_SIZE,&nalus);//do not send p frames todo add by kali
}
}
else
{
LOGE(" %s %d say : Invaild encoded data!!",__FUNCTION__,__LINE__);
}
rfc3984_pack(m_packer,&nalus,&m_RFC3984queue,rtpTime);//m_nUser_Timestamp
mblk_t *im = ms_queue_get(&m_RFC3984queue);
do {
mblk_t *header;
if (im){
header = rtp_session_create_packet(m_Session, 12, NULL, 0);
rtp_set_markbit(header, mblk_get_marker_info(im));
header->b_cont = im;
rtp_session_sendm_with_ts(m_Session, header, rtpTime);//m_nUser_Timestamp
mNumRTPSent++;
LOGD("send rtp packages ts=%d",rtpTime);
}
else
{

break;
}
}while ((im = ms_queue_get(&m_RFC3984queue)) != NULL);
m_nUser_Timestamp+=3600;
}//end of sendAVCData


static void dump_t(const uint8_t *data ,int len)
{
return;
char szmsg[256];
char sz1[32];
int i = 0;
memset(szmsg,'\0',sizeof(szmsg));
for( i = 0;i < len;i++ )
{
sprintf(sz1,"x ", data[i]);
strcat(szmsg,sz1);
if( i>0 && (i % 16) == 0)
{
LOGD("%s",szmsg);
memset(szmsg,'\0',sizeof(szmsg));
}
}
if( i % 16 )
LOGD("%s",szmsg);
}
static void savetofile(const char *filename,const uint8_t *data ,int len)
{
return;
FILE *fp = NULL;
fp = fopen(filename,"a+");
if( fp )
{
fwrite(data,1,len,fp);
fclose(fp);
}
}
static bool getSampleRateTableIndex(int sampleRate, uint8_t* tableIndex) {
      static const int kSampleRateTable[] = {
            96000, 88200, 64000, 48000, 44100, 32000,
            24000, 22050, 16000, 12000, 11025, 8000
      };
      const int tableSize =
            sizeof(kSampleRateTable) / sizeof(kSampleRateTable[0]);

      *tableIndex = 0;
      for (int index = 0; index < tableSize; ++index) {
            if (sampleRate == kSampleRateTable[index]) {
                  LOGV("Sample rate: %d and index: %d",
                        sampleRate, index);
                  *tableIndex = index;
                  return true;
            }
      }

      LOGE("Sampling rate %d bps is not supported", sampleRate);
      return false;
}
status_t RFC3984Writer::Track::writeAdtsHeader(uint32_t frameLength,uint8_t header[7]) {
int idx_w = 0;
      uint8_t data = 0xFF;
      //write(mFd, &data, 1);
      header[idx_w++] = data;

      const uint8_t kFieldId = 0;
      const uint8_t kMpegLayer = 0;
      const uint8_t kProtectionAbsense = 1;   // 1: kAdtsHeaderLength = 7
      data = 0xF0;
      data |= (kFieldId << 3);
      data |= (kMpegLayer << 1);
      data |= kProtectionAbsense;
      //write(mFd, &data, 1);
      header[idx_w++] = data;

      const uint8_t kProfileCode = 1;   // AAC-LC
      uint8_t kSampleFreqIndex;
      CHECK(getSampleRateTableIndex(mSampleRate, &kSampleFreqIndex));
      const uint8_t kPrivateStream = 0;
      const uint8_t kChannelConfigCode = mChannelCount;
      data = (kProfileCode << 6);
      data |= (kSampleFreqIndex << 2);
      data |= (kPrivateStream << 1);
      data |= (kChannelConfigCode >> 2);
      //write(mFd, &data, 1);
      header[idx_w++] = data;

      // 4 bits from originality to copyright start
      const uint8_t kCopyright = 0;
      const uint32_t kFrameLength = frameLength;
      data = ((kChannelConfigCode & 3) << 6);
      data |= (kCopyright << 2);
      data |= ((kFrameLength & 0x1800) >> 11);
      //write(mFd, &data, 1);
      header[idx_w++] = data;

      data = ((kFrameLength & 0x07F8) >> 3);
      //write(mFd, &data, 1);
      header[idx_w++] = data;

      const uint32_t kBufferFullness = 0x7FF;   // VBR
      data = ((kFrameLength & 0x07) << 5);
      data |= ((kBufferFullness & 0x07C0) >> 6);
      //write(mFd, &data, 1);
      header[idx_w++] = data;

      const uint8_t kFrameCount = 0;
      data = ((kBufferFullness & 0x03F) << 2);
      data |= kFrameCount;
      //write(mFd, &data, 1);
      header[idx_w++] = data;

      return OK;
}

void RFC3984Writer::Track::sendAACData(MediaBuffer *mediaBuf,const sp &meta_data) 
{
static const int kMaxRawAACPackSize = 1024;
      const uint8_t *mediaData =
            (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset();

      size_t mediaLength = mediaBuf->range_length();
      int64_t timeUs;
      CHECK(meta_data->findInt64(kKeyTime, &timeUs));
      uint32_t rtpTime = m_nUser_Timestamp;
savetofile("/mnt/sdcard/raw.aac",mediaData,mediaLength);
dump_t(mediaData,mediaLength);
sp buffer = new ABuffer(kMaxRawAACPackSize);
uint8_t *data = buffer->data();
writeAdtsHeader(kAdtsHeaderLength+mediaLength,data);
memcpy(&data[kAdtsHeaderLength],mediaData,mediaLength);
mediaLength += kAdtsHeaderLength;
savetofuse("/mnt/sdcard/fuse/wAAC.aac",data,mediaLength);
}

void RFC3984Writer::Track::sendAMRData(MediaBuffer *mediaBuf,const sp &meta_data) {
      const uint8_t *mediaData =
            (const uint8_t *)mediaBuf->data() + mediaBuf->range_offset();

      size_t mediaLength = mediaBuf->range_length();

      CHECK_GE(kMaxPacketSize, 12u + 1u + mediaLength);

      const bool isWide = (mMode == AMR_WB);
//LOGD("RFC3984Writer::Track::sendAMRData +++");
      int64_t timeUs;
      CHECK(meta_data->findInt64(kKeyTime, &timeUs));
      //uint32_t rtpTime = mRTPTimeBase + (timeUs / (isWide ? 250 : 125));
      uint32_t rtpTime = m_nUser_Timestamp;
      // hexdump(mediaData, mediaLength);
      savetofile("/mnt/sdcard/001.amr",mediaData,mediaLength);
// LOGD("ori+++");
dump_t(mediaData,mediaLength);
// LOGD("ori---");
      Vector tableOfContents;
      size_t srcOffset = 0;
      while (srcOffset < mediaLength) {
            uint8_t toc = mediaData[srcOffset];

            unsigned FT = (toc >> 3) & 0x0f;
            CHECK((isWide && FT <= 8) || (!isWide && FT <= 7));

            tableOfContents.push(toc);
            srcOffset += getFrameSize(isWide, FT);
      }
      CHECK_EQ(srcOffset, mediaLength);

      sp buffer = new ABuffer(kMaxPacketSize);
      CHECK_LE(mediaLength + 12 + 1, buffer->capacity());

      // The data fits into a single packet
      uint8_t *data = buffer->data();
      data[0] = 0x80;
      data[1] = PT_AMR;
      if (mNumRTPSent == 0) {
            // Signal start of talk-spurt.
            data[1] |= 0x80;   // M-bit
      }
 

      data[12] = 0xf0;   // CMR=15, RR=0

      size_t dstOffset = 13;

      for (size_t i = 0; i < tableOfContents.size(); ++i) {
            uint8_t toc = tableOfContents[i];

            if (i + 1 < tableOfContents.size()) {
                  toc |= 0x80;
            } else {
                  toc &= ~0x80;
}
           data[dstOffset++] = toc;
}

      srcOffset = 0;
      for (size_t i = 0; i < tableOfContents.size(); ++i) {
            uint8_t toc = tableOfContents[i];
            unsigned FT = (toc >> 3) & 0x0f;
            size_t frameSize = getFrameSize(isWide, FT);

            ++srcOffset;   // skip toc
            memcpy(&data[dstOffset], &mediaData[srcOffset], frameSize - 1);
            srcOffset += frameSize - 1;
            dstOffset += frameSize - 1;
      }

      buffer->setRange(0, dstOffset);

//ortp spec +++
mblk_t *im;
im=allocb(dstOffset,0);
if( mNumRTPSent <=   0 )   // M-bit
{
mblk_set_marker_info(im,1);//begin talking
}
memcpy(im->b_wptr,&data[12],dstOffset-12); //skip rtp header
im->b_wptr+=dstOffset-12; //payload length
mblk_t *header;
header = rtp_session_create_packet(m_Session, 12, NULL, 0);
rtp_set_markbit(header, mblk_get_marker_info(im));
header->b_cont = im;
// LOGD("send rtp packages AMR ts=%d RTPlen=%d mediaLength=%d",rtpTime,(im->b_wptr-im->b_rptr),mediaLength);
// LOGD("rtp data++++");
dump_t(header->b_rptr,header->b_wptr-header->b_rptr);
dump_t(im->b_rptr,im->b_wptr-im->b_rptr);
// LOGD("rtp data----");
rtp_session_sendm_with_ts(m_Session, header, rtpTime);//m_nUser_Timestamp
mNumRTPSent++;
m_nUser_Timestamp += 160;
//ortp spec   ---

      //send(buffer, false );

      //++mSeqNo;
      //mNumRTPOctetsSent += buffer->size() - 12;

   //   mLastRTPTime = rtpTime;
   //   mLastNTPTime = GetNowNTP();
}

status_t RFC3984Writer::start(MetaData *param) {
    
      status_t err = OK;
// mStartTimestampUs = -1;
LOGD("RFC3984Writer::start +++");
      if (mStarted) {
            if (mPaused) {
                  mPaused = false;
LOGD("RFC3984Writer::start 000---");
                  return startTracks(param);
            }
LOGD("RFC3984Writer::start 001---");
            return OK;
      }
ortp_init();
ortp_scheduler_init();

      err = startTracks(param);
      if (err != OK) {
LOGD("RFC3984Writer::start 002---");
            return err;
      }

      mStarted = true;
      LOGD("RFC3984Writer::start ---");
      return OK;
}

status_t RFC3984Writer::stop() {
    
      status_t err = OK;
LOGD("RFC3984Writer::stop +++");
      for (List::iterator it = mTracks.begin();
              it != mTracks.end(); ++it) {
            status_t status = (*it)->stop();
            if (err == OK && status != OK) {
                  err = status;
            }
      }
      release();
      LOGD("RFC3984Writer::stop ---");
      return err;
}

void RFC3984Writer::release() {
ortp_exit();
      mStarted = false;
}

status_t RFC3984Writer::addSource(const sp &source) {
      Mutex::Autolock l(mLock);
      LOGD("RFC3984Writer::addSource +++");
      if (mStarted) {
            LOGE("Attempt to add source AFTER recording is started");
            return UNKNOWN_ERROR;
      }
      Track *track = new Track(this, source, mTracks.size());
      mTracks.push_back(track);
LOGD("RFC3984Writer::addSource ---");
      return OK;
}

status_t RFC3984Writer::startTracks(MetaData *params) {
LOGD("RFC3984Writer::startTracks +++");
      for (List::iterator it = mTracks.begin();
              it != mTracks.end(); ++it) {
            status_t err = (*it)->start(params);

            if (err != OK) {
                  for (List::iterator it2 = mTracks.begin();
                          it2 != it; ++it2) {
                        (*it2)->stop();
                  }
LOGD("RFC3984Writer::startTracks ---");
                  return err;
            }
      }
      return OK;
}
RFC3984Writer::RFC3984Writer(int fd)
      : mFd(dup(fd)),
//m_nPort(1234),
//mRTPTimeBase(0),
//m_nUser_Timestamp(0),
         mPaused(false),
         mStarted(false) {
}
RFC3984Writer::~RFC3984Writer() {
      stop();

      while (!mTracks.empty()) {
            List::iterator it = mTracks.begin();
            delete *it;
            (*it) = NULL;
            mTracks.erase(it);
      }
      mTracks.clear();
}

status_t RFC3984Writer::pause() {

      mPaused = true;
      status_t err = OK;
      for (List::iterator it = mTracks.begin();
              it != mTracks.end(); ++it) {
            status_t status = (*it)->pause();
            if (status != OK) {
                  err = status;
            }
      }
      return err;
}

bool RFC3984Writer::reachedEOS() {
      bool allDone = true;
      for (List::iterator it = mTracks.begin();
              it != mTracks.end(); ++it) {
            if (!(*it)->reachedEOS()) {
                  allDone = false;
                  break;
            }
      }

      return allDone;
}



}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值