Ejemplo n.º 1
0
PJ_DEF(int) session_info_buildSoftNackList(Session_Info *session_info, int *seq_num_list,
                                            int seq_num_list_len, pj_uint32_t rtt_ms) {
    if(seq_num_list_len == 0) return 0;
    int empty_low_seq_num = session_info->empty_low_seq_num;
    int empty_high_seq_num = session_info->empty_high_seq_num;
    //clear empty packets
    if(empty_low_seq_num != -1)
        ClearEmptyPackets(session_info, seq_num_list, seq_num_list_len);
    JTPacket *packet = session_info->packetList.next;
    printf("check if has packets in session\n");
    if(packet == &session_info->packetList ) //empty
        return 0;
    int media_seq_num_low, media_seq_num_high;
    pj_bool_t session_nacked = PJ_TRUE;
    //if not key frame and previous frame lost, don't retransmit
    if(session_info->previous_frame_loss && !session_info->isKeyFrame) {
        session_nacked = PJ_FALSE;
    }
    //if (now + rtt) > (ts + FRAME_MAX_DELAY), don't retransmit
    //use ntp time, but ts in rtp is not ntp time in current, so substitute received time for ts
    //if (now + rtt * 1.5) > (received + FRAME_MAX_DELAY), don't retransmit
    if(session_info->frame_type != PJMEDIA_FRAME_TYPE_NONE && session_info->frame_type != 
            PJMEDIA_FRAME_TYPE_EMPTY) {
        //has media packets
        pj_timestamp now, received;
        pj_get_timestamp(&now);
        pj_add_timestamp32(&now, rtt_ms * 1000 * 3 / 2);
        memcpy(&received, &session_info->oldest_media_packet, sizeof(pj_timestamp));
        pj_add_timestamp32(&received, FRAME_MAX_DELAY * 1000);
        if(pj_cmp_timestamp(&now, &received) > 0) {
            session_nacked = PJ_FALSE;
        }     
    }
    if(!session_nacked) {
        media_seq_num_low = session_info->packetList.next->isFirst? session_info->packetList.next->seq:
                                    session_info->packetList.next->seq - 1;
        media_seq_num_high = session_info->packetList.prev->isMarket? session_info->packetList.prev->seq:
                                    session_info->packetList.prev->seq + 1;
        ClearPackets(seq_num_list, seq_num_list_len, media_seq_num_low, media_seq_num_high, -1);
        return 0;
    }
    
    return session_info_buildHardNackList(session_info, seq_num_list, seq_num_list_len);   
}
Ejemplo n.º 2
0
pjmedia_clock_src_get_current_timestamp( const pjmedia_clock_src *clocksrc,
                                         pj_timestamp *timestamp)
{
    pj_timestamp now;
    unsigned elapsed_ms;
    
    PJ_ASSERT_RETURN(clocksrc && timestamp, PJ_EINVAL);

    pj_get_timestamp(&now);
    elapsed_ms = pj_elapsed_msec(&clocksrc->last_update, &now);
    pj_memcpy(timestamp, &clocksrc->timestamp, sizeof(pj_timestamp));
    pj_add_timestamp32(timestamp, elapsed_ms * clocksrc->clock_rate / 1000);

    return PJ_SUCCESS;
}
Ejemplo n.º 3
0
PJ_DEF(Frame_Buffer *) jitter_buffer_getCompleteFrameForDecoding(Jitter_Buffer *jitter_buffer, pj_uint32_t max_wait_time_ms) {
    //running
    if(!jitter_buffer->running)
            return NULL;
    if(pj_mutex_lock(jitter_buffer->jb_mutex) != PJ_SUCCESS) { //error
        return NULL;
    }
    /*{
        char buf[1024];
        getFrameInfo(&jitter_buffer->frameList, &jitter_buffer->decode_state, buf, 1024);
        PJ_LOG(4, (THIS_FILE, "jb status:\n%s\n", buf));
    }*/
    //the first frame must be a key frame
    if(jitter_buffer->decode_state.inited == PJ_FALSE)
        jitter_buffer->waiting_for_key_frame == PJ_TRUE;
    //clean old frames
    CleanOldFrames(jitter_buffer);
    //get complete , continuous frame
    Frame_Buffer * frame = findOldestCompleteContinuousFrame(jitter_buffer);
    //if not got, try to wait a frame
    if(frame == NULL) {
        if(max_wait_time_ms == 0)
            goto ON_RET;
        pj_timestamp current ;
        pj_get_timestamp(&current);
        pj_timestamp end = current;
        pj_add_timestamp32(&end, max_wait_time_ms);
        pj_int32_t wait_time_ms = max_wait_time_ms;
        event_reset(jitter_buffer->packet_event);
        while(wait_time_ms > 0) {
            pj_mutex_unlock(jitter_buffer->jb_mutex);
            if(event_wait(jitter_buffer->packet_event, wait_time_ms) == WAIT_RET_SIGNAL) {
                //incoming a packet
                pj_mutex_lock(jitter_buffer->jb_mutex);
                if(!jitter_buffer->running) //jitter buffer stoped
                    goto ON_RET;
                CleanOldFrames(jitter_buffer);
                frame = findOldestCompleteContinuousFrame(jitter_buffer);
                if(frame != NULL)
                    break;
                pj_get_timestamp(&current);
                int elapsed_msec = pj_elapsed_msec(&current, &end);
                wait_time_ms = elapsed_msec;
            } else {
                pj_mutex_lock(jitter_buffer->jb_mutex); //error or timeout
                break;
            }
        }
    } else
        event_reset(jitter_buffer->packet_event);
    if(frame == NULL)
        goto ON_RET;
    /*if(jitter_buffer->waiting_for_key_frame && !frame->session_info.isKeyFrame) {
        frame = NULL; //not a key frame
        goto ON_RET;
    }*/
    //got one, update jitter
    if(frame->nack_count > 0) {
        jitter_estimator_frameNacked(&jitter_buffer->jitter_estimator); //nacked
    } else {
        //update jitter estimator
        UpdateJitterEstimatorForFrame(jitter_buffer, frame);
    }
    //set frame status
    frame_buffer_setStatus(frame, FRAME_STATUS_DECODING);
    //update decode state
    decode_state_updateFrame(frame, &jitter_buffer->decode_state);
    //waiting for key frame
    if(frame->session_info.isKeyFrame)
        jitter_buffer->waiting_for_key_frame = PJ_FALSE;
    //clean old frames
    CleanOldFrames(jitter_buffer);
    //return frame
    ON_RET:
        pj_mutex_unlock(jitter_buffer->jb_mutex);
        return frame;
}