ref: 6d9c27e525cb86a650ff7d4fc82fc27bb74fd59c
dir: /ivfh264.c/
#include <u.h> #include <libc.h> #include <bio.h> #include "vpuctx.h" enum { Extended_SAR = 255, }; typedef struct Bits Bits; typedef struct Bitspos Bitspos; typedef struct nal_unit_header_svc_extension nal_unit_header_svc_extension; typedef struct nal_unit_header_mvc_extension nal_unit_header_mvc_extension; struct Bitspos { vlong boff; u64int p; int c; int nb; int nz; int eof; }; struct Bits { Bitspos; Biobuf *b; }; struct nal_unit_header_svc_extension { u8int idr_flag; u8int priority_id; u8int no_inter_layer_pred_flag; u8int dependency_id; u8int quality_id; u8int temporal_id; u8int use_ref_base_pic_flag; u8int discardable_flag; u8int output_flag; u8int reserved_three_2bits; }; struct nal_unit_header_mvc_extension { u8int non_idr_flag; u8int priority_id; u16int view_id; u8int temporal_id; u8int anchor_pic_flag; u8int inter_view_flag; u8int reserved_one_bit; }; #define Default_4x4_Intra {6, 13, 13, 20, 20, 20, 28, 28, 28, 28, 32, 32, 32, 37, 37, 42} #define Default_4x4_Inter {10, 14, 14, 20, 20, 20, 24, 24, 24, 24, 27, 27, 27, 30, 30, 34} #define Default_8x8_Intra \ {6, 10, 10, 13, 11, 13, 16, 16, 16, 16, 18, 18, 18, 18, 18, 23, \ 23, 23, 23, 23, 23, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, \ 27, 27, 27, 27, 29, 29, 29, 29, 29, 29, 29, 31, 31, 31, 31, 31, \ 31, 33, 33, 33, 33, 33, 36, 36, 36, 36, 38, 38, 38, 40, 40, 42} #define Default_8x8_Inter \ {9, 13, 13, 15, 13, 15, 17, 17, 17, 17, 19, 19, 19, 19, 19, 21, \ 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 24, 24, 24, 24, \ 24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 27, 27, 27, 27, 27, \ 27, 28, 28, 28, 28, 28, 30, 30, 30, 30, 32, 32, 32, 33, 33, 35} static u8int defsl4x4[6][16] = { Default_4x4_Intra, /* Sl_4x4_Intra_Y */ Default_4x4_Intra, /* Sl_4x4_Intra_Cb */ Default_4x4_Intra, /* Sl_4x4_Intra_Cr */ Default_4x4_Inter, /* Sl_4x4_Inter_Y */ Default_4x4_Inter, /* Sl_4x4_Inter_Cb */ Default_4x4_Inter, /* Sl_4x4_Inter_Cr */ }; static u8int defs8x8[6][64] = { Default_8x8_Intra, /* Sl_8x8_Intra_Y */ Default_8x8_Inter, /* Sl_8x8_Inter_Y */ Default_8x8_Intra, /* Sl_8x8_Intra_Cb */ Default_8x8_Inter, /* Sl_8x8_Inter_Cb */ Default_8x8_Intra, /* Sl_8x8_Intra_Cr */ Default_8x8_Inter, /* Sl_8x8_Inter_Cr */ }; static Biobuf stdout; static int clz(u32int x) { int r; if(x == 0) return 0; for(r = 0; (x & (1U<<31)) == 0; x <<= 1, r++); return r; } #define ceillog2(x) (32-clz(x)) void mark(Bits *b, Bitspos *pos) { *pos = b->Bitspos; pos->boff = Boffset(b->b); } void unroll(Bits *b, Bitspos *pos) { while(Boffset(b->b) != pos->boff){ if(Bungetc(b->b) < 0) sysfatal("Bungetc\n"); } b->Bitspos = *pos; } u32int rb_u(Bits *b, int n, char *s) { int m; u32int x; if(n == 0) return 0; if(s != nil) Bprint(&stdout, "%llud\t%s = ", b->p, s); x = 0; for(; n > 0; n -= m, b->p += m){ if(b->nb == 0){ again: if((b->c = Bgetc(b->b)) == Beof){ b->eof = 1; return -1; } if(b->nz == 2 && b->c == 3){ b->nz = 0; goto again; } b->nz = b->c == 0 ? b->nz+1 : 0; b->nb = 8; } if((m = n) > b->nb) m = b->nb; x <<= m; x |= (b->c >> b->nb-m) & (1<<m)-1; b->nb -= m; } if(s != nil) Bprint(&stdout, "%ud\n", x); return x; } u32int rb_ue(Bits *b, char *s) { u32int x; int n; if(s != nil) Bprint(&stdout, "%llud\t%s = ", b->p, s); for(n = 0; rb_u(b, 1, nil) == 0 && n < 32 && !b->eof; n++); x = rb_u(b, n, nil) + (1<<n) - 1; if(s != nil) Bprint(&stdout, "%ud\n", x); return x; } int rb_se(Bits *b, char *s) { int x; if(s != nil) Bprint(&stdout, "%llud\t%s = ", b->p, s); x = rb_ue(b, nil); x = ((x & 1) == 0 ? -x : x+1) >> 1; if(s != nil) Bprint(&stdout, "%d\n", x); return x; } #define u(n, s) rb_u(b, n, s) #define ue(s) rb_ue(b, s) #define se(s) rb_se(b, s) static void hrd_parameters(VPUctx *v, Bits *b) { int i, n; USED(v); n = ue("cpb_cnt_minus1"); u(4, "bit_rate_scale"); u(4, "cpb_size_scale"); for(i = 0; i < n; i++){ char t[32]; snprint(t, sizeof(t), "bit_rate_value_minus1[%d]", i); ue(t); snprint(t, sizeof(t), "cpb_size_value_minus1[%d]", i); ue(t); snprint(t, sizeof(t), "cbr_flag[%d]", i); u(1, t); } u(5, "initial_cpb_removal_delay_length_minus1"); u(5, "cpb_removal_delay_length_minus1"); u(5, "dpb_output_delay_length_minus1"); u(5, "time_offset_length"); } static void scaling_list(VPUctx *v, Bits *b, int i) { u8int *scalingList; int f, j, lastScale, nextScale, sizeOfScalingList, delta_scale; lastScale = nextScale = 8; if(i < 6){ sizeOfScalingList = 16; scalingList = &v->sl4x4[i*sizeOfScalingList]; }else{ sizeOfScalingList = 64; scalingList = &v->sl8x8[(i-6)*sizeOfScalingList]; } for(j = 0; j < sizeOfScalingList; j++){ if(nextScale != 0){ delta_scale = se("delta_scale"); nextScale = (lastScale + delta_scale + 256) % 256; f = (j == 0 && nextScale == 0) << j; v->useDefaultScalingMatrixFlag &= ~f; v->useDefaultScalingMatrixFlag |= f; } lastScale = scalingList[j] = nextScale == 0 ? lastScale : nextScale; } } static void vui_parameters(VPUctx *v, Bits *b) { int n; if(u(1, "aspect_ratio_info_present_flag")){ n = u(8, "aspect_ratio_idc"); if(n == Extended_SAR){ u(16, "sar_width"); u(16, "sar_height"); } } if(u(1, "overscan_info_present_flag")) u(1, "overscan_appropriate_flag"); if(u(1, "video_signal_type_present_flag")){ u(3, "video_format"); u(1, "video_full_range_flag"); if(u(1, "colour_description_present_flag")){ u(8, "color_primaries"); u(8, "transfer_characteristics"); u(8, "matrix_coefficients"); } } if(u(1, "chroma_loc_info_present_flag")){ ue("chroma_sample_loc_type_top_field"); ue("chroma_sample_loc_type_bottom_field"); } if(u(1, "timing_info_present_flag")){ u(32, "num_units_in_tick"); u(32, "time_scale"); u(1, "fixed_frame_rate_flag"); } if((n = u(1, "nal_hrd_parameters_present_flag"))) hrd_parameters(v, b); if((n |= u(1, "vcl_hrd_parameters_present_flag"))) hrd_parameters(v, b); if(n != 0) u(1, "low_delay_hrd_flag"); u(1, "pic_struct_present_flag"); if(u(1, "bitstream_restriction_flag")){ u(1, "motion_vectors_over_pic_boundaries_flag"); ue("max_bytes_per_pic_denom"); ue("max_bits_per_mb_denom"); ue("log2_max_mv_length_horizontal"); ue("log2_max_mv_length_vertical"); ue("max_num_reorder_frames"); ue("max_dec_frame_buffering"); } } static void rbsp_trailing_bits(Bits *b) { u(1, "rbsp_stop_one_bit"); u(8 - (b->p & 7), "rbsp_alignment_zero_bit"); } static int more_rbsp_data(Bits *b) { Bitspos pos; int more; mark(b, &pos); more = u(1, nil) == 0 || u(8 - (b->p & 7), nil) != 0; unroll(b, &pos); return more; } static u32int next_bits(Bits *b, int n) { Bitspos pos; u32int x; mark(b, &pos); x = u(n, nil); unroll(b, &pos); return x; } static void unit_header_svc_extension(VPUctx *v, Bits *b) { nal_unit_header_svc_extension e; USED(v); Bprint(&stdout, "nal_unit_header_svc_extension()\n"); e.idr_flag = u(1, "idr_flag"); e.priority_id = u(6, "priority_id"); e.no_inter_layer_pred_flag = u(1, "no_inter_layer_pred_flag"); e.dependency_id = u(3, "dependency_id"); e.quality_id = u(4, "quality_id"); e.temporal_id = u(3, "temporal_id"); e.use_ref_base_pic_flag = u(1, "use_ref_base_pic_flag"); e.discardable_flag = u(1, "discardable_flag"); e.output_flag = u(1, "output_flag"); e.reserved_three_2bits = u(2, "reserved_three_2bits"); } static void unit_header_mvc_extension(VPUctx *v, Bits *b) { nal_unit_header_mvc_extension e; USED(v); Bprint(&stdout, "nal_unit_header_mvc_extension()\n"); e.non_idr_flag = u(1, "non_idr_flag"); e.priority_id = u(6, "priority_id"); e.view_id = u(10, "view_id"); e.temporal_id = u(3, "temporal_id"); e.anchor_pic_flag = u(1, "anchor_pic_flag"); e.inter_view_flag = u(1, "inter_view_flag"); e.reserved_one_bit = u(1, "reserved_one_bit"); } static int more_rbsp_trailing_data(Bits *b) { USED(b); assert(nil); return 0; } static void rbsp_slice_trailing_bits(VPUctx *v, Bits *b) { rbsp_trailing_bits(b); if(v->pps.entropy_coding_mode_flag){ while(more_rbsp_trailing_data(b)) u(16, "cabac_zero_word"); } } static void slice_header(VPUctx *v, Bits *b) { u64int p; Bprint(&stdout, "slice_header()\n"); ue("first_mb_in_slice"); ue("slice_type"); /* % 5 */ ue("pic_parameter_set_id"); if(v->sps.separate_colour_plane_flag) u(2, "colour_plane_id"); v->sh.frame_num = u(v->sps.log2_max_frame_num_minus4 + 4, "frame_num"); v->sh.field_pic_flag = 0; v->sh.bottom_field_flag = 0; if(!v->sps.frame_mbs_only_flag){ if((v->sh.field_pic_flag = u(1, "field_pic_flag")) != 0) v->sh.bottom_field_flag = u(1, "bottom_field_flag"); } if(v->nal_unit_type == 5) v->sh.idr_pic_id = ue("idr_pic_id"); v->sh.size_pic_order_cnt_lsb = 0; v->sh.size_delta_pic_order_cnt_bottom = 0; if(v->sps.pic_order_cnt_type == 0){ v->sh.size_pic_order_cnt_lsb = v->sps.log2_max_pic_order_cnt_lsb_minus4 + 4; u(v->sh.size_pic_order_cnt_lsb, "pic_order_cnt_lsb"); if(v->pps.bottom_field_pic_order_in_frame_present_flag && !v->sh.field_pic_flag){ p = b->p; se("delta_pic_order_cnt_bottom"); v->sh.size_delta_pic_order_cnt_bottom = b->p - p; } } v->sh.size_delta_pic_order_cnt0 = 0; v->sh.size_delta_pic_order_cnt1 = 0; if(v->sps.pic_order_cnt_type == 1 && !v->sps.delta_pic_order_always_zero_flag){ p = b->p; se("delta_pic_order_cnt[0]"); v->sh.size_delta_pic_order_cnt0 = b->p - p; if(v->pps.bottom_field_pic_order_in_frame_present_flag && !v->sh.field_pic_flag){ p = b->p; se("delta_pic_order_cnt[1]"); v->sh.size_delta_pic_order_cnt1 = b->p - p; } } /* the rest isn't needed for VPU decoding */ } static void slice_layer_without_partitioning_rbsp(VPUctx *v, Bits *b) { Bprint(&stdout, "slice_layer_without_partitioning_rbsp()\n"); slice_header(v, b); /* the rest isn't needed for VPU decoding */ } static void sei_rbsp(VPUctx *v, Bits *b) { int payloadType, payloadSize, i, n; USED(v); Bprint(&stdout, "sei_rbps()\n"); do{ Bprint(&stdout, "sei_message()\n"); payloadType = 0; while(1){ Bprint(&stdout, "%lld\t", b->p); n = u(8, nil); payloadType += n; if(n != 0xff) break; Bprint(&stdout, "ff_byte\n"); } Bprint(&stdout, "last_payload_type_byte = %d\n", n); payloadSize = 0; while(1){ Bprint(&stdout, "%lld\t", b->p); n = u(8, nil); payloadSize += n; if(n != 0xff) break; Bprint(&stdout, "ff_byte\n"); } Bprint(&stdout, "last_payload_size_byte = %d\n", n); Bprint(&stdout, "%llud\tsei_payload(%d, %d) = ...\n", b->p, payloadType, payloadSize); for(i = 0; i < payloadSize; i++) u(8, nil); if(b->p & 7){ u(1, nil); u(8 - (b->p & 7), nil); } }while(more_rbsp_data(b)); rbsp_trailing_bits(b); } static void seq_parameter_set_rbsp(VPUctx *v, Bits *b) { int i, n; Bprint(&stdout, "seq_parameter_set_rbsp()\n"); v->sps.profile_idc = u(8, "profile_idc"); v->sps.frame_mbs_only_flag = 0; for(i = 0; i < 6; i++){ char t[32]; snprint(t, sizeof(t), "constraint_set%d_flag", i); if(u(1, t) && i == 4 && (v->sps.profile_idc == 77 || v->sps.profile_idc == 88 || v->sps.profile_idc == 100)) v->sps.frame_mbs_only_flag = 1; } u(2, "reserved_zero_2bits"); u(8, "level_idc"); ue("seq_parameter_set_id"); switch(v->sps.profile_idc){ case 100: case 110: case 122: case 244: case 44: case 83: case 86: case 118: case 128: case 138: case 139: case 134: case 135: if((v->sps.chroma_format_idc = ue("chroma_format_idc")) == 3) v->sps.separate_colour_plane_flag = u(1, "separate_colour_plane_flag"); ue("bit_depth_luma_minus8"); ue("bit_depth_chroma_minus8"); u(1, "qpprime_y_zero_transform_bypass_flag"); if((v->sps.seq_scaling_matrix_present_flag = u(1, "seq_scaling_matrix_present_flag"))){ for(i = 0; i < (v->sps.chroma_format_idc != 3) ? 8 : 12; i++){ if(u(1, "seq_scaling_list_present_flag")) scaling_list(v, b, i); } } break; } v->sps.log2_max_frame_num_minus4 = ue("log2_max_frame_num_minus4"); if((v->sps.pic_order_cnt_type = ue("pic_order_cnt_type")) == 0){ v->sps.log2_max_pic_order_cnt_lsb_minus4 = ue("log2_max_pic_order_cnt_lsb_minus4"); }else if(v->sps.pic_order_cnt_type == 1){ v->sps.delta_pic_order_always_zero_flag = u(1, "delta_pic_order_always_zero_flag"); se("offset_for_non_ref_pic"); se("offset_for_top_to_bottom_field"); n = ue("num_ref_frames_in_pic_order_cnt_cycle"); for(i = 0; i < n; i++){ char t[32]; snprint(t, sizeof(t), "offset_for_ref_frame[i]"); se(t); } } v->sps.max_num_ref_frames = ue("max_num_ref_frames"); u(1, "gaps_in_frame_num_value_allowed_flag"); v->sps.pic_width_in_mbs_minus1 = ue("pic_width_in_mbs_minus1"); v->sps.pic_height_in_map_units_minus1 = ue("pic_height_in_map_units_minus1"); v->PicSizeInMapUnits = ((int)v->sps.pic_width_in_mbs_minus1 + 1) * ((int)v->sps.pic_height_in_map_units_minus1 + 1); if((v->sps.frame_mbs_only_flag |= u(1, "frame_mbs_only_flag")) == 0) v->sps.mb_adaptive_frame_field_flag = u(1, "mb_adaptive_frame_field_flag"); v->sps.direct_8x8_inference_flag = u(1, "direct_8x8_inference_flag"); if(u(1, "frame_cropping_flag")){ v->crop.left = ue("frame_crop_left_offset"); v->crop.right = ue("frame_crop_right_offset"); v->crop.top = ue("frame_crop_top_offset"); v->crop.bottom = ue("frame_crop_bottom_offset"); } if(u(1, "vui_parameters_present_flag")) vui_parameters(v, b); rbsp_trailing_bits(b); } static void pic_parameter_set_rbsp(VPUctx *v, Bits *b) { int i, n, x; Bprint(&stdout, "pic_parameter_set_rbsp()\n"); v->pps.pic_parameter_set_id = ue("pic_parameter_set_id"); ue("seq_parameter_set_id"); v->pps.entropy_coding_mode_flag = u(1, "entropy_coding_mode_flag"); v->pps.bottom_field_pic_order_in_frame_present_flag = u(1, "bottom_field_pic_order_in_frame_present_flag"); if((v->pps.num_slice_groups_minus1 = ue("num_slice_groups_minus1")) > 0){ if((v->pps.slice_group_map_type = ue("slice_group_map_type")) == 0){ for(i = 0; i <= v->pps.num_slice_groups_minus1; i++){ char t[32]; snprint(t, sizeof(t), "run_length_minus1[%d]", i); ue(t); } }else if(v->pps.slice_group_map_type == 2){ for(i = 0; i <= v->pps.num_slice_groups_minus1; i++){ char t[32]; snprint(t, sizeof(t), "top_left[%d]", i); ue(t); snprint(t, sizeof(t), "bottom_right[%d]", i); ue(t); } }else if(v->pps.slice_group_map_type >= 3 && v->pps.slice_group_map_type <= 5){ u(1, "slice_group_change_direction_flag"); ue("slice_group_change_rate_minus1"); }else if(v->pps.slice_group_map_type == 6){ n = ue("pic_size_in_map_units_minus1"); x = ceillog2(v->pps.num_slice_groups_minus1 + 1); for(i = 0; i <= n; i++){ char t[32]; snprint(t, sizeof(t), "slice_group_id[%d]", i); u(x, t); } } } v->pps.num_ref_idx_l0_default_active_minus1 = ue("num_ref_idx_l0_default_active_minus1"); v->pps.num_ref_idx_l1_default_active_minus1 = ue("num_ref_idx_l1_default_active_minus1"); v->pps.weighted_pred_flag = u(1, "weighted_pred_flag"); v->pps.weighted_bipred_idc = u(2, "weighted_bipred_idc"); v->pps.pic_init_qp_minus26 = se("pic_init_qp_minus26"); se("pic_init_qs_minus26"); v->pps.chroma_qp_index_offset = se("chroma_qp_index_offset"); v->pps.deblocking_filter_control_present_flag = u(1, "deblocking_filter_control_present_flag"); v->pps.constrained_intra_pred_flag = u(1, "constrained_intra_pred_flag"); v->pps.redundant_pic_cnt_present_flag = u(1, "redundant_pic_cnt_present_flag"); if(more_rbsp_data(b)){ v->pps.transform_8x8_mode_flag = u(1, "transform_8x8_mode_flag"); v->pps.pic_scaling_matrix_present_flag = u(1, "pic_scaling_matrix_present_flag"); if(v->pps.pic_scaling_matrix_present_flag){ for(i = 0; i < 6 + ((v->sps.chroma_format_idc != 3) ? 2 : 6)*v->pps.transform_8x8_mode_flag; i++){ char t[32]; snprint(t, sizeof(t), "pic_scaling_list_present_flag[%d]", i); if(u(1, t)) scaling_list(v, b, i); } } v->pps.second_chroma_qp_index_offset = se("second_chroma_qp_index_offset"); } rbsp_trailing_bits(b); } static void (*rbsp_f[])(VPUctx *v, Bits *b) = { [1] = slice_layer_without_partitioning_rbsp, [5] = slice_layer_without_partitioning_rbsp, [6] = sei_rbsp, [7] = seq_parameter_set_rbsp, [8] = pic_parameter_set_rbsp, [19] = slice_layer_without_partitioning_rbsp, }; static int Bu16le(Biobuf *b, u16int *o) { int x; x = Bgetc(b); x |= Bgetc(b)<<8; *o = x; if(x < 0) werrstr("failed to read 2 bytes"); return x < 0 ? -1 : 0; } static int Bu32le(Biobuf *b, u32int *o) { int x, i; *o = 0; for(i = 0; i < 4; *o |= x<<(i*8), i++){ if((x = Bgetc(b)) < 0){ werrstr("failed to read 4 bytes"); return -1; } } return 0; } static int Bu64le(Biobuf *b, u64int *o) { int x, i; *o = 0; for(i = 0; i < 8; *o |= (uvlong)x<<(i*8), i++){ if((x = Bgetc(b)) < 0){ werrstr("failed to read 8 bytes"); return -1; } } return 0; } static void usage(void) { fprint(2, "usage: %s [file.ivf]\n", argv0); exits("usage"); } static int decode(VPUctx *v, Bits *b, int sz) { u32int x; Bprint(&stdout, "@ 0x%llx [%d]\n", Boffset(b->b), sz); if((x = u(24, nil)) == 0) x = u(8, nil); if(x != 1){ Bprint(&stdout, "invalid start code %02x\n", x); return -1; } b->p = 0; u(1, "forbidden_zero_bit"); v->nal_ref_idc = u(2, "nal_ref_idc"); v->nal_unit_type = u(5, "nal_unit_type"); if(v->nal_unit_type == 14 || v->nal_unit_type == 20){ if(u(1, "svc_extension_flag")) unit_header_svc_extension(v, b); else unit_header_mvc_extension(v, b); } if(v->nal_unit_type >= nelem(rbsp_f) || rbsp_f[v->nal_unit_type] == nil) Bprint(&stdout, "unexpected nal_unit_type %d", v->nal_unit_type); else rbsp_f[v->nal_unit_type](v, b); Bprint(&stdout, "\n"); return 0; } void main(int argc, char **argv) { u64int timestamp, framenum; int fd, shgo, vpu; u32int tbnum, tbdenum; u16int w, h, hlen; Biobuf in, settings; char tmp[6], *s, *buf; u32int sz; VPUctx v; Bits bits; vlong off; ARGBEGIN{ default: usage(); }ARGEND vpu = open("/dev/vpu", ORDWR); fd = 0; if(argc == 1){ if((fd = open(*argv, OREAD)) < 0) sysfatal("%r"); }else if(argc != 0) usage(); Binit(&in, fd, OREAD); Binit(&stdout, 2, OWRITE); Binit(&settings, 1, OWRITE); memset(&v, 0, sizeof(v)); memset(&bits, 0, sizeof(bits)); bits.b = ∈ if(Bread(&in, tmp, 6) != 6 || Bu16le(&in, &hlen) < 0) sysfatal("header read failed"); if(memcmp(tmp, "DKIF", 4) != 0) sysfatal("expected DKIF, got %02x%02x%02x%02x", tmp[0], tmp[1], tmp[2], tmp[3]); if(hlen < 0x20 || Bread(&in, tmp, 4) != 4) sysfatal("invalid header: hlen=%d", hlen); if(Bu16le(&in, &w) < 0 || Bu16le(&in, &h) < 0 || Bu32le(&in, &tbdenum) < 0 || Bu32le(&in, &tbnum) < 0) sysfatal("invalid header: %r"); if(Bseek(&in, hlen, 0) != hlen) sysfatal("invalid IVF stream"); shgo = 0; buf = malloc(1 * 1024 * 1024); for(framenum = 0;; framenum++){ if(Bu32le(&in, &sz) < 0 || Bu64le(&in, ×tamp) < 0 || (int)sz < 0) break; off = Boffset(&in); if(decode(&v, &bits, sz) != 0) sysfatal("decode failed"); if(v.nal_unit_type == 8){ /* have sps+pps */ s = smprint( "decode h.264\n" "sps pic_height_in_map_units_minus1 %d\n" "sps pic_width_in_mbs_minus1 %d\n" "sps chroma_format_idc %d\n" "sps frame_mbs_only_flag %d\n" "sps log2_max_frame_num_minus4 %d\n" "sps max_num_ref_frames %d\n" "sps profile_idc %d\n" "sps direct_8x8_inference_flag %d\n" "sps mb_adaptive_frame_field_flag %d\n" "sps seq_scaling_matrix_present_flag %d\n" "sps separate_colour_plane_flag %d\n" "pps chroma_qp_index_offset %d\n" "pps pic_init_qp_minus26 %d\n" "pps second_chroma_qp_index_offset %d\n" "pps weighted_bipred_idc %d\n" "pps num_ref_idx_l0_default_active_minus1 %d\n" "pps num_ref_idx_l1_default_active_minus1 %d\n" "pps constrained_intra_pred_flag %d\n" "pps deblocking_filter_control_present_flag %d\n" "pps entropy_coding_mode_flag %d\n" "pps pic_scaling_matrix_present_flag %d\n" "pps redundant_pic_cnt_present_flag %d\n" "pps transform_8x8_mode_flag %d\n" "pps weighted_pred_flag %d\n" "pps pic_parameter_set_id %d\n", v.sps.pic_height_in_map_units_minus1, v.sps.pic_width_in_mbs_minus1, v.sps.chroma_format_idc, v.sps.frame_mbs_only_flag, v.sps.log2_max_frame_num_minus4, v.sps.max_num_ref_frames, v.sps.profile_idc, v.sps.direct_8x8_inference_flag, v.sps.mb_adaptive_frame_field_flag, v.sps.seq_scaling_matrix_present_flag, v.sps.separate_colour_plane_flag, v.pps.chroma_qp_index_offset, v.pps.pic_init_qp_minus26, v.pps.second_chroma_qp_index_offset, v.pps.weighted_bipred_idc, v.pps.num_ref_idx_l0_default_active_minus1, v.pps.num_ref_idx_l1_default_active_minus1, v.pps.constrained_intra_pred_flag, v.pps.deblocking_filter_control_present_flag, v.pps.entropy_coding_mode_flag, v.pps.pic_scaling_matrix_present_flag, v.pps.redundant_pic_cnt_present_flag, v.pps.transform_8x8_mode_flag, v.pps.weighted_pred_flag, v.pps.pic_parameter_set_id ); if(pwrite(vpu, s, strlen(s), 0) < 0) sysfatal("sps+pps: %r"); free(s); shgo = 1; }else if(shgo){ s = smprint( "nal_ref_idc %d\n" "nal_unit_type %d\n" "sh frame_num %d\n" "sh idr_pic_id %d\n" "sh size_dec_ref_pic_marking %d\n" "sh size_pic_order_cnt_lsb %d\n" "sh size_delta_pic_order_cnt_bottom %d\n" "sh size_delta_pic_order_cnt0 %d\n" "sh size_delta_pic_order_cnt1 %d\n" "sh field_pic_flag %d\n" "sh bottom_field_flag %d\n", v.nal_ref_idc, v.nal_unit_type, v.sh.frame_num, v.sh.idr_pic_id, v.sh.size_dec_ref_pic_marking, v.sh.size_pic_order_cnt_lsb, v.sh.size_delta_pic_order_cnt_bottom, v.sh.size_delta_pic_order_cnt0, v.sh.size_delta_pic_order_cnt1, v.sh.field_pic_flag, v.sh.bottom_field_flag ); if(pwrite(vpu, s, strlen(s), 0) < 0) sysfatal("sh: %r"); Bseek(&in, off, 0); Bread(&in, buf, sz); if(pwrite(vpu, buf, sz, 1) < 0) sysfatal("data: %r"); if(pread(vpu, buf, 0, 0) < 0){ sleep(1000); sysfatal("read: %r"); } sleep(1000); } Bseek(&in, off+sz, 0); bits.nb = 0; } Bterm(&in); Bterm(&stdout); exits(nil); }