1bf215546Sopenharmony_ci/**************************************************************************
2bf215546Sopenharmony_ci *
3bf215546Sopenharmony_ci * Copyright 2013 Advanced Micro Devices, Inc.
4bf215546Sopenharmony_ci * All Rights Reserved.
5bf215546Sopenharmony_ci *
6bf215546Sopenharmony_ci * Permission is hereby granted, free of charge, to any person obtaining a
7bf215546Sopenharmony_ci * copy of this software and associated documentation files (the
8bf215546Sopenharmony_ci * "Software"), to deal in the Software without restriction, including
9bf215546Sopenharmony_ci * without limitation the rights to use, copy, modify, merge, publish,
10bf215546Sopenharmony_ci * distribute, sub license, and/or sell copies of the Software, and to
11bf215546Sopenharmony_ci * permit persons to whom the Software is furnished to do so, subject to
12bf215546Sopenharmony_ci * the following conditions:
13bf215546Sopenharmony_ci *
14bf215546Sopenharmony_ci * The above copyright notice and this permission notice (including the
15bf215546Sopenharmony_ci * next paragraph) shall be included in all copies or substantial portions
16bf215546Sopenharmony_ci * of the Software.
17bf215546Sopenharmony_ci *
18bf215546Sopenharmony_ci * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19bf215546Sopenharmony_ci * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20bf215546Sopenharmony_ci * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
21bf215546Sopenharmony_ci * IN NO EVENT SHALL THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR
22bf215546Sopenharmony_ci * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23bf215546Sopenharmony_ci * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24bf215546Sopenharmony_ci * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
25bf215546Sopenharmony_ci *
26bf215546Sopenharmony_ci **************************************************************************/
27bf215546Sopenharmony_ci
28bf215546Sopenharmony_ci#include "pipe/p_video_codec.h"
29bf215546Sopenharmony_ci#include "radeon_vce.h"
30bf215546Sopenharmony_ci#include "radeon_video.h"
31bf215546Sopenharmony_ci#include "si_pipe.h"
32bf215546Sopenharmony_ci#include "util/u_memory.h"
33bf215546Sopenharmony_ci#include "util/u_video.h"
34bf215546Sopenharmony_ci#include "vl/vl_video_buffer.h"
35bf215546Sopenharmony_ci
36bf215546Sopenharmony_ci#include <stdio.h>
37bf215546Sopenharmony_ci
38bf215546Sopenharmony_cistatic void rate_control(struct rvce_encoder *enc)
39bf215546Sopenharmony_ci{
40bf215546Sopenharmony_ci   RVCE_BEGIN(0x04000005);                                 // rate control
41bf215546Sopenharmony_ci   RVCE_CS(enc->pic.rate_ctrl[0].rate_ctrl_method);           // encRateControlMethod
42bf215546Sopenharmony_ci   RVCE_CS(enc->pic.rate_ctrl[0].target_bitrate);             // encRateControlTargetBitRate
43bf215546Sopenharmony_ci   RVCE_CS(enc->pic.rate_ctrl[0].peak_bitrate);               // encRateControlPeakBitRate
44bf215546Sopenharmony_ci   RVCE_CS(enc->pic.rate_ctrl[0].frame_rate_num);             // encRateControlFrameRateNum
45bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                                    // encGOPSize
46bf215546Sopenharmony_ci   RVCE_CS(enc->pic.quant_i_frames);                       // encQP_I
47bf215546Sopenharmony_ci   RVCE_CS(enc->pic.quant_p_frames);                       // encQP_P
48bf215546Sopenharmony_ci   RVCE_CS(enc->pic.quant_b_frames);                       // encQP_B
49bf215546Sopenharmony_ci   RVCE_CS(enc->pic.rate_ctrl[0].vbv_buffer_size);            // encVBVBufferSize
50bf215546Sopenharmony_ci   RVCE_CS(enc->pic.rate_ctrl[0].frame_rate_den);             // encRateControlFrameRateDen
51bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                                    // encVBVBufferLevel
52bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                                    // encMaxAUSize
53bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                                    // encQPInitialMode
54bf215546Sopenharmony_ci   RVCE_CS(enc->pic.rate_ctrl[0].target_bits_picture);        // encTargetBitsPerPicture
55bf215546Sopenharmony_ci   RVCE_CS(enc->pic.rate_ctrl[0].peak_bits_picture_integer);  // encPeakBitsPerPictureInteger
56bf215546Sopenharmony_ci   RVCE_CS(enc->pic.rate_ctrl[0].peak_bits_picture_fraction); // encPeakBitsPerPictureFractional
57bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                                    // encMinQP
58bf215546Sopenharmony_ci   RVCE_CS(0x00000033);                                    // encMaxQP
59bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                                    // encSkipFrameEnable
60bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                                    // encFillerDataEnable
61bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                                    // encEnforceHRD
62bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                                    // encBPicsDeltaQP
63bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                                    // encReferenceBPicsDeltaQP
64bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                                    // encRateControlReInitDisable
65bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                                    // encLCVBRInitQPFlag
66bf215546Sopenharmony_ci   RVCE_CS(0x00000000); // encLCVBRSATDBasedNonlinearBitBudgetFlag
67bf215546Sopenharmony_ci   RVCE_END();
68bf215546Sopenharmony_ci}
69bf215546Sopenharmony_ci
70bf215546Sopenharmony_cistatic void encode(struct rvce_encoder *enc)
71bf215546Sopenharmony_ci{
72bf215546Sopenharmony_ci   signed luma_offset, chroma_offset, bs_offset;
73bf215546Sopenharmony_ci   unsigned dep, bs_idx = enc->bs_idx++;
74bf215546Sopenharmony_ci   int i;
75bf215546Sopenharmony_ci
76bf215546Sopenharmony_ci   if (enc->dual_inst) {
77bf215546Sopenharmony_ci      if (bs_idx == 0)
78bf215546Sopenharmony_ci         dep = 1;
79bf215546Sopenharmony_ci      else if (enc->pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR)
80bf215546Sopenharmony_ci         dep = 0;
81bf215546Sopenharmony_ci      else
82bf215546Sopenharmony_ci         dep = 2;
83bf215546Sopenharmony_ci   } else
84bf215546Sopenharmony_ci      dep = 0;
85bf215546Sopenharmony_ci
86bf215546Sopenharmony_ci   enc->task_info(enc, 0x00000003, dep, 0, bs_idx);
87bf215546Sopenharmony_ci
88bf215546Sopenharmony_ci   RVCE_BEGIN(0x05000001);                                      // context buffer
89bf215546Sopenharmony_ci   RVCE_READWRITE(enc->cpb.res->buf, enc->cpb.res->domains, 0); // encodeContextAddressHi/Lo
90bf215546Sopenharmony_ci   RVCE_END();
91bf215546Sopenharmony_ci
92bf215546Sopenharmony_ci   bs_offset = -(signed)(bs_idx * enc->bs_size);
93bf215546Sopenharmony_ci
94bf215546Sopenharmony_ci   RVCE_BEGIN(0x05000004);                                   // video bitstream buffer
95bf215546Sopenharmony_ci   RVCE_WRITE(enc->bs_handle, RADEON_DOMAIN_GTT, bs_offset); // videoBitstreamRingAddressHi/Lo
96bf215546Sopenharmony_ci   RVCE_CS(enc->bs_size);                                    // videoBitstreamRingSize
97bf215546Sopenharmony_ci   RVCE_END();
98bf215546Sopenharmony_ci
99bf215546Sopenharmony_ci   if (enc->dual_pipe) {
100bf215546Sopenharmony_ci      unsigned aux_offset =
101bf215546Sopenharmony_ci         enc->cpb.res->buf->size - RVCE_MAX_AUX_BUFFER_NUM * RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE * 2;
102bf215546Sopenharmony_ci      RVCE_BEGIN(0x05000002); // auxiliary buffer
103bf215546Sopenharmony_ci      for (i = 0; i < 8; ++i) {
104bf215546Sopenharmony_ci         RVCE_CS(aux_offset);
105bf215546Sopenharmony_ci         aux_offset += RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE;
106bf215546Sopenharmony_ci      }
107bf215546Sopenharmony_ci      for (i = 0; i < 8; ++i)
108bf215546Sopenharmony_ci         RVCE_CS(RVCE_MAX_BITSTREAM_OUTPUT_ROW_SIZE);
109bf215546Sopenharmony_ci      RVCE_END();
110bf215546Sopenharmony_ci   }
111bf215546Sopenharmony_ci
112bf215546Sopenharmony_ci   RVCE_BEGIN(0x03000001);                   // encode
113bf215546Sopenharmony_ci   RVCE_CS(enc->pic.frame_num ? 0x0 : 0x11); // insertHeaders
114bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                      // pictureStructure
115bf215546Sopenharmony_ci   RVCE_CS(enc->bs_size);                    // allowedMaxBitstreamSize
116bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                      // forceRefreshMap
117bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                      // insertAUD
118bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                      // endOfSequence
119bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                      // endOfStream
120bf215546Sopenharmony_ci   RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM,
121bf215546Sopenharmony_ci             (uint64_t)enc->luma->u.legacy.level[0].offset_256B * 256); // inputPictureLumaAddressHi/Lo
122bf215546Sopenharmony_ci   RVCE_READ(enc->handle, RADEON_DOMAIN_VRAM,
123bf215546Sopenharmony_ci             (uint64_t)enc->chroma->u.legacy.level[0].offset_256B * 256);              // inputPictureChromaAddressHi/Lo
124bf215546Sopenharmony_ci   RVCE_CS(align(enc->luma->u.legacy.level[0].nblk_y, 16));       // encInputFrameYPitch
125bf215546Sopenharmony_ci   RVCE_CS(enc->luma->u.legacy.level[0].nblk_x * enc->luma->bpe); // encInputPicLumaPitch
126bf215546Sopenharmony_ci   RVCE_CS(enc->chroma->u.legacy.level[0].nblk_x * enc->chroma->bpe); // encInputPicChromaPitch
127bf215546Sopenharmony_ci   if (enc->dual_pipe)
128bf215546Sopenharmony_ci      RVCE_CS(0x00000000); // encInputPic(Addr|Array)Mode,encDisable(TwoPipeMode|MBOffloading)
129bf215546Sopenharmony_ci   else
130bf215546Sopenharmony_ci      RVCE_CS(0x00010000); // encInputPic(Addr|Array)Mode,encDisable(TwoPipeMode|MBOffloading)
131bf215546Sopenharmony_ci   RVCE_CS(0x00000000);    // encInputPicTileConfig
132bf215546Sopenharmony_ci   RVCE_CS(enc->pic.picture_type);                                   // encPicType
133bf215546Sopenharmony_ci   RVCE_CS(enc->pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_IDR);// encIdrFlag
134bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                                              // encIdrPicId
135bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                                              // encMGSKeyPic
136bf215546Sopenharmony_ci   RVCE_CS(!enc->pic.not_referenced);                                // encReferenceFlag
137bf215546Sopenharmony_ci   RVCE_CS(0x00000000);                                              // encTemporalLayerIndex
138bf215546Sopenharmony_ci   RVCE_CS(0x00000000); // num_ref_idx_active_override_flag
139bf215546Sopenharmony_ci   RVCE_CS(0x00000000); // num_ref_idx_l0_active_minus1
140bf215546Sopenharmony_ci   RVCE_CS(0x00000000); // num_ref_idx_l1_active_minus1
141bf215546Sopenharmony_ci
142bf215546Sopenharmony_ci   i = enc->pic.frame_num - enc->pic.ref_idx_l0_list[0];
143bf215546Sopenharmony_ci   if (i > 1 && enc->pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_P) {
144bf215546Sopenharmony_ci      RVCE_CS(0x00000001); // encRefListModificationOp
145bf215546Sopenharmony_ci      RVCE_CS(i - 1);      // encRefListModificationNum
146bf215546Sopenharmony_ci   } else {
147bf215546Sopenharmony_ci      RVCE_CS(0x00000000); // encRefListModificationOp
148bf215546Sopenharmony_ci      RVCE_CS(0x00000000); // encRefListModificationNum
149bf215546Sopenharmony_ci   }
150bf215546Sopenharmony_ci
151bf215546Sopenharmony_ci   for (i = 0; i < 3; ++i) {
152bf215546Sopenharmony_ci      RVCE_CS(0x00000000); // encRefListModificationOp
153bf215546Sopenharmony_ci      RVCE_CS(0x00000000); // encRefListModificationNum
154bf215546Sopenharmony_ci   }
155bf215546Sopenharmony_ci   for (i = 0; i < 4; ++i) {
156bf215546Sopenharmony_ci      RVCE_CS(0x00000000); // encDecodedPictureMarkingOp
157bf215546Sopenharmony_ci      RVCE_CS(0x00000000); // encDecodedPictureMarkingNum
158bf215546Sopenharmony_ci      RVCE_CS(0x00000000); // encDecodedPictureMarkingIdx
159bf215546Sopenharmony_ci      RVCE_CS(0x00000000); // encDecodedRefBasePictureMarkingOp
160bf215546Sopenharmony_ci      RVCE_CS(0x00000000); // encDecodedRefBasePictureMarkingNum
161bf215546Sopenharmony_ci   }
162bf215546Sopenharmony_ci
163bf215546Sopenharmony_ci   // encReferencePictureL0[0]
164bf215546Sopenharmony_ci   RVCE_CS(0x00000000); // pictureStructure
165bf215546Sopenharmony_ci   if (enc->pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_P ||
166bf215546Sopenharmony_ci       enc->pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_B) {
167bf215546Sopenharmony_ci      struct rvce_cpb_slot *l0 = si_l0_slot(enc);
168bf215546Sopenharmony_ci      si_vce_frame_offset(enc, l0, &luma_offset, &chroma_offset);
169bf215546Sopenharmony_ci      RVCE_CS(l0->picture_type);  // encPicType
170bf215546Sopenharmony_ci      RVCE_CS(l0->frame_num);     // frameNumber
171bf215546Sopenharmony_ci      RVCE_CS(l0->pic_order_cnt); // pictureOrderCount
172bf215546Sopenharmony_ci      RVCE_CS(luma_offset);       // lumaOffset
173bf215546Sopenharmony_ci      RVCE_CS(chroma_offset);     // chromaOffset
174bf215546Sopenharmony_ci   } else {
175bf215546Sopenharmony_ci      RVCE_CS(0x00000000); // encPicType
176bf215546Sopenharmony_ci      RVCE_CS(0x00000000); // frameNumber
177bf215546Sopenharmony_ci      RVCE_CS(0x00000000); // pictureOrderCount
178bf215546Sopenharmony_ci      RVCE_CS(0xffffffff); // lumaOffset
179bf215546Sopenharmony_ci      RVCE_CS(0xffffffff); // chromaOffset
180bf215546Sopenharmony_ci   }
181bf215546Sopenharmony_ci
182bf215546Sopenharmony_ci   // encReferencePictureL0[1]
183bf215546Sopenharmony_ci   RVCE_CS(0x00000000); // pictureStructure
184bf215546Sopenharmony_ci   RVCE_CS(0x00000000); // encPicType
185bf215546Sopenharmony_ci   RVCE_CS(0x00000000); // frameNumber
186bf215546Sopenharmony_ci   RVCE_CS(0x00000000); // pictureOrderCount
187bf215546Sopenharmony_ci   RVCE_CS(0xffffffff); // lumaOffset
188bf215546Sopenharmony_ci   RVCE_CS(0xffffffff); // chromaOffset
189bf215546Sopenharmony_ci
190bf215546Sopenharmony_ci   // encReferencePictureL1[0]
191bf215546Sopenharmony_ci   RVCE_CS(0x00000000); // pictureStructure
192bf215546Sopenharmony_ci   if (enc->pic.picture_type == PIPE_H2645_ENC_PICTURE_TYPE_B) {
193bf215546Sopenharmony_ci      struct rvce_cpb_slot *l1 = si_l1_slot(enc);
194bf215546Sopenharmony_ci      si_vce_frame_offset(enc, l1, &luma_offset, &chroma_offset);
195bf215546Sopenharmony_ci      RVCE_CS(l1->picture_type);  // encPicType
196bf215546Sopenharmony_ci      RVCE_CS(l1->frame_num);     // frameNumber
197bf215546Sopenharmony_ci      RVCE_CS(l1->pic_order_cnt); // pictureOrderCount
198bf215546Sopenharmony_ci      RVCE_CS(luma_offset);       // lumaOffset
199bf215546Sopenharmony_ci      RVCE_CS(chroma_offset);     // chromaOffset
200bf215546Sopenharmony_ci   } else {
201bf215546Sopenharmony_ci      RVCE_CS(0x00000000); // encPicType
202bf215546Sopenharmony_ci      RVCE_CS(0x00000000); // frameNumber
203bf215546Sopenharmony_ci      RVCE_CS(0x00000000); // pictureOrderCount
204bf215546Sopenharmony_ci      RVCE_CS(0xffffffff); // lumaOffset
205bf215546Sopenharmony_ci      RVCE_CS(0xffffffff); // chromaOffset
206bf215546Sopenharmony_ci   }
207bf215546Sopenharmony_ci
208bf215546Sopenharmony_ci   si_vce_frame_offset(enc, si_current_slot(enc), &luma_offset, &chroma_offset);
209bf215546Sopenharmony_ci   RVCE_CS(luma_offset);            // encReconstructedLumaOffset
210bf215546Sopenharmony_ci   RVCE_CS(chroma_offset);          // encReconstructedChromaOffset
211bf215546Sopenharmony_ci   RVCE_CS(0x00000000);             // encColocBufferOffset
212bf215546Sopenharmony_ci   RVCE_CS(0x00000000);             // encReconstructedRefBasePictureLumaOffset
213bf215546Sopenharmony_ci   RVCE_CS(0x00000000);             // encReconstructedRefBasePictureChromaOffset
214bf215546Sopenharmony_ci   RVCE_CS(0x00000000);             // encReferenceRefBasePictureLumaOffset
215bf215546Sopenharmony_ci   RVCE_CS(0x00000000);             // encReferenceRefBasePictureChromaOffset
216bf215546Sopenharmony_ci   RVCE_CS(0x00000000);             // pictureCount
217bf215546Sopenharmony_ci   RVCE_CS(enc->pic.frame_num);     // frameNumber
218bf215546Sopenharmony_ci   RVCE_CS(enc->pic.pic_order_cnt); // pictureOrderCount
219bf215546Sopenharmony_ci   RVCE_CS(0x00000000);             // numIPicRemainInRCGOP
220bf215546Sopenharmony_ci   RVCE_CS(0x00000000);             // numPPicRemainInRCGOP
221bf215546Sopenharmony_ci   RVCE_CS(0x00000000);             // numBPicRemainInRCGOP
222bf215546Sopenharmony_ci   RVCE_CS(0x00000000);             // numIRPicRemainInRCGOP
223bf215546Sopenharmony_ci   RVCE_CS(0x00000000);             // enableIntraRefresh
224bf215546Sopenharmony_ci   RVCE_END();
225bf215546Sopenharmony_ci}
226bf215546Sopenharmony_ci
227bf215546Sopenharmony_civoid si_vce_50_get_param(struct rvce_encoder *enc, struct pipe_h264_enc_picture_desc *pic)
228bf215546Sopenharmony_ci{
229bf215546Sopenharmony_ci}
230bf215546Sopenharmony_ci
231bf215546Sopenharmony_civoid si_vce_50_init(struct rvce_encoder *enc)
232bf215546Sopenharmony_ci{
233bf215546Sopenharmony_ci   si_vce_40_2_2_init(enc);
234bf215546Sopenharmony_ci
235bf215546Sopenharmony_ci   /* only the two below are different */
236bf215546Sopenharmony_ci   enc->rate_control = rate_control;
237bf215546Sopenharmony_ci   enc->encode = encode;
238bf215546Sopenharmony_ci   enc->si_get_pic_param = si_vce_50_get_param;
239bf215546Sopenharmony_ci}
240