diff options
author | Elaine Wang <elaine.wang@intel.com> | 2013-04-27 18:08:23 +0800 |
---|---|---|
committer | Xiang, Haihao <haihao.xiang@intel.com> | 2013-06-25 13:53:46 +0800 |
commit | 47ae954514066e55d320a77975ef61acf8238d78 (patch) | |
tree | 8369982119c33725f9d40ec7c618feee1972b208 | |
parent | 2c0f324544cd4ccf7c672ffbf13b8f9f844b4425 (diff) | |
download | libva-47ae954514066e55d320a77975ef61acf8238d78.tar.gz |
h264encode: refine calculation logic of reference frame setting
Signed-off-by: Elaine Wang <elaine.wang@intel.com>
-rw-r--r-- | test/encode/h264encode.c | 400 |
1 files changed, 263 insertions, 137 deletions
diff --git a/test/encode/h264encode.c b/test/encode/h264encode.c index 4376965..c06d066 100644 --- a/test/encode/h264encode.c +++ b/test/encode/h264encode.c @@ -70,26 +70,34 @@ #define BITSTREAM_ALLOCATE_STEPPING 4096 -#define SRC_SURFACE_NUM 16 /* 16 surfaces for source YUV */ -#define REF_SURFACE_NUM 16 /* 16 surfaces for reference */ +#define SURFACE_NUM 16 /* 16 surfaces for source YUV */ +#define SURFACE_NUM 16 /* 16 surfaces for reference */ static VADisplay va_dpy; static VAProfile h264_profile; static VAConfigAttrib attrib[VAConfigAttribTypeMax]; static VAConfigAttrib config_attrib[VAConfigAttribTypeMax]; static int config_attrib_num = 0; -static VASurfaceID src_surface[SRC_SURFACE_NUM]; -static VABufferID coded_buf[SRC_SURFACE_NUM]; -static VASurfaceID ref_surface[REF_SURFACE_NUM]; +static VASurfaceID src_surface[SURFACE_NUM]; +static VABufferID coded_buf[SURFACE_NUM]; +static VASurfaceID ref_surface[SURFACE_NUM]; static VAConfigID config_id; static VAContextID context_id; static VAEncSequenceParameterBufferH264 seq_param; static VAEncPictureParameterBufferH264 pic_param; static VAEncSliceParameterBufferH264 slice_param; -static VAPictureH264 LLastCurrPic={picture_id:VA_INVALID_SURFACE}, LastCurrPic={picture_id:VA_INVALID_SURFACE}, CurrentCurrPic; /* One reference for P and two for B */ +static VAPictureH264 CurrentCurrPic; +static VAPictureH264 ReferenceFrames[16], RefPicList0_P[32], RefPicList0_B[32], RefPicList1_B[32]; +static unsigned int MaxFrameNum = (2<<16); +static unsigned int MaxPicOrderCntLsb = (2<<8); +static unsigned int Log2MaxFrameNum = 16; +static unsigned int Log2MaxPicOrderCntLsb = 8; + +static unsigned int num_ref_frames = 2; +static unsigned int numShortTerm = 0; static int constraint_set_flag = 0; static int h264_packedheader = 0; /* support pack header? */ -static int h264_maxref = 3; +static int h264_maxref = (1<<16|1); static char *coded_fn = NULL, *srcyuv_fn = NULL, *recyuv_fn = NULL; static FILE *coded_fp = NULL, *srcyuv_fp = NULL, *recyuv_fp = NULL; static unsigned long long srcyuv_frames = 0; @@ -108,11 +116,11 @@ static int intra_period = 30; static int intra_idr_period = 60; static int ip_period = 1; static int rc_mode = VA_RC_VBR; -static int slice_refoverride = 1; /* use VAEncSliceParameterBufferH264:RefPicList0/1 */ static unsigned long long current_frame_encoding = 0; static unsigned long long current_frame_display = 0; static int current_frame_num = 0; static int current_frame_type; +#define current_slot (current_frame_display % SURFACE_NUM) /* thread to save coded data/upload source YUV */ struct storage_task_t { @@ -123,12 +131,12 @@ struct storage_task_t { static struct storage_task_t *storage_task_header = NULL, *storage_task_tail = NULL; #define SRC_SURFACE_IN_ENCODING 0 #define SRC_SURFACE_IN_STORAGE 1 -static int srcsurface_status[SRC_SURFACE_NUM]; +static int srcsurface_status[SURFACE_NUM]; static int encode_syncmode = 0; static pthread_mutex_t encode_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t encode_cond = PTHREAD_COND_INITIALIZER; static pthread_t encode_thread; - + /* for performance profiling */ static unsigned int UploadPictureTicks=0; static unsigned int BeginPictureTicks=0; @@ -670,7 +678,7 @@ static int string_to_rc(char *str) else if (!strncmp(str, "VBR_CONSTRAINED", 15)) rc_mode = VA_RC_VBR_CONSTRAINED; else { - printf("Unknow RC mode\n"); + printf("Unknown RC mode\n"); rc_mode = -1; } return rc_mode; @@ -691,7 +699,6 @@ static int print_help(void) printf(" --initialqp <number>\n"); printf(" --minqp <number>\n"); printf(" --rcmode <NONE|CBR|VBR|VCM|CQP|VBR_CONTRAINED>\n"); - printf(" --refoverride: use VAEncSliceParameterBufferH264 to override reference frames\n"); printf(" --syncmode: sequentially upload source, encoding, save result, no multi-thread\n"); printf(" --srcyuv <filename> load YUV from a file\n"); printf(" --fourcc <NV12|IYUV|I420|YV12> source YUV fourcc\n"); @@ -710,7 +717,6 @@ static int process_cmdline(int argc, char *argv[]) {"idr_period", required_argument, NULL, 5 }, {"ip_period", required_argument, NULL, 6 }, {"rcmode", required_argument, NULL, 7 }, - {"refoverride", required_argument, NULL, 8 }, {"srcyuv", required_argument, NULL, 9 }, {"fourcc", required_argument, NULL, 10 }, {"syncmode", no_argument, NULL, 11 }, @@ -759,9 +765,6 @@ static int process_cmdline(int argc, char *argv[]) exit(1); } break; - case 8: - slice_refoverride = atoi(optarg); - break; case 9: srcyuv_fn = strdup(optarg); break; @@ -795,10 +798,9 @@ static int process_cmdline(int argc, char *argv[]) exit(0); } - if (frame_bitrate == 0) { + if (frame_bitrate == 0) frame_bitrate = frame_width * frame_height * 12 * frame_rate / 50; - printf("Set bitrate to %dbps\n", frame_bitrate); - } + /* open source file */ if (srcyuv_fn) { srcyuv_fp = fopen(srcyuv_fn,"r"); @@ -1031,7 +1033,7 @@ static int setup_encode() /* create source surfaces */ va_status = vaCreateSurfaces(va_dpy, VA_RT_FORMAT_YUV420, frame_width, frame_height, - &src_surface[0], SRC_SURFACE_NUM, + &src_surface[0], SURFACE_NUM, NULL, 0); CHECK_VASTATUS(va_status, "vaCreateSurfaces"); @@ -1039,27 +1041,27 @@ static int setup_encode() va_status = vaCreateSurfaces( va_dpy, VA_RT_FORMAT_YUV420, frame_width, frame_height, - &ref_surface[0], h264_maxref, + &ref_surface[0], SURFACE_NUM, NULL, 0 ); CHECK_VASTATUS(va_status, "vaCreateSurfaces"); - tmp_surfaceid = calloc(SRC_SURFACE_NUM + h264_maxref, sizeof(VASurfaceID)); - memcpy(tmp_surfaceid, src_surface, SRC_SURFACE_NUM * sizeof(VASurfaceID)); - memcpy(tmp_surfaceid + SRC_SURFACE_NUM, ref_surface, h264_maxref * sizeof(VASurfaceID)); + tmp_surfaceid = calloc(2 * SURFACE_NUM, sizeof(VASurfaceID)); + memcpy(tmp_surfaceid, src_surface, SURFACE_NUM * sizeof(VASurfaceID)); + memcpy(tmp_surfaceid + SURFACE_NUM, ref_surface, SURFACE_NUM * sizeof(VASurfaceID)); /* Create a context for this encode pipe */ va_status = vaCreateContext(va_dpy, config_id, frame_width, frame_height, VA_PROGRESSIVE, - tmp_surfaceid, SRC_SURFACE_NUM + h264_maxref, + tmp_surfaceid, 2 * SURFACE_NUM, &context_id); CHECK_VASTATUS(va_status, "vaCreateContext"); free(tmp_surfaceid); codedbuf_size = (frame_width * frame_height * 400) / (16*16); - for (i = 0; i < SRC_SURFACE_NUM; i++) { + for (i = 0; i < SURFACE_NUM; i++) { /* create coded buffer once for all * other VA buffers which won't be used again after vaRenderPicture. * so APP can always vaCreateBuffer for every frame @@ -1074,6 +1076,122 @@ static int setup_encode() return 0; } + + +#define partition(ref, field, key, ascending) \ + while (i <= j) { \ + if (ascending) { \ + while (ref[i].field < key) \ + i++; \ + while (ref[j].field > key) \ + j--; \ + } else { \ + while (ref[i].field > key) \ + i++; \ + while (ref[j].field < key) \ + j--; \ + } \ + if (i <= j) { \ + tmp = ref[i]; \ + ref[i] = ref[j]; \ + ref[j] = tmp; \ + i++; \ + j--; \ + } \ + } \ + +static void sort_one(VAPictureH264 ref[], int left, int right, + int ascending, int frame_idx) +{ + int i = left, j = right; + unsigned int key; + VAPictureH264 tmp; + + if (frame_idx) { + key = ref[(left + right) / 2].frame_idx; + partition(ref, frame_idx, key, ascending); + } else { + key = ref[(left + right) / 2].TopFieldOrderCnt; + partition(ref, TopFieldOrderCnt, key, ascending); + } + + /* recursion */ + if (left < j) + sort_one(ref, left, j, ascending, frame_idx); + + if (i < right) + sort_one(ref, i, right, ascending, frame_idx); +} + +static void sort_two(VAPictureH264 ref[], int left, int right, int key, int frame_idx, + int divide_ascending, int list0_ascending, int list1_ascending) +{ + int i = left, j = right; + VAPictureH264 tmp; + + if (frame_idx) { + partition(ref, frame_idx, key, divide_ascending); + } else { + partition(ref, TopFieldOrderCnt, key, divide_ascending); + } + + + sort_one(ref, left, i-1, list0_ascending, frame_idx); + sort_one(ref, j+1, right, list1_ascending, frame_idx); +} + +static int update_ReferenceFrames(void) +{ + int i; + + if (current_frame_type == FRAME_B) + return 0; + + CurrentCurrPic.flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE; + numShortTerm++; + if (numShortTerm > num_ref_frames) + numShortTerm = num_ref_frames; + for (i=numShortTerm-1; i>0; i--) + ReferenceFrames[i] = ReferenceFrames[i-1]; + ReferenceFrames[0] = CurrentCurrPic; + + if (current_frame_type != FRAME_B) + current_frame_num++; + if (current_frame_num > MaxFrameNum) + current_frame_num = 0; + + return 0; +} + +static int update_RefPicList(void) +{ + unsigned int current_poc = CurrentCurrPic.TopFieldOrderCnt; + + if (current_frame_type == FRAME_IDR) { + numShortTerm = 0; + current_frame_num = 0; + return 0; + } + + if (current_frame_type == FRAME_P) { + memcpy(RefPicList0_P, ReferenceFrames, numShortTerm * sizeof(VAPictureH264)); + sort_one(RefPicList0_P, 0, numShortTerm-1, 0, 1); + } + + if (current_frame_type == FRAME_B) { + memcpy(RefPicList0_B, ReferenceFrames, numShortTerm * sizeof(VAPictureH264)); + sort_two(RefPicList0_B, 0, numShortTerm-1, current_poc, 0, + 1, 0, 1); + + memcpy(RefPicList1_B, ReferenceFrames, numShortTerm * sizeof(VAPictureH264)); + sort_two(RefPicList1_B, 0, numShortTerm-1, current_poc, 0, + 0, 1, 0); + } + + return 0; +} + + static int render_sequence(void) { VABufferID seq_param_buf, rc_param_buf, render_id[2]; @@ -1090,11 +1208,12 @@ static int render_sequence(void) seq_param.intra_idr_period = intra_idr_period; seq_param.ip_period = ip_period; - seq_param.max_num_ref_frames = h264_maxref; + seq_param.max_num_ref_frames = num_ref_frames; seq_param.seq_fields.bits.frame_mbs_only_flag = 1; seq_param.time_scale = 900; seq_param.num_units_in_tick = 15; /* Tc = num_units_in_tick / time_sacle */ - seq_param.seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = 2; + seq_param.seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = Log2MaxPicOrderCntLsb - 4; + seq_param.seq_fields.bits.log2_max_frame_num_minus4 = Log2MaxFrameNum - 4;; seq_param.seq_fields.bits.frame_mbs_only_flag = 1; va_status = vaCreateBuffer(va_dpy, context_id, @@ -1127,61 +1246,58 @@ static int render_sequence(void) return 0; } +static unsigned int calc_poc(unsigned int pic_order_cnt_lsb) +{ + static unsigned int prevPicOrderCntMsb = 0, prevPicOrderCntLsb = 0; + static unsigned int PicOrderCntMsb = 0; + unsigned int TopFieldOrderCnt; + + if (current_frame_type == FRAME_IDR) + prevPicOrderCntMsb = prevPicOrderCntLsb = 0; + + prevPicOrderCntMsb = PicOrderCntMsb; + if ((pic_order_cnt_lsb < prevPicOrderCntLsb) && + ((prevPicOrderCntLsb - pic_order_cnt_lsb) >= (MaxPicOrderCntLsb / 2))) + PicOrderCntMsb = prevPicOrderCntMsb + MaxPicOrderCntLsb; + else if ((pic_order_cnt_lsb > prevPicOrderCntLsb) && + ((pic_order_cnt_lsb - prevPicOrderCntLsb) > (MaxPicOrderCntLsb / 2))) + PicOrderCntMsb = prevPicOrderCntMsb - MaxPicOrderCntLsb; + else + PicOrderCntMsb = prevPicOrderCntMsb; + + TopFieldOrderCnt = PicOrderCntMsb + pic_order_cnt_lsb; + + return TopFieldOrderCnt; +} + static int render_picture(void) { VABufferID pic_param_buf; VAStatus va_status; int i = 0; - /* use frame_num as reference frame index */ - pic_param.CurrPic.picture_id = ref_surface[current_frame_num % h264_maxref]; - //pic_param.CurrPic.frame_idx = current_frame_num % h264_maxref; + pic_param.CurrPic.picture_id = ref_surface[current_slot]; + pic_param.CurrPic.frame_idx = current_frame_num; pic_param.CurrPic.flags = 0; - pic_param.CurrPic.TopFieldOrderCnt = 2 * current_frame_display; - pic_param.CurrPic.BottomFieldOrderCnt = 0; - if (current_frame_type != FRAME_B) - CurrentCurrPic = pic_param.CurrPic; /* save it */ - - if (slice_refoverride) { - /* always setup all reference frame into encoder */ - for (i = 0; i < h264_maxref; i++) { - pic_param.ReferenceFrames[i].picture_id = ref_surface[i]; - pic_param.ReferenceFrames[i].frame_idx = i; - pic_param.ReferenceFrames[i].flags = 0; - if (pic_param.CurrPic.picture_id == pic_param.ReferenceFrames[i].picture_id) { - pic_param.ReferenceFrames[i].TopFieldOrderCnt = 2 * current_frame_encoding; - //pic_param.ReferenceFrames[i].picture_id = VA_INVALID_SURFACE; - //pic_param.ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID; - } - pic_param.ReferenceFrames[i].BottomFieldOrderCnt = 0; - } - } else { - if (current_frame_type == FRAME_I || current_frame_type == FRAME_IDR) - i = 0; - else if (current_frame_type == FRAME_P) { - pic_param.ReferenceFrames[0] = LastCurrPic; - pic_param.ReferenceFrames[0].flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE; - i = 1; - //#if 0 - if (LLastCurrPic.picture_id == VA_INVALID_SURFACE) - pic_param.ReferenceFrames[1] = LastCurrPic; - else - pic_param.ReferenceFrames[1] = LLastCurrPic; - pic_param.ReferenceFrames[1].flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE; - i = 2; - //#endif + pic_param.CurrPic.TopFieldOrderCnt = calc_poc(current_frame_display % MaxPicOrderCntLsb); + pic_param.CurrPic.BottomFieldOrderCnt = pic_param.CurrPic.TopFieldOrderCnt; + CurrentCurrPic = pic_param.CurrPic; + + if (getenv("TO_DEL")) { + update_RefPicList(); + memset(pic_param.ReferenceFrames, 1, 16 * sizeof(VAPictureH264)); + if (current_frame_type == FRAME_P) { + pic_param.ReferenceFrames[0] = RefPicList0_P[0]; } else if (current_frame_type == FRAME_B) { - pic_param.ReferenceFrames[0] = LLastCurrPic; - pic_param.ReferenceFrames[0].flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE; - pic_param.ReferenceFrames[1] = LastCurrPic; - pic_param.ReferenceFrames[1].flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE; - i = 2; + pic_param.ReferenceFrames[0] = RefPicList0_B[0]; + pic_param.ReferenceFrames[1] = RefPicList1_B[0]; + } + } else { + memcpy(pic_param.ReferenceFrames, ReferenceFrames, numShortTerm*sizeof(VAPictureH264)); + for (i = numShortTerm; i < SURFACE_NUM; i++) { + pic_param.ReferenceFrames[i].picture_id = VA_INVALID_SURFACE; + pic_param.ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID; } - } - - for (; i < REF_SURFACE_NUM; i++) { - pic_param.ReferenceFrames[i].picture_id = VA_INVALID_SURFACE; - pic_param.ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID; } pic_param.pic_fields.bits.idr_pic_flag = (current_frame_type == FRAME_IDR); @@ -1189,9 +1305,7 @@ static int render_picture(void) pic_param.pic_fields.bits.entropy_coding_mode_flag = 1; pic_param.pic_fields.bits.deblocking_filter_control_present_flag = 1; pic_param.frame_num = current_frame_num; - if (current_frame_type != FRAME_B) - current_frame_num++; - pic_param.coded_buf = coded_buf[current_frame_display % SRC_SURFACE_NUM]; + pic_param.coded_buf = coded_buf[current_slot]; pic_param.last_picture = (current_frame_encoding == frame_count); pic_param.pic_init_qp = initial_qp; @@ -1385,38 +1499,51 @@ static int render_slice(void) VABufferID slice_param_buf; VAStatus va_status; int i; + + update_RefPicList(); /* one frame, one slice */ slice_param.macroblock_address = 0; slice_param.num_macroblocks = frame_width*frame_height/(16*16); /* Measured by MB */ slice_param.slice_type = (current_frame_type == FRAME_IDR)?2:current_frame_type; + if (current_frame_type == FRAME_I || current_frame_type == FRAME_IDR) { + ; + } else if (current_frame_type == FRAME_P) { + int refpiclist0_max = h264_maxref & 0xffff; + memcpy(slice_param.RefPicList0, RefPicList0_P, refpiclist0_max*sizeof(VAPictureH264)); + + for (i = refpiclist0_max; i < 32; i++) { + slice_param.RefPicList0[i].picture_id = VA_INVALID_SURFACE; + slice_param.RefPicList0[i].flags = VA_PICTURE_H264_INVALID; + } + } else if (current_frame_type == FRAME_B) { + int refpiclist0_max = h264_maxref & 0xffff; + int refpiclist1_max = (h264_maxref >> 16) & 0xffff; + + memcpy(slice_param.RefPicList0, RefPicList0_B, refpiclist0_max*sizeof(VAPictureH264)); + for (i = refpiclist0_max; i < 32; i++) { + slice_param.RefPicList0[i].picture_id = VA_INVALID_SURFACE; + slice_param.RefPicList0[i].flags = VA_PICTURE_H264_INVALID; + } - for (i = 0; i < 32; i++) { - slice_param.RefPicList0[i].picture_id = VA_INVALID_SURFACE; - slice_param.RefPicList0[i].flags = VA_PICTURE_H264_INVALID; - slice_param.RefPicList1[i].picture_id = VA_INVALID_SURFACE; - slice_param.RefPicList1[i].flags = VA_PICTURE_H264_INVALID; + memcpy(slice_param.RefPicList1, RefPicList1_B, refpiclist1_max*sizeof(VAPictureH264)); + for (i = refpiclist1_max; i < 32; i++) { + slice_param.RefPicList1[i].picture_id = VA_INVALID_SURFACE; + slice_param.RefPicList1[i].flags = VA_PICTURE_H264_INVALID; + } } - /* cause issue on some implementation if slice_refoverride = 1 */ - //slice_param.num_ref_idx_active_override_flag = 1; - if (slice_refoverride) { - /* set the real reference frame */ - if (current_frame_type == FRAME_I || current_frame_type == FRAME_IDR) { - ; - } else if (current_frame_type == FRAME_P) { - slice_param.RefPicList0[0] = LastCurrPic; - slice_param.RefPicList0[0].flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE; - } else if (current_frame_type == FRAME_B) { - slice_param.RefPicList0[0] = LLastCurrPic; - slice_param.RefPicList0[0].flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE; - slice_param.RefPicList1[0] = LastCurrPic; - slice_param.RefPicList1[0].flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE; + if (getenv("NOREF")) { + for (i = 0; i < 32; i++) { + slice_param.RefPicList0[i].picture_id = VA_INVALID_SURFACE; + slice_param.RefPicList1[i].picture_id = VA_INVALID_SURFACE; } } + + slice_param.slice_alpha_c0_offset_div2 = 2; slice_param.slice_beta_offset_div2 = 2; - slice_param.pic_order_cnt_lsb = current_frame_display % 64; + slice_param.pic_order_cnt_lsb = current_frame_display % MaxPicOrderCntLsb; va_status = vaCreateBuffer(va_dpy,context_id,VAEncSliceParameterBufferType, sizeof(slice_param),1,&slice_param,&slice_param_buf); @@ -1429,25 +1556,13 @@ static int render_slice(void) } -static int update_reflist(void) -{ - if (current_frame_type == FRAME_B) - return 0; - - LLastCurrPic = LastCurrPic; - LastCurrPic = CurrentCurrPic; - - return 0; -} - - static int upload_source_YUV_once_for_all() { int box_width=8; int row_shift=0; int i; - for (i = 0; i < SRC_SURFACE_NUM; i++) { + for (i = 0; i < SURFACE_NUM; i++) { printf("\rLoading data into surface %d.....", i); upload_surface(va_dpy, src_surface[i], box_width, row_shift, 0); @@ -1463,8 +1578,8 @@ static int upload_source_YUV_once_for_all() static int load_surface(VASurfaceID surface_id, unsigned long long display_order) { VAImage surface_image; - unsigned char *surface_p=NULL, *Y_start=NULL, *U_start=NULL,*V_start=NULL; - int Y_pitch=0, U_pitch=0, row, V_pitch; + unsigned char *surface_p=NULL, *Y_start=NULL, *U_start=NULL,*V_start=NULL, *uv_ptr; + int Y_pitch=0, U_pitch=0, row, V_pitch, uv_size; VAStatus va_status; if (srcyuv_fp == NULL) @@ -1524,30 +1639,42 @@ static int load_surface(VASurfaceID surface_id, unsigned long long display_order fseek(srcyuv_fp, display_order * frame_width * frame_height * 1.5 + frame_width * frame_height, SEEK_SET); + + uv_size = 2 * (frame_width/2) * (frame_height/2); + uv_ptr = malloc(uv_size); + fread(uv_ptr, uv_size, 1, srcyuv_fp); for (row =0; row < surface_image.height/2; row++) { unsigned char *U_row = U_start + row * U_pitch; - //unsigned char *V_row = V_start + row * V_pitch; + unsigned char *u_ptr, *v_ptr; + int j; switch (surface_image.format.fourcc) { case VA_FOURCC_NV12: - if (srcyuv_fourcc == VA_FOURCC_NV12) - (void)fread(U_row, 1, surface_image.width, srcyuv_fp); - else if (srcyuv_fourcc == VA_FOURCC_IYUV) { - /* tbd */ + if (srcyuv_fourcc == VA_FOURCC_NV12) { + memcpy(U_row, uv_ptr + row * frame_width, frame_width); + break; + } else if (srcyuv_fourcc == VA_FOURCC_IYUV) { + u_ptr = uv_ptr + row * (frame_width/2); + v_ptr = uv_ptr + (frame_width/2) * (frame_height/2) + row * (frame_width/2); + } else if (srcyuv_fourcc == VA_FOURCC_YV12) { + v_ptr = uv_ptr + row * (frame_height/2); + u_ptr = uv_ptr + (frame_width/2) * (frame_height/2) + row * (frame_width/2); + } + for(j = 0; j < frame_width/2; j++) { + U_row[2*j] = u_ptr[j]; + U_row[2*j+1] = v_ptr[j]; } break; + case VA_FOURCC_IYUV: case VA_FOURCC_YV12: - /* tbd */ - break; case VA_FOURCC_YUY2: - // see above. it is set with Y update. - break; default: printf("unsupported fourcc in load_surface\n"); assert(0); } } - + free(uv_ptr); + vaUnmapBuffer(va_dpy,surface_image.buf); vaDestroyImage(va_dpy,surface_image.image_id); @@ -1562,13 +1689,13 @@ static int save_codeddata(unsigned long long display_order, unsigned long long e VAStatus va_status; unsigned int coded_size = 0; - va_status = vaMapBuffer(va_dpy,coded_buf[display_order % SRC_SURFACE_NUM],(void **)(&buf_list)); + va_status = vaMapBuffer(va_dpy,coded_buf[display_order % SURFACE_NUM],(void **)(&buf_list)); CHECK_VASTATUS(va_status,"vaMapBuffer"); while (buf_list != NULL) { coded_size += fwrite(buf_list->buf, 1, buf_list->size, coded_fp); buf_list = (VACodedBufferSegment *) buf_list->next; } - vaUnmapBuffer(va_dpy,coded_buf[display_order % SRC_SURFACE_NUM]); + vaUnmapBuffer(va_dpy,coded_buf[display_order % SURFACE_NUM]); printf("\r "); /* return back to startpoint */ switch (encode_order % 4) { @@ -1636,7 +1763,7 @@ static int storage_task_queue(unsigned long long display_order, unsigned long lo storage_task_tail = tmp; } - srcsurface_status[display_order % SRC_SURFACE_NUM] = SRC_SURFACE_IN_STORAGE; + srcsurface_status[display_order % SURFACE_NUM] = SRC_SURFACE_IN_STORAGE; pthread_cond_signal(&encode_cond); pthread_mutex_unlock(&encode_mutex); @@ -1650,7 +1777,7 @@ static void storage_task(unsigned long long display_order, unsigned long encode_ VAStatus va_status; tmp = GetTickCount(); - va_status = vaSyncSurface(va_dpy, src_surface[display_order % SRC_SURFACE_NUM]); + va_status = vaSyncSurface(va_dpy, src_surface[display_order % SURFACE_NUM]); CHECK_VASTATUS(va_status,"vaSyncSurface"); SyncPictureTicks += GetTickCount() - tmp; tmp = GetTickCount(); @@ -1661,11 +1788,11 @@ static void storage_task(unsigned long long display_order, unsigned long encode_ /* reload a new frame data */ tmp = GetTickCount(); if (srcyuv_fp != NULL) - load_surface(src_surface[display_order % SRC_SURFACE_NUM], display_order + SRC_SURFACE_NUM); + load_surface(src_surface[display_order % SURFACE_NUM], display_order + SURFACE_NUM); UploadPictureTicks += GetTickCount() - tmp; pthread_mutex_lock(&encode_mutex); - srcsurface_status[display_order % SRC_SURFACE_NUM] = SRC_SURFACE_IN_ENCODING; + srcsurface_status[display_order % SURFACE_NUM] = SRC_SURFACE_IN_ENCODING; pthread_mutex_unlock(&encode_mutex); } @@ -1705,7 +1832,7 @@ static int encode_frames(void) /* upload RAW YUV data into all surfaces */ tmp = GetTickCount(); if (srcyuv_fp != NULL) { - for (i = 0; i < SRC_SURFACE_NUM; i++) + for (i = 0; i < SURFACE_NUM; i++) load_surface(src_surface[i], i); } else upload_source_YUV_once_for_all(); @@ -1726,10 +1853,10 @@ static int encode_frames(void) ¤t_frame_display, ¤t_frame_type); /* check if the source frame is ready */ - while (srcsurface_status[current_frame_display % SRC_SURFACE_NUM] != SRC_SURFACE_IN_ENCODING); + while (srcsurface_status[current_slot] != SRC_SURFACE_IN_ENCODING); tmp = GetTickCount(); - va_status = vaBeginPicture(va_dpy, context_id, src_surface[current_frame_display % SRC_SURFACE_NUM]); + va_status = vaBeginPicture(va_dpy, context_id, src_surface[current_slot]); CHECK_VASTATUS(va_status,"vaBeginPicture"); BeginPictureTicks += GetTickCount() - tmp; @@ -1766,11 +1893,10 @@ static int encode_frames(void) /* how to process skipped frames surface_status = (VASurfaceStatus) 0; - va_status = vaQuerySurfaceStatus(va_dpy, src_surface[i%SRC_SURFACE_NUM],&surface_status); + va_status = vaQuerySurfaceStatus(va_dpy, src_surface[i%SURFACE_NUM],&surface_status); frame_skipped = (surface_status & VASurfaceSkipped); */ - - update_reflist(); + update_ReferenceFrames(); } if (encode_syncmode == 0) { @@ -1786,10 +1912,10 @@ static int release_encode() { int i; - vaDestroySurfaces(va_dpy,&src_surface[0],SRC_SURFACE_NUM); - vaDestroySurfaces(va_dpy,&ref_surface[0],h264_maxref); + vaDestroySurfaces(va_dpy,&src_surface[0],SURFACE_NUM); + vaDestroySurfaces(va_dpy,&ref_surface[0],SURFACE_NUM); - for (i = 0; i < SRC_SURFACE_NUM; i++) + for (i = 0; i < SURFACE_NUM; i++) vaDestroyBuffer(va_dpy,coded_buf[i]); vaDestroyContext(va_dpy,context_id); |