1409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan/*
2409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * Copyright (c) 2007-2013 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#include "sysdeps.h"
25409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <stdio.h>
26409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <string.h>
27409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <stdlib.h>
28409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <getopt.h>
29409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <unistd.h>
30409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <sys/types.h>
31409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <sys/stat.h>
32409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <sys/time.h>
332efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan#include <sys/mman.h>
34409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <fcntl.h>
35409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <assert.h>
36409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <pthread.h>
372efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan#include <errno.h>
382efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan#include <math.h>
39409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <va/va.h>
40409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include <va/va_enc_h264.h>
41409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include "va_display.h"
42409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
43409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define CHECK_VASTATUS(va_status,func)                                  \
44409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (va_status != VA_STATUS_SUCCESS) {                               \
45409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        fprintf(stderr,"%s:%s (%d) failed,exit\n", __func__, func, __LINE__); \
46409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        exit(1);                                                        \
47409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
48409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
49409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#include "../loadsurface.h"
50409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
51409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define NAL_REF_IDC_NONE        0
52409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define NAL_REF_IDC_LOW         1
53409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define NAL_REF_IDC_MEDIUM      2
54409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define NAL_REF_IDC_HIGH        3
55409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
56409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define NAL_NON_IDR             1
57409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define NAL_IDR                 5
58409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define NAL_SPS                 7
59409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define NAL_PPS                 8
60409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define NAL_SEI			6
61409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
62409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define SLICE_TYPE_P            0
63409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define SLICE_TYPE_B            1
64409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define SLICE_TYPE_I            2
65409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
66409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define ENTROPY_MODE_CAVLC      0
67409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define ENTROPY_MODE_CABAC      1
68409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
69409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define PROFILE_IDC_BASELINE    66
70409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define PROFILE_IDC_MAIN        77
71409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define PROFILE_IDC_HIGH        100
72409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
73409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define BITSTREAM_ALLOCATE_STEPPING     4096
74409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
756044ab9a375eb73b08f45d87966652f98f918668Austin Yuan#define SURFACE_NUM 16 /* 16 surfaces for source YUV */
766044ab9a375eb73b08f45d87966652f98f918668Austin Yuan#define SURFACE_NUM 16 /* 16 surfaces for reference */
77409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  VADisplay va_dpy;
782efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuanstatic  VAProfile h264_profile = ~0;
79409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  VAConfigAttrib attrib[VAConfigAttribTypeMax];
80409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  VAConfigAttrib config_attrib[VAConfigAttribTypeMax];
81409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  int config_attrib_num = 0;
826044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic  VASurfaceID src_surface[SURFACE_NUM];
836044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic  VABufferID  coded_buf[SURFACE_NUM];
846044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic  VASurfaceID ref_surface[SURFACE_NUM];
85409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  VAConfigID config_id;
86409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  VAContextID context_id;
87409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  VAEncSequenceParameterBufferH264 seq_param;
88409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  VAEncPictureParameterBufferH264 pic_param;
89409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  VAEncSliceParameterBufferH264 slice_param;
906044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic  VAPictureH264 CurrentCurrPic;
916044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic  VAPictureH264 ReferenceFrames[16], RefPicList0_P[32], RefPicList0_B[32], RefPicList1_B[32];
92409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
936044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic  unsigned int MaxFrameNum = (2<<16);
946044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic  unsigned int MaxPicOrderCntLsb = (2<<8);
956044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic  unsigned int Log2MaxFrameNum = 16;
966044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic  unsigned int Log2MaxPicOrderCntLsb = 8;
976044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
986044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic  unsigned int num_ref_frames = 2;
996044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic  unsigned int numShortTerm = 0;
100409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  int constraint_set_flag = 0;
101409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  int h264_packedheader = 0; /* support pack header? */
1026044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic  int h264_maxref = (1<<16|1);
1032efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuanstatic  int h264_entropy_mode = 1; /* cabac */
1042efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
105409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  char *coded_fn = NULL, *srcyuv_fn = NULL, *recyuv_fn = NULL;
106409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  FILE *coded_fp = NULL, *srcyuv_fp = NULL, *recyuv_fp = NULL;
107409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  unsigned long long srcyuv_frames = 0;
1086044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic  int srcyuv_fourcc = VA_FOURCC_NV12;
1092efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuanstatic  int calc_psnr = 0;
110409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
111409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  int frame_width = 176;
112409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  int frame_height = 144;
1132efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuanstatic  int frame_width_mbaligned;
1142efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuanstatic  int frame_height_mbaligned;
115409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  int frame_rate = 30;
116409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  unsigned int frame_count = 60;
117409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  unsigned int frame_coded = 0;
118409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  unsigned int frame_bitrate = 0;
119409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  unsigned int frame_slices = 1;
1206044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic  double frame_size = 0;
1212efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuanstatic  int initial_qp = 26;
122409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  int minimal_qp = 0;
123409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  int intra_period = 30;
124409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  int intra_idr_period = 60;
125409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  int ip_period = 1;
126409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  int rc_mode = VA_RC_VBR;
127409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  unsigned long long current_frame_encoding = 0;
128409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  unsigned long long current_frame_display = 0;
1296044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic  unsigned long long current_IDR_display = 0;
1302efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuanstatic  unsigned int current_frame_num = 0;
131409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  int current_frame_type;
1326044ab9a375eb73b08f45d87966652f98f918668Austin Yuan#define current_slot (current_frame_display % SURFACE_NUM)
133409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1342efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuanstatic  int misc_priv_type = 0;
1352efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuanstatic  int misc_priv_value = 0;
1362efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
1372efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan#define MIN(a, b) ((a)>(b)?(b):(a))
1382efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan#define MAX(a, b) ((a)>(b)?(a):(b))
1392efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
140409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan/* thread to save coded data/upload source YUV */
141409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstruct storage_task_t {
142409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    void *next;
143409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned long long display_order;
144409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned long long encode_order;
145409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan};
146409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  struct storage_task_t *storage_task_header = NULL, *storage_task_tail = NULL;
147409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define SRC_SURFACE_IN_ENCODING 0
148409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define SRC_SURFACE_IN_STORAGE  1
1496044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic  int srcsurface_status[SURFACE_NUM];
150409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  int encode_syncmode = 0;
151409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  pthread_mutex_t encode_mutex = PTHREAD_MUTEX_INITIALIZER;
152409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  pthread_cond_t  encode_cond = PTHREAD_COND_INITIALIZER;
153409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic  pthread_t encode_thread;
1546044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
155409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan/* for performance profiling */
156409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic unsigned int UploadPictureTicks=0;
157409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic unsigned int BeginPictureTicks=0;
158409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic unsigned int RenderPictureTicks=0;
159409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic unsigned int EndPictureTicks=0;
160409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic unsigned int SyncPictureTicks=0;
161409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic unsigned int SavePictureTicks=0;
162409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic unsigned int TotalTicks=0;
163409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
164409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstruct __bitstream {
165409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int *buffer;
166409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int bit_offset;
167409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int max_size_in_dword;
168409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan};
169409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuantypedef struct __bitstream bitstream;
170409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
171409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
172409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic unsigned int
173409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanva_swap32(unsigned int val)
174409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
175409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned char *pval = (unsigned char *)&val;
176409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
177409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return ((pval[0] << 24)     |
178409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            (pval[1] << 16)     |
179409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            (pval[2] << 8)      |
180409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            (pval[3] << 0));
181409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
182409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
183409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void
184409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanbitstream_start(bitstream *bs)
185409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
186409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bs->max_size_in_dword = BITSTREAM_ALLOCATE_STEPPING;
187409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bs->buffer = calloc(bs->max_size_in_dword * sizeof(int), 1);
188409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bs->bit_offset = 0;
189409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
190409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
191409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void
192409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanbitstream_end(bitstream *bs)
193409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
194409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int pos = (bs->bit_offset >> 5);
195409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int bit_offset = (bs->bit_offset & 0x1f);
196409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int bit_left = 32 - bit_offset;
197409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
198409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (bit_offset) {
199409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bs->buffer[pos] = va_swap32((bs->buffer[pos] << bit_left));
200409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
201409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
202409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
203409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void
204409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanbitstream_put_ui(bitstream *bs, unsigned int val, int size_in_bits)
205409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
206409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int pos = (bs->bit_offset >> 5);
207409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int bit_offset = (bs->bit_offset & 0x1f);
208409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int bit_left = 32 - bit_offset;
209409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
210409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (!size_in_bits)
211409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return;
212409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
213409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bs->bit_offset += size_in_bits;
214409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
215409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (bit_left > size_in_bits) {
216409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bs->buffer[pos] = (bs->buffer[pos] << size_in_bits | val);
217409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    } else {
218409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        size_in_bits -= bit_left;
219409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bs->buffer[pos] = (bs->buffer[pos] << bit_left) | (val >> size_in_bits);
220409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bs->buffer[pos] = va_swap32(bs->buffer[pos]);
221409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
222409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (pos + 1 == bs->max_size_in_dword) {
223409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            bs->max_size_in_dword += BITSTREAM_ALLOCATE_STEPPING;
224409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            bs->buffer = realloc(bs->buffer, bs->max_size_in_dword * sizeof(unsigned int));
225409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
226409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
227409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bs->buffer[pos + 1] = val;
228409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
229409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
230409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
231409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void
232409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanbitstream_put_ue(bitstream *bs, unsigned int val)
233409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
234409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int size_in_bits = 0;
235409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int tmp_val = ++val;
236409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
237409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    while (tmp_val) {
238409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        tmp_val >>= 1;
239409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        size_in_bits++;
240409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
241409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
242409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, 0, size_in_bits - 1); // leading zero
243409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, val, size_in_bits);
244409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
245409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
246409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void
247409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanbitstream_put_se(bitstream *bs, int val)
248409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
249409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int new_val;
250409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
251409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (val <= 0)
252409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        new_val = -2 * val;
253409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else
254409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        new_val = 2 * val - 1;
255409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
256409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ue(bs, new_val);
257409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
258409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
259409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void
260409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanbitstream_byte_aligning(bitstream *bs, int bit)
261409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
262409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int bit_offset = (bs->bit_offset & 0x7);
263409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int bit_left = 8 - bit_offset;
264409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int new_val;
265409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
266409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (!bit_offset)
267409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return;
268409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
269409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    assert(bit == 0 || bit == 1);
270409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
271409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (bit)
272409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        new_val = (1 << bit_left) - 1;
273409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else
274409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        new_val = 0;
275409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
276409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, new_val, bit_left);
277409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
278409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
279409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void
280409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanrbsp_trailing_bits(bitstream *bs)
281409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
282409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, 1, 1);
283409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_byte_aligning(bs, 0);
284409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
285409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
286409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void nal_start_code_prefix(bitstream *bs)
287409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
288409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, 0x00000001, 32);
289409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
290409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
291409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void nal_header(bitstream *bs, int nal_ref_idc, int nal_unit_type)
292409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
293409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, 0, 1);                /* forbidden_zero_bit: 0 */
294409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, nal_ref_idc, 2);
295409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, nal_unit_type, 5);
296409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
297409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
298409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void sps_rbsp(bitstream *bs)
299409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
300409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int profile_idc = PROFILE_IDC_BASELINE;
301409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
302409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (h264_profile  == VAProfileH264High)
303409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        profile_idc = PROFILE_IDC_HIGH;
304409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else if (h264_profile  == VAProfileH264Main)
305409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        profile_idc = PROFILE_IDC_MAIN;
306409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
307409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, profile_idc, 8);               /* profile_idc */
308409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, !!(constraint_set_flag & 1), 1);                         /* constraint_set0_flag */
309409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, !!(constraint_set_flag & 2), 1);                         /* constraint_set1_flag */
310409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, !!(constraint_set_flag & 4), 1);                         /* constraint_set2_flag */
311409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, !!(constraint_set_flag & 8), 1);                         /* constraint_set3_flag */
312409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, 0, 4);                         /* reserved_zero_4bits */
313409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, seq_param.level_idc, 8);      /* level_idc */
314409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ue(bs, seq_param.seq_parameter_set_id);      /* seq_parameter_set_id */
315409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
316409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if ( profile_idc == PROFILE_IDC_HIGH) {
317409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ue(bs, 1);        /* chroma_format_idc = 1, 4:2:0 */
318409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ue(bs, 0);        /* bit_depth_luma_minus8 */
319409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ue(bs, 0);        /* bit_depth_chroma_minus8 */
320409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(bs, 0, 1);     /* qpprime_y_zero_transform_bypass_flag */
321409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(bs, 0, 1);     /* seq_scaling_matrix_present_flag */
322409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
323409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
324409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ue(bs, seq_param.seq_fields.bits.log2_max_frame_num_minus4); /* log2_max_frame_num_minus4 */
325409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ue(bs, seq_param.seq_fields.bits.pic_order_cnt_type);        /* pic_order_cnt_type */
326409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
327409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (seq_param.seq_fields.bits.pic_order_cnt_type == 0)
328409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ue(bs, seq_param.seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4);     /* log2_max_pic_order_cnt_lsb_minus4 */
329409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else {
330409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        assert(0);
331409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
332409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
333409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ue(bs, seq_param.max_num_ref_frames);        /* num_ref_frames */
334409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, 0, 1);                                 /* gaps_in_frame_num_value_allowed_flag */
335409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
336409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ue(bs, seq_param.picture_width_in_mbs - 1);  /* pic_width_in_mbs_minus1 */
337409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ue(bs, seq_param.picture_height_in_mbs - 1); /* pic_height_in_map_units_minus1 */
338409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, seq_param.seq_fields.bits.frame_mbs_only_flag, 1);    /* frame_mbs_only_flag */
339409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
340409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (!seq_param.seq_fields.bits.frame_mbs_only_flag) {
341409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        assert(0);
342409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
343409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
344409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, seq_param.seq_fields.bits.direct_8x8_inference_flag, 1);      /* direct_8x8_inference_flag */
345409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, seq_param.frame_cropping_flag, 1);            /* frame_cropping_flag */
346409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
347409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (seq_param.frame_cropping_flag) {
348409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ue(bs, seq_param.frame_crop_left_offset);        /* frame_crop_left_offset */
349409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ue(bs, seq_param.frame_crop_right_offset);       /* frame_crop_right_offset */
350409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ue(bs, seq_param.frame_crop_top_offset);         /* frame_crop_top_offset */
351409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ue(bs, seq_param.frame_crop_bottom_offset);      /* frame_crop_bottom_offset */
352409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
353409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
354409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    //if ( frame_bit_rate < 0 ) { //TODO EW: the vui header isn't correct
355409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if ( 1 ) {
356409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(bs, 0, 1); /* vui_parameters_present_flag */
357409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    } else {
358409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(bs, 1, 1); /* vui_parameters_present_flag */
359409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(bs, 0, 1); /* aspect_ratio_info_present_flag */
360409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(bs, 0, 1); /* overscan_info_present_flag */
361409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(bs, 0, 1); /* video_signal_type_present_flag */
362409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(bs, 0, 1); /* chroma_loc_info_present_flag */
363409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(bs, 1, 1); /* timing_info_present_flag */
364409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        {
365409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            bitstream_put_ui(bs, 15, 32);
366409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            bitstream_put_ui(bs, 900, 32);
367409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            bitstream_put_ui(bs, 1, 1);
368409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
369409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(bs, 1, 1); /* nal_hrd_parameters_present_flag */
370409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        {
371409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            // hrd_parameters
372409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            bitstream_put_ue(bs, 0);    /* cpb_cnt_minus1 */
373409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            bitstream_put_ui(bs, 4, 4); /* bit_rate_scale */
374409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            bitstream_put_ui(bs, 6, 4); /* cpb_size_scale */
375409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
376409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            bitstream_put_ue(bs, frame_bitrate - 1); /* bit_rate_value_minus1[0] */
377409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            bitstream_put_ue(bs, frame_bitrate*8 - 1); /* cpb_size_value_minus1[0] */
378409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            bitstream_put_ui(bs, 1, 1);  /* cbr_flag[0] */
379409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
380409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            bitstream_put_ui(bs, 23, 5);   /* initial_cpb_removal_delay_length_minus1 */
381409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            bitstream_put_ui(bs, 23, 5);   /* cpb_removal_delay_length_minus1 */
382409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            bitstream_put_ui(bs, 23, 5);   /* dpb_output_delay_length_minus1 */
383409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            bitstream_put_ui(bs, 23, 5);   /* time_offset_length  */
384409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
385409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(bs, 0, 1);   /* vcl_hrd_parameters_present_flag */
386409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(bs, 0, 1);   /* low_delay_hrd_flag */
387409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
388409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(bs, 0, 1); /* pic_struct_present_flag */
389409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(bs, 0, 1); /* bitstream_restriction_flag */
390409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
391409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
392409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    rbsp_trailing_bits(bs);     /* rbsp_trailing_bits */
393409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
394409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
395409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
396409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void pps_rbsp(bitstream *bs)
397409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
398409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ue(bs, pic_param.pic_parameter_set_id);      /* pic_parameter_set_id */
399409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ue(bs, pic_param.seq_parameter_set_id);      /* seq_parameter_set_id */
400409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
401409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, pic_param.pic_fields.bits.entropy_coding_mode_flag, 1);  /* entropy_coding_mode_flag */
402409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
403409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, 0, 1);                         /* pic_order_present_flag: 0 */
404409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
405409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ue(bs, 0);                            /* num_slice_groups_minus1 */
406409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
407409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ue(bs, pic_param.num_ref_idx_l0_active_minus1);      /* num_ref_idx_l0_active_minus1 */
408409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ue(bs, pic_param.num_ref_idx_l1_active_minus1);      /* num_ref_idx_l1_active_minus1 1 */
409409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
410409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, pic_param.pic_fields.bits.weighted_pred_flag, 1);     /* weighted_pred_flag: 0 */
411409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, pic_param.pic_fields.bits.weighted_bipred_idc, 2);	/* weighted_bipred_idc: 0 */
412409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
413409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_se(bs, pic_param.pic_init_qp - 26);  /* pic_init_qp_minus26 */
414409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_se(bs, 0);                            /* pic_init_qs_minus26 */
415409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_se(bs, 0);                            /* chroma_qp_index_offset */
416409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
417409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, pic_param.pic_fields.bits.deblocking_filter_control_present_flag, 1); /* deblocking_filter_control_present_flag */
418409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, 0, 1);                         /* constrained_intra_pred_flag */
419409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, 0, 1);                         /* redundant_pic_cnt_present_flag */
420409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
421409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* more_rbsp_data */
422409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, pic_param.pic_fields.bits.transform_8x8_mode_flag, 1);    /*transform_8x8_mode_flag */
423409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(bs, 0, 1);                         /* pic_scaling_matrix_present_flag */
424409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_se(bs, pic_param.second_chroma_qp_index_offset );    /*second_chroma_qp_index_offset */
425409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
426409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    rbsp_trailing_bits(bs);
427409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
428409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
429409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
430409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int
431409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanbuild_packed_pic_buffer(unsigned char **header_buffer)
432409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
433409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream bs;
434409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
435409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_start(&bs);
436409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    nal_start_code_prefix(&bs);
437409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    nal_header(&bs, NAL_REF_IDC_HIGH, NAL_PPS);
438409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    pps_rbsp(&bs);
439409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_end(&bs);
440409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
441409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    *header_buffer = (unsigned char *)bs.buffer;
442409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return bs.bit_offset;
443409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
444409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
445409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int
446409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanbuild_packed_seq_buffer(unsigned char **header_buffer)
447409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
448409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream bs;
449409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
450409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_start(&bs);
451409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    nal_start_code_prefix(&bs);
452409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    nal_header(&bs, NAL_REF_IDC_HIGH, NAL_SPS);
453409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    sps_rbsp(&bs);
454409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_end(&bs);
455409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
456409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    *header_buffer = (unsigned char *)bs.buffer;
457409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return bs.bit_offset;
458409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
459409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
460409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int
461409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanbuild_packed_sei_buffer_timing(unsigned int init_cpb_removal_length,
462409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan				unsigned int init_cpb_removal_delay,
463409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan				unsigned int init_cpb_removal_delay_offset,
464409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan				unsigned int cpb_removal_length,
465409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan				unsigned int cpb_removal_delay,
466409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan				unsigned int dpb_output_length,
467409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan				unsigned int dpb_output_delay,
468409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan				unsigned char **sei_buffer)
469409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
470409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned char *byte_buf;
471409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int bp_byte_size, i, pic_byte_size;
472409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
473409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream nal_bs;
474409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream sei_bp_bs, sei_pic_bs;
475409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
476409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_start(&sei_bp_bs);
477409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ue(&sei_bp_bs, 0);       /*seq_parameter_set_id*/
478409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(&sei_bp_bs, init_cpb_removal_delay, cpb_removal_length);
479409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(&sei_bp_bs, init_cpb_removal_delay_offset, cpb_removal_length);
480409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if ( sei_bp_bs.bit_offset & 0x7) {
481409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(&sei_bp_bs, 1, 1);
482409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
483409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_end(&sei_bp_bs);
484409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bp_byte_size = (sei_bp_bs.bit_offset + 7) / 8;
485409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
486409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_start(&sei_pic_bs);
487409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(&sei_pic_bs, cpb_removal_delay, cpb_removal_length);
488409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(&sei_pic_bs, dpb_output_delay, dpb_output_length);
489409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if ( sei_pic_bs.bit_offset & 0x7) {
490409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(&sei_pic_bs, 1, 1);
491409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
492409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_end(&sei_pic_bs);
493409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    pic_byte_size = (sei_pic_bs.bit_offset + 7) / 8;
494409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
495409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_start(&nal_bs);
496409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    nal_start_code_prefix(&nal_bs);
497409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    nal_header(&nal_bs, NAL_REF_IDC_NONE, NAL_SEI);
498409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
499409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan	/* Write the SEI buffer period data */
500409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(&nal_bs, 0, 8);
501409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(&nal_bs, bp_byte_size, 8);
502409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
503409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    byte_buf = (unsigned char *)sei_bp_bs.buffer;
504409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    for(i = 0; i < bp_byte_size; i++) {
505409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(&nal_bs, byte_buf[i], 8);
506409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
507409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    free(byte_buf);
508409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan	/* write the SEI timing data */
509409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(&nal_bs, 0x01, 8);
510409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_put_ui(&nal_bs, pic_byte_size, 8);
511409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
512409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    byte_buf = (unsigned char *)sei_pic_bs.buffer;
513409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    for(i = 0; i < pic_byte_size; i++) {
514409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        bitstream_put_ui(&nal_bs, byte_buf[i], 8);
515409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
516409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    free(byte_buf);
517409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
518409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    rbsp_trailing_bits(&nal_bs);
519409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    bitstream_end(&nal_bs);
520409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
521409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    *sei_buffer = (unsigned char *)nal_bs.buffer;
522409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
523409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return nal_bs.bit_offset;
524409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
525409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
526409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
527409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
528409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan/*
529409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * Helper function for profiling purposes
530409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan */
531409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic unsigned int GetTickCount()
532409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
533409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct timeval tv;
534409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (gettimeofday(&tv, NULL))
535409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return 0;
536409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return tv.tv_usec/1000+tv.tv_sec*1000;
537409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
538409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
539409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan/*
540409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  Assume frame sequence is: Frame#0,#1,#2,...,#M,...,#X,... (encoding order)
541409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  1) period between Frame #X and Frame #N = #X - #N
542409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  2) 0 means infinite for intra_period/intra_idr_period, and 0 is invalid for ip_period
543409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  3) intra_idr_period % intra_period (intra_period > 0) and intra_period % ip_period must be 0
544409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  4) intra_period and intra_idr_period take precedence over ip_period
545409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  5) if ip_period > 1, intra_period and intra_idr_period are not  the strict periods
546409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan     of I/IDR frames, see bellow examples
547409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  -------------------------------------------------------------------
548409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  intra_period intra_idr_period ip_period frame sequence (intra_period/intra_idr_period/ip_period)
549409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  0            ignored          1          IDRPPPPPPP ...     (No IDR/I any more)
550409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  0            ignored        >=2          IDR(PBB)(PBB)...   (No IDR/I any more)
551409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  1            0                ignored    IDRIIIIIII...      (No IDR any more)
552409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  1            1                ignored    IDR IDR IDR IDR...
553409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  1            >=2              ignored    IDRII IDRII IDR... (1/3/ignore)
554409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  >=2          0                1          IDRPPP IPPP I...   (3/0/1)
555409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  >=2          0              >=2          IDR(PBB)(PBB)(IBB) (6/0/3)
556409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                                              (PBB)(IBB)(PBB)(IBB)...
557409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  >=2          >=2              1          IDRPPPPP IPPPPP IPPPPP (6/18/1)
558409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                                           IDRPPPPP IPPPPP IPPPPP...
559409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan  >=2          >=2              >=2        {IDR(PBB)(PBB)(IBB)(PBB)(IBB)(PBB)} (6/18/3)
560409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                                           {IDR(PBB)(PBB)(IBB)(PBB)(IBB)(PBB)}...
561409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                                           {IDR(PBB)(PBB)(IBB)(PBB)}           (6/12/3)
562409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                                           {IDR(PBB)(PBB)(IBB)(PBB)}...
563409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                                           {IDR(PBB)(PBB)}                     (6/6/3)
564409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                                           {IDR(PBB)(PBB)}.
565409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan*/
566409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
567409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan/*
568409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * Return displaying order with specified periods and encoding order
569409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * displaying_order: displaying order
570409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan * frame_type: frame type
571409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan */
572409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define FRAME_P 0
573409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define FRAME_B 1
574409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define FRAME_I 2
575409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan#define FRAME_IDR 7
576409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanvoid encoding2display_order(
577409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned long long encoding_order,int intra_period,
578409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int intra_idr_period,int ip_period,
579409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned long long *displaying_order,
580409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int *frame_type)
581409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
582409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int encoding_order_gop = 0;
583409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
584409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (intra_period == 1) { /* all are I/IDR frames */
585409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        *displaying_order = encoding_order;
586409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (intra_idr_period == 0)
587409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            *frame_type = (encoding_order == 0)?FRAME_IDR:FRAME_I;
588409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        else
589409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            *frame_type = (encoding_order % intra_idr_period == 0)?FRAME_IDR:FRAME_I;
590409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return;
591409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
592409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
593409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (intra_period == 0)
594409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        intra_idr_period = 0;
595409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
596409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* new sequence like
597409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan     * IDR PPPPP IPPPPP
598409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan     * IDR (PBB)(PBB)(IBB)(PBB)
599409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan     */
600409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    encoding_order_gop = (intra_idr_period == 0)? encoding_order:
601409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        (encoding_order % (intra_idr_period + ((ip_period == 1)?0:1)));
602409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
603409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (encoding_order_gop == 0) { /* the first frame */
604409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        *frame_type = FRAME_IDR;
605409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        *displaying_order = encoding_order;
606409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    } else if (((encoding_order_gop - 1) % ip_period) != 0) { /* B frames */
607409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan	*frame_type = FRAME_B;
608409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        *displaying_order = encoding_order - 1;
609409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    } else if ((intra_period != 0) && /* have I frames */
610409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan               (encoding_order_gop >= 2) &&
611409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan               ((ip_period == 1 && encoding_order_gop % intra_period == 0) || /* for IDR PPPPP IPPPP */
612409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                /* for IDR (PBB)(PBB)(IBB) */
613409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                (ip_period >= 2 && ((encoding_order_gop - 1) / ip_period % (intra_period / ip_period)) == 0))) {
614409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan	*frame_type = FRAME_I;
615409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan	*displaying_order = encoding_order + ip_period - 1;
616409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    } else {
617409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan	*frame_type = FRAME_P;
618409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan	*displaying_order = encoding_order + ip_period - 1;
619409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
620409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
621409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
622409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
623409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic char *fourcc_to_string(int fourcc)
624409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
625409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    switch (fourcc) {
626409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    case VA_FOURCC_NV12:
6276044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        return "NV12";
628409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    case VA_FOURCC_IYUV:
629409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return "IYUV";
630409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    case VA_FOURCC_YV12:
631409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return "YV12";
632409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    case VA_FOURCC_UYVY:
633409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return "UYVY";
634409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    default:
635409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return "Unknown";
636409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
637409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
638409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
639409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int string_to_fourcc(char *str)
640409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
641409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int fourcc;
642409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
643409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (!strncmp(str, "NV12", 4))
644409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        fourcc = VA_FOURCC_NV12;
645409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else if (!strncmp(str, "IYUV", 4))
646409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        fourcc = VA_FOURCC_IYUV;
647409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else if (!strncmp(str, "YV12", 4))
648409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        fourcc = VA_FOURCC_YV12;
649409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else if (!strncmp(str, "UYVY", 4))
650409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        fourcc = VA_FOURCC_UYVY;
651409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else {
652409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        printf("Unknow FOURCC\n");
653409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        fourcc = -1;
654409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
655409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return fourcc;
656409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
657409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
658409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
659409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic char *rc_to_string(int rcmode)
660409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
661409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    switch (rc_mode) {
662409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    case VA_RC_NONE:
663409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return "NONE";
664409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    case VA_RC_CBR:
665409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return "CBR";
666409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    case VA_RC_VBR:
667409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return "VBR";
668409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    case VA_RC_VCM:
669409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return "VCM";
670409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    case VA_RC_CQP:
671409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return "CQP";
672409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    case VA_RC_VBR_CONSTRAINED:
673409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return "VBR_CONSTRAINED";
674409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    default:
675409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return "Unknown";
676409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
677409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
678409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
679409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int string_to_rc(char *str)
680409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
681409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int rc_mode;
682409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
683409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (!strncmp(str, "NONE", 4))
684409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        rc_mode = VA_RC_NONE;
685409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else if (!strncmp(str, "CBR", 3))
686409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        rc_mode = VA_RC_CBR;
687409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else if (!strncmp(str, "VBR", 3))
688409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        rc_mode = VA_RC_VBR;
689409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else if (!strncmp(str, "VCM", 3))
690409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        rc_mode = VA_RC_VCM;
691409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else if (!strncmp(str, "CQP", 3))
692409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        rc_mode = VA_RC_CQP;
693409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else if (!strncmp(str, "VBR_CONSTRAINED", 15))
694409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        rc_mode = VA_RC_VBR_CONSTRAINED;
695409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else {
6966044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        printf("Unknown RC mode\n");
697409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        rc_mode = -1;
698409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
699409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return rc_mode;
700409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
701409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
702409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
703409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int print_help(void)
704409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
705409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("./h264encode <options>\n");
706409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("   -w <width> -h <height>\n");
7072efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    printf("   -framecount <frame number>\n");
708409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("   -n <frame number>\n");
7092efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    printf("      if set to 0 and srcyuv is set, the frame count is from srcuv file\n");
710409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("   -o <coded file>\n");
711409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("   -f <frame rate>\n");
712409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("   --intra_period <number>\n");
713409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("   --idr_period <number>\n");
714409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("   --ip_period <number>\n");
715409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("   --bitrate <bitrate>\n");
716409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("   --initialqp <number>\n");
717409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("   --minqp <number>\n");
718409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("   --rcmode <NONE|CBR|VBR|VCM|CQP|VBR_CONTRAINED>\n");
719409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("   --syncmode: sequentially upload source, encoding, save result, no multi-thread\n");
720409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("   --srcyuv <filename> load YUV from a file\n");
7212efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    printf("   --fourcc <NV12|IYUV|YV12> source YUV fourcc\n");
7222efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    printf("   --recyuv <filename> save reconstructed YUV into a file\n");
7232efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    printf("   --enablePSNR calculate PSNR of recyuv vs. srcyuv\n");
7242efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    printf("   --entropy <0|1>, 1 means cabac, 0 cavlc\n");
7252efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    printf("   --profile <BP|MP|HP>\n");
726409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
727409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
728409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
729409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int process_cmdline(int argc, char *argv[])
730409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
731409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    char c;
732409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    const struct option long_opts[] = {
7332efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        {"help", no_argument, NULL, 0 },
734409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        {"bitrate", required_argument, NULL, 1 },
735409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        {"minqp", required_argument, NULL, 2 },
736409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        {"initialqp", required_argument, NULL, 3 },
737409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        {"intra_period", required_argument, NULL, 4 },
738409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        {"idr_period", required_argument, NULL, 5 },
739409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        {"ip_period", required_argument, NULL, 6 },
740409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        {"rcmode", required_argument, NULL, 7 },
741409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        {"srcyuv", required_argument, NULL, 9 },
7422efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        {"recyuv", required_argument, NULL, 10 },
7432efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        {"fourcc", required_argument, NULL, 11 },
7442efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        {"syncmode", no_argument, NULL, 12 },
7452efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        {"enablePSNR", no_argument, NULL, 13 },
7462efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        {"prit", required_argument, NULL, 14 },
7472efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        {"priv", required_argument, NULL, 15 },
7482efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        {"framecount", required_argument, NULL, 16 },
7492efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        {"entropy", required_argument, NULL, 17 },
7502efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        {"profile", required_argument, NULL, 18 },
751409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        {NULL, no_argument, NULL, 0 }};
752409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int long_index;
753409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
754409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    while ((c =getopt_long_only(argc,argv,"w:h:n:f:o:?",long_opts,&long_index)) != EOF) {
755409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        switch (c) {
756409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 'w':
757409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            frame_width = atoi(optarg);
758409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
759409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 'h':
760409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            frame_height = atoi(optarg);
761409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
762409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 'n':
7632efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        case 16:
764409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            frame_count = atoi(optarg);
765409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
766409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 'f':
767409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            frame_rate = atoi(optarg);
768409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
769409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 'o':
770409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            coded_fn = strdup(optarg);
771409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
7722efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        case 0:
7732efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            print_help();
7742efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            exit(0);
775409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 1:
776409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            frame_bitrate = atoi(optarg);
777409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
778409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 2:
779409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            minimal_qp = atoi(optarg);
780409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
781409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 3:
782409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            initial_qp = atoi(optarg);
783409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
784409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 4:
785409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            intra_period = atoi(optarg);
786409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
787409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 5:
788409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            intra_idr_period = atoi(optarg);
789409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
790409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 6:
791409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            ip_period = atoi(optarg);
792409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
793409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 7:
794409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            rc_mode = string_to_rc(optarg);
795409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            if (rc_mode < 0) {
796409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                print_help();
797409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                exit(1);
798409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            }
799409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
800409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 9:
801409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            srcyuv_fn = strdup(optarg);
802409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
803409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 10:
8042efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            recyuv_fn = strdup(optarg);
8052efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            break;
8062efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        case 11:
807409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            srcyuv_fourcc = string_to_fourcc(optarg);
808409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            if (srcyuv_fourcc <= 0) {
809409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                print_help();
810409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                exit(1);
811409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            }
812409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
8132efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        case 12:
814409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            encode_syncmode = 1;
815409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
8162efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        case 13:
8172efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            calc_psnr = 1;
8182efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            break;
8192efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        case 14:
8202efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            misc_priv_type = strtol(optarg, NULL, 0);
8212efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            break;
8222efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        case 15:
8232efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            misc_priv_value = strtol(optarg, NULL, 0);
8242efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            break;
8252efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        case 17:
8262efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            h264_entropy_mode = atoi(optarg) ? 1: 0;
8272efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            break;
8282efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        case 18:
8292efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            if (strncmp(optarg, "BP", 2) == 0)
8302efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                h264_profile = VAProfileH264Baseline;
8312efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            else if (strncmp(optarg, "MP", 2) == 0)
8322efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                h264_profile = VAProfileH264Main;
8332efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            else if (strncmp(optarg, "HP", 2) == 0)
8342efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                h264_profile = VAProfileH264High;
8352efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            else
8362efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                h264_profile = 0;
8372efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            break;
838409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case ':':
839409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case '?':
840409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            print_help();
841409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            exit(0);
842409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
843409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
844409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
845409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (ip_period < 1) {
846409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan	printf(" ip_period must be greater than 0\n");
847409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        exit(0);
848409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
849409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (intra_period != 1 && intra_period % ip_period != 0) {
850409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan	printf(" intra_period must be a multiplier of ip_period\n");
851409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        exit(0);
852409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
853409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (intra_period != 0 && intra_idr_period % intra_period != 0) {
854409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan	printf(" intra_idr_period must be a multiplier of intra_period\n");
855409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        exit(0);
856409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
857409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
8586044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if (frame_bitrate == 0)
859409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        frame_bitrate = frame_width * frame_height * 12 * frame_rate / 50;
8606044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
861409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* open source file */
862409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (srcyuv_fn) {
863409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        srcyuv_fp = fopen(srcyuv_fn,"r");
864409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
865409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (srcyuv_fp == NULL)
866409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("Open source YUV file %s failed, use auto-generated YUV data\n", srcyuv_fn);
867409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        else {
8682efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            struct stat tmp;
8692efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
8702efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            fstat(fileno(srcyuv_fp), &tmp);
8712efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            srcyuv_frames = tmp.st_size / (frame_width * frame_height * 1.5);
872409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("Source YUV file %s with %llu frames\n", srcyuv_fn, srcyuv_frames);
8732efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
8742efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            if (frame_count == 0)
8752efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                frame_count = srcyuv_frames;
876409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
877409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
8782efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
8792efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    /* open source file */
8802efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (recyuv_fn) {
8812efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        recyuv_fp = fopen(recyuv_fn,"w+");
8822efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
8832efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        if (recyuv_fp == NULL)
8842efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            printf("Open reconstructed YUV file %s failed\n", recyuv_fn);
8852efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    }
886409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
887409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (coded_fn == NULL) {
888409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        struct stat buf;
889409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (stat("/tmp", &buf) == 0)
890409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            coded_fn = strdup("/tmp/test.264");
891409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        else if (stat("/sdcard", &buf) == 0)
892409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            coded_fn = strdup("/sdcard/test.264");
893409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        else
894409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            coded_fn = strdup("./test.264");
895409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
896409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
897409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* store coded data into a file */
898409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    coded_fp = fopen(coded_fn,"w+");
899409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (coded_fp == NULL) {
900409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        printf("Open file %s failed, exit\n", coded_fn);
901409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        exit(1);
902409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
903409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
9042efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    frame_width_mbaligned = (frame_width + 15) & (~15);
9052efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    frame_height_mbaligned = (frame_height + 15) & (~15);
9062efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (frame_width != frame_width_mbaligned ||
9072efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        frame_height != frame_height_mbaligned) {
9082efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        printf("Source frame is %dx%d and will code clip to %dx%d with crop\n",
9092efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan               frame_width, frame_height,
9102efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan               frame_width_mbaligned, frame_height_mbaligned
9112efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan               );
9122efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    }
913409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
914409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
915409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
916409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
917409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int init_va(void)
918409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
919409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAProfile profile_list[]={VAProfileH264High,VAProfileH264Main,VAProfileH264Baseline,VAProfileH264ConstrainedBaseline};
92010d94aff40fa7cb9349f839613856ea37327268cAustin Yuan    VAEntrypoint *entrypoints;
92110d94aff40fa7cb9349f839613856ea37327268cAustin Yuan    int num_entrypoints, slice_entrypoint;
922409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int support_encode = 0;
923409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int major_ver, minor_ver;
924409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAStatus va_status;
925409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int i;
926409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
927409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_dpy = va_open_display();
928409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaInitialize(va_dpy, &major_ver, &minor_ver);
929409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status, "vaInitialize");
930409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
93110d94aff40fa7cb9349f839613856ea37327268cAustin Yuan    num_entrypoints = vaMaxNumEntrypoints(va_dpy);
93210d94aff40fa7cb9349f839613856ea37327268cAustin Yuan    entrypoints = malloc(num_entrypoints * sizeof(*entrypoints));
93310d94aff40fa7cb9349f839613856ea37327268cAustin Yuan    if (!entrypoints) {
93410d94aff40fa7cb9349f839613856ea37327268cAustin Yuan        fprintf(stderr, "error: failed to initialize VA entrypoints array\n");
93510d94aff40fa7cb9349f839613856ea37327268cAustin Yuan        exit(1);
93610d94aff40fa7cb9349f839613856ea37327268cAustin Yuan    }
93710d94aff40fa7cb9349f839613856ea37327268cAustin Yuan
938409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* use the highest profile */
939409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    for (i = 0; i < sizeof(profile_list)/sizeof(profile_list[0]); i++) {
9402efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        if ((h264_profile != ~0) && h264_profile != profile_list[i])
9412efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            continue;
9422efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
943409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        h264_profile = profile_list[i];
944409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        vaQueryConfigEntrypoints(va_dpy, h264_profile, entrypoints, &num_entrypoints);
945409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        for (slice_entrypoint = 0; slice_entrypoint < num_entrypoints; slice_entrypoint++) {
946409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            if (entrypoints[slice_entrypoint] == VAEntrypointEncSlice) {
947409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                support_encode = 1;
948409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                break;
949409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            }
950409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
951409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (support_encode == 1)
952409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
953409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
954409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
955409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (support_encode == 0) {
956409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        printf("Can't find VAEntrypointEncSlice for H264 profiles\n");
957409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        exit(1);
958409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    } else {
959409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        switch (h264_profile) {
960409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            case VAProfileH264Baseline:
961409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                printf("Use profile VAProfileH264Baseline\n");
962409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                ip_period = 1;
963409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                constraint_set_flag |= (1 << 0); /* Annex A.2.1 */
9642efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                h264_entropy_mode = 0;
965409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                break;
966409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            case VAProfileH264ConstrainedBaseline:
967409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                printf("Use profile VAProfileH264ConstrainedBaseline\n");
968409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                constraint_set_flag |= (1 << 0 | 1 << 1); /* Annex A.2.2 */
969409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                ip_period = 1;
970409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                break;
971409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
972409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            case VAProfileH264Main:
973409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                printf("Use profile VAProfileH264Main\n");
974409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                constraint_set_flag |= (1 << 1); /* Annex A.2.2 */
975409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                break;
976409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
977409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            case VAProfileH264High:
978409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                constraint_set_flag |= (1 << 3); /* Annex A.2.4 */
979409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                printf("Use profile VAProfileH264High\n");
980409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                break;
981409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            default:
982409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                printf("unknow profile. Set to Baseline");
983409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                h264_profile = VAProfileH264Baseline;
984409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                ip_period = 1;
985409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                constraint_set_flag |= (1 << 0); /* Annex A.2.1 */
986409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                break;
987409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
988409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
989409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
990409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* find out the format for the render target, and rate control mode */
991409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    for (i = 0; i < VAConfigAttribTypeMax; i++)
992409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        attrib[i].type = i;
993409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
994409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaGetConfigAttributes(va_dpy, h264_profile, VAEntrypointEncSlice,
995409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                                      &attrib[0], VAConfigAttribTypeMax);
996409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status, "vaGetConfigAttributes");
997409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* check the interested configattrib */
998409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if ((attrib[VAConfigAttribRTFormat].value & VA_RT_FORMAT_YUV420) == 0) {
999409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        printf("Not find desired YUV420 RT format\n");
1000409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        exit(1);
1001409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    } else {
1002409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        config_attrib[config_attrib_num].type = VAConfigAttribRTFormat;
1003409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        config_attrib[config_attrib_num].value = VA_RT_FORMAT_YUV420;
1004409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        config_attrib_num++;
1005409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
1006409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1007409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (attrib[VAConfigAttribRateControl].value != VA_ATTRIB_NOT_SUPPORTED) {
1008409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        int tmp = attrib[VAConfigAttribRateControl].value;
1009409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
10102efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        printf("Support rate control mode (0x%x):", tmp);
1011409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1012409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_RC_NONE)
1013409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("NONE ");
1014409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_RC_CBR)
1015409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("CBR ");
1016409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_RC_VBR)
1017409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("VBR ");
1018409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_RC_VCM)
1019409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("VCM ");
1020409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_RC_CQP)
1021409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("CQP ");
1022409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_RC_VBR_CONSTRAINED)
1023409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("VBR_CONSTRAINED ");
1024409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1025409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        printf("\n");
1026409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1027409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        /* need to check if support rc_mode */
1028409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        config_attrib[config_attrib_num].type = VAConfigAttribRateControl;
1029409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        config_attrib[config_attrib_num].value = rc_mode;
1030409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        config_attrib_num++;
1031409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
1032409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1033409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1034409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (attrib[VAConfigAttribEncPackedHeaders].value != VA_ATTRIB_NOT_SUPPORTED) {
1035409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        int tmp = attrib[VAConfigAttribEncPackedHeaders].value;
1036409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1037409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        printf("Support VAConfigAttribEncPackedHeaders\n");
1038409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1039409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        h264_packedheader = 1;
1040409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        config_attrib[config_attrib_num].type = VAConfigAttribEncPackedHeaders;
1041409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        config_attrib[config_attrib_num].value = VA_ENC_PACKED_HEADER_NONE;
1042409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1043409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_ENC_PACKED_HEADER_SEQUENCE) {
1044409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("Support packed sequence headers\n");
1045409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            config_attrib[config_attrib_num].value |= VA_ENC_PACKED_HEADER_SEQUENCE;
1046409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
1047409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1048409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_ENC_PACKED_HEADER_PICTURE) {
1049409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("Support packed picture headers\n");
1050409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            config_attrib[config_attrib_num].value |= VA_ENC_PACKED_HEADER_PICTURE;
1051409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
1052409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1053409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_ENC_PACKED_HEADER_SLICE) {
1054409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("Support packed slice headers\n");
1055409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            config_attrib[config_attrib_num].value |= VA_ENC_PACKED_HEADER_SLICE;
1056409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
1057409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1058409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_ENC_PACKED_HEADER_MISC) {
1059409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("Support packed misc headers\n");
1060409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            config_attrib[config_attrib_num].value |= VA_ENC_PACKED_HEADER_MISC;
1061409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
1062409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1063409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        config_attrib_num++;
1064409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
1065409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1066409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (attrib[VAConfigAttribEncInterlaced].value != VA_ATTRIB_NOT_SUPPORTED) {
1067409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        int tmp = attrib[VAConfigAttribEncInterlaced].value;
1068409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1069409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        printf("Support VAConfigAttribEncInterlaced\n");
1070409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1071409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_ENC_INTERLACED_FRAME)
1072409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("support VA_ENC_INTERLACED_FRAME\n");
1073409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_ENC_INTERLACED_FIELD)
1074409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("Support VA_ENC_INTERLACED_FIELD\n");
1075409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_ENC_INTERLACED_MBAFF)
1076409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("Support VA_ENC_INTERLACED_MBAFF\n");
1077409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_ENC_INTERLACED_PAFF)
1078409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("Support VA_ENC_INTERLACED_PAFF\n");
1079409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1080409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        config_attrib[config_attrib_num].type = VAConfigAttribEncInterlaced;
1081409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        config_attrib[config_attrib_num].value = VA_ENC_PACKED_HEADER_NONE;
1082409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        config_attrib_num++;
1083409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
1084409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1085409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (attrib[VAConfigAttribEncMaxRefFrames].value != VA_ATTRIB_NOT_SUPPORTED) {
1086409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        h264_maxref = attrib[VAConfigAttribEncMaxRefFrames].value;
1087409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
10882efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        printf("Support %d RefPicList0 and %d RefPicList1\n",
10892efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan               h264_maxref & 0xffff, (h264_maxref >> 16) & 0xffff );
1090409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
1091409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1092409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (attrib[VAConfigAttribEncMaxSlices].value != VA_ATTRIB_NOT_SUPPORTED)
1093409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        printf("Support %d slices\n", attrib[VAConfigAttribEncMaxSlices].value);
1094409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1095409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (attrib[VAConfigAttribEncSliceStructure].value != VA_ATTRIB_NOT_SUPPORTED) {
1096409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        int tmp = attrib[VAConfigAttribEncSliceStructure].value;
1097409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1098409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        printf("Support VAConfigAttribEncSliceStructure\n");
1099409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1100409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS)
1101409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("Support VA_ENC_SLICE_STRUCTURE_ARBITRARY_ROWS\n");
1102409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS)
1103409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("Support VA_ENC_SLICE_STRUCTURE_POWER_OF_TWO_ROWS\n");
1104409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (tmp & VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS)
1105409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("Support VA_ENC_SLICE_STRUCTURE_ARBITRARY_MACROBLOCKS\n");
1106409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
1107409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (attrib[VAConfigAttribEncMacroblockInfo].value != VA_ATTRIB_NOT_SUPPORTED) {
1108409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        printf("Support VAConfigAttribEncMacroblockInfo\n");
1109409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
1110409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
111110d94aff40fa7cb9349f839613856ea37327268cAustin Yuan    free(entrypoints);
1112409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
1113409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
1114409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1115409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int setup_encode()
1116409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
1117409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAStatus va_status;
1118409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VASurfaceID *tmp_surfaceid;
1119409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int codedbuf_size, i;
1120409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1121409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaCreateConfig(va_dpy, h264_profile, VAEntrypointEncSlice,
1122409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            &config_attrib[0], config_attrib_num, &config_id);
1123409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status, "vaCreateConfig");
1124409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1125409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* create source surfaces */
1126409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaCreateSurfaces(va_dpy,
11272efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                                 VA_RT_FORMAT_YUV420, frame_width_mbaligned, frame_height_mbaligned,
11286044ab9a375eb73b08f45d87966652f98f918668Austin Yuan                                 &src_surface[0], SURFACE_NUM,
1129409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                                 NULL, 0);
1130409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status, "vaCreateSurfaces");
1131409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1132409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* create reference surfaces */
1133409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaCreateSurfaces(
1134409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            va_dpy,
11352efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            VA_RT_FORMAT_YUV420, frame_width_mbaligned, frame_height_mbaligned,
11366044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            &ref_surface[0], SURFACE_NUM,
1137409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            NULL, 0
1138409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            );
1139409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status, "vaCreateSurfaces");
1140409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
11416044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    tmp_surfaceid = calloc(2 * SURFACE_NUM, sizeof(VASurfaceID));
11426044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    memcpy(tmp_surfaceid, src_surface, SURFACE_NUM * sizeof(VASurfaceID));
11436044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    memcpy(tmp_surfaceid + SURFACE_NUM, ref_surface, SURFACE_NUM * sizeof(VASurfaceID));
1144409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1145409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* Create a context for this encode pipe */
1146409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaCreateContext(va_dpy, config_id,
11472efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                                frame_width_mbaligned, frame_height_mbaligned,
1148409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                                VA_PROGRESSIVE,
11496044ab9a375eb73b08f45d87966652f98f918668Austin Yuan                                tmp_surfaceid, 2 * SURFACE_NUM,
1150409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                                &context_id);
1151409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status, "vaCreateContext");
1152409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    free(tmp_surfaceid);
1153409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
11542efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    codedbuf_size = (frame_width_mbaligned * frame_height_mbaligned * 400) / (16*16);
1155409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
11566044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    for (i = 0; i < SURFACE_NUM; i++) {
1157409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        /* create coded buffer once for all
1158409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan         * other VA buffers which won't be used again after vaRenderPicture.
1159409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan         * so APP can always vaCreateBuffer for every frame
1160409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan         * but coded buffer need to be mapped and accessed after vaRenderPicture/vaEndPicture
1161409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan         * so VA won't maintain the coded buffer
1162409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan         */
1163409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        va_status = vaCreateBuffer(va_dpy,context_id,VAEncCodedBufferType,
1164409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                codedbuf_size, 1, NULL, &coded_buf[i]);
1165409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        CHECK_VASTATUS(va_status,"vaCreateBuffer");
1166409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
1167409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1168409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
1169409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
1170409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
11716044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
11726044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
11736044ab9a375eb73b08f45d87966652f98f918668Austin Yuan#define partition(ref, field, key, ascending)   \
11746044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    while (i <= j) {                            \
11756044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        if (ascending) {                        \
11766044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            while (ref[i].field < key)          \
11776044ab9a375eb73b08f45d87966652f98f918668Austin Yuan                i++;                            \
11786044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            while (ref[j].field > key)          \
11796044ab9a375eb73b08f45d87966652f98f918668Austin Yuan                j--;                            \
11806044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        } else {                                \
11816044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            while (ref[i].field > key)          \
11826044ab9a375eb73b08f45d87966652f98f918668Austin Yuan                i++;                            \
11836044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            while (ref[j].field < key)          \
11846044ab9a375eb73b08f45d87966652f98f918668Austin Yuan                j--;                            \
11856044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        }                                       \
11866044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        if (i <= j) {                           \
11876044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            tmp = ref[i];                       \
11886044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            ref[i] = ref[j];                    \
11896044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            ref[j] = tmp;                       \
11906044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            i++;                                \
11916044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            j--;                                \
11926044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        }                                       \
11936044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    }                                           \
11946044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
11956044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic void sort_one(VAPictureH264 ref[], int left, int right,
11966044ab9a375eb73b08f45d87966652f98f918668Austin Yuan                     int ascending, int frame_idx)
11976044ab9a375eb73b08f45d87966652f98f918668Austin Yuan{
11986044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    int i = left, j = right;
11996044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    unsigned int key;
12006044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    VAPictureH264 tmp;
12016044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12026044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if (frame_idx) {
12036044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        key = ref[(left + right) / 2].frame_idx;
12046044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        partition(ref, frame_idx, key, ascending);
12056044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    } else {
12066044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        key = ref[(left + right) / 2].TopFieldOrderCnt;
12072efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        partition(ref, TopFieldOrderCnt, (signed int)key, ascending);
12086044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    }
12096044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12106044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    /* recursion */
12116044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if (left < j)
12126044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        sort_one(ref, left, j, ascending, frame_idx);
12136044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12146044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if (i < right)
12156044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        sort_one(ref, i, right, ascending, frame_idx);
12166044ab9a375eb73b08f45d87966652f98f918668Austin Yuan}
12176044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12182efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuanstatic void sort_two(VAPictureH264 ref[], int left, int right, unsigned int key, unsigned int frame_idx,
12192efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                     int partition_ascending, int list0_ascending, int list1_ascending)
12206044ab9a375eb73b08f45d87966652f98f918668Austin Yuan{
12216044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    int i = left, j = right;
12226044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    VAPictureH264 tmp;
12236044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12246044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if (frame_idx) {
12252efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        partition(ref, frame_idx, key, partition_ascending);
12266044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    } else {
12272efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        partition(ref, TopFieldOrderCnt, (signed int)key, partition_ascending);
12286044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    }
12296044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12306044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12316044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    sort_one(ref, left, i-1, list0_ascending, frame_idx);
12326044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    sort_one(ref, j+1, right, list1_ascending, frame_idx);
12336044ab9a375eb73b08f45d87966652f98f918668Austin Yuan}
12346044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12356044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic int update_ReferenceFrames(void)
12366044ab9a375eb73b08f45d87966652f98f918668Austin Yuan{
12376044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    int i;
12386044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12396044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if (current_frame_type == FRAME_B)
12406044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        return 0;
12416044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12426044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    CurrentCurrPic.flags = VA_PICTURE_H264_SHORT_TERM_REFERENCE;
12436044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    numShortTerm++;
12446044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if (numShortTerm > num_ref_frames)
12456044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        numShortTerm = num_ref_frames;
12466044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    for (i=numShortTerm-1; i>0; i--)
12476044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        ReferenceFrames[i] = ReferenceFrames[i-1];
12486044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    ReferenceFrames[0] = CurrentCurrPic;
12496044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12506044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if (current_frame_type != FRAME_B)
12516044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        current_frame_num++;
12526044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if (current_frame_num > MaxFrameNum)
12536044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        current_frame_num = 0;
12546044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12556044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    return 0;
12566044ab9a375eb73b08f45d87966652f98f918668Austin Yuan}
12576044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12586044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12596044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic int update_RefPicList(void)
12606044ab9a375eb73b08f45d87966652f98f918668Austin Yuan{
12616044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    unsigned int current_poc = CurrentCurrPic.TopFieldOrderCnt;
12626044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12636044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if (current_frame_type == FRAME_P) {
12646044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        memcpy(RefPicList0_P, ReferenceFrames, numShortTerm * sizeof(VAPictureH264));
12656044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        sort_one(RefPicList0_P, 0, numShortTerm-1, 0, 1);
12666044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    }
12676044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12686044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if (current_frame_type == FRAME_B) {
12696044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        memcpy(RefPicList0_B, ReferenceFrames, numShortTerm * sizeof(VAPictureH264));
12706044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        sort_two(RefPicList0_B, 0, numShortTerm-1, current_poc, 0,
12716044ab9a375eb73b08f45d87966652f98f918668Austin Yuan                 1, 0, 1);
12726044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12736044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        memcpy(RefPicList1_B, ReferenceFrames, numShortTerm * sizeof(VAPictureH264));
12746044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        sort_two(RefPicList1_B, 0, numShortTerm-1, current_poc, 0,
12756044ab9a375eb73b08f45d87966652f98f918668Austin Yuan                 0, 1, 0);
12766044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    }
12776044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12786044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    return 0;
12796044ab9a375eb73b08f45d87966652f98f918668Austin Yuan}
12806044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
12816044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
1282409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int render_sequence(void)
1283409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
12842efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    VABufferID seq_param_buf, rc_param_buf, misc_param_tmpbuf, render_id[2];
1285409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAStatus va_status;
12862efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    VAEncMiscParameterBuffer *misc_param, *misc_param_tmp;
1287409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAEncMiscParameterRateControl *misc_rate_ctrl;
1288409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1289409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    seq_param.level_idc = 41 /*SH_LEVEL_3*/;
12902efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    seq_param.picture_width_in_mbs = frame_width_mbaligned / 16;
12912efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    seq_param.picture_height_in_mbs = frame_height_mbaligned / 16;
1292409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    seq_param.bits_per_second = frame_bitrate;
1293409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1294409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    seq_param.intra_period = intra_period;
1295409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    seq_param.intra_idr_period = intra_idr_period;
1296409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    seq_param.ip_period = ip_period;
1297409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
12986044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    seq_param.max_num_ref_frames = num_ref_frames;
1299409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    seq_param.seq_fields.bits.frame_mbs_only_flag = 1;
1300409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    seq_param.time_scale = 900;
1301409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    seq_param.num_units_in_tick = 15; /* Tc = num_units_in_tick / time_sacle */
13026044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    seq_param.seq_fields.bits.log2_max_pic_order_cnt_lsb_minus4 = Log2MaxPicOrderCntLsb - 4;
13036044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    seq_param.seq_fields.bits.log2_max_frame_num_minus4 = Log2MaxFrameNum - 4;;
1304409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    seq_param.seq_fields.bits.frame_mbs_only_flag = 1;
13052efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    seq_param.seq_fields.bits.chroma_format_idc = 1;
13062efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    seq_param.seq_fields.bits.direct_8x8_inference_flag = 1;
13072efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
13082efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (frame_width != frame_width_mbaligned ||
13092efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        frame_height != frame_height_mbaligned) {
13102efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        seq_param.frame_cropping_flag = 1;
13112efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        seq_param.frame_crop_left_offset = 0;
13122efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        seq_param.frame_crop_right_offset = (frame_width_mbaligned - frame_width)/2;
13132efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        seq_param.frame_crop_top_offset = 0;
13142efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        seq_param.frame_crop_bottom_offset = (frame_height_mbaligned - frame_height)/2;
13152efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    }
1316409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1317409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaCreateBuffer(va_dpy, context_id,
1318409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               VAEncSequenceParameterBufferType,
1319409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               sizeof(seq_param),1,&seq_param,&seq_param_buf);
1320409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaCreateBuffer");
1321409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1322409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaCreateBuffer(va_dpy, context_id,
1323409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               VAEncMiscParameterBufferType,
1324409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParameterRateControl),
1325409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               1,NULL,&rc_param_buf);
1326409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaCreateBuffer");
1327409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1328409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    vaMapBuffer(va_dpy, rc_param_buf,(void **)&misc_param);
1329409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    misc_param->type = VAEncMiscParameterTypeRateControl;
1330409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    misc_rate_ctrl = (VAEncMiscParameterRateControl *)misc_param->data;
1331409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    memset(misc_rate_ctrl, 0, sizeof(*misc_rate_ctrl));
1332409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    misc_rate_ctrl->bits_per_second = frame_bitrate;
13332efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    misc_rate_ctrl->target_percentage = 66;
13342efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    misc_rate_ctrl->window_size = 1000;
1335409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    misc_rate_ctrl->initial_qp = initial_qp;
1336409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    misc_rate_ctrl->min_qp = minimal_qp;
1337409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    misc_rate_ctrl->basic_unit_size = 0;
1338409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    vaUnmapBuffer(va_dpy, rc_param_buf);
1339409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1340409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    render_id[0] = seq_param_buf;
1341409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    render_id[1] = rc_param_buf;
1342409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1343409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaRenderPicture(va_dpy,context_id, &render_id[0], 2);
1344409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaRenderPicture");;
1345409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
13462efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (misc_priv_type != 0) {
13472efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        va_status = vaCreateBuffer(va_dpy, context_id,
13482efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                                   VAEncMiscParameterBufferType,
13492efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                                   sizeof(VAEncMiscParameterBuffer),
13502efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                                   1, NULL, &misc_param_tmpbuf);
13512efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        CHECK_VASTATUS(va_status,"vaCreateBuffer");
13522efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        vaMapBuffer(va_dpy, misc_param_tmpbuf,(void **)&misc_param_tmp);
13532efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        misc_param_tmp->type = misc_priv_type;
13542efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        misc_param_tmp->data[0] = misc_priv_value;
13552efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        vaUnmapBuffer(va_dpy, misc_param_tmpbuf);
13562efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
13572efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        va_status = vaRenderPicture(va_dpy,context_id, &misc_param_tmpbuf, 1);
13582efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    }
13592efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
1360409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
1361409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
1362409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
13632efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuanstatic int calc_poc(int pic_order_cnt_lsb)
13646044ab9a375eb73b08f45d87966652f98f918668Austin Yuan{
13656044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    static int PicOrderCntMsb_ref = 0, pic_order_cnt_lsb_ref = 0;
13666044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    int prevPicOrderCntMsb, prevPicOrderCntLsb;
13676044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    int PicOrderCntMsb, TopFieldOrderCnt;
13686044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
13696044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if (current_frame_type == FRAME_IDR)
13706044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        prevPicOrderCntMsb = prevPicOrderCntLsb = 0;
13716044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    else {
13726044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        prevPicOrderCntMsb = PicOrderCntMsb_ref;
13736044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        prevPicOrderCntLsb = pic_order_cnt_lsb_ref;
13746044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    }
13756044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
13766044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if ((pic_order_cnt_lsb < prevPicOrderCntLsb) &&
13772efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        ((prevPicOrderCntLsb - pic_order_cnt_lsb) >= (int)(MaxPicOrderCntLsb / 2)))
13786044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        PicOrderCntMsb = prevPicOrderCntMsb + MaxPicOrderCntLsb;
13796044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    else if ((pic_order_cnt_lsb > prevPicOrderCntLsb) &&
13802efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan             ((pic_order_cnt_lsb - prevPicOrderCntLsb) > (int)(MaxPicOrderCntLsb / 2)))
13816044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        PicOrderCntMsb = prevPicOrderCntMsb - MaxPicOrderCntLsb;
13826044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    else
13836044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        PicOrderCntMsb = prevPicOrderCntMsb;
13846044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
13856044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    TopFieldOrderCnt = PicOrderCntMsb + pic_order_cnt_lsb;
13866044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
13876044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if (current_frame_type != FRAME_B) {
13886044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        PicOrderCntMsb_ref = PicOrderCntMsb;
13896044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        pic_order_cnt_lsb_ref = pic_order_cnt_lsb;
13906044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    }
13916044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
13926044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    return TopFieldOrderCnt;
13936044ab9a375eb73b08f45d87966652f98f918668Austin Yuan}
13946044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
1395409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int render_picture(void)
1396409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
1397409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VABufferID pic_param_buf;
1398409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAStatus va_status;
1399409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int i = 0;
1400409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
14016044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    pic_param.CurrPic.picture_id = ref_surface[current_slot];
14026044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    pic_param.CurrPic.frame_idx = current_frame_num;
1403409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    pic_param.CurrPic.flags = 0;
14046044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    pic_param.CurrPic.TopFieldOrderCnt = calc_poc((current_frame_display - current_IDR_display) % MaxPicOrderCntLsb);
14056044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    pic_param.CurrPic.BottomFieldOrderCnt = pic_param.CurrPic.TopFieldOrderCnt;
14066044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    CurrentCurrPic = pic_param.CurrPic;
14076044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
14086044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if (getenv("TO_DEL")) { /* set RefPicList into ReferenceFrames */
14096044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        update_RefPicList(); /* calc RefPicList */
14106044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        memset(pic_param.ReferenceFrames, 0xff, 16 * sizeof(VAPictureH264)); /* invalid all */
14116044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        if (current_frame_type == FRAME_P) {
14126044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            pic_param.ReferenceFrames[0] = RefPicList0_P[0];
1413409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        } else if (current_frame_type == FRAME_B) {
14146044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            pic_param.ReferenceFrames[0] = RefPicList0_B[0];
14156044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            pic_param.ReferenceFrames[1] = RefPicList1_B[0];
14166044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        }
14176044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    } else {
14186044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        memcpy(pic_param.ReferenceFrames, ReferenceFrames, numShortTerm*sizeof(VAPictureH264));
14196044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        for (i = numShortTerm; i < SURFACE_NUM; i++) {
14206044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            pic_param.ReferenceFrames[i].picture_id = VA_INVALID_SURFACE;
14216044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            pic_param.ReferenceFrames[i].flags = VA_PICTURE_H264_INVALID;
1422409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
1423409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
1424409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1425409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    pic_param.pic_fields.bits.idr_pic_flag = (current_frame_type == FRAME_IDR);
1426409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    pic_param.pic_fields.bits.reference_pic_flag = (current_frame_type != FRAME_B);
14272efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    pic_param.pic_fields.bits.entropy_coding_mode_flag = h264_entropy_mode;
1428409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    pic_param.pic_fields.bits.deblocking_filter_control_present_flag = 1;
1429409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    pic_param.frame_num = current_frame_num;
14306044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    pic_param.coded_buf = coded_buf[current_slot];
1431409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    pic_param.last_picture = (current_frame_encoding == frame_count);
1432409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    pic_param.pic_init_qp = initial_qp;
1433409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1434409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaCreateBuffer(va_dpy, context_id,VAEncPictureParameterBufferType,
1435409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               sizeof(pic_param),1,&pic_param, &pic_param_buf);
1436409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaCreateBuffer");;
1437409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1438409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaRenderPicture(va_dpy,context_id, &pic_param_buf, 1);
1439409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaRenderPicture");
1440409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1441409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
1442409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
1443409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1444409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int render_packedsequence(void)
1445409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
14462efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    VAEncPackedHeaderParameterBuffer packedheader_param_buffer;
1447409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VABufferID packedseq_para_bufid, packedseq_data_bufid, render_id[2];
1448409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int length_in_bits;
1449409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned char *packedseq_buffer = NULL;
1450409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAStatus va_status;
1451409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1452409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    length_in_bits = build_packed_seq_buffer(&packedseq_buffer);
1453409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1454409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    packedheader_param_buffer.type = VAEncPackedHeaderSequence;
1455409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1456409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    packedheader_param_buffer.bit_length = length_in_bits; /*length_in_bits*/
1457409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    packedheader_param_buffer.has_emulation_bytes = 0;
1458409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaCreateBuffer(va_dpy,
1459409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               context_id,
1460409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               VAEncPackedHeaderParameterBufferType,
1461409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               sizeof(packedheader_param_buffer), 1, &packedheader_param_buffer,
1462409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               &packedseq_para_bufid);
1463409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaCreateBuffer");
1464409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1465409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaCreateBuffer(va_dpy,
1466409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               context_id,
1467409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               VAEncPackedHeaderDataBufferType,
1468409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               (length_in_bits + 7) / 8, 1, packedseq_buffer,
1469409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               &packedseq_data_bufid);
1470409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaCreateBuffer");
1471409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1472409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    render_id[0] = packedseq_para_bufid;
1473409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    render_id[1] = packedseq_data_bufid;
1474409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaRenderPicture(va_dpy,context_id, render_id, 2);
1475409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaRenderPicture");
1476409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1477409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    free(packedseq_buffer);
1478409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1479409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
1480409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
1481409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1482409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1483409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int render_packedpicture(void)
1484409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
14852efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    VAEncPackedHeaderParameterBuffer packedheader_param_buffer;
1486409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VABufferID packedpic_para_bufid, packedpic_data_bufid, render_id[2];
1487409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int length_in_bits;
1488409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned char *packedpic_buffer = NULL;
1489409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAStatus va_status;
1490409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1491409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    length_in_bits = build_packed_pic_buffer(&packedpic_buffer);
1492409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    packedheader_param_buffer.type = VAEncPackedHeaderPicture;
1493409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    packedheader_param_buffer.bit_length = length_in_bits;
1494409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    packedheader_param_buffer.has_emulation_bytes = 0;
1495409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1496409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaCreateBuffer(va_dpy,
1497409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               context_id,
1498409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               VAEncPackedHeaderParameterBufferType,
1499409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               sizeof(packedheader_param_buffer), 1, &packedheader_param_buffer,
1500409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               &packedpic_para_bufid);
1501409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaCreateBuffer");
1502409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1503409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaCreateBuffer(va_dpy,
1504409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               context_id,
1505409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               VAEncPackedHeaderDataBufferType,
1506409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               (length_in_bits + 7) / 8, 1, packedpic_buffer,
1507409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               &packedpic_data_bufid);
1508409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaCreateBuffer");
1509409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1510409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    render_id[0] = packedpic_para_bufid;
1511409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    render_id[1] = packedpic_data_bufid;
1512409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaRenderPicture(va_dpy,context_id, render_id, 2);
1513409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaRenderPicture");
1514409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1515409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    free(packedpic_buffer);
1516409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1517409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
1518409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
1519409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1520409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void render_packedsei(void)
1521409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
1522409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAEncPackedHeaderParameterBuffer packed_header_param_buffer;
1523409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VABufferID packed_sei_header_param_buf_id, packed_sei_buf_id, render_id[2];
15242efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    unsigned int length_in_bits /*offset_in_bytes*/;
1525409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned char *packed_sei_buffer = NULL;
1526409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAStatus va_status;
1527409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int init_cpb_size, target_bit_rate, i_initial_cpb_removal_delay_length, i_initial_cpb_removal_delay;
1528409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int i_cpb_removal_delay, i_dpb_output_delay_length, i_cpb_removal_delay_length;
1529409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1530409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* it comes for the bps defined in SPS */
1531409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    target_bit_rate = frame_bitrate;
1532409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    init_cpb_size = (target_bit_rate * 8) >> 10;
1533409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    i_initial_cpb_removal_delay = init_cpb_size * 0.5 * 1024 / target_bit_rate * 90000;
1534409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1535409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    i_cpb_removal_delay = 2;
1536409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    i_initial_cpb_removal_delay_length = 24;
1537409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    i_cpb_removal_delay_length = 24;
1538409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    i_dpb_output_delay_length = 24;
1539409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1540409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1541409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    length_in_bits = build_packed_sei_buffer_timing(
1542409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        i_initial_cpb_removal_delay_length,
1543409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        i_initial_cpb_removal_delay,
1544409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        0,
1545409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        i_cpb_removal_delay_length,
1546409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        i_cpb_removal_delay * current_frame_encoding,
1547409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        i_dpb_output_delay_length,
1548409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        0,
1549409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        &packed_sei_buffer);
1550409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
15512efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    //offset_in_bytes = 0;
1552409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    packed_header_param_buffer.type = VAEncPackedHeaderH264_SEI;
1553409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    packed_header_param_buffer.bit_length = length_in_bits;
1554409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    packed_header_param_buffer.has_emulation_bytes = 0;
1555409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1556409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaCreateBuffer(va_dpy,
1557409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               context_id,
1558409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               VAEncPackedHeaderParameterBufferType,
1559409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               sizeof(packed_header_param_buffer), 1, &packed_header_param_buffer,
1560409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               &packed_sei_header_param_buf_id);
1561409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaCreateBuffer");
1562409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1563409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaCreateBuffer(va_dpy,
1564409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               context_id,
1565409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               VAEncPackedHeaderDataBufferType,
1566409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               (length_in_bits + 7) / 8, 1, packed_sei_buffer,
1567409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               &packed_sei_buf_id);
1568409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaCreateBuffer");
1569409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1570409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1571409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    render_id[0] = packed_sei_header_param_buf_id;
1572409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    render_id[1] = packed_sei_buf_id;
1573409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaRenderPicture(va_dpy,context_id, render_id, 2);
1574409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaRenderPicture");
1575409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1576409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1577409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    free(packed_sei_buffer);
1578409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1579409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return;
1580409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
1581409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1582409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1583409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int render_hrd(void)
1584409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
1585409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VABufferID misc_parameter_hrd_buf_id;
1586409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAStatus va_status;
1587409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAEncMiscParameterBuffer *misc_param;
1588409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAEncMiscParameterHRD *misc_hrd_param;
1589409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1590409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaCreateBuffer(va_dpy, context_id,
1591409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                   VAEncMiscParameterBufferType,
1592409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                   sizeof(VAEncMiscParameterBuffer) + sizeof(VAEncMiscParameterHRD),
1593409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                   1,
1594409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                   NULL,
1595409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                   &misc_parameter_hrd_buf_id);
1596409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status, "vaCreateBuffer");
1597409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1598409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    vaMapBuffer(va_dpy,
1599409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                misc_parameter_hrd_buf_id,
1600409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                (void **)&misc_param);
1601409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    misc_param->type = VAEncMiscParameterTypeHRD;
1602409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    misc_hrd_param = (VAEncMiscParameterHRD *)misc_param->data;
1603409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1604409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (frame_bitrate > 0) {
1605409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        misc_hrd_param->initial_buffer_fullness = frame_bitrate * 1024 * 4;
1606409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        misc_hrd_param->buffer_size = frame_bitrate * 1024 * 8;
1607409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    } else {
1608409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        misc_hrd_param->initial_buffer_fullness = 0;
1609409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        misc_hrd_param->buffer_size = 0;
1610409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
1611409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    vaUnmapBuffer(va_dpy, misc_parameter_hrd_buf_id);
1612409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1613409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaRenderPicture(va_dpy,context_id, &misc_parameter_hrd_buf_id, 1);
1614409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaRenderPicture");;
1615409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1616409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
1617409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
1618409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1619409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int render_slice(void)
1620409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
1621409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VABufferID slice_param_buf;
1622409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAStatus va_status;
1623409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int i;
16246044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
16256044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    update_RefPicList();
1626409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1627409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* one frame, one slice */
1628409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    slice_param.macroblock_address = 0;
16292efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    slice_param.num_macroblocks = frame_width_mbaligned * frame_height_mbaligned/(16*16); /* Measured by MB */
1630409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    slice_param.slice_type = (current_frame_type == FRAME_IDR)?2:current_frame_type;
16312efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (current_frame_type == FRAME_IDR) {
16322efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        if (current_frame_encoding != 0)
16332efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            ++slice_param.idr_pic_id;
16346044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    } else if (current_frame_type == FRAME_P) {
16356044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        int refpiclist0_max = h264_maxref & 0xffff;
16366044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        memcpy(slice_param.RefPicList0, RefPicList0_P, refpiclist0_max*sizeof(VAPictureH264));
16376044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
16386044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        for (i = refpiclist0_max; i < 32; i++) {
16396044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            slice_param.RefPicList0[i].picture_id = VA_INVALID_SURFACE;
16406044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            slice_param.RefPicList0[i].flags = VA_PICTURE_H264_INVALID;
16416044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        }
16426044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    } else if (current_frame_type == FRAME_B) {
16436044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        int refpiclist0_max = h264_maxref & 0xffff;
16446044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        int refpiclist1_max = (h264_maxref >> 16) & 0xffff;
16456044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
16466044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        memcpy(slice_param.RefPicList0, RefPicList0_B, refpiclist0_max*sizeof(VAPictureH264));
16476044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        for (i = refpiclist0_max; i < 32; i++) {
16486044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            slice_param.RefPicList0[i].picture_id = VA_INVALID_SURFACE;
16496044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            slice_param.RefPicList0[i].flags = VA_PICTURE_H264_INVALID;
16506044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        }
1651409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
16526044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        memcpy(slice_param.RefPicList1, RefPicList1_B, refpiclist1_max*sizeof(VAPictureH264));
16536044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        for (i = refpiclist1_max; i < 32; i++) {
16546044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            slice_param.RefPicList1[i].picture_id = VA_INVALID_SURFACE;
16556044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            slice_param.RefPicList1[i].flags = VA_PICTURE_H264_INVALID;
1656409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
1657409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
16586044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
16592efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    slice_param.slice_alpha_c0_offset_div2 = 0;
16602efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    slice_param.slice_beta_offset_div2 = 0;
16612efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    slice_param.direct_spatial_mv_pred_flag = 1;
16622efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    slice_param.pic_order_cnt_lsb = (current_frame_display - current_IDR_display) % MaxPicOrderCntLsb;
1663409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1664409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaCreateBuffer(va_dpy,context_id,VAEncSliceParameterBufferType,
1665409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               sizeof(slice_param),1,&slice_param,&slice_param_buf);
1666409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaCreateBuffer");;
1667409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1668409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_status = vaRenderPicture(va_dpy,context_id, &slice_param_buf, 1);
1669409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaRenderPicture");
16702efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
1671409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
1672409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
1673409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1674409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1675409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int upload_source_YUV_once_for_all()
1676409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
1677409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int box_width=8;
1678409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int row_shift=0;
1679409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int i;
1680409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
16816044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    for (i = 0; i < SURFACE_NUM; i++) {
1682409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        printf("\rLoading data into surface %d.....", i);
1683409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        upload_surface(va_dpy, src_surface[i], box_width, row_shift, 0);
1684409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1685409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        row_shift++;
1686409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (row_shift==(2*box_width)) row_shift= 0;
1687409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
16882efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    printf("Complete surface loading\n");
1689409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1690409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
1691409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
1692409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1693409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int load_surface(VASurfaceID surface_id, unsigned long long display_order)
1694409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
16952efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    unsigned char *srcyuv_ptr = NULL, *src_Y = NULL, *src_U = NULL, *src_V = NULL;
16962efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    unsigned long long frame_start, mmap_start;
16972efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    char *mmap_ptr = NULL;
16982efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    int frame_size, mmap_size;
16992efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
1700409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (srcyuv_fp == NULL)
1701409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        return 0;
1702409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
17032efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    /* allow encoding more than srcyuv_frames */
1704409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    display_order = display_order % srcyuv_frames;
17052efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    frame_size = frame_width * frame_height * 3 / 2; /* for YUV420 */
17062efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    frame_start = display_order * frame_size;
17072efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
17082efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    mmap_start = frame_start & (~0xfff);
17092efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    mmap_size = (frame_size + (frame_start & 0xfff) + 0xfff) & (~0xfff);
17102efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    mmap_ptr = mmap(0, mmap_size, PROT_READ, MAP_SHARED,
17112efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                    fileno(srcyuv_fp), mmap_start);
17122efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (mmap_ptr == MAP_FAILED) {
17132efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        printf("Failed to mmap YUV file (%s)\n", strerror(errno));
17142efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        return 1;
17152efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    }
17162efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    srcyuv_ptr = (unsigned char *)mmap_ptr +  (frame_start & 0xfff);
17172efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (srcyuv_fourcc == VA_FOURCC_NV12) {
17182efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        src_Y = srcyuv_ptr;
17192efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        src_U = src_Y + frame_width * frame_height;
17202efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        src_V = NULL;
17212efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    } else if (srcyuv_fourcc == VA_FOURCC_IYUV ||
17222efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        srcyuv_fourcc == VA_FOURCC_YV12) {
17232efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        src_Y = srcyuv_ptr;
17242efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        if (srcyuv_fourcc == VA_FOURCC_IYUV) {
17252efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            src_U = src_Y + frame_width * frame_height;
17262efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            src_V = src_U + (frame_width/2) * (frame_height/2);
17272efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        } else { /* YV12 */
17282efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            src_V = src_Y + frame_width * frame_height;
17292efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            src_U = src_V + (frame_width/2) * (frame_height/2);
17302efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        }
17312efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    } else {
17322efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        printf("Unsupported source YUV format\n");
17332efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        exit(1);
17342efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    }
1735409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
17362efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    upload_surface_yuv(va_dpy, surface_id,
17372efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                       srcyuv_fourcc, frame_width, frame_height,
17382efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                       src_Y, src_U, src_V);
17392efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (mmap_ptr)
17402efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        munmap(mmap_ptr, mmap_size);
17412efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
17422efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    return 0;
17432efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan}
1744409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1745409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
17462efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuanstatic int save_recyuv(VASurfaceID surface_id,
17472efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                       unsigned long long display_order,
17482efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                       unsigned long long encode_order)
17492efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan{
17502efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    unsigned char *dst_Y = NULL, *dst_U = NULL, *dst_V = NULL;
17512efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
17522efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (recyuv_fp == NULL)
17532efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        return 0;
1754409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
17552efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (srcyuv_fourcc == VA_FOURCC_NV12) {
17562efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        int uv_size = 2 * (frame_width/2) * (frame_height/2);
17572efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        dst_Y = malloc(2*uv_size);
17582efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        dst_U = malloc(uv_size);
17592efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    } else if (srcyuv_fourcc == VA_FOURCC_IYUV ||
17602efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan               srcyuv_fourcc == VA_FOURCC_YV12) {
17612efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        int uv_size = (frame_width/2) * (frame_height/2);
17622efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        dst_Y = malloc(4*uv_size);
17632efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        dst_U = malloc(uv_size);
17642efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        dst_V = malloc(uv_size);
17652efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    } else {
17662efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        printf("Unsupported source YUV format\n");
17672efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        exit(1);
1768409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
17692efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
17702efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    download_surface_yuv(va_dpy, surface_id,
17712efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                         srcyuv_fourcc, frame_width, frame_height,
17722efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                         dst_Y, dst_U, dst_V);
17732efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    fseek(recyuv_fp, display_order * frame_width * frame_height * 1.5, SEEK_SET);
17742efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
17752efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (srcyuv_fourcc == VA_FOURCC_NV12) {
17762efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        int uv_size = 2 * (frame_width/2) * (frame_height/2);
17772efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        fwrite(dst_Y, uv_size * 2, 1, recyuv_fp);
17782efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        fwrite(dst_U, uv_size, 1, recyuv_fp);
17792efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    } else if (srcyuv_fourcc == VA_FOURCC_IYUV ||
17802efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan               srcyuv_fourcc == VA_FOURCC_YV12) {
17812efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        int uv_size = (frame_width/2) * (frame_height/2);
17822efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        fwrite(dst_Y, uv_size * 4, 1, recyuv_fp);
17832efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
17842efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        if (srcyuv_fourcc == VA_FOURCC_IYUV) {
17852efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            fwrite(dst_U, uv_size, 1, recyuv_fp);
17862efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            fwrite(dst_V, uv_size, 1, recyuv_fp);
17872efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        } else {
17882efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            fwrite(dst_V, uv_size, 1, recyuv_fp);
17892efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            fwrite(dst_U, uv_size, 1, recyuv_fp);
1790409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
17912efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    } else {
17922efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        printf("Unsupported YUV format\n");
17932efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        exit(1);
1794409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
17956044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
17962efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (dst_Y)
17972efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        free(dst_Y);
17982efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (dst_U)
17992efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        free(dst_U);
18002efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (dst_V)
18012efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        free(dst_V);
1802409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
18032efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    fflush(recyuv_fp);
1804409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1805409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
1806409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
1807409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1808409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1809409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int save_codeddata(unsigned long long display_order, unsigned long long encode_order)
1810409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
1811409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VACodedBufferSegment *buf_list = NULL;
1812409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAStatus va_status;
1813409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int coded_size = 0;
1814409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
18156044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    va_status = vaMapBuffer(va_dpy,coded_buf[display_order % SURFACE_NUM],(void **)(&buf_list));
1816409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaMapBuffer");
1817409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    while (buf_list != NULL) {
1818409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        coded_size += fwrite(buf_list->buf, 1, buf_list->size, coded_fp);
1819409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        buf_list = (VACodedBufferSegment *) buf_list->next;
18206044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
18216044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        frame_size += coded_size;
1822409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
18236044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    vaUnmapBuffer(va_dpy,coded_buf[display_order % SURFACE_NUM]);
1824409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1825409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("\r      "); /* return back to startpoint */
1826409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    switch (encode_order % 4) {
1827409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 0:
1828409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("|");
1829409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
1830409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 1:
1831409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("/");
1832409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
1833409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 2:
1834409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("-");
1835409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
1836409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        case 3:
1837409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            printf("\\");
1838409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
1839409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
1840409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("%08lld", encode_order);
1841409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("(%06d bytes coded)",coded_size);
1842409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
18432efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    fflush(coded_fp);
18442efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
1845409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
1846409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
1847409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1848409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
18492efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuanstatic struct storage_task_t * storage_task_dequeue(void)
1850409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
1851409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct storage_task_t *header;
1852409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1853409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    pthread_mutex_lock(&encode_mutex);
1854409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1855409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    header = storage_task_header;
1856409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (storage_task_header != NULL) {
1857409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (storage_task_tail == storage_task_header)
1858409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            storage_task_tail = NULL;
1859409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        storage_task_header = header->next;
1860409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
1861409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1862409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    pthread_mutex_unlock(&encode_mutex);
1863409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1864409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return header;
1865409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
1866409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1867409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int storage_task_queue(unsigned long long display_order, unsigned long long encode_order)
1868409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
1869409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    struct storage_task_t *tmp;
1870409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1871409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    tmp = calloc(1, sizeof(struct storage_task_t));
1872409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    tmp->display_order = display_order;
1873409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    tmp->encode_order = encode_order;
1874409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1875409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    pthread_mutex_lock(&encode_mutex);
1876409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1877409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (storage_task_header == NULL) {
1878409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        storage_task_header = tmp;
1879409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        storage_task_tail = tmp;
1880409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    } else {
1881409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        storage_task_tail->next = tmp;
1882409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        storage_task_tail = tmp;
1883409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
1884409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
18856044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    srcsurface_status[display_order % SURFACE_NUM] = SRC_SURFACE_IN_STORAGE;
1886409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    pthread_cond_signal(&encode_cond);
1887409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1888409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    pthread_mutex_unlock(&encode_mutex);
1889409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1890409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
1891409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
1892409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
18936044ab9a375eb73b08f45d87966652f98f918668Austin Yuanstatic void storage_task(unsigned long long display_order, unsigned long long encode_order)
1894409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
1895409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int tmp;
1896409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAStatus va_status;
1897409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1898409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    tmp = GetTickCount();
18996044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    va_status = vaSyncSurface(va_dpy, src_surface[display_order % SURFACE_NUM]);
1900409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    CHECK_VASTATUS(va_status,"vaSyncSurface");
1901409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    SyncPictureTicks += GetTickCount() - tmp;
1902409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    tmp = GetTickCount();
1903409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    save_codeddata(display_order, encode_order);
1904409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    SavePictureTicks += GetTickCount() - tmp;
19052efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
19062efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    save_recyuv(ref_surface[display_order % SURFACE_NUM], display_order, encode_order);
19072efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
1908409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* reload a new frame data */
1909409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    tmp = GetTickCount();
1910409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (srcyuv_fp != NULL)
19116044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        load_surface(src_surface[display_order % SURFACE_NUM], display_order + SURFACE_NUM);
1912409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    UploadPictureTicks += GetTickCount() - tmp;
1913409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1914409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    pthread_mutex_lock(&encode_mutex);
19156044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    srcsurface_status[display_order % SURFACE_NUM] = SRC_SURFACE_IN_ENCODING;
1916409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    pthread_mutex_unlock(&encode_mutex);
1917409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
1918409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1919409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1920409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic void * storage_task_thread(void *t)
1921409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
1922409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    while (1) {
1923409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        struct storage_task_t *current;
1924409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
19252efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        current = storage_task_dequeue();
1926409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (current == NULL) {
1927409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            pthread_mutex_lock(&encode_mutex);
1928409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            pthread_cond_wait(&encode_cond, &encode_mutex);
1929409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            pthread_mutex_unlock(&encode_mutex);
1930409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            continue;
1931409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
1932409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1933409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        storage_task(current->display_order, current->encode_order);
1934409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1935409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        free(current);
1936409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1937409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        /* all frames are saved, exit the thread */
1938409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (++frame_coded >= frame_count)
1939409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            break;
1940409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
1941409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1942409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
1943409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
1944409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1945409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1946409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int encode_frames(void)
1947409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
1948409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int i, tmp;
1949409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    VAStatus va_status;
1950409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    //VASurfaceStatus surface_status;
1951409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1952409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* upload RAW YUV data into all surfaces */
1953409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    tmp = GetTickCount();
1954409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (srcyuv_fp != NULL) {
19556044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        for (i = 0; i < SURFACE_NUM; i++)
1956409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            load_surface(src_surface[i], i);
1957409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    } else
1958409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        upload_source_YUV_once_for_all();
1959409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    UploadPictureTicks += GetTickCount() - tmp;
1960409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1961409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    /* ready for encoding */
1962409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    memset(srcsurface_status, SRC_SURFACE_IN_ENCODING, sizeof(srcsurface_status));
1963409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1964409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    memset(&seq_param, 0, sizeof(seq_param));
1965409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    memset(&pic_param, 0, sizeof(pic_param));
1966409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    memset(&slice_param, 0, sizeof(slice_param));
1967409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1968409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (encode_syncmode == 0)
1969409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        pthread_create(&encode_thread, NULL, storage_task_thread, NULL);
1970409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1971409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    for (current_frame_encoding = 0; current_frame_encoding < frame_count; current_frame_encoding++) {
1972409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        encoding2display_order(current_frame_encoding, intra_period, intra_idr_period, ip_period,
1973409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                               &current_frame_display, &current_frame_type);
19746044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        if (current_frame_type == FRAME_IDR) {
19756044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            numShortTerm = 0;
19766044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            current_frame_num = 0;
19776044ab9a375eb73b08f45d87966652f98f918668Austin Yuan            current_IDR_display = current_frame_display;
19786044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        }
19792efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
1980409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        /* check if the source frame is ready */
19812efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        while (srcsurface_status[current_slot] != SRC_SURFACE_IN_ENCODING) {
19822efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            usleep(1);
19832efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        }
19842efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
1985409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        tmp = GetTickCount();
19866044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        va_status = vaBeginPicture(va_dpy, context_id, src_surface[current_slot]);
1987409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        CHECK_VASTATUS(va_status,"vaBeginPicture");
1988409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        BeginPictureTicks += GetTickCount() - tmp;
1989409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
1990409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        tmp = GetTickCount();
19916044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        if (current_frame_type == FRAME_IDR) {
1992409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            render_sequence();
1993409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            render_picture();
1994409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            if (h264_packedheader) {
1995409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                render_packedsequence();
1996409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan                render_packedpicture();
1997409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            }
1998409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            //if (rc_mode == VA_RC_CBR)
1999409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            //    render_packedsei();
2000409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            //render_hrd();
2001409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        } else {
2002409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            //render_sequence();
2003409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            render_picture();
2004409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            //if (rc_mode == VA_RC_CBR)
2005409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            //    render_packedsei();
2006409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            //render_hrd();
2007409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        }
2008409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        render_slice();
2009409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        RenderPictureTicks += GetTickCount() - tmp;
2010409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2011409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        tmp = GetTickCount();
2012409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        va_status = vaEndPicture(va_dpy,context_id);
2013409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        CHECK_VASTATUS(va_status,"vaEndPicture");;
2014409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        EndPictureTicks += GetTickCount() - tmp;
2015409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2016409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        if (encode_syncmode)
2017409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            storage_task(current_frame_display, current_frame_encoding);
2018409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        else /* queue the storage task queue */
2019409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan            storage_task_queue(current_frame_display, current_frame_encoding);
20202efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
20216044ab9a375eb73b08f45d87966652f98f918668Austin Yuan        update_ReferenceFrames();
2022409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
2023409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2024409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (encode_syncmode == 0) {
2025409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        int ret;
2026409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        pthread_join(encode_thread, (void **)&ret);
2027409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    }
2028409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2029409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
2030409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
2031409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2032409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2033409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int release_encode()
2034409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
2035409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    int i;
2036409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
20376044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    vaDestroySurfaces(va_dpy,&src_surface[0],SURFACE_NUM);
20386044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    vaDestroySurfaces(va_dpy,&ref_surface[0],SURFACE_NUM);
2039409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
20406044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    for (i = 0; i < SURFACE_NUM; i++)
2041409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        vaDestroyBuffer(va_dpy,coded_buf[i]);
2042409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2043409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    vaDestroyContext(va_dpy,context_id);
2044409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    vaDestroyConfig(va_dpy,config_id);
2045409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2046409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
2047409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
2048409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2049409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int deinit_va()
2050409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
2051409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    vaTerminate(va_dpy);
2052409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2053409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    va_close_display(va_dpy);
2054409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2055409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
2056409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
2057409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2058409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2059409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int print_input()
2060409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
2061409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("\n\nINPUT:Try to encode H264...\n");
2062409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("INPUT: RateControl  : %s\n", rc_to_string(rc_mode));
2063409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("INPUT: Resolution   : %dx%d, %d frames\n",
2064409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           frame_width, frame_height, frame_count);
2065409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("INPUT: FrameRate    : %d\n", frame_rate);
2066409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("INPUT: Bitrate      : %d\n", frame_bitrate);
2067409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("INPUT: Slieces      : %d\n", frame_slices);
2068409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("INPUT: IntraPeriod  : %d\n", intra_period);
2069409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("INPUT: IDRPeriod    : %d\n", intra_idr_period);
2070409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("INPUT: IpPeriod     : %d\n", ip_period);
2071409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("INPUT: Initial QP   : %d\n", initial_qp);
2072409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("INPUT: Min QP       : %d\n", minimal_qp);
20736044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    printf("INPUT: Source YUV   : %s", srcyuv_fp?"FILE":"AUTO generated");
2074409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    if (srcyuv_fp)
2075409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        printf(":%s (fourcc %s)\n", srcyuv_fn, fourcc_to_string(srcyuv_fourcc));
2076409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else
2077409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        printf("\n");
2078409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("INPUT: Coded Clip   : %s\n", coded_fn);
20796044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if (recyuv_fp == NULL)
2080409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        printf("INPUT: Rec   Clip   : %s\n", "Not save reconstructed frame");
2081409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    else
2082409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        printf("INPUT: Rec   Clip   : Save reconstructed frame into %s (fourcc %s)\n", recyuv_fn,
2083409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan               fourcc_to_string(srcyuv_fourcc));
2084409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2085409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("\n\n"); /* return back to startpoint */
2086409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2087409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
2088409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
2089409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
20902efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuanstatic int calc_PSNR(double *psnr)
20912efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan{
20922efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    char *srcyuv_ptr = NULL, *recyuv_ptr = NULL, tmp;
20932efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    unsigned long long min_size;
20942efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    unsigned long long i, sse=0;
20952efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    double ssemean;
20962efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    int fourM = 0x400000; /* 4M */
20972efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
20982efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    min_size = MIN(srcyuv_frames, frame_count) * frame_width * frame_height * 1.5;
20992efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    for (i=0; i<min_size; i++) {
21002efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        unsigned long long j = i % fourM;
21012efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
21022efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        if ((i % fourM) == 0) {
21032efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            if (srcyuv_ptr)
21042efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                munmap(srcyuv_ptr, fourM);
21052efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            if (recyuv_ptr)
21062efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                munmap(recyuv_ptr, fourM);
21072efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
21082efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            srcyuv_ptr = mmap(0, fourM, PROT_READ, MAP_SHARED, fileno(srcyuv_fp), i);
21092efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            recyuv_ptr = mmap(0, fourM, PROT_READ, MAP_SHARED, fileno(recyuv_fp), i);
21102efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            if ((srcyuv_ptr == MAP_FAILED) || (recyuv_ptr == MAP_FAILED)) {
21112efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                printf("Failed to mmap YUV files\n");
21122efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan                return 1;
21132efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan            }
21142efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        }
21152efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        tmp = srcyuv_ptr[j] - recyuv_ptr[j];
21162efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        sse += tmp * tmp;
21172efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    }
21182efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    ssemean = (double)sse/(double)min_size;
21192efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    *psnr = 20.0*log10(255) - 10.0*log10(ssemean);
21202efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
21212efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (srcyuv_ptr)
21222efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        munmap(srcyuv_ptr, fourM);
21232efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (recyuv_ptr)
21242efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        munmap(recyuv_ptr, fourM);
21252efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
21262efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    return 0;
21272efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan}
2128409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2129409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanstatic int print_performance(unsigned int PictureCount)
2130409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
21312efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    unsigned int psnr_ret = 1, others = 0;
21322efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    double psnr = 0, total_size = frame_width * frame_height * 1.5 * frame_count;
2133409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
21342efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (calc_psnr && srcyuv_fp && recyuv_fp)
21352efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        psnr_ret = calc_PSNR(&psnr);
21362efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
2137409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    others = TotalTicks - UploadPictureTicks - BeginPictureTicks
2138409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan        - RenderPictureTicks - EndPictureTicks - SyncPictureTicks - SavePictureTicks;
21396044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
2140409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("\n\n");
2141409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2142409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("PERFORMANCE:   Frame Rate           : %.2f fps (%d frames, %d ms (%.2f ms per frame))\n",
2143409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           (double) 1000*PictureCount / TotalTicks, PictureCount,
2144409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           TotalTicks, ((double)  TotalTicks) / (double) PictureCount);
21456044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    printf("PERFORMANCE:   Compression ratio    : %d:1\n", (unsigned int)(total_size / frame_size));
21462efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan    if (psnr_ret == 0)
21472efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        printf("PERFORMANCE:   PSNR                 : %.2f (%lld frames calculated)\n",
21482efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan               psnr, MIN(frame_count, srcyuv_frames));
2149409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2150409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("PERFORMANCE:     UploadPicture      : %d ms (%.2f, %.2f%% percent)\n",
2151409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           (int) UploadPictureTicks, ((double)  UploadPictureTicks) / (double) PictureCount,
2152409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           UploadPictureTicks/(double) TotalTicks/0.01);
2153409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("PERFORMANCE:     vaBeginPicture     : %d ms (%.2f, %.2f%% percent)\n",
2154409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           (int) BeginPictureTicks, ((double)  BeginPictureTicks) / (double) PictureCount,
2155409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           BeginPictureTicks/(double) TotalTicks/0.01);
2156409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("PERFORMANCE:     vaRenderHeader     : %d ms (%.2f, %.2f%% percent)\n",
2157409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           (int) RenderPictureTicks, ((double)  RenderPictureTicks) / (double) PictureCount,
2158409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           RenderPictureTicks/(double) TotalTicks/0.01);
2159409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("PERFORMANCE:     vaEndPicture       : %d ms (%.2f, %.2f%% percent)\n",
2160409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           (int) EndPictureTicks, ((double)  EndPictureTicks) / (double) PictureCount,
2161409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           EndPictureTicks/(double) TotalTicks/0.01);
2162409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("PERFORMANCE:     vaSyncSurface      : %d ms (%.2f, %.2f%% percent)\n",
2163409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           (int) SyncPictureTicks, ((double) SyncPictureTicks) / (double) PictureCount,
2164409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           SyncPictureTicks/(double) TotalTicks/0.01);
2165409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("PERFORMANCE:     SavePicture        : %d ms (%.2f, %.2f%% percent)\n",
2166409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           (int) SavePictureTicks, ((double)  SavePictureTicks) / (double) PictureCount,
2167409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           SavePictureTicks/(double) TotalTicks/0.01);
2168409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    printf("PERFORMANCE:     Others             : %d ms (%.2f, %.2f%% percent)\n",
2169409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           (int) others, ((double) others) / (double) PictureCount,
2170409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan           others/(double) TotalTicks/0.01);
21716044ab9a375eb73b08f45d87966652f98f918668Austin Yuan
21726044ab9a375eb73b08f45d87966652f98f918668Austin Yuan    if (encode_syncmode == 0)
21732efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan        printf("(Multithread enabled, the timing is only for reference)\n");
21742efbafef6046e1d9372c58de2b0d7b03377c686cAustin Yuan
2175409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
2176409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
2177409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2178409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2179409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuanint main(int argc,char **argv)
2180409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan{
2181409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    unsigned int start;
2182409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2183409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    process_cmdline(argc, argv);
2184409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2185409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    print_input();
2186409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2187409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    start = GetTickCount();
2188409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2189409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    init_va();
2190409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    setup_encode();
2191409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2192409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    encode_frames();
2193409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2194409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    release_encode();
2195409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    deinit_va();
2196409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2197409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    TotalTicks += GetTickCount() - start;
2198409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    print_performance(frame_count);
2199409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan
2200409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan    return 0;
2201409de6acb4473c973ed2532e340831dc582e5e0eAustin Yuan}
2202