diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/libvdpau/Makefile.am | 2 | ||||
-rw-r--r-- | src/libvdpau/dpb.c | 222 | ||||
-rw-r--r-- | src/libvdpau/dpb.h | 41 | ||||
-rw-r--r-- | src/libvdpau/h264_parser.c (renamed from src/libvdpau/nal_parser.c) | 209 | ||||
-rw-r--r-- | src/libvdpau/h264_parser.h | 48 | ||||
-rw-r--r-- | src/libvdpau/nal.c | 46 | ||||
-rw-r--r-- | src/libvdpau/nal.h | 350 | ||||
-rw-r--r-- | src/libvdpau/nal_parser.h | 377 | ||||
-rw-r--r-- | src/libvdpau/vdpau_h264.c | 14 |
9 files changed, 845 insertions, 464 deletions
diff --git a/src/libvdpau/Makefile.am b/src/libvdpau/Makefile.am index 31afca222..6cbce1016 100644 --- a/src/libvdpau/Makefile.am +++ b/src/libvdpau/Makefile.am @@ -10,6 +10,6 @@ endif xineplug_LTLIBRARIES = $(vdpau_h264_module) -xineplug_decode_vdpau_h264_la_SOURCES = nal_parser.c vdpau_h264.c +xineplug_decode_vdpau_h264_la_SOURCES = nal.c dpb.c h264_parser.c vdpau_h264.c xineplug_decode_vdpau_h264_la_CFLAGS = $(AM_CFLAGS) $(VDPAU_CFLAGS) xineplug_decode_vdpau_h264_la_LIBADD = $(XINE_LIB) $(DYNAMIC_LD_LIBS) diff --git a/src/libvdpau/dpb.c b/src/libvdpau/dpb.c new file mode 100644 index 000000000..460149ea3 --- /dev/null +++ b/src/libvdpau/dpb.c @@ -0,0 +1,222 @@ +/* + * dpb.c + * + * Created on: 07.12.2008 + * Author: julian + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "dpb.h" + +struct decoded_picture* init_decoded_picture(struct nal_unit *src_nal, + VdpVideoSurface surface) +{ + struct decoded_picture *pic = malloc(sizeof(struct decoded_picture)); + pic->nal = init_nal_unit(); + copy_nal_unit(pic->nal, src_nal); + pic->surface = surface; + pic->next = NULL; + + return pic; +} + +void free_decoded_picture(struct decoded_picture *pic) +{ + free_nal_unit(pic->nal); +} + +struct decoded_picture* dpb_get_picture(struct dpb *dpb, uint32_t picnum) +{ + struct decoded_picture *pic = dpb->pictures; + + if (pic != NULL) + do { + if (pic->nal->curr_pic_num == picnum) + return pic; + } while ((pic = pic->next) != NULL); + + return NULL; +} + +struct decoded_picture* dpb_get_picture_by_ltpn(struct dpb *dpb, + uint32_t longterm_picnum) +{ + struct decoded_picture *pic = dpb->pictures; + + if (pic != NULL) + do { + if (pic->nal->long_term_pic_num == longterm_picnum) + return pic; + } while ((pic = pic->next) != NULL); + + return NULL; +} + +struct decoded_picture* dpb_get_picture_by_ltidx(struct dpb *dpb, + uint32_t longterm_idx) +{ + struct decoded_picture *pic = dpb->pictures; + + if (pic != NULL) + do { + if (pic->nal->long_term_frame_idx == longterm_idx) + return pic; + } while ((pic = pic->next) != NULL); + + return NULL; +} + +int dpb_remove_picture(struct dpb *dpb, uint32_t picnum) +{ + struct decoded_picture *pic = dpb->pictures; + struct decoded_picture *last_pic = NULL; + + if (pic != NULL) + do { + if (pic->nal->curr_pic_num == picnum) { + // FIXME: free the picture.... + + if (last_pic != NULL) + last_pic->next = pic->next; + else + dpb->pictures = pic->next; + + free_decoded_picture(pic); + return 0; + } + + last_pic = pic; + } while ((pic = pic->next) != NULL); + + return -1; +} + +int dpb_remove_picture_by_ltpn(struct dpb *dpb, uint32_t longterm_picnum) +{ + struct decoded_picture *pic = dpb->pictures; + struct decoded_picture *last_pic = NULL; + + if (pic != NULL) + do { + if (pic->nal->long_term_pic_num == longterm_picnum) { + // FIXME: free the picture.... + + if (last_pic != NULL) + last_pic->next = pic->next; + else + dpb->pictures = pic->next; + + free_decoded_picture(pic); + return 0; + } + + last_pic = pic; + } while ((pic = pic->next) != NULL); + + return -1; +} + +int dpb_remove_picture_by_ltidx(struct dpb *dpb, uint32_t longterm_idx) +{ + struct decoded_picture *pic = dpb->pictures; + struct decoded_picture *last_pic = NULL; + + if (pic != NULL) + do { + if (pic->nal->long_term_frame_idx == longterm_idx) { + // FIXME: free the picture.... + + if (last_pic != NULL) + last_pic->next = pic->next; + else + dpb->pictures = pic->next; + + free_decoded_picture(pic); + return 0; + } + + last_pic = pic; + } while ((pic = pic->next) != NULL); + + return -1; +} + +int dpb_remove_ltidx_gt(struct dpb *dpb, uint32_t longterm_max) +{ + struct decoded_picture *pic = dpb->pictures; + struct decoded_picture *last_pic = NULL; + + if (pic != NULL) + do { + if (pic->nal->long_term_frame_idx > longterm_max) { + // FIXME: free the picture.... + if (last_pic != NULL) + last_pic->next = pic->next; + else + dpb->pictures = pic->next; + + + free_decoded_picture(pic); + + /* don't increase last_pic to current pic + * in case we delete current pic */ + continue; + } + + last_pic = pic; + } while ((pic = pic->next) != NULL); + + return 0; +} + +int dpb_add_picture(struct dpb *dpb, struct decoded_picture *pic) +{ + pic->next = dpb->pictures; + dpb->pictures = pic; + + return 0; +} + +int dpb_flush(struct dpb *dpb) +{ + struct decoded_picture *pic = dpb->pictures; + struct decoded_picture *last_pic = NULL; + + if (pic != NULL) + do { + //FIXME: free the picture + + last_pic = pic; + } while ((pic = pic->next) != NULL); + + dpb->pictures = NULL; + + return 0; +} + +void fill_vdpau_reference_list(struct dpb *dpb, VdpReferenceFrameH264 *reflist) +{ + struct decoded_picture *pic = dpb->pictures; + struct decoded_picture *last_pic = NULL; + + int i = 0; + + if (pic != NULL) + do { + if (pic->nal->nal_ref_idc != 0) { + reflist[i].surface = pic->surface; + reflist[i].is_long_term = pic->nal->used_for_long_term_ref; + reflist[i].top_is_reference = pic->nal->slc->field_pic_flag + ? (pic->nal->slc->bottom_field_flag ? 0 : 1) : 1; + reflist[i].bottom_is_reference = pic->nal->slc->field_pic_flag + ? (pic->nal->slc->bottom_field_flag ? 1 : 0) : 1; + reflist[i].field_order_cnt[0] = pic->nal->top_field_order_cnt; + reflist[i].field_order_cnt[1] = pic->nal->bottom_field_order_cnt; + i++; + } + last_pic = pic; + } while ((pic = pic->next) != NULL && i < 16); +} diff --git a/src/libvdpau/dpb.h b/src/libvdpau/dpb.h new file mode 100644 index 000000000..8aa430c26 --- /dev/null +++ b/src/libvdpau/dpb.h @@ -0,0 +1,41 @@ +/* + * dpb.h + * + * Created on: 06.12.2008 + * Author: julian + */ + +#ifndef DPB_H_ +#define DPB_H_ + +#include "nal.h" + +struct decoded_picture { + VdpVideoSurface surface; + struct nal_unit *nal; + + struct decoded_picture *next; +}; + +/* Decoded Picture Buffer */ +struct dpb { + struct decoded_picture *pictures; +}; + +struct decoded_picture* init_decoded_picture(struct nal_unit *src_nal, + VdpVideoSurface surface); +void free_decoded_picture(struct decoded_picture *pic); + +struct decoded_picture* dpb_get_picture(struct dpb *dpb, uint32_t picnum); +struct decoded_picture* dpb_get_picture_by_ltpn(struct dpb *dpb, uint32_t longterm_picnum); +struct decoded_picture* dpb_get_picture_by_ltidx(struct dpb *dpb, uint32_t longterm_idx); +int dpb_remove_picture(struct dpb *dpb, uint32_t picnum); +int dpb_remove_picture_by_ltpn(struct dpb *dpb, uint32_t longterm_picnum); +int dpb_remove_picture_by_ltidx(struct dpb *dpb, uint32_t longterm_idx); +int dpb_remove_ltidx_gt(struct dpb *dpb, uint32_t longterm_max); +int dpb_add_picture(struct dpb *dpb, struct decoded_picture *pic); +int dpb_flush(struct dpb *dpb); + +void fill_vdpau_reference_list(struct dpb *dpb, VdpReferenceFrameH264 *reflist); + +#endif /* DPB_H_ */ diff --git a/src/libvdpau/nal_parser.c b/src/libvdpau/h264_parser.c index bf5ad3287..7ae1cc216 100644 --- a/src/libvdpau/nal_parser.c +++ b/src/libvdpau/h264_parser.c @@ -2,7 +2,8 @@ #include <stdlib.h> #include <math.h> -#include "nal_parser.h" +#include "h264_parser.h" +#include "nal.h" /* default scaling_lists according to Table 7-2 */ uint8_t default_4x4_intra[16] = { 6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, @@ -47,8 +48,12 @@ uint8_t parse_pps(struct buf_reader *buf, struct pic_parameter_set_rbsp *pps, uint8_t parse_slice_header(struct buf_reader *buf, struct nal_parser *parser); void parse_ref_pic_list_reordering(struct buf_reader *buf, struct nal_unit *nal); +void decode_ref_pic_marking(uint32_t memory_management_control_operation, + struct nal_parser *parser); void parse_pred_weight_table(struct buf_reader *buf, struct nal_unit *nal); -void parse_dec_ref_pic_marking(struct buf_reader *buf, struct nal_unit *nal); +void parse_dec_ref_pic_marking(struct buf_reader *buf, struct nal_parser *parser); + +/* here goes the parser implementation */ static void decode_nal(uint8_t **ret, int *len_ret, uint8_t *buf, int buf_len) { @@ -71,23 +76,6 @@ static void decode_nal(uint8_t **ret, int *len_ret, uint8_t *buf, int buf_len) *len_ret = pos - *ret; } -/*uint32_t read_bits(struct buf_reader *buf, int len) - { - uint32_t bits = 0x00; - int i, j; - for(i=0, j=0; i<len; i++) { - while(buf->cur_offset >= 8) { - buf->cur_pos++; - buf->cur_offset -= 8; - } - uint8_t bit = (*buf->cur_pos >> (7 - buf->cur_offset)) & 0x01; - bits |= ((uint32_t)bit) << i; - buf->cur_offset++; - } - printf("ret: 0x%08x\n", bits); - return bits; - }*/ - static inline uint32_t read_bits(struct buf_reader *buf, int len) { static uint32_t i_mask[33] = { 0x00, 0x01, 0x03, 0x07, 0x0f, 0x1f, 0x3f, @@ -185,8 +173,6 @@ int parse_nal_header(struct buf_reader *buf, struct nal_parser *parser) case NAL_SPS: decode_nal(&ibuf.buf, &ibuf.len, buf->cur_pos, buf->len - 1); ibuf.cur_pos = ibuf.buf; - if (!nal->sps) - nal->sps = malloc(sizeof(struct seq_parameter_set_rbsp)); memset(nal->sps, 0x00, sizeof(struct seq_parameter_set_rbsp)); @@ -195,9 +181,6 @@ int parse_nal_header(struct buf_reader *buf, struct nal_parser *parser) ret = NAL_SPS; break; case NAL_PPS: - if (!nal->pps) - nal->pps = malloc(sizeof(struct pic_parameter_set_rbsp)); - memset(nal->pps, 0x00, sizeof(struct pic_parameter_set_rbsp)); parse_pps(buf, nal->pps, nal->sps); @@ -209,10 +192,7 @@ int parse_nal_header(struct buf_reader *buf, struct nal_parser *parser) case NAL_PART_C: case NAL_SLICE_IDR: if (nal->sps && nal->pps) { - if (!nal->slc) - nal->slc = malloc(sizeof(struct slice_header)); - else - memset(nal->slc, 0x00, sizeof(struct slice_header)); + memset(nal->slc, 0x00, sizeof(struct slice_header)); parse_slice_header(buf, parser); ret = nal->nal_unit_type; @@ -229,7 +209,6 @@ int parse_nal_header(struct buf_reader *buf, struct nal_parser *parser) void calculate_pic_order(struct nal_parser *parser) { struct nal_unit *nal = parser->current_nal; - struct dpb *dpb = parser->dpb; struct seq_parameter_set_rbsp *sps = nal->sps; struct pic_parameter_set_rbsp *pps = nal->pps; @@ -237,34 +216,6 @@ void calculate_pic_order(struct nal_parser *parser) if (!sps || !pps || !slc) return; - /*uint32_t max_frame_num = pow(2, sps->log2_max_frame_num_minus4+4); - if(dpb->max_frame_num == 0) - dpb->max_frame_num = max_frame_num; - - if(dpb->max_frame_num != max_frame_num && dpb->max_frame_num != 0) - printf("ERROR, FIXME, max_frame_num changed"); - - / * calculate frame_num based stuff * / - if(nal->nal_unit_type == NAL_SLICE_IDR) { - dpb->prev_ref_frame_number = 0; - } else { - // FIXME: understand p92 in h264 spec - } - - if(slc->frame_num != dpb->prev_ref_frame_number) { - memset(dpb->non_existing_pictures, 0, 32); - int i = 0; - dpb->unused_short_term_frame_num = (dpb->prev_ref_frame_number + 1) % dpb->max_frame_num; - dpb->non_existing_pictures[i] = dpb->unused_short_term_frame_num; - i++; - - while(dpb->unused_short_term_frame_num != slc->frame_num) { - dpb->unused_short_term_frame_num = (dpb->unused_short_term_frame_num + 1) % dpb->max_frame_num; - dpb->non_existing_pictures[i] = dpb->unused_short_term_frame_num; - i++; - } - }*/ - if (sps->pic_order_cnt_type == 0) { if (nal->nal_unit_type == NAL_SLICE_IDR) { parser->prev_pic_order_cnt_lsb = 0; @@ -287,16 +238,20 @@ void calculate_pic_order(struct nal_parser *parser) parser->pic_order_cnt_msb = parser->prev_pic_order_cnt_msb; if (!slc->bottom_field_flag) { - parser->top_field_order_cnt = parser->pic_order_cnt_msb + nal->top_field_order_cnt = parser->pic_order_cnt_msb + slc->pic_order_cnt_lsb; - parser->bottom_field_order_cnt = 0; + + if (!slc->field_pic_flag) + nal->bottom_field_order_cnt = nal->top_field_order_cnt; + else + nal->bottom_field_order_cnt = 0; } else - parser->bottom_field_order_cnt = parser->pic_order_cnt_msb + nal->bottom_field_order_cnt = parser->pic_order_cnt_msb + slc->pic_order_cnt_lsb; if (parser->field == -1) - parser->bottom_field_order_cnt += slc->delta_pic_order_cnt_bottom; + nal->bottom_field_order_cnt += slc->delta_pic_order_cnt_bottom; } } @@ -362,8 +317,8 @@ uint8_t parse_sps(struct buf_reader *buf, struct seq_parameter_set_rbsp *sps) buf->cur_pos = buf->buf + 3; sps->seq_parameter_set_id = read_exp_golomb(buf); - if (sps->profile_idc == 100 || sps->profile_idc == 110 || - sps->profile_idc == 122 || sps->profile_idc == 144) { + if (sps->profile_idc == 100 || sps->profile_idc == 110 || sps->profile_idc + == 122 || sps->profile_idc == 144) { sps->chroma_format_idc = read_exp_golomb(buf); if (sps->chroma_format_idc == 3) { sps->residual_colour_transform_flag = read_bits(buf, 1); @@ -641,6 +596,11 @@ uint8_t parse_slice_header(struct buf_reader *buf, struct nal_parser *parser) slc->bottom_field_flag = 0; } + if (slc->field_pic_flag == 0) + nal->curr_pic_num = slc->frame_num; + else + nal->curr_pic_num = 2 * slc->frame_num + 1; + if (nal->nal_unit_type == NAL_SLICE_IDR) slc->idr_pic_id = read_exp_golomb(buf); @@ -688,7 +648,7 @@ uint8_t parse_slice_header(struct buf_reader *buf, struct nal_parser *parser) /* --- dec_ref_pic_marking --- */ if (nal->nal_ref_idc != 0) - parse_dec_ref_pic_marking(buf, nal); + parse_dec_ref_pic_marking(buf, parser); return 0; } @@ -807,8 +767,102 @@ void parse_pred_weight_table(struct buf_reader *buf, struct nal_unit *nal) } } -void parse_dec_ref_pic_marking(struct buf_reader *buf, struct nal_unit *nal) +void decode_ref_pic_marking(uint32_t memory_management_control_operation, + struct nal_parser *parser) { + struct nal_unit *nal = parser->current_nal; + struct seq_parameter_set_rbsp *sps = nal->sps; + struct pic_parameter_set_rbsp *pps = nal->pps; + struct slice_header *slc = nal->slc; + struct dpb *dpb = &parser->dpb; + if (!sps || !pps || !slc) + return; + + if (memory_management_control_operation == 1) { + // short-term -> unused for reference + uint32_t pic_num_x = nal->curr_pic_num + - (slc->dec_ref_pic_marking.difference_of_pic_nums_minus1 + 1); + struct decoded_picture* pic = dpb_get_picture(dpb, pic_num_x); + if (pic != NULL) { + if (pic->nal->slc->field_pic_flag == 0) + dpb_remove_picture(dpb, pic_num_x); + else { + dpb_remove_picture(dpb, pic_num_x); + printf("FIXME: We might need do delete more from the DPB...\n"); + // FIXME: some more handling needed here?! See 8.2.5.4.1, p. 120 + } + } + } + else if (memory_management_control_operation == 2) { + // long-term -> unused for reference + struct decoded_picture* pic = dpb_get_picture_by_ltpn(dpb, + slc->dec_ref_pic_marking.long_term_pic_num); + if (pic != NULL) { + if (pic->nal->slc->field_pic_flag == 0) + dpb_remove_picture_by_ltpn(dpb, + slc->dec_ref_pic_marking.long_term_pic_num); + else { + dpb_remove_picture_by_ltpn(dpb, + slc->dec_ref_pic_marking.long_term_pic_num); + printf("FIXME: We might need do delete more from the DPB...\n"); + } + } + } + else if (memory_management_control_operation == 3) { + // short-term -> long-term, set long-term frame index + uint32_t pic_num_x = nal->curr_pic_num + - (slc->dec_ref_pic_marking.difference_of_pic_nums_minus1 + 1); + struct decoded_picture* pic = dpb_get_picture_by_ltidx(dpb, + slc->dec_ref_pic_marking.long_term_pic_num); + if (pic != NULL) + dpb_remove_picture_by_ltidx(dpb, + slc->dec_ref_pic_marking.long_term_frame_idx); + + if (pic->nal->slc->field_pic_flag == 0) { + pic = dpb_get_picture(dpb, pic_num_x); + pic->nal->long_term_frame_idx + = slc->dec_ref_pic_marking.long_term_frame_idx; + } + else + printf("FIXME: B Set frame %d to long-term ref\n", pic_num_x); + } + else if (memory_management_control_operation == 4) { + // set max-long-term frame index, + // mark all long-term pictures with long-term frame idx + // greater max-long-term farme idx as unused for ref + if (slc->dec_ref_pic_marking.max_long_term_frame_idx_plus1 == 0) + dpb_remove_ltidx_gt(dpb, 0); + else + dpb_remove_ltidx_gt(dpb, + slc->dec_ref_pic_marking.max_long_term_frame_idx_plus1 - 1); + } + else if (memory_management_control_operation == 5) { + // mark all ref pics as unused for reference, + // set max-long-term frame index = no long-term frame idxs + dpb_flush(dpb); + } + else if (memory_management_control_operation == 6) { + // mark current picture as used for long-term ref, + // assing long-term frame idx to it + struct decoded_picture* pic = dpb_get_picture_by_ltidx(dpb, + slc->dec_ref_pic_marking.long_term_frame_idx); + if (pic != NULL) + dpb_remove_picture_by_ltidx(dpb, + slc->dec_ref_pic_marking.long_term_frame_idx); + + nal->long_term_frame_idx = slc->dec_ref_pic_marking.long_term_frame_idx; + + if (slc->field_pic_flag == 0) { + nal->used_for_long_term_ref = 1; + } + else + printf("FIXME: BY Set frame to long-term ref\n"); + } +} + +void parse_dec_ref_pic_marking(struct buf_reader *buf, struct nal_parser *parser) +{ + struct nal_unit *nal = parser->current_nal; struct seq_parameter_set_rbsp *sps = nal->sps; struct pic_parameter_set_rbsp *pps = nal->pps; struct slice_header *slc = nal->slc; @@ -845,6 +899,9 @@ void parse_dec_ref_pic_marking(struct buf_reader *buf, struct nal_unit *nal) if (slc->dec_ref_pic_marking.memory_management_control_operation == 4) slc->dec_ref_pic_marking.max_long_term_frame_idx_plus1 = read_exp_golomb(buf); + + decode_ref_pic_marking( + slc->dec_ref_pic_marking.memory_management_control_operation, parser); } while (slc->dec_ref_pic_marking.memory_management_control_operation != 0); } @@ -860,10 +917,8 @@ struct nal_parser* init_parser() parser->buf_len = 0; parser->found_sps = 0; parser->found_pps = 0; - parser->nal0 = malloc(sizeof(struct nal_unit)); - memset(parser->nal0, 0x00, sizeof(struct nal_unit)); - parser->nal1 = malloc(sizeof(struct nal_unit)); - memset(parser->nal1, 0x00, sizeof(struct nal_unit)); + parser->nal0 = init_nal_unit(); + parser->nal1 = init_nal_unit(); parser->current_nal = parser->nal0; parser->last_nal = parser->nal1; @@ -985,33 +1040,26 @@ int parse_nal(uint8_t *buf, int buf_len, struct nal_parser *parser) parser->slice = 1; if (nal->slc == NULL || last_nal->slc == NULL) { - printf("A\n"); ret = 1; } if (nal->slc && last_nal->slc && (nal->slc->frame_num != last_nal->slc->frame_num)) { - printf("B\n"); ret = 1; } if (nal->slc && last_nal->slc && (nal->slc->pic_parameter_set_id != last_nal->slc->pic_parameter_set_id)) { - printf("C\n"); ret = 1; } if (nal->slc && last_nal->slc && (nal->slc->field_pic_flag != last_nal->slc->field_pic_flag)) { - printf("D\n"); ret = 1; } - if (nal->slc && last_nal->slc && (nal->slc->bottom_field_flag != -1 - && last_nal->slc->bottom_field_flag != -1 - && nal->slc->bottom_field_flag != last_nal->slc->bottom_field_flag)) { - printf("E\n"); + if (nal->slc && last_nal->slc && nal->slc->bottom_field_flag + != last_nal->slc->bottom_field_flag) { ret = 1; } if (nal->nal_ref_idc != last_nal->nal_ref_idc && (nal->nal_ref_idc == 0 || last_nal->nal_ref_idc == 0)) { - printf("F\n"); ret = 1; } if (nal->sps && nal->slc && last_nal->slc && (nal->sps->pic_order_cnt_type @@ -1019,7 +1067,6 @@ int parse_nal(uint8_t *buf, int buf_len, struct nal_parser *parser) && (nal->slc->pic_order_cnt_lsb != last_nal->slc->pic_order_cnt_lsb || nal->slc->delta_pic_order_cnt_bottom != last_nal->slc->delta_pic_order_cnt_bottom))) { - printf("G\n"); ret = 1; } if (nal->slc && last_nal->slc && (nal->sps->pic_order_cnt_type == 1 @@ -1028,18 +1075,15 @@ int parse_nal(uint8_t *buf, int buf_len, struct nal_parser *parser) != last_nal->slc->delta_pic_order_cnt[0] || nal->slc->delta_pic_order_cnt[1] != last_nal->slc->delta_pic_order_cnt[1]))) { - printf("H\n"); ret = 1; } if (nal->nal_unit_type != last_nal->nal_unit_type && (nal->nal_unit_type == 5 || last_nal->nal_unit_type == 5)) { - printf("I\n"); ret = 1; } if (nal->slc && last_nal->slc && (nal->nal_unit_type == 5 && last_nal->nal_unit_type == 5 && nal->slc->idr_pic_id != last_nal->slc->idr_pic_id)) { - printf("J\n"); ret = 1; } @@ -1067,7 +1111,6 @@ int parse_nal(uint8_t *buf, int buf_len, struct nal_parser *parser) return 2; } else if (res >= NAL_SEI) { - //printf("New Frame\n"); return 2; } diff --git a/src/libvdpau/h264_parser.h b/src/libvdpau/h264_parser.h new file mode 100644 index 000000000..e067f9741 --- /dev/null +++ b/src/libvdpau/h264_parser.h @@ -0,0 +1,48 @@ +#ifndef NAL_PARSER_H_ +#define NAL_PARSER_H_ + +#include <stdlib.h> + +#include "xine_internal.h" +#include "nal.h" +#include "dpb.h" + +#define MAX_FRAME_SIZE 1024*1024 + +struct nal_parser { + uint8_t buf[MAX_FRAME_SIZE]; + int buf_len; + int found_sps; + int found_pps; + int last_nal_res; + + int is_idr; + int field; /* 0=top, 1=bottom, -1=both */ + int slice; + int slice_cnt; + int have_top; + int have_frame; + + struct nal_unit *nal0; + struct nal_unit *nal1; + struct nal_unit *current_nal; + struct nal_unit *last_nal; + + uint32_t pic_order_cnt_lsb; + uint32_t pic_order_cnt_msb; + uint32_t prev_pic_order_cnt_lsb; + uint32_t prev_pic_order_cnt_msb; + + struct dpb dpb; +}; + +int parse_nal(uint8_t *buf, int buf_len, struct nal_parser *parser); + +int seek_for_nal(uint8_t *buf, int buf_len); + +struct nal_parser* init_parser(); +void free_parser(struct nal_parser *parser); +int parse_frame(struct nal_parser *parser, uint8_t *inbuf, int inbuf_len, + uint8_t **ret_buf, uint32_t *ret_len, uint32_t *ret_slice_cnt); + +#endif diff --git a/src/libvdpau/nal.c b/src/libvdpau/nal.c new file mode 100644 index 000000000..a9717d76e --- /dev/null +++ b/src/libvdpau/nal.c @@ -0,0 +1,46 @@ +/* + * nal.c + * + * Created on: 07.12.2008 + * Author: julian + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include "nal.h" +#include "xine_internal.h" + +struct nal_unit* init_nal_unit() +{ + struct nal_unit *nal = malloc(sizeof(struct nal_unit)); + memset(nal, 0x00, sizeof(struct nal_unit)); + + nal->sps = malloc(sizeof(struct seq_parameter_set_rbsp)); + nal->pps = malloc(sizeof(struct pic_parameter_set_rbsp)); + nal->slc = malloc(sizeof(struct slice_header)); + + return nal; +} + +void free_nal_unit(struct nal_unit *nal) +{ + free(nal->sps); + free(nal->pps); + free(nal->slc); + free(nal); +} + +void copy_nal_unit(struct nal_unit *dest, struct nal_unit *src) +{ + /* size without pps, sps and slc units: */ + int size = sizeof(struct nal_unit) - sizeof(struct seq_parameter_set_rbsp*) + - sizeof(struct pic_parameter_set_rbsp*) - sizeof(struct slice_header*); + + xine_fast_memcpy(dest, src, size); + + xine_fast_memcpy(dest->sps, src->sps, sizeof(struct seq_parameter_set_rbsp)); + xine_fast_memcpy(dest->pps, src->pps, sizeof(struct pic_parameter_set_rbsp)); + xine_fast_memcpy(dest->slc, src->slc, sizeof(struct slice_header)); +} diff --git a/src/libvdpau/nal.h b/src/libvdpau/nal.h new file mode 100644 index 000000000..c07c1d9a3 --- /dev/null +++ b/src/libvdpau/nal.h @@ -0,0 +1,350 @@ +/* + * nal.h + * + * Created on: 07.12.2008 + * Author: julian + */ + +#ifndef NAL_H_ +#define NAL_H_ +#include <stdint.h> +#include <vdpau/vdpau.h> + +enum nal_unit_types +{ + NAL_UNSPECIFIED = 0, + NAL_SLICE, + NAL_PART_A, + NAL_PART_B, + NAL_PART_C, + NAL_SLICE_IDR, + NAL_SEI, + NAL_SPS, + NAL_PPS, + NAL_AU_DELIMITER, + NAL_END_OF_SEQUENCE, + NAL_END_OF_STREAM, + NAL_FILLER_DATA, + NAL_SPS_EXT +}; + +/* slice types repeat from 5-9, we + * need a helper function for comparison + */ +enum slice_types +{ + SLICE_P = 0, SLICE_B, SLICE_I, SLICE_SP, SLICE_SI +}; + +enum aspect_ratio +{ + ASPECT_UNSPECIFIED = 0, + ASPECT_1_1, + ASPECT_12_11, + ASPECT_10_11, + ASPECT_16_11, + ASPECT_40_33, + ASPECT_24_11, + ASPECT_20_11, + ASPECT_32_11, + ASPECT_80_33, + ASPECT_18_11, + ASPECT_15_11, + ASPECT_64_33, + ASPECT_160_99, + ASPECT_4_3, + ASPECT_3_2, + ASPECT_2_1, + ASPECT_RESERVED +}; + +static inline uint32_t slice_type(uint32_t slice_type) +{ + return (slice_type < 10 ? slice_type % 5 : slice_type); +} + +struct nal_unit +{ + uint8_t nal_ref_idc; // 0x03 + uint8_t nal_unit_type; // 0x1f + + uint32_t curr_pic_num; + uint8_t used_for_long_term_ref; + uint32_t long_term_pic_num; + uint32_t long_term_frame_idx; + + uint32_t top_field_order_cnt; + uint32_t bottom_field_order_cnt; + + struct seq_parameter_set_rbsp *sps; + struct pic_parameter_set_rbsp *pps; + struct slice_header *slc; +}; + +struct hrd_parameters +{ + uint32_t cpb_cnt_minus1; + uint8_t bit_rate_scale; + uint8_t cpb_size_scale; + + uint32_t bit_rate_value_minus1[32]; + uint32_t cpb_size_value_minus1[32]; + uint8_t cbr_flag[32]; + + uint8_t initial_cpb_removal_delay_length_minus1; + uint8_t cpb_removal_delay_length_minus1; + uint8_t dpb_output_delay_length_minus1; + uint8_t time_offset_length; +}; + +struct seq_parameter_set_rbsp +{ + uint8_t profile_idc; // 0xff + uint8_t constraint_setN_flag; // 0x0f + uint8_t level_idc; // 0xff + uint32_t seq_parameter_set_id; + uint32_t chroma_format_idc; + uint8_t residual_colour_transform_flag; // 0x01 + uint32_t bit_depth_luma_minus8; + uint32_t bit_depth_chroma_minus8; + uint8_t qpprime_y_zero_transform_bypass_flag; + uint8_t seq_scaling_matrix_present_flag; + + /* if(seq_scaling_matrix_present_flag) */ + uint8_t seq_scaling_list_present_flag[8]; + + uint8_t scaling_lists_4x4[6][16]; + uint8_t scaling_lists_8x8[2][64]; + /* endif */ + + uint32_t log2_max_frame_num_minus4; + uint32_t pic_order_cnt_type; + // if pic_order_cnt_type==0 + uint32_t log2_max_pic_order_cnt_lsb_minus4; + // else + uint8_t delta_pic_order_always_zero_flag; + int32_t offset_for_non_ref_pic; + int32_t offset_for_top_to_bottom_field; + uint8_t num_ref_frames_in_pic_order_cnt_cycle; + int32_t offset_for_ref_frame[256]; + // TODO: some more ignored here + uint32_t num_ref_frames; + uint8_t gaps_in_frame_num_value_allowed_flag; + /*uint32_t pic_width_in_mbs_minus1; + uint32_t pic_height_in_map_units_minus1;*/ + uint32_t pic_width; + uint32_t pic_height; + uint8_t frame_mbs_only_flag; + uint8_t mb_adaptive_frame_field_flag; + uint8_t direct_8x8_inference_flag; + uint8_t frame_cropping_flag; + uint32_t frame_crop_left_offset; + uint32_t frame_crop_right_offset; + uint32_t frame_crop_top_offset; + uint32_t frame_crop_bottom_offset; + uint8_t vui_parameters_present_flag; + + /* vui_parameters */ + union + { + uint8_t aspect_ration_info_present_flag; + + /* aspect_ration_info_present_flag == 1 */ + uint8_t aspect_ratio_idc; + uint16_t sar_width; + uint16_t sar_height; + + uint8_t overscan_info_present_flag; + /* overscan_info_present_flag == 1 */ + uint8_t overscan_appropriate_flag; + + uint8_t video_signal_type_present_flag; + /* video_signal_type_present_flag == 1 */ + uint8_t video_format; + uint8_t video_full_range_flag; + uint8_t colour_description_present; + /* colour_description_present == 1 */ + uint8_t colour_primaries; + uint8_t transfer_characteristics; + uint8_t matrix_coefficients; + + uint8_t chroma_loc_info_present_flag; + /* chroma_loc_info_present_flag == 1 */ + uint8_t chroma_sample_loc_type_top_field; + uint8_t chroma_sample_loc_type_bottom_field; + + uint8_t timing_info_present_flag; + /* timing_info_present_flag == 1 */ + uint32_t num_units_in_tick; + uint32_t time_scale; + uint8_t fixed_frame_rate_flag; + + uint8_t nal_hrd_parameters_present_flag; + struct hrd_parameters nal_hrd_parameters; + + uint8_t vc1_hrd_parameters_present_flag; + struct hrd_parameters vc1_hrd_parameters; + + uint8_t low_delay_hrd_flag; + + uint8_t pic_struct_present_flag; + uint8_t bitstream_restriction_flag; + + /* bitstream_restriction_flag == 1 */ + uint8_t motion_vectors_over_pic_boundaries; + uint32_t max_bytes_per_pic_denom; + uint32_t max_bits_per_mb_denom; + uint32_t log2_max_mv_length_horizontal; + uint32_t log2_max_mv_length_vertical; + uint32_t num_reorder_frames; + uint32_t max_dec_frame_buffering; + } vui_parameters; + +}; + +struct pic_parameter_set_rbsp +{ + uint32_t pic_parameter_set_id; + uint32_t seq_parameter_set_id; + uint8_t entropy_coding_mode_flag; + uint8_t pic_order_present_flag; + + uint32_t num_slice_groups_minus1; + + /* num_slice_groups_minus1 > 0 */ + uint32_t slice_group_map_type; + + /* slice_group_map_type == 1 */ + uint32_t run_length_minus1[64]; + + /* slice_group_map_type == 2 */ + uint32_t top_left[64]; + uint32_t bottom_right[64]; + + /* slice_group_map_type == 3,4,5 */ + uint8_t slice_group_change_direction_flag; + uint32_t slice_group_change_rate_minus1; + + /* slice_group_map_type == 6 */ + uint32_t pic_size_in_map_units_minus1; + uint8_t slice_group_id[64]; + + uint32_t num_ref_idx_l0_active_minus1; + uint32_t num_ref_idx_l1_active_minus1; + uint8_t weighted_pred_flag; + uint8_t weighted_bipred_idc; + int32_t pic_init_qp_minus26; + int32_t pic_init_qs_minus26; + int32_t chroma_qp_index_offset; + uint8_t deblocking_filter_control_present_flag; + uint8_t constrained_intra_pred_flag; + uint8_t redundant_pic_cnt_present_flag; + + /* if(more_rbsp_data) */ + uint8_t transform_8x8_mode_flag; + uint8_t pic_scaling_matrix_present_flag; + + /* if(pic_scaling_matrix_present_flag) */ + uint8_t pic_scaling_list_present_flag[8]; + + uint8_t scaling_lists_4x4[6][16]; + uint8_t scaling_lists_8x8[2][64]; + + int32_t second_chroma_qp_index_offset; +}; + +struct slice_header +{ + uint32_t first_mb_in_slice; + uint32_t slice_type; + uint32_t pic_parameter_set_id; + uint32_t frame_num; + uint8_t field_pic_flag; + uint8_t bottom_field_flag; + uint32_t idr_pic_id; + + /* sps->pic_order_cnt_type == 0 */ + uint32_t pic_order_cnt_lsb; + int32_t delta_pic_order_cnt_bottom; + /* sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag */ + int32_t delta_pic_order_cnt[2]; + + /* pps->redundant_pic_cnt_present_flag == 1 */ + int32_t redundant_pic_cnt; + + /* slice_type == B */ + uint8_t direct_spatial_mv_pred_flag; + + /* slice_type == P, SP, B */ + uint8_t num_ref_idx_active_override_flag; + /* num_ref_idx_active_override_flag == 1 */ + uint32_t num_ref_idx_l0_active_minus1; + /* slice type == B */ + uint32_t num_ref_idx_l1_active_minus1; + + /* ref_pic_list_reordering */ + union + { + /* slice_type != I && slice_type != SI */ + uint8_t ref_pic_list_reordering_flag_l0; + + /* slice_type == B */ + uint8_t ref_pic_list_reordering_flag_l1; + + /* ref_pic_list_reordering_flag_l0 == 1 */ + uint32_t reordering_of_pic_nums_idc; + + /* reordering_of_pic_nums_idc == 0, 1 */ + uint32_t abs_diff_pic_num_minus1; + + /* reordering_of_pic_nums_idc == 2) */ + uint32_t long_term_pic_num; + } ref_pic_list_reordering; + + /* pred_weight_table */ + union + { + uint32_t luma_log2_weight_denom; + + /* chroma_format_idc != 0 */ + uint32_t chroma_log2_weight_denom; + + int32_t luma_weight_l0[32]; + int32_t luma_offset_l0[32]; + + int32_t chroma_weight_l0[32][2]; + int32_t chroma_offset_l0[32][2]; + + int32_t luma_weight_l1[32]; + int32_t luma_offset_l1[32]; + + int32_t chroma_weight_l1[32][2]; + int32_t chroma_offset_l1[32][2]; + } pred_weight_table; + + /* def_rec_pic_marking */ + union + { + + /* nal_unit_type == NAL_SLICE_IDR */ + uint8_t no_output_of_prior_pics_flag; + uint8_t long_term_reference_flag; + + /* else */ + uint8_t adaptive_ref_pic_marking_mode_flag; + uint32_t memory_management_control_operation; + + uint32_t difference_of_pic_nums_minus1; + uint32_t long_term_pic_num; + uint32_t long_term_frame_idx; + uint32_t max_long_term_frame_idx_plus1; + } dec_ref_pic_marking; +}; + + +struct nal_unit* init_nal_unit(); +void free_nal_unit(struct nal_unit *nal); +void copy_nal_unit(struct nal_unit *dest, struct nal_unit *src); + + +#endif /* NAL_H_ */ diff --git a/src/libvdpau/nal_parser.h b/src/libvdpau/nal_parser.h deleted file mode 100644 index 7c43070cb..000000000 --- a/src/libvdpau/nal_parser.h +++ /dev/null @@ -1,377 +0,0 @@ -#ifndef NAL_PARSER_H_ -#define NAL_PARSER_H_ - -#include <stdlib.h> - -#include "xine_internal.h" - -enum nal_unit_types { - NAL_UNSPECIFIED = 0, - NAL_SLICE, - NAL_PART_A, - NAL_PART_B, - NAL_PART_C, - NAL_SLICE_IDR, - NAL_SEI, - NAL_SPS, - NAL_PPS, - NAL_AU_DELIMITER, - NAL_END_OF_SEQUENCE, - NAL_END_OF_STREAM, - NAL_FILLER_DATA, - NAL_SPS_EXT -}; - -/* slice types repeat from 5-9, we - * need a helper function for comparison - */ -enum slice_types { - SLICE_P = 0, - SLICE_B, - SLICE_I, - SLICE_SP, - SLICE_SI -}; - -enum aspect_ratio { - ASPECT_UNSPECIFIED = 0, - ASPECT_1_1, - ASPECT_12_11, - ASPECT_10_11, - ASPECT_16_11, - ASPECT_40_33, - ASPECT_24_11, - ASPECT_20_11, - ASPECT_32_11, - ASPECT_80_33, - ASPECT_18_11, - ASPECT_15_11, - ASPECT_64_33, - ASPECT_160_99, - ASPECT_4_3, - ASPECT_3_2, - ASPECT_2_1, - ASPECT_RESERVED -}; - -static inline uint32_t slice_type(uint32_t slice_type) { return (slice_type < 10 ? slice_type % 5 : slice_type); } - -struct nal_unit { - uint8_t nal_ref_idc; // 0x03 - uint8_t nal_unit_type; // 0x1f - - struct seq_parameter_set_rbsp *sps; - struct pic_parameter_set_rbsp *pps; - struct slice_header *slc; -}; - -struct hrd_parameters { - uint32_t cpb_cnt_minus1; - uint8_t bit_rate_scale; - uint8_t cpb_size_scale; - - uint32_t bit_rate_value_minus1[32]; - uint32_t cpb_size_value_minus1[32]; - uint8_t cbr_flag[32]; - - uint8_t initial_cpb_removal_delay_length_minus1; - uint8_t cpb_removal_delay_length_minus1; - uint8_t dpb_output_delay_length_minus1; - uint8_t time_offset_length; -}; - -struct seq_parameter_set_rbsp { - uint8_t profile_idc; // 0xff - uint8_t constraint_setN_flag; // 0x0f - uint8_t level_idc; // 0xff - uint32_t seq_parameter_set_id; - uint32_t chroma_format_idc; - uint8_t residual_colour_transform_flag; // 0x01 - uint32_t bit_depth_luma_minus8; - uint32_t bit_depth_chroma_minus8; - uint8_t qpprime_y_zero_transform_bypass_flag; - uint8_t seq_scaling_matrix_present_flag; - - /* if(seq_scaling_matrix_present_flag) */ - uint8_t seq_scaling_list_present_flag[8]; - - uint8_t scaling_lists_4x4[6][16]; - uint8_t scaling_lists_8x8[2][64]; - /* endif */ - - uint32_t log2_max_frame_num_minus4; - uint32_t pic_order_cnt_type; - // if pic_order_cnt_type==0 - uint32_t log2_max_pic_order_cnt_lsb_minus4; - // else - uint8_t delta_pic_order_always_zero_flag; - int32_t offset_for_non_ref_pic; - int32_t offset_for_top_to_bottom_field; - uint8_t num_ref_frames_in_pic_order_cnt_cycle; - int32_t offset_for_ref_frame[256]; - // TODO: some more ignored here - uint32_t num_ref_frames; - uint8_t gaps_in_frame_num_value_allowed_flag; - /*uint32_t pic_width_in_mbs_minus1; - uint32_t pic_height_in_map_units_minus1;*/ - uint32_t pic_width; - uint32_t pic_height; - uint8_t frame_mbs_only_flag; - uint8_t mb_adaptive_frame_field_flag; - uint8_t direct_8x8_inference_flag; - uint8_t frame_cropping_flag; - uint32_t frame_crop_left_offset; - uint32_t frame_crop_right_offset; - uint32_t frame_crop_top_offset; - uint32_t frame_crop_bottom_offset; - uint8_t vui_parameters_present_flag; - - /* vui_parameters */ - union { - uint8_t aspect_ration_info_present_flag; - - /* aspect_ration_info_present_flag == 1 */ - uint8_t aspect_ratio_idc; - uint16_t sar_width; - uint16_t sar_height; - - uint8_t overscan_info_present_flag; - /* overscan_info_present_flag == 1 */ - uint8_t overscan_appropriate_flag; - - uint8_t video_signal_type_present_flag; - /* video_signal_type_present_flag == 1 */ - uint8_t video_format; - uint8_t video_full_range_flag; - uint8_t colour_description_present; - /* colour_description_present == 1 */ - uint8_t colour_primaries; - uint8_t transfer_characteristics; - uint8_t matrix_coefficients; - - uint8_t chroma_loc_info_present_flag; - /* chroma_loc_info_present_flag == 1 */ - uint8_t chroma_sample_loc_type_top_field; - uint8_t chroma_sample_loc_type_bottom_field; - - uint8_t timing_info_present_flag; - /* timing_info_present_flag == 1 */ - uint32_t num_units_in_tick; - uint32_t time_scale; - uint8_t fixed_frame_rate_flag; - - uint8_t nal_hrd_parameters_present_flag; - struct hrd_parameters nal_hrd_parameters; - - uint8_t vc1_hrd_parameters_present_flag; - struct hrd_parameters vc1_hrd_parameters; - - uint8_t low_delay_hrd_flag; - - uint8_t pic_struct_present_flag; - uint8_t bitstream_restriction_flag; - - /* bitstream_restriction_flag == 1 */ - uint8_t motion_vectors_over_pic_boundaries; - uint32_t max_bytes_per_pic_denom; - uint32_t max_bits_per_mb_denom; - uint32_t log2_max_mv_length_horizontal; - uint32_t log2_max_mv_length_vertical; - uint32_t num_reorder_frames; - uint32_t max_dec_frame_buffering; - } vui_parameters; - -}; - -struct pic_parameter_set_rbsp { - uint32_t pic_parameter_set_id; - uint32_t seq_parameter_set_id; - uint8_t entropy_coding_mode_flag; - uint8_t pic_order_present_flag; - - uint32_t num_slice_groups_minus1; - - /* num_slice_groups_minus1 > 0 */ - uint32_t slice_group_map_type; - - /* slice_group_map_type == 1 */ - uint32_t run_length_minus1[64]; - - /* slice_group_map_type == 2 */ - uint32_t top_left[64]; - uint32_t bottom_right[64]; - - /* slice_group_map_type == 3,4,5 */ - uint8_t slice_group_change_direction_flag; - uint32_t slice_group_change_rate_minus1; - - /* slice_group_map_type == 6 */ - uint32_t pic_size_in_map_units_minus1; - uint8_t slice_group_id[64]; - - uint32_t num_ref_idx_l0_active_minus1; - uint32_t num_ref_idx_l1_active_minus1; - uint8_t weighted_pred_flag; - uint8_t weighted_bipred_idc; - int32_t pic_init_qp_minus26; - int32_t pic_init_qs_minus26; - int32_t chroma_qp_index_offset; - uint8_t deblocking_filter_control_present_flag; - uint8_t constrained_intra_pred_flag; - uint8_t redundant_pic_cnt_present_flag; - - /* if(more_rbsp_data) */ - uint8_t transform_8x8_mode_flag; - uint8_t pic_scaling_matrix_present_flag; - - /* if(pic_scaling_matrix_present_flag) */ - uint8_t pic_scaling_list_present_flag[8]; - - uint8_t scaling_lists_4x4[6][16]; - uint8_t scaling_lists_8x8[2][64]; - - int32_t second_chroma_qp_index_offset; -}; - -struct slice_header { - uint32_t first_mb_in_slice; - uint32_t slice_type; - uint32_t pic_parameter_set_id; - uint32_t frame_num; - uint8_t field_pic_flag; - uint8_t bottom_field_flag; - uint32_t idr_pic_id; - - /* sps->pic_order_cnt_type == 0 */ - uint32_t pic_order_cnt_lsb; - int32_t delta_pic_order_cnt_bottom; - /* sps->pic_order_cnt_type == 1 && !sps->delta_pic_order_always_zero_flag */ - int32_t delta_pic_order_cnt[2]; - - /* pps->redundant_pic_cnt_present_flag == 1 */ - int32_t redundant_pic_cnt; - - /* slice_type == B */ - uint8_t direct_spatial_mv_pred_flag; - - /* slice_type == P, SP, B */ - uint8_t num_ref_idx_active_override_flag; - /* num_ref_idx_active_override_flag == 1 */ - uint32_t num_ref_idx_l0_active_minus1; - /* slice type == B */ - uint32_t num_ref_idx_l1_active_minus1; - - /* ref_pic_list_reordering */ - union { - /* slice_type != I && slice_type != SI */ - uint8_t ref_pic_list_reordering_flag_l0; - - /* slice_type == B */ - uint8_t ref_pic_list_reordering_flag_l1; - - /* ref_pic_list_reordering_flag_l0 == 1 */ - uint32_t reordering_of_pic_nums_idc; - - /* reordering_of_pic_nums_idc == 0, 1 */ - uint32_t abs_diff_pic_num_minus1; - - /* reordering_of_pic_nums_idc == 2) */ - uint32_t long_term_pic_num; - } ref_pic_list_reordering; - - /* pred_weight_table */ - union { - uint32_t luma_log2_weight_denom; - - /* chroma_format_idc != 0 */ - uint32_t chroma_log2_weight_denom; - - int32_t luma_weight_l0[32]; - int32_t luma_offset_l0[32]; - - int32_t chroma_weight_l0[32][2]; - int32_t chroma_offset_l0[32][2]; - - int32_t luma_weight_l1[32]; - int32_t luma_offset_l1[32]; - - int32_t chroma_weight_l1[32][2]; - int32_t chroma_offset_l1[32][2]; - } pred_weight_table; - - /* def_rec_pic_marking */ - union { - - /* nal_unit_type == NAL_SLICE_IDR */ - uint8_t no_output_of_prior_pics_flag; - uint8_t long_term_reference_flag; - - /* else */ - uint8_t adaptive_ref_pic_marking_mode_flag; - uint32_t memory_management_control_operation; - - uint32_t difference_of_pic_nums_minus1; - uint32_t long_term_pic_num; - uint32_t long_term_frame_idx; - uint32_t max_long_term_frame_idx_plus1; - } dec_ref_pic_marking; -}; - - -struct decoded_picture { - //VdpReferenceFrameH264 surface; - struct nal_unit *nal; -}; - -/* Decoded Picture Buffer */ -struct dpb { - uint32_t max_frame_num; - - uint32_t prev_ref_frame_number; - uint32_t unused_short_term_frame_num; - uint32_t non_existing_pictures[32]; - - struct decoded_picture *pictures; -}; - -#define MAX_FRAME_SIZE 1024*1024 - -struct nal_parser { - uint8_t buf[MAX_FRAME_SIZE]; - int buf_len; - int found_sps; - int found_pps; - int last_nal_res; - - int is_idr; - int field; /* 0=top, 1=bottom, -1=both */ - int slice; - int slice_cnt; - int have_top; - int have_frame; - - struct nal_unit *nal0; - struct nal_unit *nal1; - struct nal_unit *current_nal; - struct nal_unit *last_nal; - - /* pic_order_cnt */ - int32_t top_field_order_cnt; - int32_t bottom_field_order_cnt; - int32_t pic_order_cnt_msb; - int32_t prev_pic_order_cnt_msb; - int32_t prev_pic_order_cnt_lsb; - - struct dpb *dpb; -}; - -int parse_nal(uint8_t *buf, int buf_len, struct nal_parser *parser); - -int seek_for_nal(uint8_t *buf, int buf_len); - -struct nal_parser* init_parser(); -void free_parser(struct nal_parser *parser); -int parse_frame(struct nal_parser *parser, uint8_t *inbuf, int inbuf_len, - uint8_t **ret_buf, uint32_t *ret_len, uint32_t *ret_slice_cnt); - -#endif diff --git a/src/libvdpau/vdpau_h264.c b/src/libvdpau/vdpau_h264.c index eb2f61040..4da276101 100644 --- a/src/libvdpau/vdpau_h264.c +++ b/src/libvdpau/vdpau_h264.c @@ -37,7 +37,8 @@ #include "xineutils.h" #include "bswap.h" #include "accel_vdpau.h" -#include "nal_parser.h" +#include "h264_parser.h" +#include "dpb.h" #define VIDEOBUFSIZE 128*1024 @@ -246,8 +247,8 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen, VdpPictureInfoH264 pic; pic.slice_count = slice_count; - pic.field_order_cnt[0] = this->nal_parser->top_field_order_cnt; - pic.field_order_cnt[1] = this->nal_parser->bottom_field_order_cnt; + pic.field_order_cnt[0] = this->nal_parser->current_nal->top_field_order_cnt; + pic.field_order_cnt[1] = this->nal_parser->current_nal->bottom_field_order_cnt; pic.is_reference = (this->nal_parser->current_nal->nal_ref_idc != 0) ? VDP_TRUE : VDP_FALSE; pic.frame_num = slc->frame_num; @@ -277,6 +278,8 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen, memcpy(pic.scaling_lists_4x4, pps->scaling_lists_4x4, sizeof(pic.scaling_lists_4x4)); memcpy(pic.scaling_lists_8x8, pps->scaling_lists_8x8, sizeof(pic.scaling_lists_8x8)); memcpy(pic.referenceFrames, this->reference_frames, sizeof(pic.referenceFrames)); + memset(pic.referenceFrames, VDP_INVALID_HANDLE, sizeof(pic.referenceFrames)); + fill_vdpau_reference_list(&(this->nal_parser->dpb), pic.referenceFrames); if(this->decoder_started || pic.is_reference) { this->nal_parser->is_idr = 0; @@ -328,6 +331,11 @@ static void vdpau_h264_decode_data (video_decoder_t *this_gen, else { printf("DECODING SUCCESS\n"); + if(pic.is_reference) { + struct decoded_picture *pic = init_decoded_picture(this->nal_parser->current_nal, surface); + dpb_add_picture(&(this->nal_parser->dpb), pic); + } + img->duration = this->video_step; img->pts = buf->pts; img->bad_frame = 0; |