avcenc.c revision f32d88b4751aa44be38f62dcd25533aec6ca46a2
110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang/* 2409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * Copyright (c) 2012 Intel Corporation. All Rights Reserved. 3409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * 4409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * Permission is hereby granted, free of charge, to any person obtaining a 5409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * copy of this software and associated documentation files (the 6409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * "Software"), to deal in the Software without restriction, including 7409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * without limitation the rights to use, copy, modify, merge, publish, 8409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * distribute, sub license, and/or sell copies of the Software, and to 9409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * permit persons to whom the Software is furnished to do so, subject to 10409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * the following conditions: 11409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * 12409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * The above copyright notice and this permission notice (including the 13409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * next paragraph) shall be included in all copies or substantial portions 14409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * of the Software. 15409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * 16409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 19409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 20409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan */ 24409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan/* 2510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang * Simple AVC encoder based on libVA. 2610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang * 2710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang * Usage: 2810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang * ./avcenc <width> <height> <input file> <output file> [qp] 2910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang */ 3010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 31409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include "sysdeps.h" 3210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#include <stdio.h> 3310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#include <string.h> 3410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#include <stdlib.h> 3510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#include <getopt.h> 3610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#include <unistd.h> 3710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 384b672db6ee89c9846451bbab23cf18e93c4260b2hding#include <sys/time.h> 3910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#include <sys/types.h> 4010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#include <sys/stat.h> 4110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#include <fcntl.h> 4210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#include <assert.h> 4310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#include <time.h> 4410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 454b672db6ee89c9846451bbab23cf18e93c4260b2hding#include <pthread.h> 464b672db6ee89c9846451bbab23cf18e93c4260b2hding 4710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#include <va/va.h> 484b672db6ee89c9846451bbab23cf18e93c4260b2hding#include <va/va_enc_h264.h> 49409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include "va_display.h" 5010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 5110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define NAL_REF_IDC_NONE 0 5210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define NAL_REF_IDC_LOW 1 5310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define NAL_REF_IDC_MEDIUM 2 5410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define NAL_REF_IDC_HIGH 3 5510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 5610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define NAL_NON_IDR 1 5710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define NAL_IDR 5 5810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define NAL_SPS 7 5910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define NAL_PPS 8 60409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define NAL_SEI 6 6110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 6210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define SLICE_TYPE_P 0 6310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define SLICE_TYPE_B 1 6410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define SLICE_TYPE_I 2 6510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 6610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define ENTROPY_MODE_CAVLC 0 6710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define ENTROPY_MODE_CABAC 1 6810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 6910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define PROFILE_IDC_BASELINE 66 7010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define PROFILE_IDC_MAIN 77 7110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define PROFILE_IDC_HIGH 100 7210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 7310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define CHECK_VASTATUS(va_status,func) \ 7410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if (va_status != VA_STATUS_SUCCESS) { \ 7510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang fprintf(stderr,"%s:%s (%d) failed,exit\n", __func__, func, __LINE__); \ 7610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang exit(1); \ 7710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 7810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 7910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic VADisplay va_dpy; 8010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 81a00f54a574bb5a51af428b03577599bcc70a17b2Austin Yuanstatic int picture_width, picture_width_in_mbs; 82a00f54a574bb5a51af428b03577599bcc70a17b2Austin Yuanstatic int picture_height, picture_height_in_mbs; 8310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic int frame_size; 8410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic unsigned char *newImageBuffer = 0; 8510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 8610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic int qp_value = 26; 8710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 884b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic int intra_period = 30; 894b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic int pb_period = 5; 904b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic int frame_bit_rate = -1; 914b672db6ee89c9846451bbab23cf18e93c4260b2hding 924b672db6ee89c9846451bbab23cf18e93c4260b2hding#define MAX_SLICES 32 934b672db6ee89c9846451bbab23cf18e93c4260b2hding 944b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic int 954b672db6ee89c9846451bbab23cf18e93c4260b2hdingbuild_packed_pic_buffer(unsigned char **header_buffer); 964b672db6ee89c9846451bbab23cf18e93c4260b2hding 974b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic int 984b672db6ee89c9846451bbab23cf18e93c4260b2hdingbuild_packed_seq_buffer(unsigned char **header_buffer); 994b672db6ee89c9846451bbab23cf18e93c4260b2hding 100409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int 101409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanbuild_packed_sei_buffer_timing(unsigned int init_cpb_removal_length, 102409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned int init_cpb_removal_delay, 103409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned int init_cpb_removal_delay_offset, 104409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned int cpb_removal_length, 105409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned int cpb_removal_delay, 106409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned int dpb_output_length, 107409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned int dpb_output_delay, 108409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned char **sei_buffer); 109409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1104b672db6ee89c9846451bbab23cf18e93c4260b2hdingstruct upload_thread_param 1114b672db6ee89c9846451bbab23cf18e93c4260b2hding{ 1124b672db6ee89c9846451bbab23cf18e93c4260b2hding FILE *yuv_fp; 1134b672db6ee89c9846451bbab23cf18e93c4260b2hding VASurfaceID surface_id; 1144b672db6ee89c9846451bbab23cf18e93c4260b2hding}; 1154b672db6ee89c9846451bbab23cf18e93c4260b2hding 1164b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic void 1174b672db6ee89c9846451bbab23cf18e93c4260b2hdingupload_yuv_to_surface(FILE *yuv_fp, VASurfaceID surface_id); 1184b672db6ee89c9846451bbab23cf18e93c4260b2hding 1194b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic struct { 1204b672db6ee89c9846451bbab23cf18e93c4260b2hding VAProfile profile; 121409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan int constraint_set_flag; 1224b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncSequenceParameterBufferH264 seq_param; 1234b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncPictureParameterBufferH264 pic_param; 1244b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncSliceParameterBufferH264 slice_param[MAX_SLICES]; 1254b672db6ee89c9846451bbab23cf18e93c4260b2hding VAContextID context_id; 1264b672db6ee89c9846451bbab23cf18e93c4260b2hding VAConfigID config_id; 1274b672db6ee89c9846451bbab23cf18e93c4260b2hding VABufferID seq_param_buf_id; /* Sequence level parameter */ 1284b672db6ee89c9846451bbab23cf18e93c4260b2hding VABufferID pic_param_buf_id; /* Picture level parameter */ 1294b672db6ee89c9846451bbab23cf18e93c4260b2hding VABufferID slice_param_buf_id[MAX_SLICES]; /* Slice level parameter, multil slices */ 1304b672db6ee89c9846451bbab23cf18e93c4260b2hding VABufferID codedbuf_buf_id; /* Output buffer, compressed data */ 1314b672db6ee89c9846451bbab23cf18e93c4260b2hding VABufferID packed_seq_header_param_buf_id; 1324b672db6ee89c9846451bbab23cf18e93c4260b2hding VABufferID packed_seq_buf_id; 1334b672db6ee89c9846451bbab23cf18e93c4260b2hding VABufferID packed_pic_header_param_buf_id; 1344b672db6ee89c9846451bbab23cf18e93c4260b2hding VABufferID packed_pic_buf_id; 135409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan VABufferID packed_sei_header_param_buf_id; /* the SEI buffer */ 136409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan VABufferID packed_sei_buf_id; 1374b672db6ee89c9846451bbab23cf18e93c4260b2hding VABufferID misc_parameter_hrd_buf_id; 1384b672db6ee89c9846451bbab23cf18e93c4260b2hding 1394b672db6ee89c9846451bbab23cf18e93c4260b2hding int num_slices; 1404b672db6ee89c9846451bbab23cf18e93c4260b2hding int codedbuf_i_size; 1414b672db6ee89c9846451bbab23cf18e93c4260b2hding int codedbuf_pb_size; 1424b672db6ee89c9846451bbab23cf18e93c4260b2hding int current_input_surface; 1434b672db6ee89c9846451bbab23cf18e93c4260b2hding int rate_control_method; 1444b672db6ee89c9846451bbab23cf18e93c4260b2hding struct upload_thread_param upload_thread_param; 1454b672db6ee89c9846451bbab23cf18e93c4260b2hding pthread_t upload_thread_id; 1464b672db6ee89c9846451bbab23cf18e93c4260b2hding int upload_thread_value; 147409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan int i_initial_cpb_removal_delay; 148409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan int i_initial_cpb_removal_delay_length; 149409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan int i_cpb_removal_delay; 150409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan int i_cpb_removal_delay_length; 151409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan int i_dpb_output_delay_length; 1524b672db6ee89c9846451bbab23cf18e93c4260b2hding} avcenc_context; 15310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 154f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolunstatic VAPictureH264 ReferenceFrames[16], RefPicList0[32], RefPicList1[32]; 155f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun 15610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void create_encode_pipe() 15710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 15810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang VAEntrypoint entrypoints[5]; 15910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int num_entrypoints,slice_entrypoint; 16010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang VAConfigAttrib attrib[2]; 16110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int major_ver, minor_ver; 16210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang VAStatus va_status; 16310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 164409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan va_dpy = va_open_display(); 16510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang va_status = vaInitialize(va_dpy, &major_ver, &minor_ver); 16610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang CHECK_VASTATUS(va_status, "vaInitialize"); 16710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 1684b672db6ee89c9846451bbab23cf18e93c4260b2hding vaQueryConfigEntrypoints(va_dpy, avcenc_context.profile, entrypoints, 16910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang &num_entrypoints); 17010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 17110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang for (slice_entrypoint = 0; slice_entrypoint < num_entrypoints; slice_entrypoint++) { 17210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if (entrypoints[slice_entrypoint] == VAEntrypointEncSlice) 17310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang break; 17410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 17510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 17610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if (slice_entrypoint == num_entrypoints) { 17710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang /* not find Slice entry point */ 17810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang assert(0); 17910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 18010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 18110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang /* find out the format for the render target, and rate control mode */ 18210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang attrib[0].type = VAConfigAttribRTFormat; 18310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang attrib[1].type = VAConfigAttribRateControl; 1844b672db6ee89c9846451bbab23cf18e93c4260b2hding vaGetConfigAttributes(va_dpy, avcenc_context.profile, VAEntrypointEncSlice, 18510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang &attrib[0], 2); 18610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 18710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if ((attrib[0].value & VA_RT_FORMAT_YUV420) == 0) { 18810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang /* not find desired YUV420 RT format */ 18910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang assert(0); 19010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 19110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 1924b672db6ee89c9846451bbab23cf18e93c4260b2hding if ((attrib[1].value & avcenc_context.rate_control_method) == 0) { 19310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang /* Can't find matched RC mode */ 1944b672db6ee89c9846451bbab23cf18e93c4260b2hding printf("Can't find the desired RC mode, exit\n"); 19510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang assert(0); 19610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 19710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 19810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang attrib[0].value = VA_RT_FORMAT_YUV420; /* set to desired RT format */ 1994b672db6ee89c9846451bbab23cf18e93c4260b2hding attrib[1].value = avcenc_context.rate_control_method; /* set to desired RC mode */ 20010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 2014b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaCreateConfig(va_dpy, avcenc_context.profile, VAEntrypointEncSlice, 2024b672db6ee89c9846451bbab23cf18e93c4260b2hding &attrib[0], 2,&avcenc_context.config_id); 20310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang CHECK_VASTATUS(va_status, "vaCreateConfig"); 20410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 20510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang /* Create a context for this decode pipe */ 2064b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaCreateContext(va_dpy, avcenc_context.config_id, 20710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang picture_width, picture_height, 20810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang VA_PROGRESSIVE, 20910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 0, 0, 2104b672db6ee89c9846451bbab23cf18e93c4260b2hding &avcenc_context.context_id); 21110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang CHECK_VASTATUS(va_status, "vaCreateContext"); 21210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 21310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 21410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void destory_encode_pipe() 21510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 2164b672db6ee89c9846451bbab23cf18e93c4260b2hding vaDestroyContext(va_dpy,avcenc_context.context_id); 2174b672db6ee89c9846451bbab23cf18e93c4260b2hding vaDestroyConfig(va_dpy,avcenc_context.config_id); 21810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang vaTerminate(va_dpy); 219409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan va_close_display(va_dpy); 22010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 22110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 22210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang/*************************************************** 22310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang * 22410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang * The encode pipe resource define 22510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang * 22610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang ***************************************************/ 2274b672db6ee89c9846451bbab23cf18e93c4260b2hding#define SID_INPUT_PICTURE_0 0 2284b672db6ee89c9846451bbab23cf18e93c4260b2hding#define SID_INPUT_PICTURE_1 1 2294b672db6ee89c9846451bbab23cf18e93c4260b2hding#define SID_REFERENCE_PICTURE_L0 2 2304b672db6ee89c9846451bbab23cf18e93c4260b2hding#define SID_REFERENCE_PICTURE_L1 3 2314b672db6ee89c9846451bbab23cf18e93c4260b2hding#define SID_RECON_PICTURE 4 2324b672db6ee89c9846451bbab23cf18e93c4260b2hding#define SID_NUMBER SID_RECON_PICTURE + 1 23310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic VASurfaceID surface_ids[SID_NUMBER]; 23410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 2354b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic int frame_number; 2364b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic int enc_frame_number; 2374b672db6ee89c9846451bbab23cf18e93c4260b2hding 23810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang/***************************************************/ 23910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 2404b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic void * 2414b672db6ee89c9846451bbab23cf18e93c4260b2hdingupload_thread_function(void *data) 24210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 2434b672db6ee89c9846451bbab23cf18e93c4260b2hding struct upload_thread_param *param = data; 24410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 2454b672db6ee89c9846451bbab23cf18e93c4260b2hding upload_yuv_to_surface(param->yuv_fp, param->surface_id); 24610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 2474b672db6ee89c9846451bbab23cf18e93c4260b2hding return NULL; 2484b672db6ee89c9846451bbab23cf18e93c4260b2hding} 249a00f54a574bb5a51af428b03577599bcc70a17b2Austin Yuan 2504b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic void alloc_encode_resource(FILE *yuv_fp) 2514b672db6ee89c9846451bbab23cf18e93c4260b2hding{ 2524b672db6ee89c9846451bbab23cf18e93c4260b2hding VAStatus va_status; 25310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 2544b672db6ee89c9846451bbab23cf18e93c4260b2hding // Create surface 2554b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaCreateSurfaces( 2564b672db6ee89c9846451bbab23cf18e93c4260b2hding va_dpy, 2574b672db6ee89c9846451bbab23cf18e93c4260b2hding VA_RT_FORMAT_YUV420, picture_width, picture_height, 2584b672db6ee89c9846451bbab23cf18e93c4260b2hding &surface_ids[0], SID_NUMBER, 2594b672db6ee89c9846451bbab23cf18e93c4260b2hding NULL, 0 2604b672db6ee89c9846451bbab23cf18e93c4260b2hding ); 26110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 26210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang CHECK_VASTATUS(va_status, "vaCreateSurfaces"); 26310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 2644b672db6ee89c9846451bbab23cf18e93c4260b2hding newImageBuffer = (unsigned char *)malloc(frame_size); 26510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 2664b672db6ee89c9846451bbab23cf18e93c4260b2hding /* firstly upload YUV data to SID_INPUT_PICTURE_1 */ 2674b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.upload_thread_param.yuv_fp = yuv_fp; 2684b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.upload_thread_param.surface_id = surface_ids[SID_INPUT_PICTURE_1]; 26910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 2704b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.upload_thread_value = pthread_create(&avcenc_context.upload_thread_id, 2714b672db6ee89c9846451bbab23cf18e93c4260b2hding NULL, 2724b672db6ee89c9846451bbab23cf18e93c4260b2hding upload_thread_function, 2734b672db6ee89c9846451bbab23cf18e93c4260b2hding (void*)&avcenc_context.upload_thread_param); 27410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 27510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 27610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void release_encode_resource() 27710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 2784b672db6ee89c9846451bbab23cf18e93c4260b2hding pthread_join(avcenc_context.upload_thread_id, NULL); 27910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang free(newImageBuffer); 28010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 2814b672db6ee89c9846451bbab23cf18e93c4260b2hding // Release all the surfaces resource 28210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang vaDestroySurfaces(va_dpy, &surface_ids[0], SID_NUMBER); 28310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 28410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 285409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void avcenc_update_sei_param(int frame_num) 286409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{ 287409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan VAEncPackedHeaderParameterBuffer packed_header_param_buffer; 288409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned int length_in_bits, offset_in_bytes; 289409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned char *packed_sei_buffer = NULL; 290409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan VAStatus va_status; 291409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 292409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan length_in_bits = build_packed_sei_buffer_timing( 293409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.i_initial_cpb_removal_delay_length, 294409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.i_initial_cpb_removal_delay, 295409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 0, 296409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.i_cpb_removal_delay_length, 297409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.i_cpb_removal_delay * frame_num, 298409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.i_dpb_output_delay_length, 299409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 0, 300409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan &packed_sei_buffer); 301409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 302409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan offset_in_bytes = 0; 303409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan packed_header_param_buffer.type = VAEncPackedHeaderH264_SEI; 304409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan packed_header_param_buffer.bit_length = length_in_bits; 305409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan packed_header_param_buffer.has_emulation_bytes = 0; 306409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 307409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan va_status = vaCreateBuffer(va_dpy, 308409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.context_id, 309409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan VAEncPackedHeaderParameterBufferType, 310409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan sizeof(packed_header_param_buffer), 1, &packed_header_param_buffer, 311409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan &avcenc_context.packed_sei_header_param_buf_id); 312409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan CHECK_VASTATUS(va_status,"vaCreateBuffer"); 313409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 314409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan va_status = vaCreateBuffer(va_dpy, 315409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.context_id, 316409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan VAEncPackedHeaderDataBufferType, 317409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan (length_in_bits + 7) / 8, 1, packed_sei_buffer, 318409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan &avcenc_context.packed_sei_buf_id); 319409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan CHECK_VASTATUS(va_status,"vaCreateBuffer"); 320409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan free(packed_sei_buffer); 321409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan return; 322409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan} 323409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 3244b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic void avcenc_update_picture_parameter(int slice_type, int frame_num, int display_num, int is_idr) 32510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 3264b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncPictureParameterBufferH264 *pic_param; 32710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang VAStatus va_status; 3284b672db6ee89c9846451bbab23cf18e93c4260b2hding 3294b672db6ee89c9846451bbab23cf18e93c4260b2hding // Picture level 3304b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param = &avcenc_context.pic_param; 3314b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->CurrPic.picture_id = surface_ids[SID_RECON_PICTURE]; 3324b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->CurrPic.TopFieldOrderCnt = display_num * 2; 3334b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->ReferenceFrames[0].picture_id = surface_ids[SID_REFERENCE_PICTURE_L0]; 3344b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->ReferenceFrames[1].picture_id = surface_ids[SID_REFERENCE_PICTURE_L1]; 3354b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->ReferenceFrames[2].picture_id = VA_INVALID_ID; 3364b672db6ee89c9846451bbab23cf18e93c4260b2hding assert(avcenc_context.codedbuf_buf_id != VA_INVALID_ID); 3374b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->coded_buf = avcenc_context.codedbuf_buf_id; 3384b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->frame_num = frame_num; 3394b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->pic_fields.bits.idr_pic_flag = !!is_idr; 3404b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->pic_fields.bits.reference_pic_flag = (slice_type != SLICE_TYPE_B); 3414b672db6ee89c9846451bbab23cf18e93c4260b2hding 3424b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaCreateBuffer(va_dpy, 3434b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.context_id, 3444b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncPictureParameterBufferType, 3454b672db6ee89c9846451bbab23cf18e93c4260b2hding sizeof(*pic_param), 1, pic_param, 3464b672db6ee89c9846451bbab23cf18e93c4260b2hding &avcenc_context.pic_param_buf_id); 3474b672db6ee89c9846451bbab23cf18e93c4260b2hding CHECK_VASTATUS(va_status,"vaCreateBuffer"); 34810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 34910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 3504b672db6ee89c9846451bbab23cf18e93c4260b2hding#ifndef VA_FOURCC_I420 3514b672db6ee89c9846451bbab23cf18e93c4260b2hding#define VA_FOURCC_I420 0x30323449 3524b672db6ee89c9846451bbab23cf18e93c4260b2hding#endif 3534b672db6ee89c9846451bbab23cf18e93c4260b2hding 35410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void upload_yuv_to_surface(FILE *yuv_fp, VASurfaceID surface_id) 35510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 35610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang VAImage surface_image; 35710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang VAStatus va_status; 35810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang void *surface_p = NULL; 35910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang unsigned char *y_src, *u_src, *v_src; 36010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang unsigned char *y_dst, *u_dst, *v_dst; 36110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int y_size = picture_width * picture_height; 36210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int u_size = (picture_width >> 1) * (picture_height >> 1); 36310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int row, col; 36410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang size_t n_items; 36510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 36610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang do { 36710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang n_items = fread(newImageBuffer, frame_size, 1, yuv_fp); 36810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } while (n_items != 1); 36910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 37010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang va_status = vaDeriveImage(va_dpy, surface_id, &surface_image); 37110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang CHECK_VASTATUS(va_status,"vaDeriveImage"); 37210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 37310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang vaMapBuffer(va_dpy, surface_image.buf, &surface_p); 37410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang assert(VA_STATUS_SUCCESS == va_status); 37510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 37610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang y_src = newImageBuffer; 37710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang u_src = newImageBuffer + y_size; /* UV offset for NV12 */ 37810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang v_src = newImageBuffer + y_size + u_size; 37910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 38010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang y_dst = surface_p + surface_image.offsets[0]; 38110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang u_dst = surface_p + surface_image.offsets[1]; /* UV offset for NV12 */ 38210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang v_dst = surface_p + surface_image.offsets[2]; 38310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 38410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang /* Y plane */ 38510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang for (row = 0; row < surface_image.height; row++) { 38610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang memcpy(y_dst, y_src, surface_image.width); 38710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang y_dst += surface_image.pitches[0]; 38810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang y_src += picture_width; 38910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 39010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 39110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if (surface_image.format.fourcc == VA_FOURCC_NV12) { /* UV plane */ 39210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang for (row = 0; row < surface_image.height / 2; row++) { 39310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang for (col = 0; col < surface_image.width / 2; col++) { 39410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang u_dst[col * 2] = u_src[col]; 39510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang u_dst[col * 2 + 1] = v_src[col]; 39610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 39710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 39810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang u_dst += surface_image.pitches[1]; 39910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang u_src += (picture_width / 2); 40010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang v_src += (picture_width / 2); 40110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 4024b672db6ee89c9846451bbab23cf18e93c4260b2hding } else if (surface_image.format.fourcc == VA_FOURCC_YV12 || 4034b672db6ee89c9846451bbab23cf18e93c4260b2hding surface_image.format.fourcc == VA_FOURCC_I420) { 4044b672db6ee89c9846451bbab23cf18e93c4260b2hding const int U = surface_image.format.fourcc == VA_FOURCC_I420 ? 1 : 2; 4054b672db6ee89c9846451bbab23cf18e93c4260b2hding const int V = surface_image.format.fourcc == VA_FOURCC_I420 ? 2 : 1; 4064b672db6ee89c9846451bbab23cf18e93c4260b2hding 4074b672db6ee89c9846451bbab23cf18e93c4260b2hding u_dst = surface_p + surface_image.offsets[U]; 4084b672db6ee89c9846451bbab23cf18e93c4260b2hding v_dst = surface_p + surface_image.offsets[V]; 4094b672db6ee89c9846451bbab23cf18e93c4260b2hding 4104b672db6ee89c9846451bbab23cf18e93c4260b2hding for (row = 0; row < surface_image.height / 2; row++) { 4114b672db6ee89c9846451bbab23cf18e93c4260b2hding memcpy(u_dst, u_src, surface_image.width / 2); 4124b672db6ee89c9846451bbab23cf18e93c4260b2hding memcpy(v_dst, v_src, surface_image.width / 2); 4134b672db6ee89c9846451bbab23cf18e93c4260b2hding u_dst += surface_image.pitches[U]; 4144b672db6ee89c9846451bbab23cf18e93c4260b2hding v_dst += surface_image.pitches[V]; 4154b672db6ee89c9846451bbab23cf18e93c4260b2hding u_src += (picture_width / 2); 4164b672db6ee89c9846451bbab23cf18e93c4260b2hding v_src += (picture_width / 2); 4174b672db6ee89c9846451bbab23cf18e93c4260b2hding } 41810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 41910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 42010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang vaUnmapBuffer(va_dpy, surface_image.buf); 42110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang vaDestroyImage(va_dpy, surface_image.image_id); 42210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 42310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 4244b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic void avcenc_update_slice_parameter(int slice_type) 42510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 4264b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncSliceParameterBufferH264 *slice_param; 42710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang VAStatus va_status; 4284b672db6ee89c9846451bbab23cf18e93c4260b2hding int i; 42910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 4304b672db6ee89c9846451bbab23cf18e93c4260b2hding // Slice level 4314b672db6ee89c9846451bbab23cf18e93c4260b2hding i = 0; 4324b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param = &avcenc_context.slice_param[i]; 4334b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->macroblock_address = 0; 4344b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->num_macroblocks = picture_height_in_mbs * picture_width_in_mbs; 4354b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->pic_parameter_set_id = 0; 4364b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->slice_type = slice_type; 4374b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->direct_spatial_mv_pred_flag = 0; 4384b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->num_ref_idx_l0_active_minus1 = 0; /* FIXME: ??? */ 4394b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->num_ref_idx_l1_active_minus1 = 0; 4404b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->cabac_init_idc = 0; 4414b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->slice_qp_delta = 0; 4424b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->disable_deblocking_filter_idc = 0; 4434b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->slice_alpha_c0_offset_div2 = 2; 4444b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->slice_beta_offset_div2 = 2; 4454b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->idr_pic_id = 0; 4464b672db6ee89c9846451bbab23cf18e93c4260b2hding 4474b672db6ee89c9846451bbab23cf18e93c4260b2hding /* FIXME: fill other fields */ 448f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun if ((slice_type == SLICE_TYPE_P) || (slice_type == SLICE_TYPE_B)) { 449f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun int j; 450f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun slice_param->RefPicList0[0].picture_id = surface_ids[SID_REFERENCE_PICTURE_L0]; 451f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun for (j = 1; j < 32; j++) { 452f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun slice_param->RefPicList0[j].picture_id = VA_INVALID_SURFACE; 453f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun slice_param->RefPicList0[j].flags = VA_PICTURE_H264_INVALID; 454f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun } 455f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun } 456f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun 457f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun if ((slice_type == SLICE_TYPE_B)) { 458f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun int j; 459f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun slice_param->RefPicList1[0].picture_id = surface_ids[SID_REFERENCE_PICTURE_L1]; 460f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun for (j = 1; j < 32; j++) { 461f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun slice_param->RefPicList1[j].picture_id = VA_INVALID_SURFACE; 462f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun slice_param->RefPicList1[j].flags = VA_PICTURE_H264_INVALID; 463f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun } 464f32d88b4751aa44be38f62dcd25533aec6ca46a2Liu Bolun } 4654b672db6ee89c9846451bbab23cf18e93c4260b2hding 4664b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaCreateBuffer(va_dpy, 4674b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.context_id, 4684b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncSliceParameterBufferType, 4694b672db6ee89c9846451bbab23cf18e93c4260b2hding sizeof(*slice_param), 1, slice_param, 4704b672db6ee89c9846451bbab23cf18e93c4260b2hding &avcenc_context.slice_param_buf_id[i]); 4714b672db6ee89c9846451bbab23cf18e93c4260b2hding CHECK_VASTATUS(va_status,"vaCreateBuffer");; 4724b672db6ee89c9846451bbab23cf18e93c4260b2hding i++; 4734b672db6ee89c9846451bbab23cf18e93c4260b2hding 4744b672db6ee89c9846451bbab23cf18e93c4260b2hding#if 0 4754b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param = &avcenc_context.slice_param[i]; 4764b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->macroblock_address = picture_height_in_mbs * picture_width_in_mbs / 2; 4774b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->num_macroblocks = picture_height_in_mbs * picture_width_in_mbs / 2; 4784b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->pic_parameter_set_id = 0; 4794b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->slice_type = slice_type; 4804b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->direct_spatial_mv_pred_flag = 0; 4814b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->num_ref_idx_l0_active_minus1 = 0; /* FIXME: ??? */ 4824b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->num_ref_idx_l1_active_minus1 = 0; 4834b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->cabac_init_idc = 0; 4844b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->slice_qp_delta = 0; 4854b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->disable_deblocking_filter_idc = 0; 4864b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->slice_alpha_c0_offset_div2 = 2; 4874b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->slice_beta_offset_div2 = 2; 4884b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_param->idr_pic_id = 0; 4894b672db6ee89c9846451bbab23cf18e93c4260b2hding 4904b672db6ee89c9846451bbab23cf18e93c4260b2hding /* FIXME: fill other fields */ 4914b672db6ee89c9846451bbab23cf18e93c4260b2hding 4924b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaCreateBuffer(va_dpy, 4934b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.context_id, 4944b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncSliceParameterBufferType, 4954b672db6ee89c9846451bbab23cf18e93c4260b2hding sizeof(*slice_param), 1, slice_param, 4964b672db6ee89c9846451bbab23cf18e93c4260b2hding &avcenc_context.slice_param_buf_id[i]); 4974b672db6ee89c9846451bbab23cf18e93c4260b2hding CHECK_VASTATUS(va_status,"vaCreateBuffer");; 4984b672db6ee89c9846451bbab23cf18e93c4260b2hding i++; 4994b672db6ee89c9846451bbab23cf18e93c4260b2hding#endif 50010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 5014b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.num_slices = i; 5024b672db6ee89c9846451bbab23cf18e93c4260b2hding} 50310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 5044b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic int begin_picture(FILE *yuv_fp, int frame_num, int display_num, int slice_type, int is_idr) 5054b672db6ee89c9846451bbab23cf18e93c4260b2hding{ 5064b672db6ee89c9846451bbab23cf18e93c4260b2hding VAStatus va_status; 5074b672db6ee89c9846451bbab23cf18e93c4260b2hding 5084b672db6ee89c9846451bbab23cf18e93c4260b2hding if (avcenc_context.upload_thread_value != 0) { 5094b672db6ee89c9846451bbab23cf18e93c4260b2hding fprintf(stderr, "FATAL error!!!\n"); 5104b672db6ee89c9846451bbab23cf18e93c4260b2hding exit(1); 5114b672db6ee89c9846451bbab23cf18e93c4260b2hding } 5124b672db6ee89c9846451bbab23cf18e93c4260b2hding 5134b672db6ee89c9846451bbab23cf18e93c4260b2hding pthread_join(avcenc_context.upload_thread_id, NULL); 5144b672db6ee89c9846451bbab23cf18e93c4260b2hding 5154b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.upload_thread_value = -1; 5164b672db6ee89c9846451bbab23cf18e93c4260b2hding 5174b672db6ee89c9846451bbab23cf18e93c4260b2hding if (avcenc_context.current_input_surface == SID_INPUT_PICTURE_0) 5184b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.current_input_surface = SID_INPUT_PICTURE_1; 5194b672db6ee89c9846451bbab23cf18e93c4260b2hding else 5204b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.current_input_surface = SID_INPUT_PICTURE_0; 5214b672db6ee89c9846451bbab23cf18e93c4260b2hding 5224b672db6ee89c9846451bbab23cf18e93c4260b2hding if (frame_num == 0) { 5234b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncPackedHeaderParameterBuffer packed_header_param_buffer; 5244b672db6ee89c9846451bbab23cf18e93c4260b2hding unsigned int length_in_bits, offset_in_bytes; 5254b672db6ee89c9846451bbab23cf18e93c4260b2hding unsigned char *packed_seq_buffer = NULL, *packed_pic_buffer = NULL; 5264b672db6ee89c9846451bbab23cf18e93c4260b2hding 5274b672db6ee89c9846451bbab23cf18e93c4260b2hding assert(slice_type == SLICE_TYPE_I); 5284b672db6ee89c9846451bbab23cf18e93c4260b2hding length_in_bits = build_packed_seq_buffer(&packed_seq_buffer); 5294b672db6ee89c9846451bbab23cf18e93c4260b2hding offset_in_bytes = 0; 5304b672db6ee89c9846451bbab23cf18e93c4260b2hding packed_header_param_buffer.type = VAEncPackedHeaderSequence; 5314b672db6ee89c9846451bbab23cf18e93c4260b2hding packed_header_param_buffer.bit_length = length_in_bits; 5324b672db6ee89c9846451bbab23cf18e93c4260b2hding packed_header_param_buffer.has_emulation_bytes = 0; 5334b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaCreateBuffer(va_dpy, 5344b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.context_id, 5354b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncPackedHeaderParameterBufferType, 5364b672db6ee89c9846451bbab23cf18e93c4260b2hding sizeof(packed_header_param_buffer), 1, &packed_header_param_buffer, 5374b672db6ee89c9846451bbab23cf18e93c4260b2hding &avcenc_context.packed_seq_header_param_buf_id); 5384b672db6ee89c9846451bbab23cf18e93c4260b2hding CHECK_VASTATUS(va_status,"vaCreateBuffer"); 5394b672db6ee89c9846451bbab23cf18e93c4260b2hding 5404b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaCreateBuffer(va_dpy, 5414b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.context_id, 5424b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncPackedHeaderDataBufferType, 5434b672db6ee89c9846451bbab23cf18e93c4260b2hding (length_in_bits + 7) / 8, 1, packed_seq_buffer, 5444b672db6ee89c9846451bbab23cf18e93c4260b2hding &avcenc_context.packed_seq_buf_id); 5454b672db6ee89c9846451bbab23cf18e93c4260b2hding CHECK_VASTATUS(va_status,"vaCreateBuffer"); 5464b672db6ee89c9846451bbab23cf18e93c4260b2hding 5474b672db6ee89c9846451bbab23cf18e93c4260b2hding length_in_bits = build_packed_pic_buffer(&packed_pic_buffer); 5484b672db6ee89c9846451bbab23cf18e93c4260b2hding offset_in_bytes = 0; 5494b672db6ee89c9846451bbab23cf18e93c4260b2hding packed_header_param_buffer.type = VAEncPackedHeaderPicture; 5504b672db6ee89c9846451bbab23cf18e93c4260b2hding packed_header_param_buffer.bit_length = length_in_bits; 5514b672db6ee89c9846451bbab23cf18e93c4260b2hding packed_header_param_buffer.has_emulation_bytes = 0; 5524b672db6ee89c9846451bbab23cf18e93c4260b2hding 5534b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaCreateBuffer(va_dpy, 5544b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.context_id, 5554b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncPackedHeaderParameterBufferType, 5564b672db6ee89c9846451bbab23cf18e93c4260b2hding sizeof(packed_header_param_buffer), 1, &packed_header_param_buffer, 5574b672db6ee89c9846451bbab23cf18e93c4260b2hding &avcenc_context.packed_pic_header_param_buf_id); 5584b672db6ee89c9846451bbab23cf18e93c4260b2hding CHECK_VASTATUS(va_status,"vaCreateBuffer"); 5594b672db6ee89c9846451bbab23cf18e93c4260b2hding 5604b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaCreateBuffer(va_dpy, 5614b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.context_id, 5624b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncPackedHeaderDataBufferType, 5634b672db6ee89c9846451bbab23cf18e93c4260b2hding (length_in_bits + 7) / 8, 1, packed_pic_buffer, 5644b672db6ee89c9846451bbab23cf18e93c4260b2hding &avcenc_context.packed_pic_buf_id); 5654b672db6ee89c9846451bbab23cf18e93c4260b2hding CHECK_VASTATUS(va_status,"vaCreateBuffer"); 5664b672db6ee89c9846451bbab23cf18e93c4260b2hding 5674b672db6ee89c9846451bbab23cf18e93c4260b2hding free(packed_seq_buffer); 5684b672db6ee89c9846451bbab23cf18e93c4260b2hding free(packed_pic_buffer); 5694b672db6ee89c9846451bbab23cf18e93c4260b2hding } 5704b672db6ee89c9846451bbab23cf18e93c4260b2hding 5714b672db6ee89c9846451bbab23cf18e93c4260b2hding /* sequence parameter set */ 5724b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncSequenceParameterBufferH264 *seq_param = &avcenc_context.seq_param; 5734b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaCreateBuffer(va_dpy, 5744b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.context_id, 5754b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncSequenceParameterBufferType, 5764b672db6ee89c9846451bbab23cf18e93c4260b2hding sizeof(*seq_param), 1, seq_param, 5774b672db6ee89c9846451bbab23cf18e93c4260b2hding &avcenc_context.seq_param_buf_id); 57810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang CHECK_VASTATUS(va_status,"vaCreateBuffer"); 57910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 5804b672db6ee89c9846451bbab23cf18e93c4260b2hding 5814b672db6ee89c9846451bbab23cf18e93c4260b2hding /* hrd parameter */ 5824b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncMiscParameterBuffer *misc_param; 5834b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncMiscParameterHRD *misc_hrd_param; 5844b672db6ee89c9846451bbab23cf18e93c4260b2hding vaCreateBuffer(va_dpy, 5854b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.context_id, 5864b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncMiscParameterBufferType, 5874b672db6ee89c9846451bbab23cf18e93c4260b2hding sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParameterRateControl), 5884b672db6ee89c9846451bbab23cf18e93c4260b2hding 1, 5894b672db6ee89c9846451bbab23cf18e93c4260b2hding NULL, 5904b672db6ee89c9846451bbab23cf18e93c4260b2hding &avcenc_context.misc_parameter_hrd_buf_id); 5914b672db6ee89c9846451bbab23cf18e93c4260b2hding CHECK_VASTATUS(va_status, "vaCreateBuffer"); 5924b672db6ee89c9846451bbab23cf18e93c4260b2hding 5934b672db6ee89c9846451bbab23cf18e93c4260b2hding vaMapBuffer(va_dpy, 5944b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.misc_parameter_hrd_buf_id, 5954b672db6ee89c9846451bbab23cf18e93c4260b2hding (void **)&misc_param); 5964b672db6ee89c9846451bbab23cf18e93c4260b2hding misc_param->type = VAEncMiscParameterTypeHRD; 5974b672db6ee89c9846451bbab23cf18e93c4260b2hding misc_hrd_param = (VAEncMiscParameterHRD *)misc_param->data; 5984b672db6ee89c9846451bbab23cf18e93c4260b2hding 5994b672db6ee89c9846451bbab23cf18e93c4260b2hding if (frame_bit_rate > 0) { 6004b672db6ee89c9846451bbab23cf18e93c4260b2hding misc_hrd_param->initial_buffer_fullness = frame_bit_rate * 1024 * 4; 6014b672db6ee89c9846451bbab23cf18e93c4260b2hding misc_hrd_param->buffer_size = frame_bit_rate * 1024 * 8; 6024b672db6ee89c9846451bbab23cf18e93c4260b2hding } else { 6034b672db6ee89c9846451bbab23cf18e93c4260b2hding misc_hrd_param->initial_buffer_fullness = 0; 6044b672db6ee89c9846451bbab23cf18e93c4260b2hding misc_hrd_param->buffer_size = 0; 6054b672db6ee89c9846451bbab23cf18e93c4260b2hding } 6064b672db6ee89c9846451bbab23cf18e93c4260b2hding 6074b672db6ee89c9846451bbab23cf18e93c4260b2hding vaUnmapBuffer(va_dpy, avcenc_context.misc_parameter_hrd_buf_id); 6084b672db6ee89c9846451bbab23cf18e93c4260b2hding 6094b672db6ee89c9846451bbab23cf18e93c4260b2hding /* slice parameter */ 6104b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_update_slice_parameter(slice_type); 6114b672db6ee89c9846451bbab23cf18e93c4260b2hding 6124b672db6ee89c9846451bbab23cf18e93c4260b2hding return 0; 61310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 61410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 6154b672db6ee89c9846451bbab23cf18e93c4260b2hdingint avcenc_render_picture() 6164b672db6ee89c9846451bbab23cf18e93c4260b2hding{ 61710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang VAStatus va_status; 618409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan VABufferID va_buffers[10]; 6194b672db6ee89c9846451bbab23cf18e93c4260b2hding unsigned int num_va_buffers = 0; 6204b672db6ee89c9846451bbab23cf18e93c4260b2hding int i; 6214b672db6ee89c9846451bbab23cf18e93c4260b2hding 6224b672db6ee89c9846451bbab23cf18e93c4260b2hding va_buffers[num_va_buffers++] = avcenc_context.seq_param_buf_id; 6234b672db6ee89c9846451bbab23cf18e93c4260b2hding va_buffers[num_va_buffers++] = avcenc_context.pic_param_buf_id; 6244b672db6ee89c9846451bbab23cf18e93c4260b2hding 6254b672db6ee89c9846451bbab23cf18e93c4260b2hding if (avcenc_context.packed_seq_header_param_buf_id != VA_INVALID_ID) 6264b672db6ee89c9846451bbab23cf18e93c4260b2hding va_buffers[num_va_buffers++] = avcenc_context.packed_seq_header_param_buf_id; 6274b672db6ee89c9846451bbab23cf18e93c4260b2hding 6284b672db6ee89c9846451bbab23cf18e93c4260b2hding if (avcenc_context.packed_seq_buf_id != VA_INVALID_ID) 6294b672db6ee89c9846451bbab23cf18e93c4260b2hding va_buffers[num_va_buffers++] = avcenc_context.packed_seq_buf_id; 6304b672db6ee89c9846451bbab23cf18e93c4260b2hding 6314b672db6ee89c9846451bbab23cf18e93c4260b2hding if (avcenc_context.packed_pic_header_param_buf_id != VA_INVALID_ID) 6324b672db6ee89c9846451bbab23cf18e93c4260b2hding va_buffers[num_va_buffers++] = avcenc_context.packed_pic_header_param_buf_id; 6334b672db6ee89c9846451bbab23cf18e93c4260b2hding 6344b672db6ee89c9846451bbab23cf18e93c4260b2hding if (avcenc_context.packed_pic_buf_id != VA_INVALID_ID) 6354b672db6ee89c9846451bbab23cf18e93c4260b2hding va_buffers[num_va_buffers++] = avcenc_context.packed_pic_buf_id; 6364b672db6ee89c9846451bbab23cf18e93c4260b2hding 637409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan if (avcenc_context.packed_sei_header_param_buf_id != VA_INVALID_ID) 638409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan va_buffers[num_va_buffers++] = avcenc_context.packed_sei_header_param_buf_id; 639409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 640409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan if (avcenc_context.packed_sei_buf_id != VA_INVALID_ID) 641409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan va_buffers[num_va_buffers++] = avcenc_context.packed_sei_buf_id; 642409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 6434b672db6ee89c9846451bbab23cf18e93c4260b2hding if (avcenc_context.misc_parameter_hrd_buf_id != VA_INVALID_ID) 6444b672db6ee89c9846451bbab23cf18e93c4260b2hding va_buffers[num_va_buffers++] = avcenc_context.misc_parameter_hrd_buf_id; 64510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 6464b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaBeginPicture(va_dpy, 6474b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.context_id, 6484b672db6ee89c9846451bbab23cf18e93c4260b2hding surface_ids[avcenc_context.current_input_surface]); 6494b672db6ee89c9846451bbab23cf18e93c4260b2hding CHECK_VASTATUS(va_status,"vaBeginPicture"); 6504b672db6ee89c9846451bbab23cf18e93c4260b2hding 6514b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaRenderPicture(va_dpy, 6524b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.context_id, 6534b672db6ee89c9846451bbab23cf18e93c4260b2hding va_buffers, 6544b672db6ee89c9846451bbab23cf18e93c4260b2hding num_va_buffers); 65510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang CHECK_VASTATUS(va_status,"vaRenderPicture"); 6564b672db6ee89c9846451bbab23cf18e93c4260b2hding 6574b672db6ee89c9846451bbab23cf18e93c4260b2hding for(i = 0; i < avcenc_context.num_slices; i++) { 6584b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaRenderPicture(va_dpy, 6594b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.context_id, 6604b672db6ee89c9846451bbab23cf18e93c4260b2hding &avcenc_context.slice_param_buf_id[i], 6614b672db6ee89c9846451bbab23cf18e93c4260b2hding 1); 6624b672db6ee89c9846451bbab23cf18e93c4260b2hding CHECK_VASTATUS(va_status,"vaRenderPicture"); 6634b672db6ee89c9846451bbab23cf18e93c4260b2hding } 6644b672db6ee89c9846451bbab23cf18e93c4260b2hding 6654b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaEndPicture(va_dpy, avcenc_context.context_id); 6664b672db6ee89c9846451bbab23cf18e93c4260b2hding CHECK_VASTATUS(va_status,"vaEndPicture"); 6674b672db6ee89c9846451bbab23cf18e93c4260b2hding 6684b672db6ee89c9846451bbab23cf18e93c4260b2hding return 0; 6694b672db6ee89c9846451bbab23cf18e93c4260b2hding} 6704b672db6ee89c9846451bbab23cf18e93c4260b2hding 6714b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic int avcenc_destroy_buffers(VABufferID *va_buffers, unsigned int num_va_buffers) 6724b672db6ee89c9846451bbab23cf18e93c4260b2hding{ 6734b672db6ee89c9846451bbab23cf18e93c4260b2hding VAStatus va_status; 6744b672db6ee89c9846451bbab23cf18e93c4260b2hding unsigned int i; 6754b672db6ee89c9846451bbab23cf18e93c4260b2hding 6764b672db6ee89c9846451bbab23cf18e93c4260b2hding for (i = 0; i < num_va_buffers; i++) { 6774b672db6ee89c9846451bbab23cf18e93c4260b2hding if (va_buffers[i] != VA_INVALID_ID) { 6784b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaDestroyBuffer(va_dpy, va_buffers[i]); 6794b672db6ee89c9846451bbab23cf18e93c4260b2hding CHECK_VASTATUS(va_status,"vaDestroyBuffer"); 6804b672db6ee89c9846451bbab23cf18e93c4260b2hding va_buffers[i] = VA_INVALID_ID; 6814b672db6ee89c9846451bbab23cf18e93c4260b2hding } 6824b672db6ee89c9846451bbab23cf18e93c4260b2hding } 6834b672db6ee89c9846451bbab23cf18e93c4260b2hding 6844b672db6ee89c9846451bbab23cf18e93c4260b2hding return 0; 6854b672db6ee89c9846451bbab23cf18e93c4260b2hding} 6864b672db6ee89c9846451bbab23cf18e93c4260b2hding 6874b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic void end_picture(int slice_type, int next_is_bpic) 6884b672db6ee89c9846451bbab23cf18e93c4260b2hding{ 6894b672db6ee89c9846451bbab23cf18e93c4260b2hding VABufferID tempID; 6904b672db6ee89c9846451bbab23cf18e93c4260b2hding 6914b672db6ee89c9846451bbab23cf18e93c4260b2hding /* Prepare for next picture */ 6924b672db6ee89c9846451bbab23cf18e93c4260b2hding tempID = surface_ids[SID_RECON_PICTURE]; 6934b672db6ee89c9846451bbab23cf18e93c4260b2hding 6944b672db6ee89c9846451bbab23cf18e93c4260b2hding if (slice_type != SLICE_TYPE_B) { 6954b672db6ee89c9846451bbab23cf18e93c4260b2hding if (next_is_bpic) { 6964b672db6ee89c9846451bbab23cf18e93c4260b2hding surface_ids[SID_RECON_PICTURE] = surface_ids[SID_REFERENCE_PICTURE_L1]; 6974b672db6ee89c9846451bbab23cf18e93c4260b2hding surface_ids[SID_REFERENCE_PICTURE_L1] = tempID; 6984b672db6ee89c9846451bbab23cf18e93c4260b2hding } else { 6994b672db6ee89c9846451bbab23cf18e93c4260b2hding surface_ids[SID_RECON_PICTURE] = surface_ids[SID_REFERENCE_PICTURE_L0]; 7004b672db6ee89c9846451bbab23cf18e93c4260b2hding surface_ids[SID_REFERENCE_PICTURE_L0] = tempID; 7014b672db6ee89c9846451bbab23cf18e93c4260b2hding } 7024b672db6ee89c9846451bbab23cf18e93c4260b2hding } else { 7034b672db6ee89c9846451bbab23cf18e93c4260b2hding if (!next_is_bpic) { 7044b672db6ee89c9846451bbab23cf18e93c4260b2hding surface_ids[SID_RECON_PICTURE] = surface_ids[SID_REFERENCE_PICTURE_L0]; 7054b672db6ee89c9846451bbab23cf18e93c4260b2hding surface_ids[SID_REFERENCE_PICTURE_L0] = surface_ids[SID_REFERENCE_PICTURE_L1]; 7064b672db6ee89c9846451bbab23cf18e93c4260b2hding surface_ids[SID_REFERENCE_PICTURE_L1] = tempID; 7074b672db6ee89c9846451bbab23cf18e93c4260b2hding } 7084b672db6ee89c9846451bbab23cf18e93c4260b2hding } 7094b672db6ee89c9846451bbab23cf18e93c4260b2hding 7104b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_destroy_buffers(&avcenc_context.seq_param_buf_id, 1); 7114b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_destroy_buffers(&avcenc_context.pic_param_buf_id, 1); 7124b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_destroy_buffers(&avcenc_context.packed_seq_header_param_buf_id, 1); 7134b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_destroy_buffers(&avcenc_context.packed_seq_buf_id, 1); 7144b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_destroy_buffers(&avcenc_context.packed_pic_header_param_buf_id, 1); 7154b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_destroy_buffers(&avcenc_context.packed_pic_buf_id, 1); 716409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_destroy_buffers(&avcenc_context.packed_sei_header_param_buf_id, 1); 717409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_destroy_buffers(&avcenc_context.packed_sei_buf_id, 1); 7184b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_destroy_buffers(&avcenc_context.slice_param_buf_id[0], avcenc_context.num_slices); 7194b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_destroy_buffers(&avcenc_context.codedbuf_buf_id, 1); 7204b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_destroy_buffers(&avcenc_context.misc_parameter_hrd_buf_id, 1); 7214b672db6ee89c9846451bbab23cf18e93c4260b2hding 7224b672db6ee89c9846451bbab23cf18e93c4260b2hding memset(avcenc_context.slice_param, 0, sizeof(avcenc_context.slice_param)); 7234b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.num_slices = 0; 72410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 72510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 72610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang#define BITSTREAM_ALLOCATE_STEPPING 4096 72710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 72810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstruct __bitstream { 72910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang unsigned int *buffer; 73010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int bit_offset; 73110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int max_size_in_dword; 73210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang}; 73310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 73410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangtypedef struct __bitstream bitstream; 73510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 7364b672db6ee89c9846451bbab23cf18e93c4260b2hding#if 0 73710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic int 73810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangget_coded_bitsteam_length(unsigned char *buffer, int buffer_length) 73910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 74010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int i; 74110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 7424b672db6ee89c9846451bbab23cf18e93c4260b2hding for (i = 0; i < buffer_length - 3; i++) { 7434b672db6ee89c9846451bbab23cf18e93c4260b2hding if (!buffer[i] && 7444b672db6ee89c9846451bbab23cf18e93c4260b2hding !buffer[i + 1] && 7454b672db6ee89c9846451bbab23cf18e93c4260b2hding !buffer[i + 2] && 7464b672db6ee89c9846451bbab23cf18e93c4260b2hding !buffer[i + 3]) 74710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang break; 74810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 74910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 7504b672db6ee89c9846451bbab23cf18e93c4260b2hding return i; 75110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 7524b672db6ee89c9846451bbab23cf18e93c4260b2hding#endif 75310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 75410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic unsigned int 755409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanva_swap32(unsigned int val) 75610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 75710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang unsigned char *pval = (unsigned char *)&val; 75810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 75910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang return ((pval[0] << 24) | 76010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang (pval[1] << 16) | 76110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang (pval[2] << 8) | 76210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang (pval[3] << 0)); 76310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 76410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 76510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void 76610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangbitstream_start(bitstream *bs) 76710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 76810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bs->max_size_in_dword = BITSTREAM_ALLOCATE_STEPPING; 76910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bs->buffer = calloc(bs->max_size_in_dword * sizeof(int), 1); 77010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bs->bit_offset = 0; 77110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 77210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 77310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void 7744b672db6ee89c9846451bbab23cf18e93c4260b2hdingbitstream_end(bitstream *bs) 77510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 77610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int pos = (bs->bit_offset >> 5); 77710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int bit_offset = (bs->bit_offset & 0x1f); 77810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int bit_left = 32 - bit_offset; 77910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 78010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if (bit_offset) { 781409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bs->buffer[pos] = va_swap32((bs->buffer[pos] << bit_left)); 78210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 78310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 78410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 78510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void 78610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangbitstream_put_ui(bitstream *bs, unsigned int val, int size_in_bits) 78710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 78810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int pos = (bs->bit_offset >> 5); 78910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int bit_offset = (bs->bit_offset & 0x1f); 79010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int bit_left = 32 - bit_offset; 79110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 79210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if (!size_in_bits) 79310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang return; 79410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 79510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bs->bit_offset += size_in_bits; 79610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 79710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if (bit_left > size_in_bits) { 79810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bs->buffer[pos] = (bs->buffer[pos] << size_in_bits | val); 79910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } else { 80010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang size_in_bits -= bit_left; 80110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bs->buffer[pos] = (bs->buffer[pos] << bit_left) | (val >> size_in_bits); 802409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bs->buffer[pos] = va_swap32(bs->buffer[pos]); 80310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 80410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if (pos + 1 == bs->max_size_in_dword) { 80510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bs->max_size_in_dword += BITSTREAM_ALLOCATE_STEPPING; 80610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bs->buffer = realloc(bs->buffer, bs->max_size_in_dword * sizeof(unsigned int)); 80710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 80810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 80910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bs->buffer[pos + 1] = val; 81010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 81110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 81210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 81310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void 81410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangbitstream_put_ue(bitstream *bs, unsigned int val) 81510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 81610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int size_in_bits = 0; 81710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int tmp_val = ++val; 81810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 81910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang while (tmp_val) { 82010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang tmp_val >>= 1; 82110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang size_in_bits++; 82210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 82310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 82410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ui(bs, 0, size_in_bits - 1); // leading zero 82510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ui(bs, val, size_in_bits); 82610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 82710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 82810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void 82910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangbitstream_put_se(bitstream *bs, int val) 83010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 83110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang unsigned int new_val; 83210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 83310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if (val <= 0) 83410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang new_val = -2 * val; 83510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang else 83610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang new_val = 2 * val - 1; 83710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 83810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ue(bs, new_val); 83910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 84010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 84110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void 84210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangbitstream_byte_aligning(bitstream *bs, int bit) 84310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 84410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int bit_offset = (bs->bit_offset & 0x7); 84510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int bit_left = 8 - bit_offset; 84610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int new_val; 84710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 84810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if (!bit_offset) 84910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang return; 85010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 85110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang assert(bit == 0 || bit == 1); 85210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 85310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if (bit) 85410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang new_val = (1 << bit_left) - 1; 85510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang else 85610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang new_val = 0; 85710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 85810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ui(bs, new_val, bit_left); 85910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 86010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 86110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void 86210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangrbsp_trailing_bits(bitstream *bs) 86310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 86410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ui(bs, 1, 1); 86510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_byte_aligning(bs, 0); 86610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 86710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 86810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void nal_start_code_prefix(bitstream *bs) 86910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 87010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ui(bs, 0x00000001, 32); 87110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 87210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 87310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void nal_header(bitstream *bs, int nal_ref_idc, int nal_unit_type) 87410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 87510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ui(bs, 0, 1); /* forbidden_zero_bit: 0 */ 87610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ui(bs, nal_ref_idc, 2); 87710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ui(bs, nal_unit_type, 5); 87810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 87910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 88010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void sps_rbsp(bitstream *bs) 88110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 8824b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncSequenceParameterBufferH264 *seq_param = &avcenc_context.seq_param; 8834b672db6ee89c9846451bbab23cf18e93c4260b2hding int profile_idc = PROFILE_IDC_BASELINE; 88410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 8854b672db6ee89c9846451bbab23cf18e93c4260b2hding if (avcenc_context.profile == VAProfileH264High) 8864b672db6ee89c9846451bbab23cf18e93c4260b2hding profile_idc = PROFILE_IDC_HIGH; 8874b672db6ee89c9846451bbab23cf18e93c4260b2hding else if (avcenc_context.profile == VAProfileH264Main) 8884b672db6ee89c9846451bbab23cf18e93c4260b2hding profile_idc = PROFILE_IDC_MAIN; 88910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 89010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ui(bs, profile_idc, 8); /* profile_idc */ 891409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ui(bs, !!(avcenc_context.constraint_set_flag & 1), 1); /* constraint_set0_flag */ 892409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ui(bs, !!(avcenc_context.constraint_set_flag & 2), 1); /* constraint_set1_flag */ 893409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ui(bs, !!(avcenc_context.constraint_set_flag & 4), 1); /* constraint_set2_flag */ 894409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ui(bs, !!(avcenc_context.constraint_set_flag & 8), 1); /* constraint_set3_flag */ 89510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ui(bs, 0, 4); /* reserved_zero_4bits */ 8964b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, seq_param->level_idc, 8); /* level_idc */ 8974b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, seq_param->seq_parameter_set_id); /* seq_parameter_set_id */ 8984b672db6ee89c9846451bbab23cf18e93c4260b2hding 8994b672db6ee89c9846451bbab23cf18e93c4260b2hding if ( profile_idc == PROFILE_IDC_HIGH) { 9004b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, 1); /* chroma_format_idc = 1, 4:2:0 */ 9014b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, 0); /* bit_depth_luma_minus8 */ 9024b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, 0); /* bit_depth_chroma_minus8 */ 9034b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* qpprime_y_zero_transform_bypass_flag */ 9044b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* seq_scaling_matrix_present_flag */ 90510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 90610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 9074b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, seq_param->seq_fields.bits.log2_max_frame_num_minus4); /* log2_max_frame_num_minus4 */ 9084b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, seq_param->seq_fields.bits.pic_order_cnt_type); /* pic_order_cnt_type */ 90910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 9104b672db6ee89c9846451bbab23cf18e93c4260b2hding if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) 9114b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4); /* log2_max_pic_order_cnt_lsb_minus4 */ 91210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang else { 91310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang assert(0); 91410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 91510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 9164b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, seq_param->max_num_ref_frames); /* num_ref_frames */ 9174b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* gaps_in_frame_num_value_allowed_flag */ 91810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 9194b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, seq_param->picture_width_in_mbs - 1); /* pic_width_in_mbs_minus1 */ 9204b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, seq_param->picture_height_in_mbs - 1); /* pic_height_in_map_units_minus1 */ 9214b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, seq_param->seq_fields.bits.frame_mbs_only_flag, 1); /* frame_mbs_only_flag */ 92210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 9234b672db6ee89c9846451bbab23cf18e93c4260b2hding if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { 92410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang assert(0); 92510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 92610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 9274b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, seq_param->seq_fields.bits.direct_8x8_inference_flag, 1); /* direct_8x8_inference_flag */ 9284b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, seq_param->frame_cropping_flag, 1); /* frame_cropping_flag */ 92910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 9304b672db6ee89c9846451bbab23cf18e93c4260b2hding if (seq_param->frame_cropping_flag) { 9314b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, seq_param->frame_crop_left_offset); /* frame_crop_left_offset */ 9324b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, seq_param->frame_crop_right_offset); /* frame_crop_right_offset */ 9334b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, seq_param->frame_crop_top_offset); /* frame_crop_top_offset */ 9344b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, seq_param->frame_crop_bottom_offset); /* frame_crop_bottom_offset */ 9354b672db6ee89c9846451bbab23cf18e93c4260b2hding } 9364b672db6ee89c9846451bbab23cf18e93c4260b2hding 9374b672db6ee89c9846451bbab23cf18e93c4260b2hding if ( frame_bit_rate < 0 ) { 9384b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* vui_parameters_present_flag */ 9394b672db6ee89c9846451bbab23cf18e93c4260b2hding } else { 9404b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 1, 1); /* vui_parameters_present_flag */ 9414b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* aspect_ratio_info_present_flag */ 9424b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* overscan_info_present_flag */ 9434b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* video_signal_type_present_flag */ 9444b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* chroma_loc_info_present_flag */ 9454b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 1, 1); /* timing_info_present_flag */ 9464b672db6ee89c9846451bbab23cf18e93c4260b2hding { 9474b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 15, 32); 9484b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 900, 32); 9494b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 1, 1); 9504b672db6ee89c9846451bbab23cf18e93c4260b2hding } 9514b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 1, 1); /* nal_hrd_parameters_present_flag */ 9524b672db6ee89c9846451bbab23cf18e93c4260b2hding { 9534b672db6ee89c9846451bbab23cf18e93c4260b2hding // hrd_parameters 9544b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, 0); /* cpb_cnt_minus1 */ 9554b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 4, 4); /* bit_rate_scale */ 9564b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 6, 4); /* cpb_size_scale */ 9574b672db6ee89c9846451bbab23cf18e93c4260b2hding 9584b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, frame_bit_rate - 1); /* bit_rate_value_minus1[0] */ 9594b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, frame_bit_rate*8 - 1); /* cpb_size_value_minus1[0] */ 9604b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 1, 1); /* cbr_flag[0] */ 9614b672db6ee89c9846451bbab23cf18e93c4260b2hding 9624b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 23, 5); /* initial_cpb_removal_delay_length_minus1 */ 9634b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 23, 5); /* cpb_removal_delay_length_minus1 */ 9644b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 23, 5); /* dpb_output_delay_length_minus1 */ 9654b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 23, 5); /* time_offset_length */ 9664b672db6ee89c9846451bbab23cf18e93c4260b2hding } 9674b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* vcl_hrd_parameters_present_flag */ 9684b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* low_delay_hrd_flag */ 9694b672db6ee89c9846451bbab23cf18e93c4260b2hding 9704b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* pic_struct_present_flag */ 9714b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* bitstream_restriction_flag */ 97210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 97310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 9744b672db6ee89c9846451bbab23cf18e93c4260b2hding rbsp_trailing_bits(bs); /* rbsp_trailing_bits */ 97510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 97610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 9774b672db6ee89c9846451bbab23cf18e93c4260b2hding#if 0 97810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void build_nal_sps(FILE *avc_fp) 97910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 98010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream bs; 98110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 98210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_start(&bs); 98310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang nal_start_code_prefix(&bs); 98410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang nal_header(&bs, NAL_REF_IDC_HIGH, NAL_SPS); 98510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang sps_rbsp(&bs); 98610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_end(&bs, avc_fp); 98710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 9884b672db6ee89c9846451bbab23cf18e93c4260b2hding#endif 98910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 99010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void pps_rbsp(bitstream *bs) 99110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 9924b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncPictureParameterBufferH264 *pic_param = &avcenc_context.pic_param; 9934b672db6ee89c9846451bbab23cf18e93c4260b2hding 9944b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, pic_param->pic_parameter_set_id); /* pic_parameter_set_id */ 9954b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, pic_param->seq_parameter_set_id); /* seq_parameter_set_id */ 99610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 9974b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, pic_param->pic_fields.bits.entropy_coding_mode_flag, 1); /* entropy_coding_mode_flag */ 99810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 99910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ui(bs, 0, 1); /* pic_order_present_flag: 0 */ 100010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 100110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ue(bs, 0); /* num_slice_groups_minus1 */ 100210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 10034b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, pic_param->num_ref_idx_l0_active_minus1); /* num_ref_idx_l0_active_minus1 */ 10044b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ue(bs, pic_param->num_ref_idx_l1_active_minus1); /* num_ref_idx_l1_active_minus1 1 */ 100510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 10064b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, pic_param->pic_fields.bits.weighted_pred_flag, 1); /* weighted_pred_flag: 0 */ 10074b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, pic_param->pic_fields.bits.weighted_bipred_idc, 2); /* weighted_bipred_idc: 0 */ 100810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 10094b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_se(bs, pic_param->pic_init_qp - 26); /* pic_init_qp_minus26 */ 101010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_se(bs, 0); /* pic_init_qs_minus26 */ 101110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_se(bs, 0); /* chroma_qp_index_offset */ 101210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 10134b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, pic_param->pic_fields.bits.deblocking_filter_control_present_flag, 1); /* deblocking_filter_control_present_flag */ 101410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ui(bs, 0, 1); /* constrained_intra_pred_flag */ 101510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ui(bs, 0, 1); /* redundant_pic_cnt_present_flag */ 10164b672db6ee89c9846451bbab23cf18e93c4260b2hding 10174b672db6ee89c9846451bbab23cf18e93c4260b2hding /* more_rbsp_data */ 10184b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, pic_param->pic_fields.bits.transform_8x8_mode_flag, 1); /*transform_8x8_mode_flag */ 10194b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* pic_scaling_matrix_present_flag */ 10204b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_se(bs, pic_param->second_chroma_qp_index_offset ); /*second_chroma_qp_index_offset */ 102110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 102210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang rbsp_trailing_bits(bs); 102310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 102410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 10254b672db6ee89c9846451bbab23cf18e93c4260b2hding#if 0 102610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void build_nal_pps(FILE *avc_fp) 102710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 102810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream bs; 102910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 103010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_start(&bs); 103110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang nal_start_code_prefix(&bs); 103210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang nal_header(&bs, NAL_REF_IDC_HIGH, NAL_PPS); 103310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang pps_rbsp(&bs); 103410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_end(&bs, avc_fp); 103510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 103610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 103710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void 103810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangbuild_header(FILE *avc_fp) 103910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 104010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang build_nal_sps(avc_fp); 104110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang build_nal_pps(avc_fp); 104210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 10434b672db6ee89c9846451bbab23cf18e93c4260b2hding#endif 10444b672db6ee89c9846451bbab23cf18e93c4260b2hding 10454b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic int 10464b672db6ee89c9846451bbab23cf18e93c4260b2hdingbuild_packed_pic_buffer(unsigned char **header_buffer) 10474b672db6ee89c9846451bbab23cf18e93c4260b2hding{ 10484b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream bs; 10494b672db6ee89c9846451bbab23cf18e93c4260b2hding 10504b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_start(&bs); 10514b672db6ee89c9846451bbab23cf18e93c4260b2hding nal_start_code_prefix(&bs); 10524b672db6ee89c9846451bbab23cf18e93c4260b2hding nal_header(&bs, NAL_REF_IDC_HIGH, NAL_PPS); 10534b672db6ee89c9846451bbab23cf18e93c4260b2hding pps_rbsp(&bs); 10544b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_end(&bs); 10554b672db6ee89c9846451bbab23cf18e93c4260b2hding 10564b672db6ee89c9846451bbab23cf18e93c4260b2hding *header_buffer = (unsigned char *)bs.buffer; 10574b672db6ee89c9846451bbab23cf18e93c4260b2hding return bs.bit_offset; 10584b672db6ee89c9846451bbab23cf18e93c4260b2hding} 105910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 10604b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic int 10614b672db6ee89c9846451bbab23cf18e93c4260b2hdingbuild_packed_seq_buffer(unsigned char **header_buffer) 10624b672db6ee89c9846451bbab23cf18e93c4260b2hding{ 10634b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream bs; 106410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 10654b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_start(&bs); 10664b672db6ee89c9846451bbab23cf18e93c4260b2hding nal_start_code_prefix(&bs); 10674b672db6ee89c9846451bbab23cf18e93c4260b2hding nal_header(&bs, NAL_REF_IDC_HIGH, NAL_SPS); 10684b672db6ee89c9846451bbab23cf18e93c4260b2hding sps_rbsp(&bs); 10694b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_end(&bs); 10704b672db6ee89c9846451bbab23cf18e93c4260b2hding 10714b672db6ee89c9846451bbab23cf18e93c4260b2hding *header_buffer = (unsigned char *)bs.buffer; 10724b672db6ee89c9846451bbab23cf18e93c4260b2hding return bs.bit_offset; 10734b672db6ee89c9846451bbab23cf18e93c4260b2hding} 10744b672db6ee89c9846451bbab23cf18e93c4260b2hding 1075409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int 1076409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanbuild_packed_sei_buffer_timing(unsigned int init_cpb_removal_length, 1077409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned int init_cpb_removal_delay, 1078409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned int init_cpb_removal_delay_offset, 1079409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned int cpb_removal_length, 1080409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned int cpb_removal_delay, 1081409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned int dpb_output_length, 1082409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned int dpb_output_delay, 1083409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned char **sei_buffer) 1084409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{ 1085409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan unsigned char *byte_buf; 1086409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan int bp_byte_size, i, pic_byte_size; 1087409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1088409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream nal_bs; 1089409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream sei_bp_bs, sei_pic_bs; 1090409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1091409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_start(&sei_bp_bs); 1092409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ue(&sei_bp_bs, 0); /*seq_parameter_set_id*/ 1093409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ui(&sei_bp_bs, init_cpb_removal_delay, cpb_removal_length); 1094409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ui(&sei_bp_bs, init_cpb_removal_delay_offset, cpb_removal_length); 1095409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan if ( sei_bp_bs.bit_offset & 0x7) { 1096409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ui(&sei_bp_bs, 1, 1); 1097409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan } 1098409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_end(&sei_bp_bs); 1099409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bp_byte_size = (sei_bp_bs.bit_offset + 7) / 8; 1100409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1101409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_start(&sei_pic_bs); 1102409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ui(&sei_pic_bs, cpb_removal_delay, cpb_removal_length); 1103409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ui(&sei_pic_bs, dpb_output_delay, dpb_output_length); 1104409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan if ( sei_pic_bs.bit_offset & 0x7) { 1105409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ui(&sei_pic_bs, 1, 1); 1106409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan } 1107409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_end(&sei_pic_bs); 1108409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan pic_byte_size = (sei_pic_bs.bit_offset + 7) / 8; 1109409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1110409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_start(&nal_bs); 1111409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan nal_start_code_prefix(&nal_bs); 1112409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan nal_header(&nal_bs, NAL_REF_IDC_NONE, NAL_SEI); 1113409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1114409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan /* Write the SEI buffer period data */ 1115409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ui(&nal_bs, 0, 8); 1116409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ui(&nal_bs, bp_byte_size, 8); 1117409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1118409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan byte_buf = (unsigned char *)sei_bp_bs.buffer; 1119409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan for(i = 0; i < bp_byte_size; i++) { 1120409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ui(&nal_bs, byte_buf[i], 8); 1121409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan } 1122409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan free(byte_buf); 1123409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan /* write the SEI timing data */ 1124409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ui(&nal_bs, 0x01, 8); 1125409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ui(&nal_bs, pic_byte_size, 8); 1126409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1127409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan byte_buf = (unsigned char *)sei_pic_bs.buffer; 1128409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan for(i = 0; i < pic_byte_size; i++) { 1129409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_put_ui(&nal_bs, byte_buf[i], 8); 1130409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan } 1131409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan free(byte_buf); 1132409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1133409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan rbsp_trailing_bits(&nal_bs); 1134409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan bitstream_end(&nal_bs); 1135409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1136409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan *sei_buffer = (unsigned char *)nal_bs.buffer; 1137409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1138409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan return nal_bs.bit_offset; 1139409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan} 11404b672db6ee89c9846451bbab23cf18e93c4260b2hding 11414b672db6ee89c9846451bbab23cf18e93c4260b2hding#if 0 114210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void 11434b672db6ee89c9846451bbab23cf18e93c4260b2hdingslice_header(bitstream *bs, int frame_num, int display_frame, int slice_type, int nal_ref_idc, int is_idr) 11444b672db6ee89c9846451bbab23cf18e93c4260b2hding{ 11454b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncSequenceParameterBufferH264 *seq_param = &avcenc_context.seq_param; 11464b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncPictureParameterBufferH264 *pic_param = &avcenc_context.pic_param; 11474b672db6ee89c9846451bbab23cf18e93c4260b2hding int is_cabac = (pic_param->pic_fields.bits.entropy_coding_mode_flag == ENTROPY_MODE_CABAC); 114810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 114910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ue(bs, 0); /* first_mb_in_slice: 0 */ 115010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ue(bs, slice_type); /* slice_type */ 115110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ue(bs, 0); /* pic_parameter_set_id: 0 */ 11524b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, frame_num & 0x0F, seq_param->seq_fields.bits.log2_max_frame_num_minus4 + 4); /* frame_num */ 115310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 115410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang /* frame_mbs_only_flag == 1 */ 11554b672db6ee89c9846451bbab23cf18e93c4260b2hding if (!seq_param->seq_fields.bits.frame_mbs_only_flag) { 115610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang /* FIXME: */ 115710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang assert(0); 115810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 115910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 116010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if (is_idr) 116110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ue(bs, 0); /* idr_pic_id: 0 */ 116210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 11634b672db6ee89c9846451bbab23cf18e93c4260b2hding if (seq_param->seq_fields.bits.pic_order_cnt_type == 0) { 11644b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, (display_frame*2) & 0x3F, seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 + 4); 116510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang /* only support frame */ 116610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } else { 116710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang /* FIXME: */ 116810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang assert(0); 116910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 117010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 117110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang /* redundant_pic_cnt_present_flag == 0 */ 117210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 117310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang /* slice type */ 117410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if (slice_type == SLICE_TYPE_P) { 117510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ui(bs, 0, 1); /* num_ref_idx_active_override_flag: 0 */ 117610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang /* ref_pic_list_reordering */ 117710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ui(bs, 0, 1); /* ref_pic_list_reordering_flag_l0: 0 */ 117810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } else if (slice_type == SLICE_TYPE_B) { 11794b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 1, 1); /* direct_spatial_mv_pred: 1 */ 11804b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* num_ref_idx_active_override_flag: 0 */ 11814b672db6ee89c9846451bbab23cf18e93c4260b2hding /* ref_pic_list_reordering */ 11824b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* ref_pic_list_reordering_flag_l0: 0 */ 11834b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* ref_pic_list_reordering_flag_l1: 0 */ 11844b672db6ee89c9846451bbab23cf18e93c4260b2hding } 118510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 118610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang /* weighted_pred_flag == 0 */ 118710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 118810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang /* dec_ref_pic_marking */ 11894b672db6ee89c9846451bbab23cf18e93c4260b2hding if (nal_ref_idc != 0) { 11904b672db6ee89c9846451bbab23cf18e93c4260b2hding if ( is_idr) { 11914b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* no_output_of_prior_pics_flag: 0 */ 11924b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* long_term_reference_flag: 0 */ 11934b672db6ee89c9846451bbab23cf18e93c4260b2hding } else { 11944b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, 0, 1); /* adaptive_ref_pic_marking_mode_flag: 0 */ 11954b672db6ee89c9846451bbab23cf18e93c4260b2hding } 119610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 119710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 119810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if (is_cabac && (slice_type != SLICE_TYPE_I)) 119910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ue(bs, 0); /* cabac_init_idc: 0 */ 120010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 120110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_se(bs, 0); /* slice_qp_delta: 0 */ 120210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 12034b672db6ee89c9846451bbab23cf18e93c4260b2hding if (pic_param->pic_fields.bits.deblocking_filter_control_present_flag == 1) { 120410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_ue(bs, 0); /* disable_deblocking_filter_idc: 0 */ 120510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_se(bs, 2); /* slice_alpha_c0_offset_div2: 2 */ 120610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_put_se(bs, 2); /* slice_beta_offset_div2: 2 */ 120710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 120810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 120910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 121010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void 121110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangslice_data(bitstream *bs) 121210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 121310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang VACodedBufferSegment *coded_buffer_segment; 121410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang unsigned char *coded_mem; 121510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int i, slice_data_length; 121610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang VAStatus va_status; 121710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang VASurfaceStatus surface_status; 121810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 12194b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaSyncSurface(va_dpy, surface_ids[avcenc_context.current_input_surface]); 122010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang CHECK_VASTATUS(va_status,"vaSyncSurface"); 122110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 122210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang surface_status = 0; 12234b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaQuerySurfaceStatus(va_dpy, surface_ids[avcenc_context.current_input_surface], &surface_status); 122410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang CHECK_VASTATUS(va_status,"vaQuerySurfaceStatus"); 122510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 12264b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaMapBuffer(va_dpy, avcenc_context.codedbuf_buf_id, (void **)(&coded_buffer_segment)); 122710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang CHECK_VASTATUS(va_status,"vaMapBuffer"); 122810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang coded_mem = coded_buffer_segment->buf; 122910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 12304b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_data_length = get_coded_bitsteam_length(coded_mem, codedbuf_size); 123110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 12324b672db6ee89c9846451bbab23cf18e93c4260b2hding for (i = 0; i < slice_data_length; i++) { 12334b672db6ee89c9846451bbab23cf18e93c4260b2hding bitstream_put_ui(bs, *coded_mem, 8); 12344b672db6ee89c9846451bbab23cf18e93c4260b2hding coded_mem++; 123510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 123610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 12374b672db6ee89c9846451bbab23cf18e93c4260b2hding vaUnmapBuffer(va_dpy, avcenc_context.codedbuf_buf_id); 123810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 123910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 124010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangstatic void 12414b672db6ee89c9846451bbab23cf18e93c4260b2hdingbuild_nal_slice(FILE *avc_fp, int frame_num, int display_frame, int slice_type, int is_idr) 124210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 124310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream bs; 124410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 124510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_start(&bs); 124610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang slice_data(&bs); 124710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang bitstream_end(&bs, avc_fp); 124810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 124910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 12504b672db6ee89c9846451bbab23cf18e93c4260b2hding#endif 12514b672db6ee89c9846451bbab23cf18e93c4260b2hding 12524b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic int 12534b672db6ee89c9846451bbab23cf18e93c4260b2hdingstore_coded_buffer(FILE *avc_fp, int slice_type) 12544b672db6ee89c9846451bbab23cf18e93c4260b2hding{ 12554b672db6ee89c9846451bbab23cf18e93c4260b2hding VACodedBufferSegment *coded_buffer_segment; 12564b672db6ee89c9846451bbab23cf18e93c4260b2hding unsigned char *coded_mem; 12574b672db6ee89c9846451bbab23cf18e93c4260b2hding int slice_data_length; 12584b672db6ee89c9846451bbab23cf18e93c4260b2hding VAStatus va_status; 12594b672db6ee89c9846451bbab23cf18e93c4260b2hding VASurfaceStatus surface_status; 12604b672db6ee89c9846451bbab23cf18e93c4260b2hding size_t w_items; 12614b672db6ee89c9846451bbab23cf18e93c4260b2hding 12624b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaSyncSurface(va_dpy, surface_ids[avcenc_context.current_input_surface]); 12634b672db6ee89c9846451bbab23cf18e93c4260b2hding CHECK_VASTATUS(va_status,"vaSyncSurface"); 12644b672db6ee89c9846451bbab23cf18e93c4260b2hding 12654b672db6ee89c9846451bbab23cf18e93c4260b2hding surface_status = 0; 12664b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaQuerySurfaceStatus(va_dpy, surface_ids[avcenc_context.current_input_surface], &surface_status); 12674b672db6ee89c9846451bbab23cf18e93c4260b2hding CHECK_VASTATUS(va_status,"vaQuerySurfaceStatus"); 12684b672db6ee89c9846451bbab23cf18e93c4260b2hding 12694b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaMapBuffer(va_dpy, avcenc_context.codedbuf_buf_id, (void **)(&coded_buffer_segment)); 12704b672db6ee89c9846451bbab23cf18e93c4260b2hding CHECK_VASTATUS(va_status,"vaMapBuffer"); 12714b672db6ee89c9846451bbab23cf18e93c4260b2hding coded_mem = coded_buffer_segment->buf; 12724b672db6ee89c9846451bbab23cf18e93c4260b2hding 12734b672db6ee89c9846451bbab23cf18e93c4260b2hding if (coded_buffer_segment->status & VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK) { 12744b672db6ee89c9846451bbab23cf18e93c4260b2hding if (slice_type == SLICE_TYPE_I) 12754b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.codedbuf_i_size *= 2; 12764b672db6ee89c9846451bbab23cf18e93c4260b2hding else 12774b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.codedbuf_pb_size *= 2; 12784b672db6ee89c9846451bbab23cf18e93c4260b2hding 12794b672db6ee89c9846451bbab23cf18e93c4260b2hding vaUnmapBuffer(va_dpy, avcenc_context.codedbuf_buf_id); 12804b672db6ee89c9846451bbab23cf18e93c4260b2hding return -1; 12814b672db6ee89c9846451bbab23cf18e93c4260b2hding } 12824b672db6ee89c9846451bbab23cf18e93c4260b2hding 12834b672db6ee89c9846451bbab23cf18e93c4260b2hding slice_data_length = coded_buffer_segment->size; 12844b672db6ee89c9846451bbab23cf18e93c4260b2hding 12854b672db6ee89c9846451bbab23cf18e93c4260b2hding do { 12864b672db6ee89c9846451bbab23cf18e93c4260b2hding w_items = fwrite(coded_mem, slice_data_length, 1, avc_fp); 12874b672db6ee89c9846451bbab23cf18e93c4260b2hding } while (w_items != 1); 12884b672db6ee89c9846451bbab23cf18e93c4260b2hding 12894b672db6ee89c9846451bbab23cf18e93c4260b2hding if (slice_type == SLICE_TYPE_I) { 12904b672db6ee89c9846451bbab23cf18e93c4260b2hding if (avcenc_context.codedbuf_i_size > slice_data_length * 3 / 2) { 12914b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.codedbuf_i_size = slice_data_length * 3 / 2; 12924b672db6ee89c9846451bbab23cf18e93c4260b2hding } 12934b672db6ee89c9846451bbab23cf18e93c4260b2hding 12944b672db6ee89c9846451bbab23cf18e93c4260b2hding if (avcenc_context.codedbuf_pb_size < slice_data_length) { 12954b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.codedbuf_pb_size = slice_data_length; 12964b672db6ee89c9846451bbab23cf18e93c4260b2hding } 12974b672db6ee89c9846451bbab23cf18e93c4260b2hding } else { 12984b672db6ee89c9846451bbab23cf18e93c4260b2hding if (avcenc_context.codedbuf_pb_size > slice_data_length * 3 / 2) { 12994b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.codedbuf_pb_size = slice_data_length * 3 / 2; 13004b672db6ee89c9846451bbab23cf18e93c4260b2hding } 13014b672db6ee89c9846451bbab23cf18e93c4260b2hding } 13024b672db6ee89c9846451bbab23cf18e93c4260b2hding 13034b672db6ee89c9846451bbab23cf18e93c4260b2hding vaUnmapBuffer(va_dpy, avcenc_context.codedbuf_buf_id); 13044b672db6ee89c9846451bbab23cf18e93c4260b2hding 13054b672db6ee89c9846451bbab23cf18e93c4260b2hding return 0; 13064b672db6ee89c9846451bbab23cf18e93c4260b2hding} 13074b672db6ee89c9846451bbab23cf18e93c4260b2hding 13084b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic void 13094b672db6ee89c9846451bbab23cf18e93c4260b2hdingencode_picture(FILE *yuv_fp, FILE *avc_fp, 13104b672db6ee89c9846451bbab23cf18e93c4260b2hding int frame_num, int display_num, 13114b672db6ee89c9846451bbab23cf18e93c4260b2hding int is_idr, 13124b672db6ee89c9846451bbab23cf18e93c4260b2hding int slice_type, int next_is_bpic, 13134b672db6ee89c9846451bbab23cf18e93c4260b2hding int next_display_num) 13144b672db6ee89c9846451bbab23cf18e93c4260b2hding{ 13154b672db6ee89c9846451bbab23cf18e93c4260b2hding VAStatus va_status; 13164b672db6ee89c9846451bbab23cf18e93c4260b2hding int ret = 0, codedbuf_size; 13174b672db6ee89c9846451bbab23cf18e93c4260b2hding 13184b672db6ee89c9846451bbab23cf18e93c4260b2hding begin_picture(yuv_fp, frame_num, display_num, slice_type, is_idr); 13194b672db6ee89c9846451bbab23cf18e93c4260b2hding 13204b672db6ee89c9846451bbab23cf18e93c4260b2hding //if (next_display_num < frame_number) { 13214b672db6ee89c9846451bbab23cf18e93c4260b2hding if (1) { 13224b672db6ee89c9846451bbab23cf18e93c4260b2hding int index; 13234b672db6ee89c9846451bbab23cf18e93c4260b2hding 13244b672db6ee89c9846451bbab23cf18e93c4260b2hding /* prepare for next frame */ 13254b672db6ee89c9846451bbab23cf18e93c4260b2hding if (avcenc_context.current_input_surface == SID_INPUT_PICTURE_0) 13264b672db6ee89c9846451bbab23cf18e93c4260b2hding index = SID_INPUT_PICTURE_1; 13274b672db6ee89c9846451bbab23cf18e93c4260b2hding else 13284b672db6ee89c9846451bbab23cf18e93c4260b2hding index = SID_INPUT_PICTURE_0; 13294b672db6ee89c9846451bbab23cf18e93c4260b2hding if ( next_display_num >= frame_number ) 13304b672db6ee89c9846451bbab23cf18e93c4260b2hding next_display_num = frame_number - 1; 13314b672db6ee89c9846451bbab23cf18e93c4260b2hding fseek(yuv_fp, frame_size * next_display_num, SEEK_SET); 13324b672db6ee89c9846451bbab23cf18e93c4260b2hding 13334b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.upload_thread_param.yuv_fp = yuv_fp; 13344b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.upload_thread_param.surface_id = surface_ids[index]; 13354b672db6ee89c9846451bbab23cf18e93c4260b2hding 13364b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.upload_thread_value = pthread_create(&avcenc_context.upload_thread_id, 13374b672db6ee89c9846451bbab23cf18e93c4260b2hding NULL, 13384b672db6ee89c9846451bbab23cf18e93c4260b2hding upload_thread_function, 13394b672db6ee89c9846451bbab23cf18e93c4260b2hding (void*)&avcenc_context.upload_thread_param); 13404b672db6ee89c9846451bbab23cf18e93c4260b2hding } 13414b672db6ee89c9846451bbab23cf18e93c4260b2hding 13424b672db6ee89c9846451bbab23cf18e93c4260b2hding do { 13434b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_destroy_buffers(&avcenc_context.codedbuf_buf_id, 1); 13444b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_destroy_buffers(&avcenc_context.pic_param_buf_id, 1); 13454b672db6ee89c9846451bbab23cf18e93c4260b2hding 13464b672db6ee89c9846451bbab23cf18e93c4260b2hding 13474b672db6ee89c9846451bbab23cf18e93c4260b2hding if (SLICE_TYPE_I == slice_type) { 13484b672db6ee89c9846451bbab23cf18e93c4260b2hding codedbuf_size = avcenc_context.codedbuf_i_size; 13494b672db6ee89c9846451bbab23cf18e93c4260b2hding } else { 13504b672db6ee89c9846451bbab23cf18e93c4260b2hding codedbuf_size = avcenc_context.codedbuf_pb_size; 13514b672db6ee89c9846451bbab23cf18e93c4260b2hding } 13524b672db6ee89c9846451bbab23cf18e93c4260b2hding 13534b672db6ee89c9846451bbab23cf18e93c4260b2hding /* coded buffer */ 13544b672db6ee89c9846451bbab23cf18e93c4260b2hding va_status = vaCreateBuffer(va_dpy, 13554b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.context_id, 13564b672db6ee89c9846451bbab23cf18e93c4260b2hding VAEncCodedBufferType, 13574b672db6ee89c9846451bbab23cf18e93c4260b2hding codedbuf_size, 1, NULL, 13584b672db6ee89c9846451bbab23cf18e93c4260b2hding &avcenc_context.codedbuf_buf_id); 13594b672db6ee89c9846451bbab23cf18e93c4260b2hding CHECK_VASTATUS(va_status,"vaCreateBuffer"); 13604b672db6ee89c9846451bbab23cf18e93c4260b2hding 13614b672db6ee89c9846451bbab23cf18e93c4260b2hding /* picture parameter set */ 13624b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_update_picture_parameter(slice_type, frame_num, display_num, is_idr); 13634b672db6ee89c9846451bbab23cf18e93c4260b2hding 1364409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan if (avcenc_context.rate_control_method == VA_RC_CBR) 1365409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_update_sei_param(frame_num); 1366409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 13674b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_render_picture(); 13684b672db6ee89c9846451bbab23cf18e93c4260b2hding 13694b672db6ee89c9846451bbab23cf18e93c4260b2hding ret = store_coded_buffer(avc_fp, slice_type); 13704b672db6ee89c9846451bbab23cf18e93c4260b2hding } while (ret); 13714b672db6ee89c9846451bbab23cf18e93c4260b2hding 13724b672db6ee89c9846451bbab23cf18e93c4260b2hding end_picture(slice_type, next_is_bpic); 13734b672db6ee89c9846451bbab23cf18e93c4260b2hding} 13744b672db6ee89c9846451bbab23cf18e93c4260b2hding 13754b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic void encode_pb_pictures(FILE *yuv_fp, FILE *avc_fp, int f, int nbframes, int next_f) 13764b672db6ee89c9846451bbab23cf18e93c4260b2hding{ 13774b672db6ee89c9846451bbab23cf18e93c4260b2hding int i; 13784b672db6ee89c9846451bbab23cf18e93c4260b2hding encode_picture(yuv_fp, avc_fp, 13794b672db6ee89c9846451bbab23cf18e93c4260b2hding enc_frame_number, f + nbframes, 13804b672db6ee89c9846451bbab23cf18e93c4260b2hding 0, 13814b672db6ee89c9846451bbab23cf18e93c4260b2hding SLICE_TYPE_P, 1, f); 13824b672db6ee89c9846451bbab23cf18e93c4260b2hding 13834b672db6ee89c9846451bbab23cf18e93c4260b2hding for( i = 0; i < nbframes - 1; i++) { 13844b672db6ee89c9846451bbab23cf18e93c4260b2hding encode_picture(yuv_fp, avc_fp, 13854b672db6ee89c9846451bbab23cf18e93c4260b2hding enc_frame_number + 1, f + i, 13864b672db6ee89c9846451bbab23cf18e93c4260b2hding 0, 13874b672db6ee89c9846451bbab23cf18e93c4260b2hding SLICE_TYPE_B, 1, f + i + 1); 13884b672db6ee89c9846451bbab23cf18e93c4260b2hding } 13894b672db6ee89c9846451bbab23cf18e93c4260b2hding 13904b672db6ee89c9846451bbab23cf18e93c4260b2hding encode_picture(yuv_fp, avc_fp, 13914b672db6ee89c9846451bbab23cf18e93c4260b2hding enc_frame_number + 1, f + nbframes - 1, 13924b672db6ee89c9846451bbab23cf18e93c4260b2hding 0, 13934b672db6ee89c9846451bbab23cf18e93c4260b2hding SLICE_TYPE_B, 0, next_f); 13944b672db6ee89c9846451bbab23cf18e93c4260b2hding} 13954b672db6ee89c9846451bbab23cf18e93c4260b2hding 13964b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic void show_help() 13974b672db6ee89c9846451bbab23cf18e93c4260b2hding{ 13984b672db6ee89c9846451bbab23cf18e93c4260b2hding printf("Usage: avnenc <width> <height> <input_yuvfile> <output_avcfile> [qp=qpvalue|fb=framebitrate] [mode=0(I frames only)/1(I and P frames)/2(I, P and B frames)\n"); 13994b672db6ee89c9846451bbab23cf18e93c4260b2hding} 14004b672db6ee89c9846451bbab23cf18e93c4260b2hding 14014b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic void avcenc_context_seq_param_init(VAEncSequenceParameterBufferH264 *seq_param, 14024b672db6ee89c9846451bbab23cf18e93c4260b2hding int width, int height) 14034b672db6ee89c9846451bbab23cf18e93c4260b2hding 14044b672db6ee89c9846451bbab23cf18e93c4260b2hding{ 14054b672db6ee89c9846451bbab23cf18e93c4260b2hding int width_in_mbs = (width + 15) / 16; 14064b672db6ee89c9846451bbab23cf18e93c4260b2hding int height_in_mbs = (height + 15) / 16; 14074b672db6ee89c9846451bbab23cf18e93c4260b2hding int frame_cropping_flag = 0; 14084b672db6ee89c9846451bbab23cf18e93c4260b2hding int frame_crop_bottom_offset = 0; 14094b672db6ee89c9846451bbab23cf18e93c4260b2hding 14104b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->seq_parameter_set_id = 0; 14114b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->level_idc = 41; 14124b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->intra_period = intra_period; 14134b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->ip_period = 0; /* FIXME: ??? */ 14144b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->max_num_ref_frames = 4; 14154b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->picture_width_in_mbs = width_in_mbs; 14164b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->picture_height_in_mbs = height_in_mbs; 14174b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->seq_fields.bits.frame_mbs_only_flag = 1; 14184b672db6ee89c9846451bbab23cf18e93c4260b2hding 14194b672db6ee89c9846451bbab23cf18e93c4260b2hding if (frame_bit_rate > 0) 14204b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->bits_per_second = 1024 * frame_bit_rate; /* use kbps as input */ 14214b672db6ee89c9846451bbab23cf18e93c4260b2hding else 14224b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->bits_per_second = 0; 14234b672db6ee89c9846451bbab23cf18e93c4260b2hding 14244b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->time_scale = 900; 14254b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->num_units_in_tick = 15; /* Tc = num_units_in_tick / time_sacle */ 14264b672db6ee89c9846451bbab23cf18e93c4260b2hding 14274b672db6ee89c9846451bbab23cf18e93c4260b2hding if (height_in_mbs * 16 - height) { 14284b672db6ee89c9846451bbab23cf18e93c4260b2hding frame_cropping_flag = 1; 14294b672db6ee89c9846451bbab23cf18e93c4260b2hding frame_crop_bottom_offset = 14304b672db6ee89c9846451bbab23cf18e93c4260b2hding (height_in_mbs * 16 - height) / (2 * (!seq_param->seq_fields.bits.frame_mbs_only_flag + 1)); 14314b672db6ee89c9846451bbab23cf18e93c4260b2hding } 14324b672db6ee89c9846451bbab23cf18e93c4260b2hding 14334b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->frame_cropping_flag = frame_cropping_flag; 14344b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->frame_crop_left_offset = 0; 14354b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->frame_crop_right_offset = 0; 14364b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->frame_crop_top_offset = 0; 14374b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->frame_crop_bottom_offset = frame_crop_bottom_offset; 14384b672db6ee89c9846451bbab23cf18e93c4260b2hding 14394b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->seq_fields.bits.pic_order_cnt_type = 0; 14404b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->seq_fields.bits.direct_8x8_inference_flag = 0; 14414b672db6ee89c9846451bbab23cf18e93c4260b2hding 14424b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->seq_fields.bits.log2_max_frame_num_minus4 = 0; 14434b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = 2; 14444b672db6ee89c9846451bbab23cf18e93c4260b2hding 14454b672db6ee89c9846451bbab23cf18e93c4260b2hding if (frame_bit_rate > 0) 14464b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->vui_parameters_present_flag = 1; //HRD info located in vui 14474b672db6ee89c9846451bbab23cf18e93c4260b2hding else 14484b672db6ee89c9846451bbab23cf18e93c4260b2hding seq_param->vui_parameters_present_flag = 0; 14494b672db6ee89c9846451bbab23cf18e93c4260b2hding} 14504b672db6ee89c9846451bbab23cf18e93c4260b2hding 14514b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic void avcenc_context_pic_param_init(VAEncPictureParameterBufferH264 *pic_param) 145210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 14534b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->seq_parameter_set_id = 0; 14544b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->pic_parameter_set_id = 0; 14554b672db6ee89c9846451bbab23cf18e93c4260b2hding 14564b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->last_picture = 0; 14574b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->frame_num = 0; 14584b672db6ee89c9846451bbab23cf18e93c4260b2hding 14594b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->pic_init_qp = (qp_value >= 0 ? qp_value : 26); 14604b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->num_ref_idx_l0_active_minus1 = 0; 14614b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->num_ref_idx_l1_active_minus1 = 0; 14624b672db6ee89c9846451bbab23cf18e93c4260b2hding 14634b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->pic_fields.bits.idr_pic_flag = 0; 14644b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->pic_fields.bits.reference_pic_flag = 0; 14654b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->pic_fields.bits.entropy_coding_mode_flag = ENTROPY_MODE_CABAC; 14664b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->pic_fields.bits.weighted_pred_flag = 0; 14674b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->pic_fields.bits.weighted_bipred_idc = 0; 1468409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1469409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan if (avcenc_context.constraint_set_flag & 0x7) 1470409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan pic_param->pic_fields.bits.transform_8x8_mode_flag = 0; 1471409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan else 1472409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan pic_param->pic_fields.bits.transform_8x8_mode_flag = 1; 1473409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 14744b672db6ee89c9846451bbab23cf18e93c4260b2hding pic_param->pic_fields.bits.deblocking_filter_control_present_flag = 1; 14754b672db6ee89c9846451bbab23cf18e93c4260b2hding} 14764b672db6ee89c9846451bbab23cf18e93c4260b2hding 1477409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void avcenc_context_sei_init() 1478409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{ 1479409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan int init_cpb_size; 1480409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan int target_bit_rate; 1481409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1482409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan /* it comes for the bps defined in SPS */ 1483409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan target_bit_rate = avcenc_context.seq_param.bits_per_second; 1484409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan init_cpb_size = (target_bit_rate * 8) >> 10; 1485409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.i_initial_cpb_removal_delay = init_cpb_size * 0.5 * 1024 / target_bit_rate * 90000; 1486409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1487409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.i_cpb_removal_delay = 2; 1488409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.i_initial_cpb_removal_delay_length = 24; 1489409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.i_cpb_removal_delay_length = 24; 1490409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.i_dpb_output_delay_length = 24; 1491409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan} 1492409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 14934b672db6ee89c9846451bbab23cf18e93c4260b2hdingstatic void avcenc_context_init(int width, int height) 14944b672db6ee89c9846451bbab23cf18e93c4260b2hding{ 14954b672db6ee89c9846451bbab23cf18e93c4260b2hding int i; 14964b672db6ee89c9846451bbab23cf18e93c4260b2hding memset(&avcenc_context, 0, sizeof(avcenc_context)); 14974b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.profile = VAProfileH264Main; 1498409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1499409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan switch (avcenc_context.profile) { 1500409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan case VAProfileH264Baseline: 1501409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.constraint_set_flag |= (1 << 0); /* Annex A.2.1 */ 1502409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan break; 1503409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1504409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan case VAProfileH264Main: 1505409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.constraint_set_flag |= (1 << 1); /* Annex A.2.2 */ 1506409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan break; 1507409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1508409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan case VAProfileH264High: 1509409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.constraint_set_flag |= (1 << 3); /* Annex A.2.4 */ 1510409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan break; 1511409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1512409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan default: 1513409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan break; 1514409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan } 1515409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 15164b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.seq_param_buf_id = VA_INVALID_ID; 15174b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.pic_param_buf_id = VA_INVALID_ID; 15184b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.packed_seq_header_param_buf_id = VA_INVALID_ID; 15194b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.packed_seq_buf_id = VA_INVALID_ID; 15204b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.packed_pic_header_param_buf_id = VA_INVALID_ID; 15214b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.packed_pic_buf_id = VA_INVALID_ID; 15224b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.codedbuf_buf_id = VA_INVALID_ID; 15234b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.misc_parameter_hrd_buf_id = VA_INVALID_ID; 15244b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.codedbuf_i_size = width * height; 15254b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.codedbuf_pb_size = 0; 15264b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.current_input_surface = SID_INPUT_PICTURE_0; 15274b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.upload_thread_value = -1; 1528409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.packed_sei_header_param_buf_id = VA_INVALID_ID; 1529409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context.packed_sei_buf_id = VA_INVALID_ID; 15304b672db6ee89c9846451bbab23cf18e93c4260b2hding 15314b672db6ee89c9846451bbab23cf18e93c4260b2hding if (qp_value == -1) 15324b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.rate_control_method = VA_RC_CBR; 15334b672db6ee89c9846451bbab23cf18e93c4260b2hding else if (qp_value == -2) 15344b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.rate_control_method = VA_RC_VBR; 15354b672db6ee89c9846451bbab23cf18e93c4260b2hding else { 15364b672db6ee89c9846451bbab23cf18e93c4260b2hding assert(qp_value >= 0 && qp_value <= 51); 15374b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.rate_control_method = VA_RC_CQP; 15384b672db6ee89c9846451bbab23cf18e93c4260b2hding } 15394b672db6ee89c9846451bbab23cf18e93c4260b2hding 15404b672db6ee89c9846451bbab23cf18e93c4260b2hding for (i = 0; i < MAX_SLICES; i++) { 15414b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context.slice_param_buf_id[i] = VA_INVALID_ID; 15424b672db6ee89c9846451bbab23cf18e93c4260b2hding } 15434b672db6ee89c9846451bbab23cf18e93c4260b2hding 15444b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context_seq_param_init(&avcenc_context.seq_param, width, height); 15454b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context_pic_param_init(&avcenc_context.pic_param); 1546409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan if (avcenc_context.rate_control_method == VA_RC_CBR) 1547409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan avcenc_context_sei_init(); 154810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 154910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 155010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wangint main(int argc, char *argv[]) 155110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang{ 155210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang int f; 155310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang FILE *yuv_fp; 155410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang FILE *avc_fp; 155510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang long file_size; 15564b672db6ee89c9846451bbab23cf18e93c4260b2hding int i_frame_only=0,i_p_frame_only=1; 15574b672db6ee89c9846451bbab23cf18e93c4260b2hding int mode_value; 15584b672db6ee89c9846451bbab23cf18e93c4260b2hding struct timeval tpstart,tpend; 15594b672db6ee89c9846451bbab23cf18e93c4260b2hding float timeuse; 1560409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 1561409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan va_init_display_args(&argc, argv); 1562409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan 15634b672db6ee89c9846451bbab23cf18e93c4260b2hding //TODO may be we should using option analytics library 15644b672db6ee89c9846451bbab23cf18e93c4260b2hding if(argc != 5 && argc != 6 && argc != 7) { 15654b672db6ee89c9846451bbab23cf18e93c4260b2hding show_help(); 156610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang return -1; 156710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 156810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 156910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang picture_width = atoi(argv[1]); 157010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang picture_height = atoi(argv[2]); 1571a00f54a574bb5a51af428b03577599bcc70a17b2Austin Yuan picture_width_in_mbs = (picture_width + 15) / 16; 1572a00f54a574bb5a51af428b03577599bcc70a17b2Austin Yuan picture_height_in_mbs = (picture_height + 15) / 16; 157310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 15744b672db6ee89c9846451bbab23cf18e93c4260b2hding if (argc == 6 || argc == 7) { 15754b672db6ee89c9846451bbab23cf18e93c4260b2hding qp_value = -1; 15764b672db6ee89c9846451bbab23cf18e93c4260b2hding sscanf(argv[5], "qp=%d", &qp_value); 15774b672db6ee89c9846451bbab23cf18e93c4260b2hding if ( qp_value == -1 ) { 15784b672db6ee89c9846451bbab23cf18e93c4260b2hding frame_bit_rate = -1; 15794b672db6ee89c9846451bbab23cf18e93c4260b2hding sscanf(argv[5], "fb=%d", &frame_bit_rate); 15804b672db6ee89c9846451bbab23cf18e93c4260b2hding if ( frame_bit_rate == -1 ) { 15814b672db6ee89c9846451bbab23cf18e93c4260b2hding show_help(); 15824b672db6ee89c9846451bbab23cf18e93c4260b2hding return -1; 15834b672db6ee89c9846451bbab23cf18e93c4260b2hding } 15844b672db6ee89c9846451bbab23cf18e93c4260b2hding } else if (qp_value > 51) { 15854b672db6ee89c9846451bbab23cf18e93c4260b2hding qp_value = 51; 15864b672db6ee89c9846451bbab23cf18e93c4260b2hding } else if (qp_value < 0) { 15874b672db6ee89c9846451bbab23cf18e93c4260b2hding qp_value = 0; 15884b672db6ee89c9846451bbab23cf18e93c4260b2hding } 15894b672db6ee89c9846451bbab23cf18e93c4260b2hding } else 15904b672db6ee89c9846451bbab23cf18e93c4260b2hding qp_value = 28; //default const QP mode 15914b672db6ee89c9846451bbab23cf18e93c4260b2hding 15924b672db6ee89c9846451bbab23cf18e93c4260b2hding if (argc == 7) { 15934b672db6ee89c9846451bbab23cf18e93c4260b2hding sscanf(argv[6], "mode=%d", &mode_value); 15944b672db6ee89c9846451bbab23cf18e93c4260b2hding if ( mode_value == 0 ) { 15954b672db6ee89c9846451bbab23cf18e93c4260b2hding i_frame_only = 1; 15964b672db6ee89c9846451bbab23cf18e93c4260b2hding i_p_frame_only = 0; 15974b672db6ee89c9846451bbab23cf18e93c4260b2hding } 15984b672db6ee89c9846451bbab23cf18e93c4260b2hding else if ( mode_value == 1) { 15994b672db6ee89c9846451bbab23cf18e93c4260b2hding i_frame_only = 0; 16004b672db6ee89c9846451bbab23cf18e93c4260b2hding i_p_frame_only = 1; 16014b672db6ee89c9846451bbab23cf18e93c4260b2hding } 16024b672db6ee89c9846451bbab23cf18e93c4260b2hding else if ( mode_value == 2 ) { 16034b672db6ee89c9846451bbab23cf18e93c4260b2hding i_frame_only = 0; 16044b672db6ee89c9846451bbab23cf18e93c4260b2hding i_p_frame_only = 0; 16054b672db6ee89c9846451bbab23cf18e93c4260b2hding } 16064b672db6ee89c9846451bbab23cf18e93c4260b2hding else { 16074b672db6ee89c9846451bbab23cf18e93c4260b2hding printf("mode_value=%d\n",mode_value); 16084b672db6ee89c9846451bbab23cf18e93c4260b2hding show_help(); 16094b672db6ee89c9846451bbab23cf18e93c4260b2hding return -1; 16104b672db6ee89c9846451bbab23cf18e93c4260b2hding } 16114b672db6ee89c9846451bbab23cf18e93c4260b2hding } 161210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 161310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang yuv_fp = fopen(argv[3],"rb"); 161410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if ( yuv_fp == NULL){ 161510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang printf("Can't open input YUV file\n"); 161610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang return -1; 161710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 161810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang fseek(yuv_fp,0l, SEEK_END); 161910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang file_size = ftell(yuv_fp); 162010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang frame_size = picture_width * picture_height + ((picture_width * picture_height) >> 1) ; 162110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 162210965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if ( (file_size < frame_size) || (file_size % frame_size) ) { 16234b672db6ee89c9846451bbab23cf18e93c4260b2hding fclose(yuv_fp); 162410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang printf("The YUV file's size is not correct\n"); 162510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang return -1; 162610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 162710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang frame_number = file_size / frame_size; 162810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang fseek(yuv_fp, 0l, SEEK_SET); 162910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 163010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang avc_fp = fopen(argv[4], "wb"); 163110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang if ( avc_fp == NULL) { 16324b672db6ee89c9846451bbab23cf18e93c4260b2hding fclose(yuv_fp); 163310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang printf("Can't open output avc file\n"); 163410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang return -1; 163510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 16364b672db6ee89c9846451bbab23cf18e93c4260b2hding gettimeofday(&tpstart,NULL); 16374b672db6ee89c9846451bbab23cf18e93c4260b2hding avcenc_context_init(picture_width, picture_height); 163810965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang create_encode_pipe(); 16394b672db6ee89c9846451bbab23cf18e93c4260b2hding alloc_encode_resource(yuv_fp); 16404b672db6ee89c9846451bbab23cf18e93c4260b2hding 16414b672db6ee89c9846451bbab23cf18e93c4260b2hding enc_frame_number = 0; 16424b672db6ee89c9846451bbab23cf18e93c4260b2hding for ( f = 0; f < frame_number; ) { //picture level loop 16434b672db6ee89c9846451bbab23cf18e93c4260b2hding static int const frame_type_pattern[][2] = { {SLICE_TYPE_I,1}, 16444b672db6ee89c9846451bbab23cf18e93c4260b2hding {SLICE_TYPE_P,3}, {SLICE_TYPE_P,3},{SLICE_TYPE_P,3}, 16454b672db6ee89c9846451bbab23cf18e93c4260b2hding {SLICE_TYPE_P,3}, {SLICE_TYPE_P,3},{SLICE_TYPE_P,3}, 16464b672db6ee89c9846451bbab23cf18e93c4260b2hding {SLICE_TYPE_P,3}, {SLICE_TYPE_P,3},{SLICE_TYPE_P,3}, 16474b672db6ee89c9846451bbab23cf18e93c4260b2hding {SLICE_TYPE_P,2} }; 16484b672db6ee89c9846451bbab23cf18e93c4260b2hding 16494b672db6ee89c9846451bbab23cf18e93c4260b2hding if ( i_frame_only ) { 16504b672db6ee89c9846451bbab23cf18e93c4260b2hding encode_picture(yuv_fp, avc_fp,enc_frame_number, f, f==0, SLICE_TYPE_I, 0, f+1); 16514b672db6ee89c9846451bbab23cf18e93c4260b2hding f++; 16524b672db6ee89c9846451bbab23cf18e93c4260b2hding enc_frame_number++; 16534b672db6ee89c9846451bbab23cf18e93c4260b2hding } else if ( i_p_frame_only ) { 16544b672db6ee89c9846451bbab23cf18e93c4260b2hding if ( (f % intra_period) == 0 ) { 16554b672db6ee89c9846451bbab23cf18e93c4260b2hding encode_picture(yuv_fp, avc_fp,enc_frame_number, f, f==0, SLICE_TYPE_I, 0, f+1); 16564b672db6ee89c9846451bbab23cf18e93c4260b2hding f++; 16574b672db6ee89c9846451bbab23cf18e93c4260b2hding enc_frame_number++; 16584b672db6ee89c9846451bbab23cf18e93c4260b2hding } else { 16594b672db6ee89c9846451bbab23cf18e93c4260b2hding encode_picture(yuv_fp, avc_fp,enc_frame_number, f, f==0, SLICE_TYPE_P, 0, f+1); 16604b672db6ee89c9846451bbab23cf18e93c4260b2hding f++; 16614b672db6ee89c9846451bbab23cf18e93c4260b2hding enc_frame_number++; 16624b672db6ee89c9846451bbab23cf18e93c4260b2hding } 16634b672db6ee89c9846451bbab23cf18e93c4260b2hding } else { // follow the i,p,b pattern 16644b672db6ee89c9846451bbab23cf18e93c4260b2hding static int fcurrent = 0; 16654b672db6ee89c9846451bbab23cf18e93c4260b2hding int fnext; 16664b672db6ee89c9846451bbab23cf18e93c4260b2hding 16674b672db6ee89c9846451bbab23cf18e93c4260b2hding fcurrent = fcurrent % (sizeof(frame_type_pattern)/sizeof(int[2])); 16684b672db6ee89c9846451bbab23cf18e93c4260b2hding fnext = (fcurrent+1) % (sizeof(frame_type_pattern)/sizeof(int[2])); 16694b672db6ee89c9846451bbab23cf18e93c4260b2hding 16704b672db6ee89c9846451bbab23cf18e93c4260b2hding if ( frame_type_pattern[fcurrent][0] == SLICE_TYPE_I ) { 16714b672db6ee89c9846451bbab23cf18e93c4260b2hding encode_picture(yuv_fp, avc_fp,enc_frame_number, f, f==0, SLICE_TYPE_I, 0, 16724b672db6ee89c9846451bbab23cf18e93c4260b2hding f+frame_type_pattern[fnext][1]); 16734b672db6ee89c9846451bbab23cf18e93c4260b2hding f++; 16744b672db6ee89c9846451bbab23cf18e93c4260b2hding enc_frame_number++; 16754b672db6ee89c9846451bbab23cf18e93c4260b2hding } else { 16764b672db6ee89c9846451bbab23cf18e93c4260b2hding encode_pb_pictures(yuv_fp, avc_fp, f, frame_type_pattern[fcurrent][1]-1, 16774b672db6ee89c9846451bbab23cf18e93c4260b2hding f + frame_type_pattern[fcurrent][1] + frame_type_pattern[fnext][1] -1 ); 16784b672db6ee89c9846451bbab23cf18e93c4260b2hding f += frame_type_pattern[fcurrent][1]; 16794b672db6ee89c9846451bbab23cf18e93c4260b2hding enc_frame_number++; 16804b672db6ee89c9846451bbab23cf18e93c4260b2hding } 16814b672db6ee89c9846451bbab23cf18e93c4260b2hding 16824b672db6ee89c9846451bbab23cf18e93c4260b2hding fcurrent++; 16834b672db6ee89c9846451bbab23cf18e93c4260b2hding } 168410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang printf("\r %d/%d ...", f+1, frame_number); 168510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang fflush(stdout); 168610965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang } 168710965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 16884b672db6ee89c9846451bbab23cf18e93c4260b2hding gettimeofday(&tpend,NULL); 16894b672db6ee89c9846451bbab23cf18e93c4260b2hding timeuse=1000000*(tpend.tv_sec-tpstart.tv_sec)+ tpend.tv_usec-tpstart.tv_usec; 16904b672db6ee89c9846451bbab23cf18e93c4260b2hding timeuse/=1000000; 169110965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang printf("\ndone!\n"); 16924b672db6ee89c9846451bbab23cf18e93c4260b2hding printf("encode %d frames in %f secondes, FPS is %.1f\n",frame_number, timeuse, frame_number/timeuse); 169310965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang release_encode_resource(); 169410965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang destory_encode_pipe(); 169510965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang 16964b672db6ee89c9846451bbab23cf18e93c4260b2hding fclose(yuv_fp); 16974b672db6ee89c9846451bbab23cf18e93c4260b2hding fclose(avc_fp); 16984b672db6ee89c9846451bbab23cf18e93c4260b2hding 169910965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang return 0; 170010965d59ea630e8a6856845faffb8e0f39b159a3Kun Wang} 1701