1/*
2* Copyright (c) 2009-2011 Intel Corporation.  All rights reserved.
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16
17#include <string.h>
18#include <stdlib.h>
19#include "VideoEncoderLog.h"
20#include "VideoEncoderH263.h"
21#include <va/va_tpi.h>
22
23VideoEncoderH263::VideoEncoderH263() {
24    mComParams.profile = (VAProfile)PROFILE_H263BASELINE;
25    mAutoReferenceSurfaceNum = 2;
26}
27
28Encode_Status VideoEncoderH263::sendEncodeCommand(EncodeTask *task) {
29
30    Encode_Status ret = ENCODE_SUCCESS;
31    LOG_V( "Begin\n");
32
33    if (mFrameNum == 0) {
34        ret = renderSequenceParams(task);
35        CHECK_ENCODE_STATUS_RETURN("renderSequenceParams");
36    }
37
38    ret = renderPictureParams(task);
39    CHECK_ENCODE_STATUS_RETURN("renderPictureParams");
40
41    ret = renderSliceParams(task);
42    CHECK_ENCODE_STATUS_RETURN("renderSliceParams");
43
44    LOG_V( "End\n");
45    return ENCODE_SUCCESS;
46}
47
48
49Encode_Status VideoEncoderH263::renderSequenceParams(EncodeTask *) {
50
51    VAStatus vaStatus = VA_STATUS_SUCCESS;
52    VAEncSequenceParameterBufferH263 h263SequenceParam = VAEncSequenceParameterBufferH263();
53    uint32_t frameRateNum = mComParams.frameRate.frameRateNum;
54    uint32_t frameRateDenom = mComParams.frameRate.frameRateDenom;
55
56    LOG_V( "Begin\n\n");
57    //set up the sequence params for HW
58    h263SequenceParam.bits_per_second= mComParams.rcParams.bitRate;
59    h263SequenceParam.frame_rate =
60            (unsigned int) (frameRateNum + frameRateDenom /2) / frameRateDenom;   //hard-coded, driver need;
61    h263SequenceParam.initial_qp = mComParams.rcParams.initQP;
62    h263SequenceParam.min_qp = mComParams.rcParams.minQP;
63    h263SequenceParam.intra_period = mComParams.intraPeriod;
64
65    //h263_seq_param.fixed_vop_rate = 30;
66
67    LOG_V("===h263 sequence params===\n");
68    LOG_I( "bitrate = %d\n", h263SequenceParam.bits_per_second);
69    LOG_I( "frame_rate = %d\n", h263SequenceParam.frame_rate);
70    LOG_I( "initial_qp = %d\n", h263SequenceParam.initial_qp);
71    LOG_I( "min_qp = %d\n", h263SequenceParam.min_qp);
72    LOG_I( "intra_period = %d\n\n", h263SequenceParam.intra_period);
73
74    vaStatus = vaCreateBuffer(
75            mVADisplay, mVAContext,
76            VAEncSequenceParameterBufferType,
77            sizeof(h263SequenceParam),
78            1, &h263SequenceParam,
79            &mSeqParamBuf);
80    CHECK_VA_STATUS_RETURN("vaCreateBuffer");
81
82    vaStatus = vaRenderPicture(mVADisplay, mVAContext, &mSeqParamBuf, 1);
83    CHECK_VA_STATUS_RETURN("vaRenderPicture");
84
85    LOG_V( "end\n");
86    return ENCODE_SUCCESS;
87}
88
89Encode_Status VideoEncoderH263::renderPictureParams(EncodeTask *task) {
90
91    VAStatus vaStatus = VA_STATUS_SUCCESS;
92    VAEncPictureParameterBufferH263 h263PictureParams = VAEncPictureParameterBufferH263();
93
94    LOG_V( "Begin\n\n");
95
96    // set picture params for HW
97    if(mAutoReference == false){
98        h263PictureParams.reference_picture = task->ref_surface;
99        h263PictureParams.reconstructed_picture = task->rec_surface;
100    }else {
101        h263PictureParams.reference_picture = mAutoRefSurfaces[0];
102        h263PictureParams.reconstructed_picture = mAutoRefSurfaces[1];
103    }
104
105    h263PictureParams.coded_buf = task->coded_buffer;
106    h263PictureParams.picture_width = mComParams.resolution.width;
107    h263PictureParams.picture_height = mComParams.resolution.height;
108    h263PictureParams.picture_type = (task->type == FTYPE_I) ? VAEncPictureTypeIntra : VAEncPictureTypePredictive;
109
110    LOG_V("======h263 picture params======\n");
111    LOG_V( "reference_picture = 0x%08x\n", h263PictureParams.reference_picture);
112    LOG_V( "reconstructed_picture = 0x%08x\n", h263PictureParams.reconstructed_picture);
113    LOG_V( "coded_buf = 0x%08x\n", h263PictureParams.coded_buf);
114//    LOG_I( "coded_buf_index = %d\n", mCodedBufIndex);
115    LOG_V( "picture_width = %d\n", h263PictureParams.picture_width);
116    LOG_V( "picture_height = %d\n",h263PictureParams.picture_height);
117    LOG_V( "picture_type = %d\n\n",h263PictureParams.picture_type);
118
119    vaStatus = vaCreateBuffer(
120            mVADisplay, mVAContext,
121            VAEncPictureParameterBufferType,
122            sizeof(h263PictureParams),
123            1,&h263PictureParams,
124            &mPicParamBuf);
125    CHECK_VA_STATUS_RETURN("vaCreateBuffer");
126
127    vaStatus = vaRenderPicture(mVADisplay, mVAContext, &mPicParamBuf , 1);
128    CHECK_VA_STATUS_RETURN("vaRenderPicture");
129
130    LOG_V( "end\n");
131    return ENCODE_SUCCESS;
132}
133
134Encode_Status VideoEncoderH263::renderSliceParams(EncodeTask *task) {
135
136    VAStatus vaStatus = VA_STATUS_SUCCESS;
137    uint32_t sliceHeight;
138    uint32_t sliceHeightInMB;
139
140    LOG_V("Begin\n\n");
141
142    sliceHeight = mComParams.resolution.height;
143    sliceHeight += 15;
144    sliceHeight &= (~15);
145    sliceHeightInMB = sliceHeight / 16;
146
147    vaStatus = vaCreateBuffer(
148            mVADisplay, mVAContext,
149            VAEncSliceParameterBufferType,
150            sizeof(VAEncSliceParameterBuffer),
151            1, NULL, &mSliceParamBuf);
152    CHECK_VA_STATUS_RETURN("vaCreateBuffer");
153
154    VAEncSliceParameterBuffer *sliceParams;
155    vaStatus = vaMapBuffer(mVADisplay, mSliceParamBuf, (void **)&sliceParams);
156    CHECK_VA_STATUS_RETURN("vaMapBuffer");
157
158    // starting MB row number for this slice
159    sliceParams->start_row_number = 0;
160    // slice height measured in MB
161    sliceParams->slice_height = sliceHeightInMB;
162    sliceParams->slice_flags.bits.is_intra = (task->type == FTYPE_I)?1:0;
163    sliceParams->slice_flags.bits.disable_deblocking_filter_idc = 0;
164
165    LOG_V("======h263 slice params======\n");
166    LOG_V("start_row_number = %d\n", (int) sliceParams->start_row_number);
167    LOG_V("slice_height_in_mb = %d\n", (int) sliceParams->slice_height);
168    LOG_V("slice.is_intra = %d\n", (int) sliceParams->slice_flags.bits.is_intra);
169
170    vaStatus = vaUnmapBuffer(mVADisplay, mSliceParamBuf);
171    CHECK_VA_STATUS_RETURN("vaUnmapBuffer");
172
173    vaStatus = vaRenderPicture(mVADisplay, mVAContext, &mSliceParamBuf, 1);
174    CHECK_VA_STATUS_RETURN("vaRenderPicture");
175
176    LOG_V("end\n");
177    return ENCODE_SUCCESS;
178}
179