[FFmpeg-devel] [PATCH 4/4] avcodec/mediacodecenc: add async mode support

Zhao Zhili quinkblack at foxmail.com
Wed Nov 27 09:42:34 EET 2024



> On Nov 27, 2024, at 14:37, Anton Khirnov <anton at khirnov.net> wrote:
> 
> Quoting Zhao Zhili (2024-11-06 13:31:34)
>> @@ -78,6 +80,17 @@ typedef struct MediaCodecEncContext {
>>     int extract_extradata;
>>     // Ref. MediaFormat KEY_OPERATING_RATE
>>     int operating_rate;
>> +    int async_mode;
>> +
>> +    AVMutex input_mutex;
>> +    AVCond input_cond;
>> +    AVFifo *input_index;
>> +
>> +    AVMutex output_mutex;
>> +    AVCond output_cond;
>> +    int encode_status;
>> +    AVFifo *output_index;
>> +    AVFifo *output_buf_info;
> 
> Those seem to always be written and read together, so why not merge them
> into one FIFO?

OK. Will add a struct to hold these two information.

> 
>> +static void on_input_available(FFAMediaCodec *codec, void *userdata,
>> +                               int32_t index)
>> +{
>> +    AVCodecContext *avctx = userdata;
>> +    MediaCodecEncContext *s = avctx->priv_data;
>> +
>> +    ff_mutex_lock(&s->input_mutex);
>> +
>> +    av_fifo_write(s->input_index, &index, 1);
> 
> The fifo is dynamic, so this can fail.

OK.

> 
>> +
>> +    ff_mutex_unlock(&s->input_mutex);
>> +    ff_cond_signal(&s->input_cond);
> 
> This looks wrong - you should signal while holding the mutex, otherwise
> the consumer may miss the signal. Same for the other two signalling
> sites.

How? The Linux Programming Interface 30.2.2:

We conclude with one final observation about the use of pthread_cond_signal()
(and pthread_cond_broadcast()). In the producer code shown earlier, we called
pthread_mutex_unlock(), and then called pthread_cond_signal(); that is, we first unlocked
the mutex associated with the shared variable, and then signaled the corresponding
condition variable. We could have reversed these two steps; SUSv3 permits them to
be done in either order.

> 
>> @@ -395,17 +569,62 @@ bailout:
>>     return ret;
>> }
>> 
>> +static int mediacodec_get_output_index(AVCodecContext *avctx, ssize_t *index,
>> +                                       FFAMediaCodecBufferInfo *out_info)
>> +{
>> +    MediaCodecEncContext *s = avctx->priv_data;
>> +    FFAMediaCodec *codec = s->codec;
>> +    int64_t timeout_us = s->eof_sent ? OUTPUT_DEQUEUE_TIMEOUT_US : 0;
>> +    int n;
>> +    int ret;
>> +
>> +    if (!s->async_mode) {
>> +        *index = ff_AMediaCodec_dequeueOutputBuffer(codec, out_info, timeout_us);
>> +        return 0;
>> +    }
>> +
>> +    ff_mutex_lock(&s->output_mutex);
>> +
>> +    n = -1;
>> +    while (n < 0 && !s->encode_status) {
>> +        if (av_fifo_can_read(s->output_index)) {
>> +            av_fifo_read(s->output_index, &n, 1);
>> +            av_fifo_read(s->output_buf_info, out_info, 1);
> 
> It's simpler and API-compliant to just call av_fifo_read() and check
> whether it failed.

OK.

> 
> -- 
> Anton Khirnov
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/ffmpeg-devel
> 
> To unsubscribe, visit link above, or email
> ffmpeg-devel-request at ffmpeg.org with subject "unsubscribe".



More information about the ffmpeg-devel mailing list