[Mesa-dev] [PATCH 4/4] st/omx: initial OpenMAX H264 encoder v6

Emil Velikov emil.l.velikov at gmail.com
Tue Feb 11 12:10:46 PST 2014


On 11/02/14 19:30, Christian König wrote:
> Am 11.02.2014 19:56, schrieb Emil Velikov:
>> On 11/02/14 17:27, Christian König wrote:
>>> From: Christian König <christian.koenig at amd.com>
>>>
>>> v2 (chk): fix eos handling
>>> v3 (leo): implement scaling configuration support
>>> v4 (leo): fix bitrate bug
>>> v5 (chk): add workaround for bug in Bellagio
>>> v6 (chk): fix div by 0 if framerate isn't known,
>>>            user separate pipe object for scale and transfer,
>>>            always flush the transfer pipe before encoding
>>>
>> Hi Christian
>>
>> Not familiar with the API, so a rather naive question:
>>
>>   * If vid_enc_Constructor fails I'm assuming that vid_enc_Destructor
>> will be executed to clean-up the mess.
> 
> To be honest I couldn't confirm that so far. I just followed the example
> code from Bellagio. Going to double check that, better save than sorry.
> 
>>   * The following four functions have some massive switch statements,
>> possibly consider
>>   - Adding a idx to variable type map
>>   - Move checkHeader(param, map[idx]) before the switch
>>   - Finally drop the brakets in the case statements
> 
> Considered that as well, but that doesn't work the because common values
> for idx are 0x02000000-0x02000015,  0x03000000- 0x0300001a,
> 0x05000000-.... etc.
> 
I feared that was the case. Alternative could be struct foo* with a loop
that checks for the idx and returns the (variable) type.

Might be an over kill, depending on how much one likes big switch
statements.

>> [snip]
>>> +OMX_ERRORTYPE vid_enc_LoaderComponent(stLoaderComponentType *comp)
>>> +{
>> Better positioned goto statements will remove all of the conditionals in
>> the error path.
> 
> Good point going to change that.
> 
>> if (variable == NULL) and be rewritten as if (!variable), to be
>> consistent with the rest of the code.
> 
> That's coding style of the example code vs. mesa coding style. I've
> already changed the indention so yeah probably a good idea to change
> that as well.
> 
Noticed that the coding style differs slightly, and thanks for sticking
with my comments.

>>> +   /* component 1 - video encoder */
>>> +   comp->componentVersion.s.nVersionMajor = 0;
>>> +   comp->componentVersion.s.nVersionMinor = 0;
>>> +   comp->componentVersion.s.nRevision = 0;
>>> +   comp->componentVersion.s.nStep = 1;
>>> +   comp->name_specific_length = 1;
>>> +
>>> +   comp->name = CALLOC(1, OMX_MAX_STRINGNAME_SIZE);
>>> +   if (comp->name == NULL)
>>> +      goto error;
>>> +
>>> +   comp->name_specific = CALLOC(comp->name_specific_length,
>>> sizeof(char *));
>>> +   if (comp->name_specific == NULL)
>>> +      goto error;
>>> +
>>> +   comp->name_specific[0] = CALLOC(1, OMX_MAX_STRINGNAME_SIZE);
>>> +   if (comp->name_specific[0] == NULL)
>>> +      goto error;
>>> +
>>> +   comp->role_specific = CALLOC(comp->name_specific_length,
>>> sizeof(char *));
>>> +   if (comp->role_specific == NULL)
>>> +      goto error;
>>> +
>>> +   comp->role_specific[0] = CALLOC(1, OMX_MAX_STRINGNAME_SIZE);
>>> +   if (comp->role_specific[0] == NULL)
>>> +      goto error;
>>> +
>>> +   vid_enc_name(comp->name);
>>> +   vid_enc_name_avc(comp->name_specific[0]);
>>> +
>>> +   strcpy(comp->role_specific[0], OMX_VID_ENC_AVC_ROLE);
>>> +
>>> +   comp->constructor = vid_enc_Constructor;
>>> +
>>> +   return 2;
>>> +
>> Why do we return 2, as there is only one component (ie the encoder) ?
> 
> Looks like a bug to me. Probably just copy & paste from the decoder.
> 
Speaking of bugs, why does omx_component_library_Setup return 2
components when both vid_dec_LoaderComponent and vid_enc_LoaderComponent
return zero (OMX_ErrorNone).

AFAICS the API does not have a recommendation but I'm inclined to
believe that returning 0 should be the better solution. As one does give
the total number of components whenever stComponents == NULL.

Cheers
-Emil

>>> +
>>> +   for (i = 0; i < 2; ++i) {
>> Is is possible for a encoder to have more than two number of ports ?
>> Would it be worth adding a define ?
> 
> Nope, one input, one output. I can't come up with a good use for
> anything else.
> 
>>
>> [snip]
>>> +static OMX_ERRORTYPE vid_enc_AllocateOutBuffer(omx_base_PortType
>>> *port, OMX_INOUT OMX_BUFFERHEADERTYPE **buf,
>>> +                                               OMX_IN OMX_U32 idx,
>>> OMX_IN OMX_PTR private, OMX_IN OMX_U32 size)
>>> +{
>>> +   OMX_ERRORTYPE r;
>>> +
>>> +   r = base_port_AllocateBuffer(port, buf, idx, private, size);
>>> +   if (r)
>>> +      return r;
>>> +
>>> +   FREE((*buf)->pBuffer);
>>> +   (*buf)->pBuffer = NULL;
>>> +   (*buf)->pOutputPortPrivate = CALLOC(1, sizeof(struct
>>> output_buf_private));
>>> +
>> I know I'm rather pedantic but can we handle CALLOC failure, please.
> 
> Missed that one, going to change it.
> 
>>> +
>>> +   if (picture.rate_ctrl.rate_ctrl_method !=
>>> PIPE_H264_ENC_RATE_CONTROL_METHOD_DISABLE) {
>>> +      if (priv->bitrate.nTargetBitrate < OMX_VID_ENC_BITRATE_MIN)
>>> +         picture.rate_ctrl.target_bitrate = OMX_VID_ENC_BITRATE_MIN;
>>> +      else if (priv->bitrate.nTargetBitrate < OMX_VID_ENC_BITRATE_MAX)
>>> +         picture.rate_ctrl.target_bitrate =
>>> priv->bitrate.nTargetBitrate;
>>> +      else
>>> +         picture.rate_ctrl.target_bitrate = OMX_VID_ENC_BITRATE_MAX;
>>> +      picture.rate_ctrl.peak_bitrate =
>>> picture.rate_ctrl.target_bitrate;
>>> +      picture.rate_ctrl.frame_rate_den =
>>> OMX_VID_ENC_CONTROL_FRAME_RATE_DEN_DEFAULT;
>>> +      picture.rate_ctrl.frame_rate_num = ((priv->frame_rate) >> 16)
>>> * picture.rate_ctrl.frame_rate_den;
>>> +      if (picture.rate_ctrl.target_bitrate <
>>> OMX_VID_ENC_BITRATE_MEDIAN)
>>> +         picture.rate_ctrl.vbv_buffer_size =
>>> MIN2((picture.rate_ctrl.target_bitrate * 2.75),
>>> OMX_VID_ENC_BITRATE_MEDIAN);
>>> +      else
>>> +         picture.rate_ctrl.vbv_buffer_size =
>>> picture.rate_ctrl.target_bitrate;
>>> +
>>> +      if (picture.rate_ctrl.frame_rate_num) {
>>> +         unsigned long long t = picture.rate_ctrl.target_bitrate;
>>> +         t *= picture.rate_ctrl.frame_rate_den;
>>> +         picture.rate_ctrl.target_bits_picture = t /
>>> picture.rate_ctrl.frame_rate_num;
>>> +      } else {
>>> +         picture.rate_ctrl.target_bits_picture =
>>> picture.rate_ctrl.target_bitrate;
>>> +      }
>>> +      picture.rate_ctrl.peak_bits_picture_integer =
>>> picture.rate_ctrl.target_bits_picture;
>>> +      picture.rate_ctrl.peak_bits_picture_fraction = 0;
>> Use local variable to store picture.rate_ctrl, to ease the eyes ?
> 
> Good idea.
> 
> Thx for the review,
> Christian.
> 
>> Cheers
>> -Emil
>>
>> _______________________________________________
>> mesa-dev mailing list
>> mesa-dev at lists.freedesktop.org
>> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
> 



More information about the mesa-dev mailing list