Example #1
0
// 函数实现
void* playeropen(char *file, void *extra)
{
    PLAYER        *player   = NULL;
    AVCodec       *decoder = NULL;
    int            vformat  = 0;
    int            width    = 0;
    int            height   = 0;
    uint64_t       alayout  = 0;
    int            aformat  = 0;
    int            arate    = 0;
    uint32_t       i        = 0;

    // init log
//  log_init(TEXT("DEBUGER"));

    // av register all
    av_register_all();

    // alloc player context
    player = (PLAYER*)malloc(sizeof(PLAYER));
    memset(player, 0, sizeof(PLAYER));

    // create packet queue
    pktqueue_create(&(player->PacketQueue));

    // open input file
    if (avformat_open_input(&(player->pAVFormatContext), file, NULL, 0) != 0) {
        goto error_handler;
    }

    // find stream info
    if (avformat_find_stream_info(player->pAVFormatContext, NULL) < 0) {
        goto error_handler;
    }

    // get video & audio codec context
    player->iAudioStreamIndex = -1;
    player->iVideoStreamIndex = -1;
    for (i=0; i<player->pAVFormatContext->nb_streams; i++)
    {
        switch (player->pAVFormatContext->streams[i]->codec->codec_type)
        {
        case AVMEDIA_TYPE_AUDIO:
            player->iAudioStreamIndex  = i;
            player->pAudioCodecContext = player->pAVFormatContext->streams[i]->codec;
            player->dAudioTimeBase     = av_q2d(player->pAVFormatContext->streams[i]->time_base) * 1000;
            break;

        case AVMEDIA_TYPE_VIDEO:
            player->iVideoStreamIndex  = i;
            player->pVideoCodecContext = player->pAVFormatContext->streams[i]->codec;
            player->dVideoTimeBase     = av_q2d(player->pAVFormatContext->streams[i]->time_base) * 1000;
            player->tVideoFrameRate    = player->pAVFormatContext->streams[i]->r_frame_rate;
            if (player->tVideoFrameRate.num / player->tVideoFrameRate.den > 100) {
                player->tVideoFrameRate.num = 30;
                player->tVideoFrameRate.den = 1;
            }
            break;
        }
    }

    // open audio codec
    if (player->iAudioStreamIndex != -1)
    {
        decoder = avcodec_find_decoder(player->pAudioCodecContext->codec_id);
        if (!decoder || avcodec_open(player->pAudioCodecContext, decoder, NULL) < 0)
        {
            log_printf(TEXT("failed to find or open decoder for audio !\n"));
            player->iAudioStreamIndex = -1;
        }
    }

    // open video codec
    if (player->iVideoStreamIndex != -1)
    {
        decoder = avcodec_find_decoder(player->pVideoCodecContext->codec_id);
        if (!decoder || avcodec_open(player->pVideoCodecContext, decoder, NULL) < 0)
        {
            log_printf(TEXT("failed to find or open decoder for video !\n"));
            player->iVideoStreamIndex = -1;
        }
    }

    // for video
    if (player->iVideoStreamIndex != -1)
    {
        vformat = player->pVideoCodecContext->pix_fmt;
        width   = player->pVideoCodecContext->width;
        height  = player->pVideoCodecContext->height;
    }

    // for audio
    if (player->iAudioStreamIndex != -1)
    {
        alayout = player->pAudioCodecContext->channel_layout;
        //++ fix audio channel layout issue
        if (alayout == 0) {
            alayout = av_get_default_channel_layout(player->pAudioCodecContext->channels);
        }
        //-- fix audio channel layout issue
        aformat = player->pAudioCodecContext->sample_fmt;
        arate   = player->pAudioCodecContext->sample_rate;
    }

    // open core render
    player->hCoreRender = renderopen(extra, player->tVideoFrameRate, vformat, width, height,
        arate, (AVSampleFormat)aformat, alayout);

    // make sure player status paused
    player->nPlayerStatus = 0xf;
    pthread_create(&(player->hAVDemuxThread), NULL, AVDemuxThreadProc    , player);
    pthread_create(&(player->hADecodeThread), NULL, AudioDecodeThreadProc, player);
    pthread_create(&(player->hVDecodeThread), NULL, VideoDecodeThreadProc, player);

    return player;

error_handler:
    playerclose(player);
    return NULL;
}
Example #2
0
int streamxmit_init(STREAM_RTP_DEST_T *pDest, const STREAM_DEST_CFG_T *pDestCfg) {
  unsigned int numPkts = 0;
  unsigned int szPkt;
  int iTmp;
  STREAM_XMIT_QUEUE_T *pAsyncQ = NULL;
  PKTQUEUE_T *pQ = NULL;
  STREAM_STATS_MONITOR_T *pMonitor = NULL;

  if(!pDest || !pDestCfg) {
    return -1;
  }

  pAsyncQ = &pDest->asyncQ;

  if(pDestCfg->pFbReq && pDestCfg->pFbReq->nackRtpRetransmit) {
    pAsyncQ->doRtcpNack = 1; 
  }

  pAsyncQ->doAsyncXmit = 0;  // TODO: implement for packet output smoothing
  //
  // We run if we are to do async RTP xmit 
  // or we support RTP-retransmissions for video (using RTCP NACK notifications) 
  //
  if(!pAsyncQ->doAsyncXmit && (!pAsyncQ->doRtcpNack || pDest->pRtpMulti->isaud)) {
    return 0;
  }

  if(pAsyncQ->doRtcpNack) {

    //
    // Compute an RTP retransmission queue size
    //
    if(pDest->pRtpMulti->pStreamerCfg->xcode.vid.common.cfgDo_xcode &&
      pDest->pRtpMulti->pStreamerCfg->xcode.vid.out[pDestCfg->xcodeOutidx].cfgBitRateOut > 0 &&
      pDest->pRtpMulti->init.maxPayloadSz > 0) {

      iTmp = (pDest->pRtpMulti->pStreamerCfg->xcode.vid.out[pDestCfg->xcodeOutidx].cfgBitRateOut / 
       (8 * 10 * pDest->pRtpMulti->init.maxPayloadSz) + 2) * 10;

      numPkts = MIN(150, MAX(50, iTmp));
    } else {
      numPkts = 100;
    }

//TODO: really only need burstmeter when capping retransmission traffic
    burstmeter_init(&pAsyncQ->retransmissionMeter, 1, 1000);

//pAsyncQ->retransmissionKbpsMax = 30;

  } else {
    numPkts = 40;
  }
  szPkt = pDest->pRtpMulti->init.maxPayloadSz + RTP_HEADER_LEN + DTLS_OVERHEAD_SIZE + 64;

  // No locking!... should rely on pAsyncQ->mtx
  if(!(pQ = pktqueue_create(numPkts, szPkt, 0, 0, 0, sizeof(STREAMXMIT_PKT_HDR_T), 0, 1))) {
    return -1;
  }

  LOG(X_DEBUG("Created RTP %soutput packet queue size: %dB x %dpkts"), pAsyncQ->doRtcpNack ? "NACK " : "", 
              szPkt, numPkts);

  pQ->cfg.overwriteType = PKTQ_OVERWRITE_OK;
  pQ->cfg.id = STREAMER_QID_NACK;
  pktqueue_setrdr(pQ, 0);
  pthread_mutex_init(&pAsyncQ->mtx, NULL);
  pAsyncQ->nackHistoryMs = RTP_RETRANSMIT_HISTORY_MS;
  pAsyncQ->pQ = pQ;

  //
  // Start the RTP output queue processor thread
  //
  if(pDestCfg->pMonitor && pDestCfg->pMonitor->active) {
    pMonitor = pDestCfg->pMonitor; 
  }
  streamxmit_async_start(pDest->pRtpMulti, pMonitor, 0);

  return 0;
}