Rather than copying data buffers around, allocate a proper frame, and use the standard AVFrame functions. This effectively makes the decoder capable of direct rendering. Signed-off-by: Vittorio Giovara <vittorio.giovara@gmail.com>tags/n3.0
| @@ -26,6 +26,7 @@ | |||||
| #include "libavutil/attributes.h" | #include "libavutil/attributes.h" | ||||
| #include "libavutil/mem.h" | #include "libavutil/mem.h" | ||||
| #include "libschroedinger.h" | #include "libschroedinger.h" | ||||
| #include "internal.h" | |||||
| static const SchroVideoFormatInfo ff_schro_video_format_info[] = { | static const SchroVideoFormatInfo ff_schro_video_format_info[] = { | ||||
| { 640, 480, 24000, 1001}, | { 640, 480, 24000, 1001}, | ||||
| @@ -167,19 +168,14 @@ int ff_get_schro_frame_format (SchroChromaFormat schro_pix_fmt, | |||||
| static void free_schro_frame(SchroFrame *frame, void *priv) | static void free_schro_frame(SchroFrame *frame, void *priv) | ||||
| { | { | ||||
| AVPicture *p_pic = priv; | |||||
| if (!p_pic) | |||||
| return; | |||||
| avpicture_free(p_pic); | |||||
| av_freep(&p_pic); | |||||
| AVFrame *p_pic = priv; | |||||
| av_frame_free(&p_pic); | |||||
| } | } | ||||
| SchroFrame *ff_create_schro_frame(AVCodecContext *avctx, | SchroFrame *ff_create_schro_frame(AVCodecContext *avctx, | ||||
| SchroFrameFormat schro_frame_fmt) | SchroFrameFormat schro_frame_fmt) | ||||
| { | { | ||||
| AVPicture *p_pic; | |||||
| AVFrame *p_pic; | |||||
| SchroFrame *p_frame; | SchroFrame *p_frame; | ||||
| int y_width, uv_width; | int y_width, uv_width; | ||||
| int y_height, uv_height; | int y_height, uv_height; | ||||
| @@ -190,10 +186,15 @@ SchroFrame *ff_create_schro_frame(AVCodecContext *avctx, | |||||
| uv_width = y_width >> (SCHRO_FRAME_FORMAT_H_SHIFT(schro_frame_fmt)); | uv_width = y_width >> (SCHRO_FRAME_FORMAT_H_SHIFT(schro_frame_fmt)); | ||||
| uv_height = y_height >> (SCHRO_FRAME_FORMAT_V_SHIFT(schro_frame_fmt)); | uv_height = y_height >> (SCHRO_FRAME_FORMAT_V_SHIFT(schro_frame_fmt)); | ||||
| p_pic = av_mallocz(sizeof(AVPicture)); | |||||
| p_pic = av_frame_alloc(); | |||||
| if (!p_pic) | if (!p_pic) | ||||
| return NULL; | return NULL; | ||||
| avpicture_alloc(p_pic, avctx->pix_fmt, y_width, y_height); | |||||
| if (ff_get_buffer(avctx, p_pic, AV_GET_BUFFER_FLAG_REF) < 0) { | |||||
| av_frame_free(&p_pic); | |||||
| av_log(avctx, AV_LOG_ERROR, "Unable to allocate buffer\n"); | |||||
| return NULL; | |||||
| } | |||||
| p_frame = schro_frame_new(); | p_frame = schro_frame_new(); | ||||
| p_frame->format = schro_frame_fmt; | p_frame->format = schro_frame_fmt; | ||||
| @@ -387,6 +387,6 @@ AVCodec ff_libschroedinger_decoder = { | |||||
| .init = libschroedinger_decode_init, | .init = libschroedinger_decode_init, | ||||
| .close = libschroedinger_decode_close, | .close = libschroedinger_decode_close, | ||||
| .decode = libschroedinger_decode_frame, | .decode = libschroedinger_decode_frame, | ||||
| .capabilities = AV_CODEC_CAP_DELAY, | |||||
| .capabilities = AV_CODEC_CAP_DELAY | AV_CODEC_CAP_DR1, | |||||
| .flush = libschroedinger_flush, | .flush = libschroedinger_flush, | ||||
| }; | }; | ||||
| @@ -32,6 +32,8 @@ | |||||
| #include <schroedinger/schrovideoformat.h> | #include <schroedinger/schrovideoformat.h> | ||||
| #include "libavutil/attributes.h" | #include "libavutil/attributes.h" | ||||
| #include "libavutil/imgutils.h" | |||||
| #include "avcodec.h" | #include "avcodec.h" | ||||
| #include "internal.h" | #include "internal.h" | ||||
| #include "libschroedinger.h" | #include "libschroedinger.h" | ||||
| @@ -154,9 +156,9 @@ static av_cold int libschroedinger_encode_init(AVCodecContext *avctx) | |||||
| p_schro_params->format->frame_rate_numerator = avctx->time_base.den; | p_schro_params->format->frame_rate_numerator = avctx->time_base.den; | ||||
| p_schro_params->format->frame_rate_denominator = avctx->time_base.num; | p_schro_params->format->frame_rate_denominator = avctx->time_base.num; | ||||
| p_schro_params->frame_size = avpicture_get_size(avctx->pix_fmt, | |||||
| avctx->width, | |||||
| avctx->height); | |||||
| p_schro_params->frame_size = av_image_get_buffer_size(avctx->pix_fmt, | |||||
| avctx->width, | |||||
| avctx->height, 1); | |||||
| if (!avctx->gop_size) { | if (!avctx->gop_size) { | ||||
| schro_encoder_setting_set_double(p_schro_params->encoder, | schro_encoder_setting_set_double(p_schro_params->encoder, | ||||
| @@ -233,17 +235,17 @@ static SchroFrame *libschroedinger_frame_from_data(AVCodecContext *avctx, | |||||
| const AVFrame *frame) | const AVFrame *frame) | ||||
| { | { | ||||
| SchroEncoderParams *p_schro_params = avctx->priv_data; | SchroEncoderParams *p_schro_params = avctx->priv_data; | ||||
| SchroFrame *in_frame; | |||||
| /* Input line size may differ from what the codec supports. Especially | |||||
| * when transcoding from one format to another. So use avpicture_layout | |||||
| * to copy the frame. */ | |||||
| in_frame = ff_create_schro_frame(avctx, p_schro_params->frame_format); | |||||
| if (in_frame) | |||||
| avpicture_layout((const AVPicture *)frame, avctx->pix_fmt, | |||||
| avctx->width, avctx->height, | |||||
| in_frame->components[0].data, | |||||
| p_schro_params->frame_size); | |||||
| SchroFrame *in_frame = ff_create_schro_frame(avctx, | |||||
| p_schro_params->frame_format); | |||||
| if (in_frame) { | |||||
| /* Copy input data to SchroFrame buffers (they match the ones | |||||
| * referenced by the AVFrame stored in priv) */ | |||||
| if (av_frame_copy(in_frame->priv, frame) < 0) { | |||||
| av_log(avctx, AV_LOG_ERROR, "Failed to copy input data\n"); | |||||
| return NULL; | |||||
| } | |||||
| } | |||||
| return in_frame; | return in_frame; | ||||
| } | } | ||||