[FFmpeg-trac] #4874(undetermined:new): AAC decoder frame->nb_samples & frame->channels is wrong at get_buffer2
FFmpeg
trac at avcodec.org
Wed Sep 23 09:53:23 CEST 2015
#4874: AAC decoder frame->nb_samples & frame->channels is wrong at get_buffer2
-------------------------------------+-------------------------------------
Reporter: zylthinking | Owner:
Type: defect | Status: new
Priority: normal | Component:
Version: git-master | undetermined
Keywords: aac | Resolution:
Blocking: | Blocked By:
Analyzed by developer: 0 | Reproduced by developer: 0
-------------------------------------+-------------------------------------
Comment (by zylthinking):
Replying to [comment:3 cehoyos]:
Ok, the code:
{{{
static void ffmpeg_frame_put(void* opaque, uint8_t* data)
{
(void) data;
struct my_buffer* mbuf = (struct my_buffer *) opaque;
mbuf->mop->free(mbuf);
}
static int frame_buffer_get(struct AVCodecContext* s, AVFrame* frame, int
flags)
{
my_assert(frame->format == AV_SAMPLE_FMT_FLTP);
audio_format* fmt = (audio_format *) s->opaque;
mark("frame->channels = %d, frame->nb_samples = %d\n",
frame->channels, frame->nb_samples);
// I know I should not set these, just testing...
// in he-aac, need the line below
// in lc-aac, must not
frame->nb_samples /= 2;
// the frame->channels changes in the first call and the next calls
// set it with my correct value.
frame->channels = fmt->pcm->channel;
int channel_bytes = frame->nb_samples * sizeof(float);
uintptr_t bytes = channel_bytes * frame->channels;
frame->linesize[0] = (int) channel_bytes;
// ffmpeg says some code may access extra 16 bytes
// and cpu alignment should be honored.
// arm64 require 4, however, some neon instruction like vst1
// require alignment 32 at max.
struct my_buffer* mbuf = mbuf_alloc_2((uint32_t) (sizeof(media_buffer)
+ bytes + 32 + 16));
if (mbuf == NULL) {
return -1;
}
media_buffer* media = (media_buffer *) mbuf->ptr[0];
memset(media->vp, 0, sizeof(media->vp));
media->angle = 0;
gidx_field(media) = 0;
group_field(media) = 1;
mbuf->length = bytes;
mbuf->ptr[1] += sizeof(media_buffer);
mbuf->ptr[1] = (char *) roundup(((uintptr_t) mbuf->ptr[1]), 32);
my_assert(frame->nb_extended_buf == 0);
frame->extended_data = frame->data;
frame->data[0] = (uint8_t *) mbuf->ptr[1];
if (frame->channels) {
frame->data[1] = (uint8_t *) (mbuf->ptr[1] + channel_bytes);
}
// because documents says buf reference chunk address than data entry
// e.g. ffmpeg don't know which data[x] buf referenced exactly.
// ok, it is another word of ffmpeg will never try to get data[x] from
// buf, then it should use buf only to call addref/release things.
// in this condition, passing mbuf than data[x] to av_buffer_create is
safe.
frame->buf[0] = av_buffer_create((uint8_t *) mbuf->ptr[1], (int)
bytes, ffmpeg_frame_put, (uint8_t *) mbuf, 0);
if (frame->buf[0] == NULL) {
mbuf->mop->free(mbuf);
return -1;
}
frame->extended_buf = NULL;
frame->nb_extended_buf = 0;
return 0;
}
static void* ffmpeg_open(fourcc** in, fourcc** out)
{
ffmpeg_wrapper_t* wrapper = (ffmpeg_wrapper_t *)
my_malloc(sizeof(ffmpeg_wrapper_t));
if (wrapper == NULL) {
return NULL;
}
wrapper->bytes = 0;
wrapper->nb_frame = 0;
wrapper->seq = 0;
wrapper->in = to_audio_format(in);
wrapper->out = to_audio_format(out);
avcodec_register_all();
AVCodec* codec = avcodec_find_decoder(AV_CODEC_ID_AAC);
if (codec == NULL) {
my_free(wrapper);
return NULL;
}
my_assert(codec->capabilities & CODEC_CAP_DR1);
AVCodecContext* context = avcodec_alloc_context3(codec);
if (context == NULL) {
my_free(wrapper);
return NULL;
}
wrapper->context = context;
AVFrame* frame_buffer = av_frame_alloc();
if(frame_buffer == NULL){
avcodec_free_context(&context);
my_free(wrapper);
return NULL;
}
wrapper->frame = frame_buffer;
context->channels = wrapper->in->pcm->channel;
context->sample_rate = wrapper->in->pcm->samrate;
context->refcounted_frames = 1;
context->opaque = wrapper->out;
context->get_buffer2 = frame_buffer_get;
context->flags |= CODEC_FLAG_LOW_DELAY;
if (codec->capabilities & CODEC_CAP_TRUNCATED) {
context->flags |= CODEC_FLAG_TRUNCATED;
context->flags2 |= CODEC_FLAG2_CHUNKS;
}
if (0 != avcodec_open2(context, codec, NULL)) {
av_frame_free(&frame_buffer);
avcodec_free_context(&context);
my_free(wrapper);
return NULL;
}
return wrapper;
}
}}}
--
Ticket URL: <https://trac.ffmpeg.org/ticket/4874#comment:4>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker
More information about the FFmpeg-trac
mailing list