예제 #1
0
static void x264_lookahead_encoder_shift( x264_t *h )
{
    int bframes  = 0;
    int i_frames = 0;

    while( h->lookahead->ofbuf.list[i_frames] )
    {
        if( IS_X264_TYPE_B( h->lookahead->ofbuf.list[bframes]->i_type ) )
            bframes++;
        else
            break;
        i_frames++;
    }
    if( h->lookahead->ofbuf.list[i_frames] )
    {
        x264_frame_push( h->frames.current, x264_frame_shift( &h->lookahead->ofbuf.list[bframes] ) );
        h->lookahead->ofbuf.i_size--;
        if( h->param.b_bframe_pyramid && bframes > 1 )
        {
            x264_frame_t *mid = x264_frame_shift( &h->lookahead->ofbuf.list[bframes/2] );
            h->lookahead->ofbuf.i_size--;
            mid->i_type = X264_TYPE_BREF;
            x264_frame_push( h->frames.current, mid );
            bframes--;
        }
        while( bframes-- )
        {
            x264_frame_push( h->frames.current, x264_frame_shift( h->lookahead->ofbuf.list ) );
            h->lookahead->ofbuf.i_size--;
        }
        x264_pthread_cond_broadcast( &h->lookahead->ofbuf.cv_empty );
    }
}
예제 #2
0
void x264_lookahead_get_frames( x264_t *h )
{
    if( h->param.i_sync_lookahead )
    {   /* We have a lookahead thread, so get frames from there */
        x264_pthread_mutex_lock( &h->lookahead->ofbuf.mutex );
        while( !h->lookahead->ofbuf.i_size && h->lookahead->b_thread_active )
            x264_pthread_cond_wait( &h->lookahead->ofbuf.cv_fill, &h->lookahead->ofbuf.mutex );
        x264_lookahead_encoder_shift( h );
        x264_pthread_mutex_unlock( &h->lookahead->ofbuf.mutex );
    }
    else
    {   /* We are not running a lookahead thread, so perform all the slicetype decide on the fly */

        if( h->frames.current[0] || !h->lookahead->next.i_size )
            return;

        x264_stack_align( x264_slicetype_decide, h );

        int bframes=0;
        while( IS_X264_TYPE_B( h->lookahead->next.list[bframes]->i_type ) )
            bframes++;

        x264_lookahead_update_last_nonb( h, h->lookahead->next.list[bframes] );
        x264_lookahead_shift( &h->lookahead->ofbuf, &h->lookahead->next, bframes + 1 );

        /* For MB-tree and VBV lookahead, we have to perform propagation analysis on I-frames too. */
        if( h->lookahead->b_analyse_keyframe && IS_X264_TYPE_I( h->lookahead->last_nonb->i_type ) )
            x264_stack_align( x264_slicetype_analyse, h, 1 );

        x264_lookahead_encoder_shift( h );
    }
}
예제 #3
0
static void x264_lookahead_slicetype_decide( x264_t *h )
{
    int bframes = 0;
    x264_stack_align( x264_slicetype_decide, h );

    while( IS_X264_TYPE_B( h->lookahead->next.list[bframes]->i_type ) )
        bframes++;
    x264_lookahead_update_last_nonb( h, h->lookahead->next.list[bframes] );

    x264_pthread_mutex_lock( &h->lookahead->ofbuf.mutex );
    while( h->lookahead->ofbuf.i_size == h->lookahead->ofbuf.i_max_size )
        x264_pthread_cond_wait( &h->lookahead->ofbuf.cv_empty, &h->lookahead->ofbuf.mutex );

    x264_pthread_mutex_lock( &h->lookahead->next.mutex );
    x264_lookahead_shift( &h->lookahead->ofbuf, &h->lookahead->next, bframes + 1 );
    x264_pthread_mutex_unlock( &h->lookahead->next.mutex );

    /* For MB-tree and VBV lookahead, we have to perform propagation analysis on I-frames too. */
    if( h->lookahead->b_analyse_keyframe && IS_X264_TYPE_I( h->lookahead->last_nonb->i_type ) )
        x264_stack_align( x264_slicetype_analyse, h, 1 );

    x264_pthread_mutex_unlock( &h->lookahead->ofbuf.mutex );
}
int BleX264Encoder::encode(unsigned char *rgbframe, mint64 pts, void *opaque)
{
    Q_UNUSED(pts);
    unsigned char *src_buf = rgbframe;
    x264_picture_init(m_pictureIn);

    m_pictureIn->img.i_csp = X264_CSP_I420;
    m_pictureIn->img.i_plane = 3;
    m_pictureIn->i_type = X264_TYPE_AUTO;
    m_pictureIn->i_qpplus1 = 0;

    // @note why i_pts plus 1 everytime
    // because the timebase set as above.
    m_pictureIn->i_pts = ++m_encoded_frames;
    m_pictureIn->opaque = opaque;

    m_pictureIn->img.plane[0] = src_buf;
    m_pictureIn->img.plane[1] = src_buf + m_x264Param->i_height * m_x264Param->i_width;
    m_pictureIn->img.plane[2] = src_buf + m_x264Param->i_height * m_x264Param->i_width * 5 / 4;
    m_pictureIn->img.i_stride[0] = m_x264Param->i_width;
    m_pictureIn->img.i_stride[1] = m_x264Param->i_width >> 1;
    m_pictureIn->img.i_stride[2] = m_x264Param->i_width >> 1;

    x264_picture_t picOut;
    int nalNum;
    x264_nal_t* nalOut;
    int len = x264_encoder_encode(m_x264Encoder, &nalOut, &nalNum, m_pictureIn, &picOut);
    if (len < 0) {
        log_error("x264 encode failed");
        return -1;
    }

    if (nalNum <= 0) {
        log_warn("frame delayed in encoder.");
        return -2;
    }

    if(!bFirstFrameProcessed && nalNum)
    {
        if(picOut.i_dts < 0)
            delayOffset = int(-picOut.i_dts);

        bFirstFrameProcessed = true;
    }

    float timeOffset = float(picOut.i_pts - picOut.i_dts) * BleAVQueue::instance()->timestampBuilder()->videoInternal();

    BleVideoPacket *pkt = dynamic_cast<BleVideoPacket *> (BleAVQueue::instance()->find_unencoded_video());
    BleAssert(pkt != NULL);

    MStream &body = pkt->data;
    unsigned char frameType;
    if (IS_X264_TYPE_I(picOut.i_type)) {
        frameType = 0x17;
    } else {
        frameType = 0x27;
    }

    body.write1Bytes(frameType);
    body.write1Bytes(0x01);
    body.write3Bytes((int)timeOffset);

    // NALU payload : 4bytes size + payload
    // NALU payload size : 4bytes size + payload size
    // for b_repeat_headers = 0 in x264_param_t
    // so NALU type is only IDR, SLICE(P or B frame)
    // so you must get SPS PPS before encoding any frame.
    for (int i = 0; i < nalNum; ++i) {
        x264_nal_t &nal = nalOut[i];
        body.writeString((char*)nal.p_payload, nal.i_payload);
    }

    if (IS_X264_TYPE_I(picOut.i_type)) {
        log_trace("I");
    } else if (IS_X264_TYPE_B(picOut.i_type)) {
        log_trace("B");
    } else {
        log_trace("P");
    }

    BleAVQueue::instance()->update_packet(pkt);

    return 0;
}