No subject

bogus at does.not.exist.com bogus at does.not.exist.com
Mon Jul 5 15:10:54 CEST 2010


committing, or you'll likely have conflicts during the review process
due to the frequent version bumps of libav*.

>  #define LIBAVCODEC_VERSION_INT  AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
>                                                 LIBAVCODEC_VERSION_MINOR, \
> @@ -964,6 +964,13 @@
>       * - decoding: Set by libavcodec\
>       */\
>      void *hwaccel_picture_private;\
> +\
> +    /**\
> +     * number of audio samples (per channel) described by this frame\
> +     * - encoding: Set by user.\
> +     * - decoding: Set by libavcodec.\
> +     */\
> +    int nb_samples;\
>  
>  
>  #define FF_QSCALE_TYPE_MPEG1 0
> @@ -3478,8 +3485,11 @@
>                           const uint8_t *buf, int buf_size);
>  #endif
>  

> +#if LIBAVCODEC_VERSION_MAJOR < 53

Define a symbol FF_API_AVCODEC_DECODE_AUDIO3 and use it like it's done
for the other FF_API_* symbols, this will help to test regressions.

>  /**
>   * Decode the audio frame of size avpkt->size from avpkt->data into samples.
> + * Wrapper function which calls avcodec_decode_audio4.
> + *
>   * Some decoders may support multiple frames in a single AVPacket, such
>   * decoders would then just decode the first frame. In this case,
>   * avcodec_decode_audio3 has to be called again with an AVPacket that contains
> @@ -3520,7 +3530,58 @@
>  int avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
>                           int *frame_size_ptr,
>                           AVPacket *avpkt);
> +#endif
>  
> +/**
> + * Decode the audio frame of size avpkt->size from avpkt->data into frame.
> + *
> + * Some decoders may support multiple frames in a single AVPacket. Such
> + * decoders would then just decode the first frame. In this case,
> + * avcodec_decode_audio4 has to be called again with an AVPacket containing
> + * the remaining data in order to decode the second frame, etc...
> + * If no frame could be output, got_frame_ptr is set to zero.
> + *
> + * @warning The input buffer, avpkt->data must be FF_INPUT_BUFFER_PADDING_SIZE
> + * larger than the actual read bytes because some optimized bitstream readers
> + * read 32 or 64 bits at once and could read over the end.
> + *
> + * @warning The end of the input buffer, avpkt->data, should be set to 0 to
> + * ensure that no overreading happens for damaged streams.
> + *
> + * @note You might have to align the input buffer, avpkt->data, and output
> + * buffer, frame->data[0].  The alignment requirements depend on the CPU: On
> + * some CPUs it isn't necessary at all, on others it won't work at all if not
> + * aligned and on others it will work but it will have an impact on performance.
> + *
> + * avpkt->data should have 4 byte alignment at minimum and frame->data[0]
> + * should be 16-byte-aligned unless the CPU doesn't need it (AltiVec and SSE do).
> + * The default get_buffer() function aligns the output buffer properly, but if
> + * the user overrides get_buffer() then alignment considerations should be
> + * taken into account.
> + *
> + * @param avctx the codec context
> + * @param[out] frame The AVFrame in which to store decoded audio samples.
> + *             Use avcodec_alloc_frame to get an AVFrame, the codec will

The use of parenthesis in avcodec_alloc_frame() helps to understand
that the symbol is a function.

> + *             allocate memory for the actual sample buffer.
> + *             With default get/release_buffer(), the decoder frees/reuses the
> + *                 sample buffer as it sees fit.
> + *             With overridden get/release_buffer() (needs CODEC_CAP_DR1) the
> + *                 user decides into what buffer the decoder decodes and the
> + *                 decoder tells the user once it does not need the data anymore,
> + *                 at which point the user app can free/reuse/keep the memory
> + *                 as it sees fit.
> + * @param[out] got_frame_ptr Zero if no frame could be decoded.  Otherwise, it is nonzero.
> + * @param[in] avpkt The input AVPacket containing the input buffer.
> + *            You can create such packet with av_init_packet() and then setting
> + *            data and size. Some decoders might also require additional fields
> + *            to be set. All decoders are designed to use as few fields as
> + *            possible though.

> + * @return On error a negative value is returned, otherwise the number of bytes
> + *         consumed from the input AVPacket.

Since this is not a complete sentence, don't capitalize and don't put
a final dot at the end.

> + */
> +int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame,
> +                          int *got_frame_ptr, AVPacket *avpkt);
> +
>  #if LIBAVCODEC_VERSION_MAJOR < 53
>  /**
>   * Decode a video frame from buf into picture.
> Index: libavcodec/utils.c
> ===================================================================
> --- libavcodec/utils.c	(revision 25266)
> +++ libavcodec/utils.c	(working copy)
> @@ -114,6 +114,9 @@
>      int linesize[4];
>      int width, height;
>      enum PixelFormat pix_fmt;
> +    int channels;
> +    int nb_samples;
> +    enum SampleFormat sample_fmt;
>  }InternalBuffer;
>  
>  #define INTERNAL_BUFFER_SIZE 32
> @@ -223,6 +226,7 @@
>      int i;
>      int w= s->width;
>      int h= s->height;
> +    int is_video = (s->codec_type == AVMEDIA_TYPE_VIDEO);

Maybe this should be changed to type (separate patch of course), will
help when will change this again for supporting text frames.

>      InternalBuffer *buf;
>      int *picture_number;
>  
> @@ -235,7 +239,7 @@
>          return -1;
>      }
>  
> -    if(av_image_check_size(w, h, 0, s))
> +    if (is_video && av_image_check_size(w, h, 0, s))
>          return -1;
>  
>      if(s->internal_buffer==NULL){
> @@ -253,7 +257,13 @@
>      picture_number= &(((InternalBuffer*)s->internal_buffer)[INTERNAL_BUFFER_SIZE]).last_pic_num; //FIXME ugly hack
>      (*picture_number)++;
>  
> -    if(buf->base[0] && (buf->width != w || buf->height != h || buf->pix_fmt != s->pix_fmt)){
> +    if (buf->base[0] &&
> +        (is_video  && (buf->width   != w ||
> +                       buf->height  != h ||
> +                       buf->pix_fmt != s->pix_fmt)) ||
> +        (!is_video && (buf->channels != s->channels       ||
> +                       buf->nb_samples != pic->nb_samples ||
> +                       buf->sample_fmt != s->sample_fmt))) {
>          for(i=0; i<4; i++){
>              av_freep(&buf->base[i]);
>              buf->data[i]= NULL;
> @@ -264,6 +274,7 @@
>          pic->age= *picture_number - buf->last_pic_num;
>          buf->last_pic_num= *picture_number;
>      }else{
> +        if (is_video) {
>          int h_chroma_shift, v_chroma_shift;
>          int size[4] = {0};
>          int tmpsize;
> @@ -326,6 +337,23 @@
>          buf->width  = s->width;
>          buf->height = s->height;
>          buf->pix_fmt= s->pix_fmt;
> +        } else { /* audio */
> +            int buf_size;
> +

> +            buf->last_pic_num = -256*256*256*64;

please explain with a comment why this weird value (isn't this -INT_MAX?)

> +            buf_size = pic->nb_samples * s->channels *
> +                       (av_get_bits_per_sample_format(s->sample_fmt) / 8);
> +
> +            buf->base[0] = buf->data[0] = av_mallocz(buf_size);
> +            if (!buf->base[0])
> +                return AVERROR(ENOMEM);
> +
> +            buf->data[0]    = buf->base[0];
> +            buf->channels   = s->channels;
> +            buf->nb_samples = pic->nb_samples;
> +            buf->sample_fmt = s->sample_fmt;
> +        }
>          pic->age= 256*256*256*64;

same as before

>      }
>      pic->type= FF_BUFFER_TYPE_INTERNAL;
> @@ -401,9 +429,14 @@
>      /* Allocate new frame */
>      if (s->get_buffer(s, pic))
>          return -1;
> -    /* Copy image data from old buffer to new buffer */
> +    /* Copy frame data from old buffer to new buffer */
> +    if (s->codec_type == AVMEDIA_TYPE_VIDEO) {
>      av_picture_copy((AVPicture*)pic, (AVPicture*)&temp_pic, s->pix_fmt, s->width,
>               s->height);
> +    } else if (s->codec_type == AVMEDIA_TYPE_AUDIO) {
> +        memcpy(pic->data[0], temp_pic.data[0], s->channels * pic->nb_samples *
> +               (av_get_bits_per_sample_format(s->sample_fmt) / 8));
> +    }
>      s->release_buffer(s, &temp_pic); // Release old frame
>      return 0;
>  }
> @@ -644,29 +677,49 @@
>  }
>  #endif
>  
> +#if LIBAVCODEC_VERSION_MAJOR < 53
>  int attribute_align_arg avcodec_decode_audio3(AVCodecContext *avctx, int16_t *samples,
>                           int *frame_size_ptr,
>                           AVPacket *avpkt)
>  {
> +    AVFrame frame;
> +    int ret, got_frame = 0;
> +
> +    avcodec_get_frame_defaults(&frame);
> +
> +    ret = avcodec_decode_audio4(avctx, &frame, &got_frame, avpkt);
> +
> +    if (ret >= 0 && got_frame) {
> +        *frame_size_ptr = frame.nb_samples * avctx->channels *
> +                          (av_get_bits_per_sample_format(avctx->sample_fmt) / 8);
> +
> +        /* ensure data will fit in the output buffer */

> +        if (*frame_size_ptr > AVCODEC_MAX_AUDIO_FRAME_SIZE) {
> +            av_log(avctx, AV_LOG_WARNING, "avcodec_decode_audio3 samples "
> +                   "truncated to AVCODEC_MAX_AUDIO_FRAME_SIZE\n");

Nit: the string it's better put on a single line, like:
            av_log(avctx, AV_LOG_WARNING,
                   "avcodec_decode_audio3 samples truncated to AVCODEC_MAX_AUDIO_FRAME_SIZE\n");

[...]

Thanks for the great work!

Regards.
-- 
FFmpeg = Friendly Furious Merciless Purposeless Exxagerate Gadget



More information about the ffmpeg-devel mailing list