static int libschroedinger_decode_frame(AVCodecContext *avccontext, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; FfmpegSchroDecoderParams *p_schro_params = avccontext->priv_data; SchroDecoder *decoder = p_schro_params->decoder; SchroVideoFormat *format; AVPicture *picture = data; SchroBuffer *enc_buf; SchroFrame* frame; int state; int go = 1; int outer = 1; FfmpegSchroParseUnitContext parse_ctx; *data_size = 0; FfmpegSchroParseContextInit(&parse_ctx, buf, buf_size); if (!buf_size) { if (!p_schro_params->eos_signalled) { state = schro_decoder_push_end_of_stream(decoder); p_schro_params->eos_signalled = 1; } } /* Loop through all the individual parse units in the input buffer */ do { if ((enc_buf = FfmpegFindNextSchroParseUnit(&parse_ctx))) { /* Push buffer into decoder. */ if (SCHRO_PARSE_CODE_IS_PICTURE(enc_buf->data[4]) && SCHRO_PARSE_CODE_NUM_REFS(enc_buf->data[4]) > 0) avccontext->has_b_frames = 1; state = schro_decoder_push(decoder, enc_buf); if (state == SCHRO_DECODER_FIRST_ACCESS_UNIT) libschroedinger_handle_first_access_unit(avccontext); go = 1; } else outer = 0; format = p_schro_params->format; while (go) { /* Parse data and process result. */ state = schro_decoder_wait(decoder); switch (state) { case SCHRO_DECODER_FIRST_ACCESS_UNIT: libschroedinger_handle_first_access_unit(avccontext); break; case SCHRO_DECODER_NEED_BITS: /* Need more input data - stop iterating over what we have. */ go = 0; break; case SCHRO_DECODER_NEED_FRAME: /* Decoder needs a frame - create one and push it in. */ frame = ff_create_schro_frame(avccontext, p_schro_params->frame_format); schro_decoder_add_output_picture(decoder, frame); break; case SCHRO_DECODER_OK: /* Pull a frame out of the decoder. */ frame = schro_decoder_pull(decoder); if (frame) ff_dirac_schro_queue_push_back(&p_schro_params->dec_frame_queue, frame); break; case SCHRO_DECODER_EOS: go = 0; p_schro_params->eos_pulled = 1; schro_decoder_reset(decoder); outer = 0; break; case SCHRO_DECODER_ERROR: return -1; break; } } } while (outer); /* Grab next frame to be returned from the top of the queue. */ frame = ff_dirac_schro_queue_pop(&p_schro_params->dec_frame_queue); if (frame) { memcpy(p_schro_params->dec_pic.data[0], frame->components[0].data, 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_pic.data[2], frame->components[2].data, 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); *data_size = sizeof(AVPicture); /* Now free the frame resources. */ libschroedinger_decode_frame_free(frame); } return buf_size; }
static int libschroedinger_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; int64_t pts = avpkt->pts; SchroTag *tag; SchroDecoderParams *p_schro_params = avctx->priv_data; SchroDecoder *decoder = p_schro_params->decoder; SchroBuffer *enc_buf; SchroFrame* frame; AVFrame *avframe = data; int state; int go = 1; int outer = 1; SchroParseUnitContext parse_ctx; LibSchroFrameContext *framewithpts = NULL; *got_frame = 0; parse_context_init(&parse_ctx, buf, buf_size); if (!buf_size) { if (!p_schro_params->eos_signalled) { state = schro_decoder_push_end_of_stream(decoder); p_schro_params->eos_signalled = 1; } } /* 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(avctx, 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) avctx->has_b_frames = 1; state = schro_decoder_push(decoder, enc_buf); if (state == SCHRO_DECODER_FIRST_ACCESS_UNIT) libschroedinger_handle_first_access_unit(avctx); go = 1; } else outer = 0; while (go) { /* Parse data and process result. */ state = schro_decoder_wait(decoder); switch (state) { case SCHRO_DECODER_FIRST_ACCESS_UNIT: libschroedinger_handle_first_access_unit(avctx); break; case SCHRO_DECODER_NEED_BITS: /* Need more input data - stop iterating over what we have. */ go = 0; break; case SCHRO_DECODER_NEED_FRAME: /* Decoder needs a frame - create one and push it in. */ frame = ff_create_schro_frame(avctx, p_schro_params->frame_format); if (!frame) return AVERROR(ENOMEM); schro_decoder_add_output_picture(decoder, frame); break; 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) { /* Add relation between schroframe and pts. */ framewithpts = av_malloc(sizeof(LibSchroFrameContext)); if (!framewithpts) { av_log(avctx, 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, framewithpts); } break; case SCHRO_DECODER_EOS: go = 0; p_schro_params->eos_pulled = 1; schro_decoder_reset(decoder); outer = 0; break; case SCHRO_DECODER_ERROR: return -1; break; } } } while (outer); /* Grab next frame to be returned from the top of the queue. */ framewithpts = ff_schro_queue_pop(&p_schro_params->dec_frame_queue); if (framewithpts && framewithpts->frame) { int ret; if ((ret = ff_get_buffer(avctx, avframe, 0)) < 0) return ret; memcpy(avframe->data[0], framewithpts->frame->components[0].data, framewithpts->frame->components[0].length); memcpy(avframe->data[1], framewithpts->frame->components[1].data, framewithpts->frame->components[1].length); memcpy(avframe->data[2], framewithpts->frame->components[2].data, framewithpts->frame->components[2].length); /* Fill frame with current buffer data from Schroedinger. */ avframe->pkt_pts = framewithpts->pts; avframe->linesize[0] = framewithpts->frame->components[0].stride; avframe->linesize[1] = framewithpts->frame->components[1].stride; avframe->linesize[2] = framewithpts->frame->components[2].stride; *got_frame = 1; /* Now free the frame resources. */ libschroedinger_decode_frame_free(framewithpts->frame); av_free(framewithpts); } else { data = NULL; *got_frame = 0; } return buf_size; }
static void handle_packet (unsigned char *data, int size) { SchroUnpack unpack; const char *parse_code; int next; int prev; if (memcmp (data, "BBCD", 4) != 0) { printf("non-Dirac packet\n"); dump_hex (data, MIN(size, 100), " "); return; } switch (data[4]) { case SCHRO_PARSE_CODE_SEQUENCE_HEADER: parse_code = "access unit header"; break; case SCHRO_PARSE_CODE_AUXILIARY_DATA: parse_code = "auxiliary data"; break; case SCHRO_PARSE_CODE_INTRA_REF: parse_code = "intra ref"; break; case SCHRO_PARSE_CODE_INTRA_NON_REF: parse_code = "intra non-ref"; break; case SCHRO_PARSE_CODE_INTER_REF_1: parse_code = "inter ref 1"; break; case SCHRO_PARSE_CODE_INTER_REF_2: parse_code = "inter ref 2"; break; case SCHRO_PARSE_CODE_INTER_NON_REF_1: parse_code = "inter non-ref 1"; break; case SCHRO_PARSE_CODE_INTER_NON_REF_2: parse_code = "inter non-ref 2"; break; case SCHRO_PARSE_CODE_END_OF_SEQUENCE: parse_code = "end of sequence"; break; case SCHRO_PARSE_CODE_LD_INTRA_REF: parse_code = "low-delay intra ref"; break; case SCHRO_PARSE_CODE_LD_INTRA_NON_REF: parse_code = "low-delay intra non-ref"; break; case SCHRO_PARSE_CODE_INTRA_REF_NOARITH: parse_code = "intra ref noarith"; break; case SCHRO_PARSE_CODE_INTRA_NON_REF_NOARITH: parse_code = "intra non-ref noarith"; break; case SCHRO_PARSE_CODE_INTER_REF_1_NOARITH: parse_code = "inter ref 1 noarith"; break; case SCHRO_PARSE_CODE_INTER_REF_2_NOARITH: parse_code = "inter ref 2 noarith"; break; case SCHRO_PARSE_CODE_INTER_NON_REF_1_NOARITH: parse_code = "inter non-ref 1 noarith"; break; case SCHRO_PARSE_CODE_INTER_NON_REF_2_NOARITH: parse_code = "inter non-ref 2 noarith"; break; default: parse_code = "unknown"; break; } schro_unpack_init_with_data (&unpack, data + 5, size - 5, 1); next = schro_unpack_decode_bits (&unpack, 32); prev = schro_unpack_decode_bits (&unpack, 32); if (data[4] == SCHRO_PARSE_CODE_SEQUENCE_HEADER) { printf("AU\n"); printf("pictur: "); printf(" "); printf(" "); printf(" ref1 "); printf(" ref2 "); printf("retire "); printf(" size \n"); } else if (SCHRO_PARSE_CODE_IS_PICTURE(data[4])) { int num_refs = SCHRO_PARSE_CODE_NUM_REFS(data[4]); int pic_num; char ref_chars[3] = { 'I', 'P', 'B' }; schro_unpack_byte_sync(&unpack); pic_num = schro_unpack_decode_bits(&unpack, 32); printf("%6d: ", pic_num); if (SCHRO_PARSE_CODE_IS_REFERENCE(data[4])) { printf("ref "); } else { printf(" "); } printf("%c ", ref_chars[num_refs]); if (num_refs > 0) { printf("%6d ", pic_num + schro_unpack_decode_sint(&unpack)); } else { printf(" "); } if (num_refs > 1) { printf("%6d ", pic_num + schro_unpack_decode_sint(&unpack)); } else { printf(" "); } if (SCHRO_PARSE_CODE_IS_REFERENCE(data[4])) { int r = schro_unpack_decode_sint(&unpack); if (r == 0) { printf(" none "); } else { printf("%6d ", pic_num + r); } } else { printf(" "); } printf(" %8d\n", next); } else if (data[4] == SCHRO_PARSE_CODE_AUXILIARY_DATA) { } schro_unpack_byte_sync (&unpack); }