void gen75_update_avc_frame_store_index( VADriverContextP ctx, struct decode_state *decode_state, VAPictureParameterBufferH264 *pic_param, GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES] ) { int i, n; /* Construct the Frame Store array, in compact form. i.e. empty or invalid entries are discarded. */ for (i = 0, n = 0; i < ARRAY_ELEMS(decode_state->reference_objects); i++) { struct object_surface * const obj_surface = decode_state->reference_objects[i]; if (!obj_surface) continue; GenFrameStore * const fs = &frame_store[n]; fs->surface_id = obj_surface->base.id; fs->obj_surface = obj_surface; fs->frame_store_id = n++; } /* Any remaining entry is marked as invalid */ for (; n < MAX_GEN_REFERENCE_FRAMES; n++) { GenFrameStore * const fs = &frame_store[n]; fs->surface_id = VA_INVALID_ID; fs->obj_surface = NULL; fs->frame_store_id = -1; } }
uint32_t image_rgba_format( int bits_per_pixel, int is_msb_first, unsigned int red_mask, unsigned int green_mask, unsigned int blue_mask, unsigned int alpha_mask ) { static const struct { int fourcc; unsigned char bits_per_pixel; unsigned char is_msb_first; unsigned int red_mask; unsigned int green_mask; unsigned int blue_mask; unsigned int alpha_mask; } #define BE 1 #define LE 0 #ifdef WORDS_BIGENDIAN #define NE BE #define OE LE #else #define NE LE #define OE BE #endif pixfmts[] = { { IMAGE_FORMAT_NE(ABGR, RGBA), 32, NE, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }, { IMAGE_FORMAT_NE(ABGR, RGBA), 32, OE, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff }, { IMAGE_FORMAT_NE(ARGB, BGRA), 32, NE, 0x00ff0000, 0x0000ff00, 0x000000ff, 0xff000000 }, { IMAGE_FORMAT_NE(ARGB, BGRA), 32, OE, 0x0000ff00, 0x00ff0000, 0xff000000, 0x000000ff }, { IMAGE_FORMAT_NE(RGBA, ABGR), 32, NE, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff }, { IMAGE_FORMAT_NE(RGBA, ABGR), 32, OE, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000 }, }; int i; for (i = 0; i < ARRAY_ELEMS(pixfmts); i++) { if (pixfmts[i].bits_per_pixel == bits_per_pixel && pixfmts[i].is_msb_first == is_msb_first && pixfmts[i].red_mask == red_mask && pixfmts[i].green_mask == green_mask && pixfmts[i].blue_mask == blue_mask && pixfmts[i].alpha_mask == alpha_mask) return pixfmts[i].fourcc; } return 0; }
// vaQueryConfigProfiles VAStatus vdpau_QueryConfigProfiles( VADriverContextP ctx, VAProfile *profile_list, int *num_profiles ) { VDPAU_DRIVER_DATA_INIT; static const VAProfile va_profiles[] = { VAProfileMPEG2Simple, VAProfileMPEG2Main, VAProfileMPEG4Simple, VAProfileMPEG4AdvancedSimple, VAProfileMPEG4Main, VAProfileH264Baseline, VAProfileH264Main, VAProfileH264High, VAProfileVC1Simple, VAProfileVC1Main, VAProfileVC1Advanced }; int i, n = 0; for (i = 0; i < ARRAY_ELEMS(va_profiles); i++) { VAProfile profile = va_profiles[i]; VdpDecoderProfile vdp_profile = get_VdpDecoderProfile(profile); if (is_supported_profile(driver_data, vdp_profile)) profile_list[n++] = profile; } /* If the assert fails then VDPAU_MAX_PROFILES needs to be bigger */ ASSERT(n <= VDPAU_MAX_PROFILES); if (num_profiles) *num_profiles = n; return VA_STATUS_SUCCESS; }
VOID media_destroy_context (struct object_heap *heap, struct object_base *obj) { struct object_context *obj_context = (struct object_context *) obj; INT i; if (obj_context->hw_context) { obj_context->hw_context->destroy (obj_context->hw_context); obj_context->hw_context = NULL; } if (obj_context->codec_type == CODEC_ENC) { MEDIA_DRV_ASSERT (obj_context->codec_state.encode.num_slice_params <= obj_context->codec_state.encode.max_slice_params); media_release_buffer_store (&obj_context->codec_state.encode.pic_param); media_release_buffer_store (&obj_context->codec_state.encode.seq_param); media_release_buffer_store (&obj_context->codec_state.encode.q_matrix); for (i = 0; i < obj_context->codec_state.encode.num_slice_params; i++) media_release_buffer_store (&obj_context->codec_state.encode. slice_params[i]); media_drv_free_memory (obj_context->codec_state.encode.slice_params); MEDIA_DRV_ASSERT (obj_context->codec_state.encode. num_slice_params_ext <= obj_context->codec_state.encode.max_slice_params_ext); media_release_buffer_store (&obj_context->codec_state.encode. pic_param_ext); media_release_buffer_store (&obj_context->codec_state.encode. seq_param_ext); media_release_buffer_store (&obj_context->codec_state. encode.frame_update_param); for (i = 0; i < ARRAY_ELEMS (obj_context->codec_state.encode.packed_header_param); i++) media_release_buffer_store (&obj_context->codec_state.encode. packed_header_param[i]); for (i = 0; i < ARRAY_ELEMS (obj_context->codec_state.encode.packed_header_data); i++) media_release_buffer_store (&obj_context->codec_state.encode. packed_header_data[i]); for (i = 0; i < ARRAY_ELEMS (obj_context->codec_state.encode.misc_param); i++) media_release_buffer_store (&obj_context->codec_state.encode. misc_param[i]); for (i = 0; i < obj_context->codec_state.encode.num_slice_params_ext; i++) media_release_buffer_store (&obj_context->codec_state.encode. slice_params_ext[i]); media_drv_free_memory (obj_context->codec_state.encode. slice_params_ext); } else if (obj_context->codec_type == CODEC_DEC) { media_release_buffer_store(&obj_context->codec_state.decode.pic_param); media_release_buffer_store(&obj_context->codec_state.decode.iq_matrix); media_release_buffer_store(&obj_context->codec_state.decode.bit_plane); media_release_buffer_store(&obj_context->codec_state.decode.huffman_table); for (i = 0; i < obj_context->codec_state.decode.num_slice_params; i++) { media_release_buffer_store(&obj_context->codec_state.decode.slice_params[i]); media_release_buffer_store(&obj_context->codec_state.decode.slice_datas[i]); } media_drv_free_memory (obj_context->codec_state.decode.slice_params); media_drv_free_memory (obj_context->codec_state.decode.slice_datas); } media_drv_free_memory (obj_context->render_targets); object_heap_free (heap, obj); }
int vaapi_exit(void) { VAAPIContext * const vaapi = vaapi_get_context(); unsigned int i; if (!vaapi) return 0; #if USE_GLX if (display_type() == DISPLAY_GLX) vaapi_glx_destroy_surface(); #endif destroy_buffers(vaapi->display, &vaapi->pic_param_buf_id, 1); destroy_buffers(vaapi->display, &vaapi->iq_matrix_buf_id, 1); destroy_buffers(vaapi->display, &vaapi->bitplane_buf_id, 1); destroy_buffers(vaapi->display, vaapi->slice_buf_ids, vaapi->n_slice_buf_ids); if (vaapi->subpic_flags) { free(vaapi->subpic_flags); vaapi->subpic_flags = NULL; } if (vaapi->subpic_formats) { free(vaapi->subpic_formats); vaapi->subpic_formats = NULL; vaapi->n_subpic_formats = 0; } if (vaapi->image_formats) { free(vaapi->image_formats); vaapi->image_formats = NULL; vaapi->n_image_formats = 0; } if (vaapi->entrypoints) { free(vaapi->entrypoints); vaapi->entrypoints = NULL; vaapi->n_entrypoints = 0; } if (vaapi->profiles) { free(vaapi->profiles); vaapi->profiles = NULL; vaapi->n_profiles = 0; } if (vaapi->slice_params) { free(vaapi->slice_params); vaapi->slice_params = NULL; vaapi->slice_params_alloc = 0; vaapi->n_slice_params = 0; } if (vaapi->slice_buf_ids) { free(vaapi->slice_buf_ids); vaapi->slice_buf_ids = NULL; vaapi->n_slice_buf_ids = 0; } if (vaapi->subpic_image.image_id != VA_INVALID_ID) { vaDestroyImage(vaapi->display, vaapi->subpic_image.image_id); vaapi->subpic_image.image_id = VA_INVALID_ID; } for (i = 0; i < ARRAY_ELEMS(vaapi->subpic_ids); i++) { if (vaapi->subpic_ids[i] != VA_INVALID_ID) { vaDestroySubpicture(vaapi->display, vaapi->subpic_ids[i]); vaapi->subpic_ids[i] = VA_INVALID_ID; } } if (vaapi->surface_id) { vaDestroySurfaces(vaapi->display, &vaapi->surface_id, 1); vaapi->surface_id = 0; } if (vaapi->context_id) { vaDestroyContext(vaapi->display, vaapi->context_id); vaapi->context_id = 0; } if (vaapi->config_id) { vaDestroyConfig(vaapi->display, vaapi->config_id); vaapi->config_id = 0; } if (vaapi->display) { vaTerminate(vaapi->display); vaapi->display = NULL; } free(vaapi_context); return 0; }
int vaapi_init(VADisplay display) { #if 0 CommonContext * common = common_get_context(); #endif VAAPIContext *vaapi; int major_version, minor_version; int i, num_display_attrs, max_display_attrs; VADisplayAttribute *display_attrs; VAStatus status; if (vaapi_context) return 0; if (!display) return -1; D(bug("VA display %p\n", display)); status = vaInitialize(display, &major_version, &minor_version); if (!vaapi_check_status(status, "vaInitialize()")) return -1; D(bug("VA API version %d.%d\n", major_version, minor_version)); max_display_attrs = vaMaxNumDisplayAttributes(display); display_attrs = malloc(max_display_attrs * sizeof(display_attrs[0])); if (!display_attrs) return -1; num_display_attrs = 0; /* XXX: workaround old GMA500 bug */ status = vaQueryDisplayAttributes(display, display_attrs, &num_display_attrs); if (!vaapi_check_status(status, "vaQueryDisplayAttributes()")) { free(display_attrs); return -1; } D(bug("%d display attributes available\n", num_display_attrs)); for (i = 0; i < num_display_attrs; i++) { VADisplayAttribute * const display_attr = &display_attrs[i]; D(bug(" %-32s (%s/%s) min %d max %d value 0x%x\n", string_of_VADisplayAttribType(display_attr->type), (display_attr->flags & VA_DISPLAY_ATTRIB_GETTABLE) ? "get" : "---", (display_attr->flags & VA_DISPLAY_ATTRIB_SETTABLE) ? "set" : "---", display_attr->min_value, display_attr->max_value, display_attr->value)); } free(display_attrs); #if 0 if (common->use_vaapi_background_color) { VADisplayAttribute attr; attr.type = VADisplayAttribBackgroundColor; attr.value = common->vaapi_background_color; status = vaSetDisplayAttributes(display, &attr, 1); if (!vaapi_check_status(status, "vaSetDisplayAttributes()")) return -1; } #endif if ((vaapi = calloc(1, sizeof(*vaapi))) == NULL) return -1; vaapi->display = display; vaapi->subpic_image.image_id = VA_INVALID_ID; for (i = 0; i < ARRAY_ELEMS(vaapi->subpic_ids); i++) vaapi->subpic_ids[i] = VA_INVALID_ID; vaapi_context = vaapi; return 0; }
static VAStatus intel_decoder_check_avc_parameter(VADriverContextP ctx, VAProfile h264_profile, struct decode_state *decode_state) { struct i965_driver_data *i965 = i965_driver_data(ctx); VAPictureParameterBufferH264 *pic_param = (VAPictureParameterBufferH264 *)decode_state->pic_param->buffer; VAStatus va_status; struct object_surface *obj_surface; int i; VASliceParameterBufferH264 *slice_param, *next_slice_param, *next_slice_group_param; int j; assert(!(pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID)); assert(pic_param->CurrPic.picture_id != VA_INVALID_SURFACE); if (pic_param->CurrPic.flags & VA_PICTURE_H264_INVALID || pic_param->CurrPic.picture_id == VA_INVALID_SURFACE) goto error; assert(pic_param->CurrPic.picture_id == decode_state->current_render_target); if (pic_param->CurrPic.picture_id != decode_state->current_render_target) goto error; if ((h264_profile != VAProfileH264Baseline)) { if (pic_param->num_slice_groups_minus1 || pic_param->pic_fields.bits.redundant_pic_cnt_present_flag) { WARN_ONCE("Unsupported the FMO/ASO constraints!!!\n"); goto error; } } /* Fill in the reference objects array with the actual VA surface objects with 1:1 correspondance with any entry in ReferenceFrames[], i.e. including "holes" for invalid entries, that are expanded to NULL in the reference_objects[] array */ for (i = 0; i < ARRAY_ELEMS(pic_param->ReferenceFrames); i++) { const VAPictureH264 * const va_pic = &pic_param->ReferenceFrames[i]; obj_surface = NULL; if (!(va_pic->flags & VA_PICTURE_H264_INVALID) && va_pic->picture_id != VA_INVALID_ID) { obj_surface = SURFACE(pic_param->ReferenceFrames[i].picture_id); if (!obj_surface) return VA_STATUS_ERROR_INVALID_SURFACE; /* * Sometimes a dummy frame comes from the upper layer * library, call i965_check_alloc_surface_bo() to make * sure the store buffer is allocated for this reference * frame */ va_status = avc_ensure_surface_bo(ctx, decode_state, obj_surface, pic_param); if (va_status != VA_STATUS_SUCCESS) return va_status; } decode_state->reference_objects[i] = obj_surface; } for (j = 0; j < decode_state->num_slice_params; j++) { assert(decode_state->slice_params && decode_state->slice_params[j]->buffer); slice_param = (VASliceParameterBufferH264 *)decode_state->slice_params[j]->buffer; if (j == decode_state->num_slice_params - 1) next_slice_group_param = NULL; else next_slice_group_param = (VASliceParameterBufferH264 *)decode_state->slice_params[j + 1]->buffer; for (i = 0; i < decode_state->slice_params[j]->num_elements; i++) { if (i < decode_state->slice_params[j]->num_elements - 1) next_slice_param = slice_param + 1; else next_slice_param = next_slice_group_param; if (next_slice_param != NULL) { /* If the mb position of next_slice is less than or equal to the current slice, * discard the current frame. */ if (next_slice_param->first_mb_in_slice <= slice_param->first_mb_in_slice) { next_slice_param = NULL; WARN_ONCE("!!!incorrect slice_param. The first_mb_in_slice of next_slice is less" " than or equal to that in current slice\n"); goto error; } } } } return VA_STATUS_SUCCESS; error: return VA_STATUS_ERROR_INVALID_PARAMETER; }
void intel_update_avc_frame_store_index( VADriverContextP ctx, struct decode_state *decode_state, VAPictureParameterBufferH264 *pic_param, GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES], GenFrameStoreContext *fs_ctx ) { GenFrameStore *free_refs[MAX_GEN_REFERENCE_FRAMES]; uint32_t used_refs = 0, add_refs = 0; uint64_t age; int i, n, num_free_refs; /* Detect changes of access unit */ const int poc = avc_get_picture_poc(&pic_param->CurrPic); if (fs_ctx->age == 0 || fs_ctx->prev_poc != poc) fs_ctx->age++; fs_ctx->prev_poc = poc; age = fs_ctx->age; /* Tag entries that are still available in our Frame Store */ for (i = 0; i < ARRAY_ELEMS(decode_state->reference_objects); i++) { struct object_surface * const obj_surface = decode_state->reference_objects[i]; if (!obj_surface) continue; GenAvcSurface * const avc_surface = obj_surface->private_data; if (!avc_surface) continue; if (avc_surface->frame_store_id >= 0) { GenFrameStore * const fs = &frame_store[avc_surface->frame_store_id]; if (fs->surface_id == obj_surface->base.id) { fs->obj_surface = obj_surface; fs->ref_age = age; used_refs |= 1 << fs->frame_store_id; continue; } } add_refs |= 1 << i; } /* Build and sort out the list of retired candidates. The resulting list is ordered by increasing age when they were last used */ for (i = 0, n = 0; i < MAX_GEN_REFERENCE_FRAMES; i++) { if (!(used_refs & (1 << i))) { GenFrameStore * const fs = &frame_store[i]; fs->obj_surface = NULL; free_refs[n++] = fs; } } num_free_refs = n; qsort(&free_refs[0], n, sizeof(free_refs[0]), compare_avc_ref_store_func); /* Append the new reference frames */ for (i = 0, n = 0; i < ARRAY_ELEMS(decode_state->reference_objects); i++) { struct object_surface * const obj_surface = decode_state->reference_objects[i]; if (!obj_surface || !(add_refs & (1 << i))) continue; GenAvcSurface * const avc_surface = obj_surface->private_data; if (!avc_surface) continue; if (n < num_free_refs) { GenFrameStore * const fs = free_refs[n++]; fs->surface_id = obj_surface->base.id; fs->obj_surface = obj_surface; fs->frame_store_id = fs - frame_store; fs->ref_age = age; avc_surface->frame_store_id = fs->frame_store_id; continue; } WARN_ONCE("No free slot found for DPB reference list!!!\n"); } }
// 从文件名称解析分辨率及YUV格式 void find_resolution(char* filename, int& fmt_idx, int& width, int& height) { #define str_debug int i = 0; int j = 0; int len = 0; int pos = 0; char* tmp = NULL; char* p = NULL; char c_width[8] = {0}; char c_height[8] = {0}; char c_fmt[8] = {0}; char c_res[8] = {0}; char c_file[128] = {0}; const char* fmt_str[] = { "yuv420", "yv12", "yuv422", "yv16", "yuv444", "yuyv", "yvyu", "uyvy", "vyuy", "nv12", "nv21", "nv16", "nv61", "rgb", "bgr", "yuv420sp", "yuv422sp", }; const char* res_str[] = { "cif", "qcif", "480p", "720p", "1080p", }; const char* wh_str[] = { "352x288", "176x144", "720x480", "1280x720", "1920x1080", }; int idx = -1; fmt_idx = -2; // trick... #if 0 len = strlen(filename); str_debug("org string len:%d %s\b", len, filename); #endif // 查找后缀名 tmp = strrchr(filename, '.'); if (tmp != NULL) { strncpy(c_file, filename, tmp-filename); pos = strlen(tmp+1); //str_debug("find ext: %s(%d) %s %s %d\n", tmp+1, pos, filename, c_file, tmp-filename); // 查找格式字符串 for (i = 0; i < ARRAY_ELEMS(fmt_str); i++) { p = strstr(tmp+1, fmt_str[i]); if (p != NULL) { strncpy(c_fmt, p, strlen(fmt_str[i])); idx = i; } } } else { strcpy(c_file, filename); } str_debug("second string:%s \n", c_file); if (idx == 0 && pos != 1) idx = -1; // 处理sp字符串 if (idx == 15) idx = 9; if (idx == 16) idx = 11; // 这里打印的是最大匹配的 if (idx != -1) str_debug("fmt(externsion)[%d]: %s(=%s)\n", idx, c_fmt, fmt_str[idx]); // 查找格式字符串 for (i = 0; i < ARRAY_ELEMS(fmt_str); i++) { p = strstr(c_file, fmt_str[i]); //str_debug("p: %s\n", p); if (p != NULL) { strncpy(c_fmt, p, strlen(fmt_str[i])); fmt_idx = i; } } if (fmt_idx == 15) fmt_idx = 9; if (fmt_idx == 16) fmt_idx = 11; // 这里打印的是最大匹配的 if (fmt_idx != -2) str_debug("fmt[%d]: %s(=%s)\n", fmt_idx, c_fmt, fmt_str[fmt_idx]); if (idx != -1 && fmt_idx == -2) fmt_idx = idx; if (fmt_idx != -2) str_debug("---final fmt[%d]: %s(=%s)---\n", fmt_idx, c_fmt, fmt_str[fmt_idx]); fmt_idx+=1; // 查找分辨率字符串 for (i = 0; i < ARRAY_ELEMS(res_str); i++) { //str_debug("res--: %s\n", res_str[i]); p = strstr(c_file, res_str[i]); if (p != NULL) { strncpy(c_res, p, strlen(res_str[i])); idx = i; //str_debug("res: %s\n", c_res); } } if (idx != -1) { sscanf(wh_str[idx], "%dx%d", &width, &height); str_debug("res[%d]: %s %d %d\n", idx, c_res, width, height); } ////////////////////// // 解析宽高 len = strlen(c_file); pos = strcspn(c_file, "xX"); if (len == pos) // 没有找到直接返回 { str_debug("---final width: %d height: %d---\n", width, height); return; } tmp = c_file + pos; str_debug("find1 x[%d len: %d] %s\n", pos, len, tmp); //return; p = c_file; len = len - pos + 1; j = pos; // 找到'x'前面的数字 for (i = 0; i < len && j > 0; i++) { str_debug("pos: %d %c\n", j, p[j]); if (!isdigit(p[--j])) { j++; break; } } str_debug("before x i:%d j: %d tmp: %s\n", i, j, p+j); strncpy(c_width, p+j, i); width = atoi(c_width); str_debug("c_width: %s %d\n", c_width, width); // 找到'x'后面的数字 p = c_file + pos+1; // 跳过'x' len = p - c_file; str_debug("after find x[%d] %s\n", pos, p); for (i = 0; i < len; i++) { if (!isdigit(p[i])) break; } strncpy(c_height, p, i); height = atoi(c_height); str_debug("c_height: %s %d\n", c_height, height); if (idx == -1 && (width == 0 || height == 0)) width = height = -1; if (idx != -1 && (width == 0 || height == 0)) sscanf(wh_str[idx], "%dx%d", &width, &height); str_debug("---final width: %d height: %d---\n", width, height); str_debug("\n"); }