summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libvdpau/Makefile.am2
-rw-r--r--src/libvdpau/dpb.c222
-rw-r--r--src/libvdpau/dpb.h41
-rw-r--r--src/libvdpau/h264_parser.c (renamed from src/libvdpau/nal_parser.c)209
-rw-r--r--src/libvdpau/h264_parser.h48
-rw-r--r--src/libvdpau/nal.c46
-rw-r--r--src/libvdpau/nal.h350
-rw-r--r--src/libvdpau/nal_parser.h377
-rw-r--r--src/libvdpau/vdpau_h264.c14
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;