Ejemplo n.º 1
0
static int libdirac_decode_frame(AVCodecContext *avccontext,
                                 void *data, int *data_size,
                                 AVPacket *avpkt)
{
    const uint8_t *buf = avpkt->data;
    int buf_size = avpkt->size;

    FfmpegDiracDecoderParams *p_dirac_params = avccontext->priv_data;
    AVPicture *picture = data;
    AVPicture pic;
    int pict_size;
    unsigned char *buffer[3];

    *data_size = 0;

    if (buf_size > 0) {
        /* set data to decode into buffer */
        dirac_buffer(p_dirac_params->p_decoder, buf, buf + buf_size);
        if ((buf[4] & 0x08) == 0x08 && (buf[4] & 0x03))
            avccontext->has_b_frames = 1;
    }
    while (1) {
         /* parse data and process result */
        DecoderState state = dirac_parse(p_dirac_params->p_decoder);
        switch (state) {
        case STATE_BUFFER:
            return buf_size;

        case STATE_SEQUENCE:
        {
            /* tell FFmpeg about sequence details */
            dirac_sourceparams_t *src_params = &p_dirac_params->p_decoder->src_params;

            if (av_image_check_size(src_params->width, src_params->height,
                                    0, avccontext) < 0) {
                av_log(avccontext, AV_LOG_ERROR, "Invalid dimensions (%dx%d)\n",
                       src_params->width, src_params->height);
                avccontext->height = avccontext->width = 0;
                return -1;
            }

            avccontext->height = src_params->height;
            avccontext->width  = src_params->width;

            avccontext->pix_fmt = GetFfmpegChromaFormat(src_params->chroma);
            if (avccontext->pix_fmt == PIX_FMT_NONE) {
                av_log(avccontext, AV_LOG_ERROR,
                       "Dirac chroma format %d not supported currently\n",
                       src_params->chroma);
                return -1;
            }

            avccontext->time_base.den = src_params->frame_rate.numerator;
            avccontext->time_base.num = src_params->frame_rate.denominator;

            /* calculate output dimensions */
            avpicture_fill(&pic, NULL, avccontext->pix_fmt,
                           avccontext->width, avccontext->height);

            pict_size = avpicture_get_size(avccontext->pix_fmt,
                                           avccontext->width,
                                           avccontext->height);

            /* allocate output buffer */
            if (!p_dirac_params->p_out_frame_buf)
                p_dirac_params->p_out_frame_buf = av_malloc(pict_size);
            buffer[0] = p_dirac_params->p_out_frame_buf;
            buffer[1] = p_dirac_params->p_out_frame_buf +
                        pic.linesize[0] * avccontext->height;
            buffer[2] = buffer[1] +
                        pic.linesize[1] * src_params->chroma_height;

            /* tell Dirac about output destination */
            dirac_set_buf(p_dirac_params->p_decoder, buffer, NULL);
            break;
        }
        case STATE_SEQUENCE_END:
            break;

        case STATE_PICTURE_AVAIL:
            /* fill picture with current buffer data from Dirac */
            avpicture_fill(picture, p_dirac_params->p_out_frame_buf,
                           avccontext->pix_fmt,
                           avccontext->width, avccontext->height);
            *data_size = sizeof(AVPicture);
            return buf_size;

        case STATE_INVALID:
            return -1;

        default:
            break;
        }
    }

    return buf_size;
}
Ejemplo n.º 2
0
static void DecodeDirac (const char *iname, const char *oname)
{
    clock_t start_t, stop_t;
    dirac_decoder_t *decoder = NULL;
    FILE *ifp;
    FILE *fpdata;
    unsigned char buffer[8192];
    int bytes = 0;
    int num_frames = 0;
    char infile_name[FILENAME_MAX];
    char outfile_hdr[FILENAME_MAX];
    char outfile_data[FILENAME_MAX];
    dirac_decoder_state_t state = STATE_BUFFER;

    strncpy(infile_name, iname, sizeof(infile_name));

    strncpy(outfile_data, oname, sizeof(outfile_data));

    if ((ifp = fopen (infile_name, "rb")) ==NULL)
    {
        perror(iname);
        return;
    }

    if ((fpdata = fopen (outfile_data, "wb")) ==NULL)
    {
        perror(outfile_hdr);
        fclose(ifp);
        return;
    }

    /* initialise the decoder */
    decoder = dirac_decoder_init(verbose);

    assert (decoder != NULL);


    start_t=clock();
    do
    {
        /* parse the input data */
        state = dirac_parse(decoder);

        switch (state)
        {
        case STATE_BUFFER:
            /*
            * parser is out of data. Read data from input stream and pass it
            * on to the parser
            */
            bytes = fread (buffer, 1, sizeof(buffer), ifp);
            if (bytes)
                dirac_buffer (decoder, buffer, buffer + bytes);
            break;

        case STATE_SEQUENCE:
            {
            /*
            * Start of sequence detected. Allocate for the frame buffers and
            * pass this buffer to the parser
            */
            unsigned char *buf[3];

            if (verbose)
            {
                fprintf (stdout, "\nSEQUENCE : major_ver=%d minor_version=%d profile=%d level=%d width=%d height=%d chroma=%s chroma_width=%d chroma_height=%d frame_rate=%d/%d, source_sampling=%s topfieldfirst=%s",
                decoder->parse_params.major_ver,
                decoder->parse_params.minor_ver,
                decoder->parse_params.profile,
                decoder->parse_params.level,
                decoder->src_params.width,
                decoder->src_params.height,
                chroma2string(decoder->src_params.chroma),
                decoder->src_params.chroma_width,
                decoder->src_params.chroma_height,
                decoder->src_params.frame_rate.numerator,
                decoder->src_params.frame_rate.denominator,
                decoder->src_params.source_sampling == 0 ? "progressive" :
                ( decoder->src_params.source_sampling == 1 ? "interlaced" : "UNKNOWN" ),
                decoder->src_params.topfieldfirst ? "yes" : "no");
            }

            FreeFrameBuffer(decoder);

            buf[0] = buf[1] = buf[2] = 0;

            buf[0] = (unsigned char *)malloc (decoder->src_params.width * decoder->src_params.height);
            buf[1] = (unsigned char *)malloc (decoder->src_params.chroma_width * decoder->src_params.chroma_height);
            buf[2] = (unsigned char *)malloc (decoder->src_params.chroma_width * decoder->src_params.chroma_height);
            dirac_set_buf (decoder, buf, NULL);


            }
            break;

        case STATE_SEQUENCE_END:
            /*
            * End of Sequence detected. Free the frame buffers
            */
            if (verbose)
                fprintf (stdout, "\nSEQUENCE_END");

            FreeFrameBuffer(decoder);
            break;

        case STATE_PICTURE_AVAIL:
            num_frames++;
            if (verbose)
            {
                fprintf (stdout, "\nFRAME_AVAIL : frame_num=%d",
                    decoder->frame_num);
            }
            /* picture available for display */
            if (!WritePicData(decoder, fpdata))
            {
                perror("Write failed");
                goto cleanup;
            }
            break;

        case STATE_INVALID:
            /* Invalid state. Stop all processing */
            fprintf (stderr, "Error processing file %s\n", iname);
            break;

        default:
            continue;
        }
    } while (bytes > 0 && state != STATE_INVALID);
cleanup:
    stop_t=clock();

    if ( verbose )
        fprintf (stdout, "\nTime per frame: %g",
                (double)(stop_t-start_t)/(double)(CLOCKS_PER_SEC*num_frames));

    fclose(fpdata);
    fclose(ifp);

    /* free all resources */
    FreeFrameBuffer(decoder);
    dirac_decoder_close(decoder);
}