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 ); } }
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 ); } }
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; }