00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00030 #include "libavutil/imgutils.h"
00031 #include "avcodec.h"
00032 #include "libdirac_libschro.h"
00033 #include "libschroedinger.h"
00034
00035 #undef NDEBUG
00036 #include <assert.h>
00037
00038
00039 #include <schroedinger/schro.h>
00040 #include <schroedinger/schrodebug.h>
00041 #include <schroedinger/schrovideoformat.h>
00042
00044 typedef struct FfmpegSchroDecoderParams {
00046 SchroVideoFormat *format;
00047
00049 SchroFrameFormat frame_format;
00050
00052 SchroDecoder* decoder;
00053
00055 FfmpegDiracSchroQueue dec_frame_queue;
00056
00058 int eos_signalled;
00059
00061 int eos_pulled;
00062
00064 AVPicture dec_pic;
00065 } FfmpegSchroDecoderParams;
00066
00067 typedef struct FfmpegSchroParseUnitContext {
00068 const uint8_t *buf;
00069 int buf_size;
00070 } FfmpegSchroParseUnitContext;
00071
00072
00073 static void libschroedinger_decode_buffer_free(SchroBuffer *schro_buf,
00074 void *priv);
00075
00076 static void FfmpegSchroParseContextInit(FfmpegSchroParseUnitContext *parse_ctx,
00077 const uint8_t *buf, int buf_size)
00078 {
00079 parse_ctx->buf = buf;
00080 parse_ctx->buf_size = buf_size;
00081 }
00082
00083 static SchroBuffer* FfmpegFindNextSchroParseUnit(FfmpegSchroParseUnitContext *parse_ctx)
00084 {
00085 SchroBuffer *enc_buf = NULL;
00086 int next_pu_offset = 0;
00087 unsigned char *in_buf;
00088
00089 if (parse_ctx->buf_size < 13 ||
00090 parse_ctx->buf[0] != 'B' ||
00091 parse_ctx->buf[1] != 'B' ||
00092 parse_ctx->buf[2] != 'C' ||
00093 parse_ctx->buf[3] != 'D')
00094 return NULL;
00095
00096 next_pu_offset = (parse_ctx->buf[5] << 24) +
00097 (parse_ctx->buf[6] << 16) +
00098 (parse_ctx->buf[7] << 8) +
00099 parse_ctx->buf[8];
00100
00101 if (next_pu_offset == 0 &&
00102 SCHRO_PARSE_CODE_IS_END_OF_SEQUENCE(parse_ctx->buf[4]))
00103 next_pu_offset = 13;
00104
00105 if (next_pu_offset <= 0 || parse_ctx->buf_size < next_pu_offset)
00106 return NULL;
00107
00108 in_buf = av_malloc(next_pu_offset);
00109 memcpy(in_buf, parse_ctx->buf, next_pu_offset);
00110 enc_buf = schro_buffer_new_with_data(in_buf, next_pu_offset);
00111 enc_buf->free = libschroedinger_decode_buffer_free;
00112 enc_buf->priv = in_buf;
00113
00114 parse_ctx->buf += next_pu_offset;
00115 parse_ctx->buf_size -= next_pu_offset;
00116
00117 return enc_buf;
00118 }
00119
00123 static enum PixelFormat GetFfmpegChromaFormat(SchroChromaFormat schro_pix_fmt)
00124 {
00125 int num_formats = sizeof(ffmpeg_schro_pixel_format_map) /
00126 sizeof(ffmpeg_schro_pixel_format_map[0]);
00127 int idx;
00128
00129 for (idx = 0; idx < num_formats; ++idx)
00130 if (ffmpeg_schro_pixel_format_map[idx].schro_pix_fmt == schro_pix_fmt)
00131 return ffmpeg_schro_pixel_format_map[idx].ff_pix_fmt;
00132 return PIX_FMT_NONE;
00133 }
00134
00135 static av_cold int libschroedinger_decode_init(AVCodecContext *avccontext)
00136 {
00137
00138 FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
00139
00140 schro_init();
00141
00142 schro_debug_set_level(avccontext->debug);
00143 p_schro_params->decoder = schro_decoder_new();
00144 schro_decoder_set_skip_ratio(p_schro_params->decoder, 1);
00145
00146 if (!p_schro_params->decoder)
00147 return -1;
00148
00149
00150 ff_dirac_schro_queue_init(&p_schro_params->dec_frame_queue);
00151 return 0;
00152 }
00153
00154 static void libschroedinger_decode_buffer_free(SchroBuffer *schro_buf,
00155 void *priv)
00156 {
00157 av_freep(&priv);
00158 }
00159
00160 static void libschroedinger_decode_frame_free(void *frame)
00161 {
00162 schro_frame_unref(frame);
00163 }
00164
00165 static void libschroedinger_handle_first_access_unit(AVCodecContext *avccontext)
00166 {
00167 FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
00168 SchroDecoder *decoder = p_schro_params->decoder;
00169
00170 p_schro_params->format = schro_decoder_get_video_format(decoder);
00171
00172
00173 if (av_image_check_size(p_schro_params->format->width, p_schro_params->format->height,
00174 0, avccontext) < 0) {
00175 av_log(avccontext, AV_LOG_ERROR, "invalid dimensions (%dx%d)\n",
00176 p_schro_params->format->width, p_schro_params->format->height);
00177 avccontext->height = avccontext->width = 0;
00178 return;
00179 }
00180 avccontext->height = p_schro_params->format->height;
00181 avccontext->width = p_schro_params->format->width;
00182 avccontext->pix_fmt = GetFfmpegChromaFormat(p_schro_params->format->chroma_format);
00183
00184 if (ff_get_schro_frame_format(p_schro_params->format->chroma_format,
00185 &p_schro_params->frame_format) == -1) {
00186 av_log(avccontext, AV_LOG_ERROR,
00187 "This codec currently only supports planar YUV 4:2:0, 4:2:2 "
00188 "and 4:4:4 formats.\n");
00189 return;
00190 }
00191
00192 avccontext->time_base.den = p_schro_params->format->frame_rate_numerator;
00193 avccontext->time_base.num = p_schro_params->format->frame_rate_denominator;
00194
00195 if (!p_schro_params->dec_pic.data[0])
00196 avpicture_alloc(&p_schro_params->dec_pic,
00197 avccontext->pix_fmt,
00198 avccontext->width,
00199 avccontext->height);
00200 }
00201
00202 static int libschroedinger_decode_frame(AVCodecContext *avccontext,
00203 void *data, int *data_size,
00204 AVPacket *avpkt)
00205 {
00206 const uint8_t *buf = avpkt->data;
00207 int buf_size = avpkt->size;
00208
00209 FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
00210 SchroDecoder *decoder = p_schro_params->decoder;
00211 SchroVideoFormat *format;
00212 AVPicture *picture = data;
00213 SchroBuffer *enc_buf;
00214 SchroFrame* frame;
00215 int state;
00216 int go = 1;
00217 int outer = 1;
00218 FfmpegSchroParseUnitContext parse_ctx;
00219
00220 *data_size = 0;
00221
00222 FfmpegSchroParseContextInit(&parse_ctx, buf, buf_size);
00223 if (!buf_size) {
00224 if (!p_schro_params->eos_signalled) {
00225 state = schro_decoder_push_end_of_stream(decoder);
00226 p_schro_params->eos_signalled = 1;
00227 }
00228 }
00229
00230
00231 do {
00232 if ((enc_buf = FfmpegFindNextSchroParseUnit(&parse_ctx))) {
00233
00234 if (SCHRO_PARSE_CODE_IS_PICTURE(enc_buf->data[4]) &&
00235 SCHRO_PARSE_CODE_NUM_REFS(enc_buf->data[4]) > 0)
00236 avccontext->has_b_frames = 1;
00237 state = schro_decoder_push(decoder, enc_buf);
00238 if (state == SCHRO_DECODER_FIRST_ACCESS_UNIT)
00239 libschroedinger_handle_first_access_unit(avccontext);
00240 go = 1;
00241 } else
00242 outer = 0;
00243 format = p_schro_params->format;
00244
00245 while (go) {
00246
00247 state = schro_decoder_wait(decoder);
00248 switch (state) {
00249 case SCHRO_DECODER_FIRST_ACCESS_UNIT:
00250 libschroedinger_handle_first_access_unit(avccontext);
00251 break;
00252
00253 case SCHRO_DECODER_NEED_BITS:
00254
00255 go = 0;
00256 break;
00257
00258 case SCHRO_DECODER_NEED_FRAME:
00259
00260 frame = ff_create_schro_frame(avccontext,
00261 p_schro_params->frame_format);
00262 schro_decoder_add_output_picture(decoder, frame);
00263 break;
00264
00265 case SCHRO_DECODER_OK:
00266
00267 frame = schro_decoder_pull(decoder);
00268
00269 if (frame)
00270 ff_dirac_schro_queue_push_back(&p_schro_params->dec_frame_queue,
00271 frame);
00272 break;
00273 case SCHRO_DECODER_EOS:
00274 go = 0;
00275 p_schro_params->eos_pulled = 1;
00276 schro_decoder_reset(decoder);
00277 outer = 0;
00278 break;
00279
00280 case SCHRO_DECODER_ERROR:
00281 return -1;
00282 break;
00283 }
00284 }
00285 } while (outer);
00286
00287
00288 frame = ff_dirac_schro_queue_pop(&p_schro_params->dec_frame_queue);
00289
00290 if (frame) {
00291 memcpy(p_schro_params->dec_pic.data[0],
00292 frame->components[0].data,
00293 frame->components[0].length);
00294
00295 memcpy(p_schro_params->dec_pic.data[1],
00296 frame->components[1].data,
00297 frame->components[1].length);
00298
00299 memcpy(p_schro_params->dec_pic.data[2],
00300 frame->components[2].data,
00301 frame->components[2].length);
00302
00303
00304 avpicture_fill(picture, p_schro_params->dec_pic.data[0],
00305 avccontext->pix_fmt,
00306 avccontext->width, avccontext->height);
00307
00308 *data_size = sizeof(AVPicture);
00309
00310
00311 libschroedinger_decode_frame_free(frame);
00312 }
00313 return buf_size;
00314 }
00315
00316
00317 static av_cold int libschroedinger_decode_close(AVCodecContext *avccontext)
00318 {
00319 FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
00320
00321 schro_decoder_free(p_schro_params->decoder);
00322 av_freep(&p_schro_params->format);
00323
00324 avpicture_free(&p_schro_params->dec_pic);
00325
00326
00327 ff_dirac_schro_queue_free(&p_schro_params->dec_frame_queue,
00328 libschroedinger_decode_frame_free);
00329
00330 return 0;
00331 }
00332
00333 static void libschroedinger_flush(AVCodecContext *avccontext)
00334 {
00335
00336
00337 FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data;
00338
00339
00340 ff_dirac_schro_queue_free(&p_schro_params->dec_frame_queue,
00341 libschroedinger_decode_frame_free);
00342
00343 ff_dirac_schro_queue_init(&p_schro_params->dec_frame_queue);
00344 schro_decoder_reset(p_schro_params->decoder);
00345 p_schro_params->eos_pulled = 0;
00346 p_schro_params->eos_signalled = 0;
00347 }
00348
00349 AVCodec ff_libschroedinger_decoder = {
00350 "libschroedinger",
00351 AVMEDIA_TYPE_VIDEO,
00352 CODEC_ID_DIRAC,
00353 sizeof(FfmpegSchroDecoderParams),
00354 libschroedinger_decode_init,
00355 NULL,
00356 libschroedinger_decode_close,
00357 libschroedinger_decode_frame,
00358 CODEC_CAP_DELAY,
00359 .flush = libschroedinger_flush,
00360 .long_name = NULL_IF_CONFIG_SMALL("libschroedinger Dirac 2.2"),
00361 };