From 38f06a1415cf8394cf60f7b7a3cad84a3659beb4 Mon Sep 17 00:00:00 2001 From: Jordi Ortiz Date: Tue, 8 May 2012 19:20:32 +0200 Subject: [PATCH] libschroedingerdec: Change AVPicture to AVFrame and use SchroTag to store pts Signed-off-by: Luca Barbato --- libavcodec/libschroedingerdec.c | 97 +++++++++++++++++++++++---------- 1 file changed, 67 insertions(+), 30 deletions(-) diff --git a/libavcodec/libschroedingerdec.c b/libavcodec/libschroedingerdec.c index 6a3b9bdb99..77f42899c1 100644 --- a/libavcodec/libschroedingerdec.c +++ b/libavcodec/libschroedingerdec.c @@ -28,6 +28,7 @@ */ #include "libavutil/imgutils.h" +#include "libavutil/intreadwrite.h" #include "avcodec.h" #include "libschroedinger.h" @@ -39,6 +40,12 @@ #include #include +/** SchroFrame and Pts relation */ +typedef struct LibSchroFrameContext { + SchroFrame *frame; + int64_t pts; +} LibSchroFrameContext; + /** libschroedinger decoder private data */ typedef struct SchroDecoderParams { /** Schroedinger video format */ @@ -60,7 +67,7 @@ typedef struct SchroDecoderParams { int eos_pulled; /** decoded picture */ - AVPicture dec_pic; + AVFrame dec_frame; } SchroDecoderParams; typedef struct SchroParseUnitContext { @@ -171,8 +178,8 @@ static void libschroedinger_handle_first_access_unit(AVCodecContext *avccontext) p_schro_params->format = schro_decoder_get_video_format(decoder); /* Tell Libav about sequence details. */ - if (av_image_check_size(p_schro_params->format->width, p_schro_params->format->height, - 0, avccontext) < 0) { + if (av_image_check_size(p_schro_params->format->width, + p_schro_params->format->height, 0, avccontext) < 0) { av_log(avccontext, AV_LOG_ERROR, "invalid dimensions (%dx%d)\n", p_schro_params->format->width, p_schro_params->format->height); avccontext->height = avccontext->width = 0; @@ -192,12 +199,6 @@ static void libschroedinger_handle_first_access_unit(AVCodecContext *avccontext) avccontext->time_base.den = p_schro_params->format->frame_rate_numerator; avccontext->time_base.num = p_schro_params->format->frame_rate_denominator; - - if (!p_schro_params->dec_pic.data[0]) - avpicture_alloc(&p_schro_params->dec_pic, - avccontext->pix_fmt, - avccontext->width, - avccontext->height); } static int libschroedinger_decode_frame(AVCodecContext *avccontext, @@ -206,16 +207,18 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext, { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; + int64_t pts = avpkt->pts; + SchroTag *tag; SchroDecoderParams *p_schro_params = avccontext->priv_data; SchroDecoder *decoder = p_schro_params->decoder; - AVPicture *picture = data; SchroBuffer *enc_buf; SchroFrame* frame; int state; int go = 1; int outer = 1; SchroParseUnitContext parse_ctx; + LibSchroFrameContext *framewithpts = NULL; *data_size = 0; @@ -230,6 +233,13 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext, /* Loop through all the individual parse units in the input buffer */ do { if ((enc_buf = find_next_parse_unit(&parse_ctx))) { + /* Set Schrotag with the pts to be recovered after decoding*/ + enc_buf->tag = schro_tag_new(av_malloc(sizeof(int64_t)), av_free); + if (!enc_buf->tag->value) { + av_log(avccontext, AV_LOG_ERROR, "Unable to allocate SchroTag\n"); + return AVERROR(ENOMEM); + } + AV_WN(64, enc_buf->tag->value, pts); /* Push buffer into decoder. */ if (SCHRO_PARSE_CODE_IS_PICTURE(enc_buf->data[4]) && SCHRO_PARSE_CODE_NUM_REFS(enc_buf->data[4]) > 0) @@ -263,11 +273,21 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext, case SCHRO_DECODER_OK: /* Pull a frame out of the decoder. */ + tag = schro_decoder_get_picture_tag(decoder); frame = schro_decoder_pull(decoder); - if (frame) + if (frame) { + /* Add relation between schroframe and pts. */ + framewithpts = av_malloc(sizeof(LibSchroFrameContext)); + if (!framewithpts) { + av_log(avccontext, AV_LOG_ERROR, "Unable to allocate FrameWithPts\n"); + return AVERROR(ENOMEM); + } + framewithpts->frame = frame; + framewithpts->pts = AV_RN64(tag->value); ff_schro_queue_push_back(&p_schro_params->dec_frame_queue, - frame); + framewithpts); + } break; case SCHRO_DECODER_EOS: go = 0; @@ -284,30 +304,46 @@ static int libschroedinger_decode_frame(AVCodecContext *avccontext, } while (outer); /* Grab next frame to be returned from the top of the queue. */ - frame = ff_schro_queue_pop(&p_schro_params->dec_frame_queue); + framewithpts = ff_schro_queue_pop(&p_schro_params->dec_frame_queue); + + if (framewithpts && framewithpts->frame) { + if (p_schro_params->dec_frame.data[0]) + avccontext->release_buffer(avccontext, &p_schro_params->dec_frame); + if (avccontext->get_buffer(avccontext, &p_schro_params->dec_frame) < 0) { + av_log(avccontext, AV_LOG_ERROR, "Unable to allocate buffer\n"); + return AVERROR(ENOMEM); + } - if (frame) { - memcpy(p_schro_params->dec_pic.data[0], - frame->components[0].data, - frame->components[0].length); + memcpy(p_schro_params->dec_frame.data[0], + framewithpts->frame->components[0].data, + framewithpts->frame->components[0].length); - memcpy(p_schro_params->dec_pic.data[1], - frame->components[1].data, - frame->components[1].length); + memcpy(p_schro_params->dec_frame.data[1], + framewithpts->frame->components[1].data, + framewithpts->frame->components[1].length); - memcpy(p_schro_params->dec_pic.data[2], - frame->components[2].data, - frame->components[2].length); + memcpy(p_schro_params->dec_frame.data[2], + framewithpts->frame->components[2].data, + framewithpts->frame->components[2].length); - /* Fill picture with current buffer data from Schroedinger. */ - avpicture_fill(picture, p_schro_params->dec_pic.data[0], - avccontext->pix_fmt, - avccontext->width, avccontext->height); + /* Fill frame with current buffer data from Schroedinger. */ + p_schro_params->dec_frame.format = -1; /* Unknown -1 */ + p_schro_params->dec_frame.width = framewithpts->frame->width; + p_schro_params->dec_frame.height = framewithpts->frame->height; + p_schro_params->dec_frame.pkt_pts = framewithpts->pts; + p_schro_params->dec_frame.linesize[0] = framewithpts->frame->components[0].stride; + p_schro_params->dec_frame.linesize[1] = framewithpts->frame->components[1].stride; + p_schro_params->dec_frame.linesize[2] = framewithpts->frame->components[2].stride; - *data_size = sizeof(AVPicture); + *(AVFrame*)data = p_schro_params->dec_frame; + *data_size = sizeof(AVFrame); /* Now free the frame resources. */ - libschroedinger_decode_frame_free(frame); + libschroedinger_decode_frame_free(framewithpts->frame); + av_free(framewithpts); + } else { + data = NULL; + *data_size = 0; } return buf_size; } @@ -320,7 +356,8 @@ static av_cold int libschroedinger_decode_close(AVCodecContext *avccontext) schro_decoder_free(p_schro_params->decoder); av_freep(&p_schro_params->format); - avpicture_free(&p_schro_params->dec_pic); + if (p_schro_params->dec_frame.data[0]) + avccontext->release_buffer(avccontext, &p_schro_params->dec_frame); /* Free data in the output frame queue. */ ff_schro_queue_free(&p_schro_params->dec_frame_queue, -- GitLab