bool is_got;
int32_t len;
AVCodecContext *avctx;
-
- // for video decoder
- size_t picture_buffer_offset;
AVFrame *frame;
- // for video encoder
- AVPacket *avpkt;
+ union {
+ // for video decoder
+ struct {
+ size_t picture_buffer_offset;
+ };
+
+ // for video encoder
+ struct {
+ AVPacket *avpkt;
+ };
+
+ // for audio encoder
+ struct {
+ bool resampled;
+ int32_t out_sample_fmt;
+ };
+ };
} DataContainer;
DeviceMemEntry *entry[CODEC_CONTEXT_MAX];
// video decode data handler
// FIXME: ignore "size" now...
-static void copy_decode_data(void *dst, void *opaque, size_t dummy)
+static void copy_decode_video_data(void *dst, void *opaque, size_t dummy)
{
DataContainer *dc = (DataContainer *)opaque;
CodecContext *context = (CodecContext *)dc->avctx->opaque;
}
static void release(void *opaque) {
- DataContainer *dc = (DataContainer *)opaque;
- if (dc->avpkt) {
- g_free(dc->avpkt->data);
- g_free(dc->avpkt);
- }
- g_free(dc);
+ g_free(opaque);
}
static DataHandler video_decode_data_handler = {
- .get_data = copy_decode_data,
+ .get_data = copy_decode_video_data,
.release = release,
};
-static void copy_encode_data(void *dst, void *opaque, size_t dummy)
+static void copy_encode_video_data(void *dst, void *opaque, size_t dummy)
{
DataContainer *dc = (DataContainer *)opaque;
struct video_encode_output *encode_output =
memcpy(&encode_output->data, dc->avpkt->data, dc->avpkt->size);
}
+
+ g_free(dc->avpkt->data);
+ g_free(dc->avpkt);
}
static DataHandler video_encode_data_handler = {
- .get_data = copy_encode_data,
+ .get_data = copy_encode_video_data,
.release = release,
};
-
static uint32_t parse_and_decode_video(AVCodecContext *avctx, AVFrame *picture,
AVCodecParserContext *pctx, int ctx_id,
AVPacket *packet, uint32_t *got_picture,
int64_t channel_layout;
} __attribute__((packed));
+struct audio_decode_input {
+ int32_t inbuf_size;
+ uint8_t inbuf; // for pointing inbuf address
+} __attribute__((packed));
+
+struct audio_decode_output {
+ int32_t len;
+ int32_t got_frame;
+ uint8_t data; // for pointing data address
+} __attribute__((packed));
+
static int convert_audio_sample_fmt(const AVCodec *codec, int codec_type, bool encode)
{
int audio_sample_fmt = AV_SAMPLE_FMT_NONE;
return resample_frame;
}
+// FIXME: ignore "size" now...
+static void copy_decode_audio_data(void *dst, void *opaque, size_t dummy)
+{
+ DataContainer *dc = (DataContainer *)opaque;
+
+ struct audio_decode_output *decode_output =
+ (struct audio_decode_output *)dst;
+
+ // FIXME
+ //decode_output->len = dc->len;
+ decode_output->len = dc->frame->linesize[0];
+ decode_output->got_frame = dc->is_got ? 1 : 0;
+
+ if (dc->is_got) {
+ struct audio_data *data = (struct audio_data *)&decode_output->data;
+ data->sample_fmt = dc->resampled ? dc->out_sample_fmt : dc->avctx->sample_fmt;
+ data->sample_rate = dc->avctx->sample_rate;
+ data->channels = dc->avctx->channels;
+ data->channel_layout = dc->avctx->channel_layout;
+
+ memcpy(dst + OFFSET_PICTURE_BUFFER, dc->frame->data[0], decode_output->len);
+
+ if (dc->resampled) {
+ av_free(dc->frame->data[0]);
+ av_free(dc->frame);
+ }
+ }
+}
+
+static DataHandler audio_decode_data_handler = {
+ .get_data = copy_decode_audio_data,
+ .release = release,
+};
+
+
/*
+ * dc->resampled = resample_frame ? true : false;
* decode_audio >> raw audio_buffer >> resample
*
* audios sink cannot handle planar format, so it is required
{
AVCodecContext *avctx;
AVPacket avpkt;
- AVFrame *audio_out = NULL;
- uint8_t *inbuf = NULL;
- int inbuf_size = 0, size = 0;
- int len = -1, got_frame = 0;
+ AVFrame *frame = NULL;
DeviceMemEntry *elem = NULL;
- uint8_t *tempbuf = NULL;
- int tempbuf_size = 0;
-
- AVFrame *resample_frame = NULL;
- uint8_t *resample_buf = NULL;
- int resample_buf_size = 0;
- int out_sample_fmt = -1;
+ struct audio_decode_input empty_input = { 0, };
+ struct audio_decode_input *decode_input = &empty_input;
+ int len = -1, got_frame = 0;
TRACE("enter: %s\n", __func__);
elem = (DeviceMemEntry *)data_buf;
- if (elem && elem->opaque) {
- memcpy(&inbuf_size, elem->opaque, sizeof(inbuf_size));
- size = sizeof(inbuf_size);
- TRACE("decode_audio. inbuf_size %d\n", inbuf_size);
-
- if (inbuf_size > 0) {
- inbuf = elem->opaque + size;
- }
+ if (!elem || !elem->opaque) {
+ TRACE("decode_video. no input buffer\n");
} else {
- ERR("decode_audio. no input buffer\n");
- // FIXME: improve error handling
- // return false;
+ decode_input = elem->opaque;
}
av_init_packet(&avpkt);
- avpkt.data = inbuf;
- avpkt.size = inbuf_size;
+ avpkt.data = &decode_input->inbuf;
+ avpkt.size = decode_input->inbuf_size;
avctx = CONTEXT(s, ctx_id)->avctx;
- // audio_out = CONTEXT(s, ctx_id)->frame;
- audio_out = avcodec_alloc_frame();
- if (!avctx) {
- ERR("decode_audio. %d of AVCodecContext is NULL\n", ctx_id);
- } else if (!avctx->codec) {
- ERR("decode_audio. %d of AVCodec is NULL\n", ctx_id);
- } else if (!audio_out) {
- ERR("decode_audio. %d of AVFrame is NULL\n", ctx_id);
- } else {
- len = avcodec_decode_audio4(avctx, audio_out, &got_frame, &avpkt);
- TRACE("decode_audio. len %d, channel_layout %lld got_frame %d\n",
+ frame = CONTEXT(s, ctx_id)->frame;
+
+ if(!avctx || !avctx->codec || !frame) {
+ ERR("critical error !!!\n");
+ assert(0);
+ }
+
+ len = avcodec_decode_audio4(avctx, frame, &got_frame, &avpkt);
+ TRACE("decode_audio. len %d, channel_layout %lld, got_frame %d\n",
len, avctx->channel_layout, got_frame);
- if (got_frame) {
- if (av_sample_fmt_is_planar(avctx->sample_fmt)) {
- out_sample_fmt = convert_audio_sample_fmt(avctx->codec, avctx->codec_type, 0);
+ AVFrame *resample_frame = NULL;
+ int resample_buf_size = 0;
+ uint32_t out_sample_fmt = -1;
+
+ if (got_frame) {
+ if (av_sample_fmt_is_planar(avctx->sample_fmt)) {
+ out_sample_fmt = convert_audio_sample_fmt(avctx->codec, avctx->codec_type, 0);
- if (avctx->channel_layout == 0) {
- avctx->channel_layout = av_get_default_channel_layout(avctx->channels);
- TRACE("decode_audio. channel_layout %lld channels %d\n",
+ if (avctx->channel_layout == 0) {
+ avctx->channel_layout = av_get_default_channel_layout(avctx->channels);
+ TRACE("decode_audio. channel_layout %lld channels %d\n",
avctx->channel_layout, avctx->channels);
- }
- resample_frame = resample_audio(avctx, audio_out, audio_out->linesize[0],
- avctx->sample_fmt, NULL, &resample_buf_size,
- out_sample_fmt);
- if (resample_frame) {
- resample_buf = resample_frame->data[0];
- } else {
- ERR("failed to resample decoded audio buffer\n");
- len = -1;
- got_frame = 0;
- }
- } else {
- INFO("decode_audio. linear audio format\n");
- resample_buf = audio_out->data[0];
- resample_buf_size = audio_out->linesize[0];
}
- }
- }
-
- tempbuf_size = (sizeof(len) + sizeof(got_frame));
- if (len < 0) {
- ERR("failed to decode audio. ctx_id: %d len: %d got_frame: %d\n",
- ctx_id, len, got_frame);
- got_frame = 0;
- } else {
- tempbuf_size += (sizeof(out_sample_fmt) + sizeof(avctx->sample_rate)
- + sizeof(avctx->channels) + sizeof(avctx->channel_layout)
- + sizeof(resample_buf_size) + resample_buf_size);
- }
-
- tempbuf = g_malloc(tempbuf_size);
- if (!tempbuf) {
- ERR("failed to allocate decoded audio buffer\n");
- } else {
- memcpy(tempbuf, &len, sizeof(len));
- size = sizeof(len);
- memcpy(tempbuf + size, &got_frame, sizeof(got_frame));
- size += sizeof(got_frame);
- if (got_frame) {
- memcpy(tempbuf + size, &out_sample_fmt, sizeof(out_sample_fmt));
- size += sizeof(out_sample_fmt);
- memcpy(tempbuf + size, &avctx->sample_rate, sizeof(avctx->sample_rate));
- size += sizeof(avctx->sample_rate);
- memcpy(tempbuf + size, &avctx->channels, sizeof(avctx->channels));
- size += sizeof(avctx->channels);
- memcpy(tempbuf + size, &avctx->channel_layout, sizeof(avctx->channel_layout));
- size += sizeof(avctx->channel_layout);
-
- memcpy(tempbuf + size, &resample_buf_size, sizeof(resample_buf_size));
- size += sizeof(resample_buf_size);
- if (resample_buf) {
- TRACE("copy resampled audio buffer\n");
- memcpy(tempbuf + size, resample_buf, resample_buf_size);
+ resample_frame = resample_audio(avctx, frame, frame->linesize[0],
+ avctx->sample_fmt, NULL, &resample_buf_size,
+ out_sample_fmt);
+ if (!resample_frame) {
+ ERR("failed to resample decoded audio buffer\n");
+ len = -1;
+ got_frame = 0;
}
}
}
- brillcodec_push_writequeue(s, tempbuf, tempbuf_size, ctx_id, NULL);
+ DataContainer *dc = g_malloc0(sizeof(DataContainer));
+ dc->len = len;
+ dc->is_got = got_frame;
+ dc->avctx = avctx;
+ dc->resampled = resample_frame ? true : false;
+ dc->out_sample_fmt = out_sample_fmt;
+ dc->frame = resample_frame ? resample_frame : frame;
- if (resample_frame) {
- TRACE("release decoded frame\n");
- av_free(resample_buf);
- av_free(resample_frame);
- }
+ brillcodec_push_writequeue(s, dc, 0, ctx_id, &audio_decode_data_handler);
TRACE("leave: %s\n", __func__);
return true;