~thopiekar/arm-mali/libvdpau-sunxi

« back to all changes in this revision

Viewing changes to h264.c

  • Committer: Jens Kuske
  • Date: 2016-02-16 13:12:22 UTC
  • Revision ID: git-v1:685769372a8281bf67046a958883323aaf14d232
Use libcedrus

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
#include <stdlib.h>
21
21
#include <string.h>
22
22
#include <unistd.h>
 
23
#include <cedrus/cedrus.h>
 
24
#include <cedrus/cedrus_regs.h>
23
25
#include "vdpau_private.h"
24
 
#include "ve.h"
25
26
 
26
27
static int find_startcode(const uint8_t *data, int len, int start)
27
28
{
144
145
 
145
146
typedef struct
146
147
{
147
 
        struct ve_mem *extra_data;
 
148
        cedrus_mem_t *extra_data;
148
149
} h264_private_t;
149
150
 
150
151
static void h264_private_free(decoder_ctx_t *decoder)
151
152
{
152
153
        h264_private_t *decoder_p = (h264_private_t *)decoder->private;
153
 
        ve_free(decoder_p->extra_data);
 
154
        cedrus_mem_free(decoder_p->extra_data);
154
155
        free(decoder_p);
155
156
}
156
157
 
160
161
 
161
162
typedef struct
162
163
{
163
 
        struct ve_mem *extra_data;
 
164
        cedrus_mem_t *extra_data;
164
165
        uint8_t pos;
165
166
        uint8_t pic_type;
166
167
} h264_video_private_t;
168
169
static void h264_video_private_free(video_surface_ctx_t *surface)
169
170
{
170
171
        h264_video_private_t *surface_p = (h264_video_private_t *)surface->decoder_private;
171
 
        ve_free(surface_p->extra_data);
 
172
        cedrus_mem_free(surface_p->extra_data);
172
173
        free(surface_p);
173
174
}
174
175
 
182
183
                if (!surface_p)
183
184
                        return NULL;
184
185
 
185
 
                surface_p->extra_data = ve_malloc(c->video_extra_data_len * 2);
 
186
                surface_p->extra_data = cedrus_mem_alloc(surface->device->cedrus, c->video_extra_data_len * 2);
186
187
                if (!surface_p->extra_data)
187
188
                {
188
189
                        free(surface_p);
674
675
                        writel((uint16_t)c->info->field_order_cnt[0], c->regs + VE_H264_RAM_WRITE_DATA);
675
676
                        writel((uint16_t)c->info->field_order_cnt[1], c->regs + VE_H264_RAM_WRITE_DATA);
676
677
                        writel(output_p->pic_type << 8, c->regs + VE_H264_RAM_WRITE_DATA);
677
 
                        writel(c->output->rec->phys, c->regs + VE_H264_RAM_WRITE_DATA);
678
 
                        writel(c->output->rec->phys + c->output->luma_size, c->regs + VE_H264_RAM_WRITE_DATA);
679
 
                        writel(output_p->extra_data->phys, c->regs + VE_H264_RAM_WRITE_DATA);
680
 
                        writel(output_p->extra_data->phys + c->video_extra_data_len, c->regs + VE_H264_RAM_WRITE_DATA);
 
678
                        writel(cedrus_mem_get_bus_addr(c->output->rec), c->regs + VE_H264_RAM_WRITE_DATA);
 
679
                        writel(cedrus_mem_get_bus_addr(c->output->rec) + c->output->luma_size, c->regs + VE_H264_RAM_WRITE_DATA);
 
680
                        writel(cedrus_mem_get_bus_addr(output_p->extra_data), c->regs + VE_H264_RAM_WRITE_DATA);
 
681
                        writel(cedrus_mem_get_bus_addr(output_p->extra_data) + c->video_extra_data_len, c->regs + VE_H264_RAM_WRITE_DATA);
681
682
                        writel(0, c->regs + VE_H264_RAM_WRITE_DATA);
682
683
 
683
684
                        output_p->pos = i;
697
698
                        writel(frame_list[i]->top_pic_order_cnt, c->regs + VE_H264_RAM_WRITE_DATA);
698
699
                        writel(frame_list[i]->bottom_pic_order_cnt, c->regs + VE_H264_RAM_WRITE_DATA);
699
700
                        writel(surface_p->pic_type << 8, c->regs + VE_H264_RAM_WRITE_DATA);
700
 
                        writel(surface->rec->phys, c->regs + VE_H264_RAM_WRITE_DATA);
701
 
                        writel(surface->rec->phys + surface->luma_size, c->regs + VE_H264_RAM_WRITE_DATA);
702
 
                        writel(surface_p->extra_data->phys, c->regs + VE_H264_RAM_WRITE_DATA);
703
 
                        writel(surface_p->extra_data->phys + c->video_extra_data_len, c->regs + VE_H264_RAM_WRITE_DATA);
 
701
                        writel(cedrus_mem_get_bus_addr(surface->rec), c->regs + VE_H264_RAM_WRITE_DATA);
 
702
                        writel(cedrus_mem_get_bus_addr(surface->rec) + surface->luma_size, c->regs + VE_H264_RAM_WRITE_DATA);
 
703
                        writel(cedrus_mem_get_bus_addr(surface_p->extra_data), c->regs + VE_H264_RAM_WRITE_DATA);
 
704
                        writel(cedrus_mem_get_bus_addr(surface_p->extra_data) + c->video_extra_data_len, c->regs + VE_H264_RAM_WRITE_DATA);
704
705
                        writel(0, c->regs + VE_H264_RAM_WRITE_DATA);
705
706
                }
706
707
        }
770
771
                output_p->pic_type = PIC_TYPE_FRAME;
771
772
 
772
773
        // activate H264 engine
773
 
        c->regs = ve_get(VE_ENGINE_H264, (decoder->width >= 2048 ? 0x1 : 0x0) << 21);
 
774
        c->regs = cedrus_ve_get(decoder->device->cedrus, CEDRUS_ENGINE_H264, (decoder->width >= 2048 ? 0x1 : 0x0) << 21);
774
775
 
775
776
        // some buffers
776
 
        uint32_t extra_buffers = decoder_p->extra_data->phys;
 
777
        uint32_t extra_buffers = cedrus_mem_get_bus_addr(decoder_p->extra_data);
777
778
        writel(extra_buffers, c->regs + VE_H264_EXTRA_BUFFER1);
778
779
        writel(extra_buffers + 0x48000, c->regs + VE_H264_EXTRA_BUFFER2);
779
 
        if (ve_get_version() == 0x1625 || decoder->width >= 2048)
 
780
        if (cedrus_get_ve_version(decoder->device->cedrus) == 0x1625 || decoder->width >= 2048)
780
781
        {
781
782
                int size = (c->picture_width_in_mbs_minus1 + 32) * 192;
782
783
                size = (size + 4095) & ~4095;
803
804
 
804
805
        // sdctrl
805
806
        writel(0x00000000, c->regs + VE_H264_SDROT_CTRL);
806
 
        if (ve_get_version() == 0x1680)
 
807
        if (cedrus_get_ve_version(decoder->device->cedrus) == 0x1680)
807
808
        {
808
 
                writel(c->output->yuv->data->phys, c->regs + VE_H264_SDROT_LUMA);
809
 
                writel(c->output->yuv->data->phys + c->output->luma_size, c->regs + VE_H264_SDROT_CHROMA);
 
809
                writel(cedrus_mem_get_bus_addr(c->output->yuv->data), c->regs + VE_H264_SDROT_LUMA);
 
810
                writel(cedrus_mem_get_bus_addr(c->output->yuv->data) + c->output->luma_size, c->regs + VE_H264_SDROT_CHROMA);
810
811
                writel((0x2 << 30) | (0x1 << 28) | (c->output->chroma_size / 2), c->regs + VE_EXTRA_OUT_FMT_OFFSET);
811
812
        }
812
813
 
822
823
                h264_header_t *h = &c->header;
823
824
                memset(h, 0, sizeof(h264_header_t));
824
825
 
825
 
                pos = find_startcode(decoder->data->virt, len, pos) + 3;
 
826
                pos = find_startcode(cedrus_mem_get_pointer(decoder->data), len, pos) + 3;
826
827
 
827
 
                h->nal_unit_type = ((uint8_t *)(decoder->data->virt))[pos++] & 0x1f;
 
828
                h->nal_unit_type = ((uint8_t *)cedrus_mem_get_pointer(decoder->data))[pos++] & 0x1f;
828
829
 
829
830
                if (h->nal_unit_type != 5 && h->nal_unit_type != 1)
830
831
                {
833
834
                }
834
835
 
835
836
                // Enable startcode detect and ??
836
 
                writel((0x1 << 25) | (0x1 << 10) | ((ve_get_version() == 0x1680) << 9), c->regs + VE_H264_CTRL);
 
837
                writel((0x1 << 25) | (0x1 << 10) | ((cedrus_get_ve_version(decoder->device->cedrus) == 0x1680) << 9), c->regs + VE_H264_CTRL);
837
838
 
838
839
                // input buffer
839
840
                writel((len - pos) * 8, c->regs + VE_H264_VLD_LEN);
840
841
                writel(pos * 8, c->regs + VE_H264_VLD_OFFSET);
841
 
                uint32_t input_addr = decoder->data->phys;
 
842
                uint32_t input_addr = cedrus_mem_get_bus_addr(decoder->data);
842
843
                writel(input_addr + VBV_SIZE - 1, c->regs + VE_H264_VLD_END);
843
844
                writel((input_addr & 0x0ffffff0) | (input_addr >> 28) | (0x7 << 28), c->regs + VE_H264_VLD_ADDR);
844
845
 
938
939
                // SHOWTIME
939
940
                writel(0x8, c->regs + VE_H264_TRIGGER);
940
941
 
941
 
                ve_wait(1);
 
942
                cedrus_ve_wait(decoder->device->cedrus, 1);
942
943
 
943
944
                // clear status flags
944
945
                writel(readl(c->regs + VE_H264_STATUS), c->regs + VE_H264_STATUS);
950
951
 
951
952
err_ve_put:
952
953
        // stop H264 engine
953
 
        ve_put();
 
954
        cedrus_ve_put(decoder->device->cedrus);
954
955
err_free:
955
956
        free(c);
956
957
        return ret;
963
964
                return VDP_STATUS_RESOURCES;
964
965
 
965
966
        int extra_data_size = 320 * 1024;
966
 
        if (ve_get_version() == 0x1625 || decoder->width >= 2048)
 
967
        if (cedrus_get_ve_version(decoder->device->cedrus) == 0x1625 || decoder->width >= 2048)
967
968
        {
968
969
                // Engine version 0x1625 needs two extra buffers
969
970
                extra_data_size += ((decoder->width - 1) / 16 + 32) * 192;
971
972
                extra_data_size += ((decoder->width - 1) / 16 + 64) * 80;
972
973
        }
973
974
 
974
 
        decoder_p->extra_data = ve_malloc(extra_data_size);
 
975
        decoder_p->extra_data = cedrus_mem_alloc(decoder->device->cedrus, extra_data_size);
975
976
        if (!decoder_p->extra_data)
976
977
        {
977
978
                free(decoder_p);