On 05/05/13 21:40, Gonzalo Garramuno wrote:
On 03/05/13 01:30, Kalileo wrote:
If you decode aac, then you might get hit by the change to planar format, which happened November 16, 2012 in the ffmpeg sources (although the effect is usually not a 'frying pan noise').
_______________________________________________

The change happened between ffmpeg-1.0.6 (which works fine) and ffmpeg-1.1.4 (which does not).

Alternatively, can anyone show me the smallest piece of code that they use for avcodec_decode_audio4.
Here is my code:

int CMedia::decode_audio3(AVCodecContext *avctx, int16_t *samples,
              int *frame_size_ptr,
              AVPacket *avpkt)
{
   AVFrame frame = { { 0 } };
   int ret, got_frame = 0;

   if (avctx->get_buffer != avcodec_default_get_buffer) {
      avctx->get_buffer = avcodec_default_get_buffer;
      avctx->release_buffer = avcodec_default_release_buffer;
   }

    ret = avcodec_decode_audio4(avctx, &frame, &got_frame, avpkt);

    if (ret >= 0 && got_frame) {
        int ch, plane_size;
        int planar = av_sample_fmt_is_planar(avctx->sample_fmt);
int data_size = av_samples_get_buffer_size(&plane_size, avctx->channels,
frame.nb_samples,
avctx->sample_fmt, 1);
        if (*frame_size_ptr < data_size) {
       IMG_ERROR( "decode_audio3 - Output buffer size is too small for "
              "the current frame ("
              << *frame_size_ptr << " < " << data_size << ")" );
       return AVERROR(EINVAL);
        }

        memcpy(samples, frame.extended_data[0], plane_size);

    if (planar && avctx->channels > 1) {
            uint8_t *out = ((uint8_t *)samples) + plane_size;
            for (ch = 1; ch < avctx->channels; ch++) {
                memcpy(out, frame.extended_data[ch], plane_size);
                out += plane_size;
            }
        }


        *frame_size_ptr = data_size;
    } else {
        *frame_size_ptr = 0;
    }
    return ret;
}

/**
 * Given an audio packet, decode it
 *
 * @param ptsframe  returned frame we decoded
 * @param frame     frame we expect
 * @param pkt       packet to decode
 *
 * @return status whether frame was decoded correctly or not.
 */
CMedia::DecodeStatus
CMedia::decode_audio_packet( boost::int64_t& ptsframe,
                 const boost::int64_t frame,
                 const AVPacket& pkt )
  AVStream* stream = get_audio_stream();
  if ( !stream ) return kDecodeNoStream;

  // Get the audio codec context
  AVCodecContext* ctx = stream->codec;


  assert( !_audio_packets.is_seek( pkt ) );
  assert( !_audio_packets.is_flush( pkt ) );
  assert( !_audio_packets.is_preroll( pkt ) );
  assert( !_audio_packets.is_loop_end( pkt ) );
  assert( !_audio_packets.is_loop_start( pkt ) );

  ptsframe = get_frame( stream, pkt );

  // Make sure audio frames are continous during playback to
  // accomodate weird sample rates not evenly divisable by frame rate
  if ( _audio_buf_used != 0 && (!_audio.empty()) )
    {
       ptsframe = _audio_last_frame + 1;
      // assert( ptsframe <= last_frame() );
    }



#ifdef DEBUG
  if ( _audio_buf_used + pkt.size >= _audio_max )
    {
      IMG_ERROR( _("Too much audio used:") << _audio_buf_used  );
    }
#endif

  AVPacket pkt_temp;
  av_init_packet(&pkt_temp);
  pkt_temp.data = pkt.data;
  pkt_temp.size = pkt.size;



  assert( pkt.data != NULL );
  assert( _audio_buf != NULL );
  assert( pkt.size + _audio_buf_used < _audio_max );

  int audio_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;  //< correct
  assert( pkt_temp.size <= audio_size );

  while ( pkt_temp.size > 0 )
    {
       // Decode the audio into the buffer
       assert( _audio_buf_used + pkt_temp.size <= _audio_max );
       assert( pkt_temp.data != NULL );
       assert( _audio_buf_used % 16 == 0 );
       assert( audio_size > 0 );
       int ret = decode_audio3( ctx,
                ( int16_t * )( (char*)_audio_buf +
                           _audio_buf_used ),
                &audio_size, &pkt_temp );

      // If no samples are returned, then break now
      if ( ret <= 0 )
    {
       pkt_temp.size = 0;
       IMG_ERROR( _("Audio missed for frame: ") << ptsframe
              << _(" ret: ") << ret
              << _(" audio max: ")  << _audio_max
              << _(" audio used: ") << _audio_buf_used
               );

      return kDecodeMissingSamples;
    }


      assert( audio_size > 0 );
      assert( ret <= pkt_temp.size );
      assert( ret > 0 );
      assert( audio_size + _audio_buf_used <= _audio_max );

      // Decrement the length by the number of bytes parsed
      pkt_temp.data += ret;
      pkt_temp.size -= ret;

      if ( audio_size <= 0 ) continue;

      _audio_buf_used += audio_size;
    }

  if ( pkt_temp.size == 0 ) return kDecodeOK;

  IMG_ERROR( _("decode_audio - missed decoding some samples") );

  return kDecodeMissingSamples;
}
_______________________________________________
Libav-user mailing list
Libav-user@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/libav-user

Reply via email to