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