📄 mpeg2edit.c
字号:
return 0;
}
scr = ps_get_system_clock_reference(tail->data) + ps_get_pack_scr_length(tail->data);
if(scr == ps_get_system_clock_reference(next)){
return 1;
}
return 0;
}
static __int64 ps_get_pack_list_scr_length(PS_PACK_LIST_ELEMENT *head)
{
__int64 r;
r = 0;
while(head){
r += ps_get_pack_scr_length(head->data);
head = (PS_PACK_LIST_ELEMENT *)head->next;
}
return r;
}
static void ps_set_pack_list_scr(PS_PACK_LIST_ELEMENT *head, __int64 scr)
{
while(head){
ps_set_system_clock_reference(head->data, scr);
scr += ps_get_pack_scr_length(head->data);
head = (PS_PACK_LIST_ELEMENT *)head->next;
}
}
static void ps_set_clock_reference_pes_packet(LIST_ELEMENT *pes_packet, __int64 diff)
{
static const unsigned char id_table[] = {
0, 1, 0, 0, /* 0xbc - 0xbf */
1, 1, 1, 1, 1, 1, 1, 1, /* 0xc0 - 0xc7 */
1, 1, 1, 1, 1, 1, 1, 1, /* 0xc8 - 0xcf */
1, 1, 1, 1, 1, 1, 1, 1, /* 0xd0 - 0xd7 */
1, 1, 1, 1, 1, 1, 1, 1, /* 0xd8 - 0xdf */
1, 1, 1, 1, 1, 1, 1, 1, /* 0xe0 - 0xe7 */
1, 1, 1, 1, 1, 1, 1, 1, /* 0xe8 - 0xef */
0, 0, 0, 1, 1, 1, 1, 1, /* 0xf0 - 0xf7 */
0, 1, 0, 0, 0, 0, 0, 0, /* 0xf8 - 0xff */
};
int id;
unsigned char *p;
int offset;
int pts_dts_flag;
int escr_flag;
__int64 base;
__int64 ext;
__int64 cr;
if(pes_packet->length < 9){
return;
}
p = pes_packet->data;
id = p[3];
if(id < 0xbc){
return;
}
if(!id_table[id-0xbc]){
return;
}
if( (p[6] & 0xc0) == 0x80 ){ /* MPEG-2 */
pts_dts_flag = p[7] >> 6;
escr_flag = (p[7] >> 5) & 1;
offset = 9;
if(pts_dts_flag == 2){ /* pts only */
base = (p[offset+0] >> 1) & 7;
base <<= 8;
base += p[offset+1];
base <<= 7;
base += p[offset+2] >> 1;
base <<= 8;
base += p[offset+3];
base <<= 7;
base += p[offset+4] >> 1;
base += (diff / 300);
p[offset+0] = (unsigned char)((p[offset+0] & 0xf0) + ((base >> 30) << 1) + 1);
p[offset+1] = (unsigned char)((base >> 22) & 0xff);
p[offset+2] = (unsigned char)((((base >> 15) << 1) & 0xfe) + 1);
p[offset+3] = (unsigned char)((base >> 7) & 0xff);
p[offset+4] = (unsigned char)(((base << 1) & 0xfe) + 1);
offset += 5;
}else if(pts_dts_flag == 3){ /* pts and dts */
base = (p[offset+0] >> 1) & 7;
base <<= 8;
base += p[offset+1];
base <<= 7;
base += p[offset+2] >> 1;
base <<= 8;
base += p[offset+3];
base <<= 7;
base += p[offset+4] >> 1;
base += (diff / 300);
p[offset+0] = (unsigned char)((p[offset+0] & 0xf0) + ((base >> 30) << 1) + 1);
p[offset+1] = (unsigned char)((base >> 22) & 0xff);
p[offset+2] = (unsigned char)((((base >> 15) << 1) & 0xfe) + 1);
p[offset+3] = (unsigned char)((base >> 7) & 0xff);
p[offset+4] = (unsigned char)(((base << 1) & 0xfe) + 1);
offset += 5; /* pts */
base = (p[offset+0] >> 1) & 7;
base <<= 8;
base += p[offset+1];
base <<= 7;
base += p[offset+2] >> 1;
base <<= 8;
base += p[offset+3];
base <<= 7;
base += p[offset+4] >> 1;
base += (diff / 300);
p[offset+0] = (unsigned char)((p[offset+0] & 0xf0) + ((base >> 30) << 1) + 1);
p[offset+1] = (unsigned char)((base >> 22) & 0xff);
p[offset+2] = (unsigned char)((((base >> 15) << 1) & 0xfe) + 1);
p[offset+3] = (unsigned char)((base >> 7) & 0xff);
p[offset+4] = (unsigned char)(((base << 1) & 0xfe) + 1);
offset += 5; /* dts */
}
if(escr_flag){
base = (p[offset+0] >> 3) & 7;
base <<= 2;
base += p[offset+0] & 3;
base <<= 8;
base += p[offset+1];
base <<= 5;
base += (p[offset+2] >> 3) & 0x1f;
base <<= 2;
base += p[offset+2] & 3;
base <<= 8;
base += p[offset+3];
base <<= 5;
base += (p[offset+4] >> 3) & 0x1f;
ext = p[offset+4] & 3;
ext <<= 7;
ext += p[offset+5] >> 1;
cr = base * 300 + ext;
cr += diff;
base = cr / 300;
ext = cr % 300;
p[offset+0] = (unsigned char)((p[offset+0] & 0xc0) + (((base >> 30) & 7) << 3) + 4 + ((base >> 28) & 3));
p[offset+1] = (unsigned char)((base >> 20) & 0xff);
p[offset+2] = (unsigned char)((((base >> 15) & 0x1f) << 3) + 4 + ((base >> 13) & 3));
p[offset+3] = (unsigned char)((base >> 5) & 0xff);
p[offset+4] = (unsigned char)(((base & 0x1f) << 3) + 4 + ((ext >> 7) & 3));
p[offset+5] = (unsigned char)(((ext & 0x7f) << 1) + 1);
}
}else{ /* MPEG-1 */
offset = 6;
while(p[offset] == 0xff){
offset += 1;
}
if( (p[offset] & 0xc0) == 0x40 ){
offset += 2;
}
if( (p[offset] & 0xf0) == 0x20 ){
base = (p[offset+0] >> 1) & 7;
base <<= 8;
base += p[offset+1];
base <<= 7;
base += (p[offset+2] >> 1) & 0x7f;
base <<= 8;
base += p[offset+3];
base <<= 7;
base += (p[offset+4] >> 1) & 0x7f;
cr = base * 300;
cr += diff;
base = cr / 300;
p[offset+0] = (unsigned char)((p[offset+0] & 0xf0) + (((base >> 30) & 7) << 1) + 1);
p[offset+1] = (unsigned char)((base >> 22) & 0xff);
p[offset+2] = (unsigned char)((((base >> 15) & 0x7f) << 1) + 1);
p[offset+3] = (unsigned char)((base >> 7) & 0xff);
p[offset+2] = (unsigned char)(((base & 0x7f) << 1) + 1);
}else if( (p[offset] & 0xf0) == 0x30 ){
base = (p[offset+0] >> 1) & 7;
base <<= 8;
base += p[offset+1];
base <<= 7;
base += (p[offset+2] >> 1) & 0x7f;
base <<= 8;
base += p[offset+3];
base <<= 7;
base += (p[offset+4] >> 1) & 0x7f;
cr = base * 300;
cr += diff;
base = cr / 300;
p[offset+0] = (unsigned char)((p[offset+0] & 0xf0) + (((base >> 30) & 7) << 1) + 1);
p[offset+1] = (unsigned char)((base >> 22) & 0xff);
p[offset+2] = (unsigned char)((((base >> 15) & 0x7f) << 1) + 1);
p[offset+3] = (unsigned char)((base >> 7) & 0xff);
p[offset+2] = (unsigned char)(((base & 0x7f) << 1) + 1);
offset += 5;
base = (p[offset+0] >> 1) & 7;
base <<= 8;
base += p[offset+1];
base <<= 7;
base += (p[offset+2] >> 1) & 0x7f;
base <<= 8;
base += p[offset+3];
base <<= 7;
base += (p[offset+4] >> 1) & 0x7f;
cr = base * 300;
cr += diff;
base = cr / 300;
p[offset+0] = (unsigned char)((p[offset+0] & 0xf0) + (((base >> 30) & 7) << 1) + 1);
p[offset+1] = (unsigned char)((base >> 22) & 0xff);
p[offset+2] = (unsigned char)((((base >> 15) & 0x7f) << 1) + 1);
p[offset+3] = (unsigned char)((base >> 7) & 0xff);
p[offset+2] = (unsigned char)(((base & 0x7f) << 1) + 1);
}
}
}
static BLOCK *ps_join_stream(PS_PACK *pack, int stream_id)
{
BLOCK *r;
BLOCK *p;
LIST_ELEMENT *packet;
int space;
if(pack == NULL){
return NULL;
}
r = (BLOCK *)malloc(sizeof(BLOCK));
if(r == NULL){
return NULL;
}
r->data = NULL;
r->length = 0;
space = 0;
packet = pack->pes_packet;
while(packet){
if(packet->data[3] == stream_id){
space += packet->length;
}
packet = (LIST_ELEMENT *)packet->next;
}
r->data = (unsigned char *)calloc(space, 1);
if(r->data == NULL){
free(r);
return NULL;
}
packet = pack->pes_packet;
while(packet){
if(packet->data[3] == stream_id){
p = ps_get_pes_packet_data(packet);
if(p == NULL){
delete_block(r);
return NULL;
}
memcpy(r->data+r->length, p->data, p->length);
r->length += p->length;
delete_block(p);
}
packet = (LIST_ELEMENT *)packet->next;
}
return r;
}
static void ps_update_stream(PS_PACK *pack, int stream_id, BLOCK *data)
{
LIST_ELEMENT *packet;
if( (pack == NULL) || (data == NULL) ){
return;
}
packet = pack->pes_packet;
while(packet){
if(packet->data[3] == stream_id){
ps_set_pes_packet_data(packet, data);
}
packet = (LIST_ELEMENT *)packet->next;
}
}
static BLOCK *ps_get_pes_packet_data(LIST_ELEMENT *pes_packet)
{
BLOCK *r;
int offset;
int length;
unsigned char *p;
if(pes_packet == NULL){
return NULL;
}
if(pes_packet->length < 9){
return NULL;
}
p = pes_packet->data;
offset = ps_get_pes_packet_header_length(pes_packet);
length = ps_get_pes_packet_data_length(pes_packet);
r = new_block(p+offset, length);
return r;
}
static void ps_set_pes_packet_data(LIST_ELEMENT *pes_packet, BLOCK *data)
{
int length;
int offset;
unsigned char *p;
if(pes_packet == NULL){
return;
}
if(pes_packet->length < 9){
return;
}
p = pes_packet->data;
offset = ps_get_pes_packet_header_length(pes_packet);
length = ps_get_pes_packet_data_length(pes_packet);
memcpy(p+offset, data->data, length);
if(data->length - length){
memmove(data->data, data->data+length, data->length-length);
data->length -= length;
}else{
free(data->data);
data->data = NULL;
data->length = 0;
}
}
static int ps_get_pes_packet_data_length(LIST_ELEMENT *pes_packet)
{
if(pes_packet == NULL){
return 0;
}
if(pes_packet->length < 9){
return 0;
}
if(pes_packet->data[3] == 0xbe){ /* padding stream */
return 0;
}
return pes_packet->length - ps_get_pes_packet_header_length(pes_packet);
}
static int ps_get_pes_packet_header_length(LIST_ELEMENT *pes_packet)
{
int r;
if(pes_packet == NULL){
return 0;
}
if(pes_packet->length < 9){
return 6;
}
if(pes_packet->data[3] == 0xbe){ /* padding stream */
return 6;
}
if( (pes_packet->data[6] & 0xc0) == 0x80 ){ /* MPEG-2 */
r = 9+pes_packet->data[8];
}else{ /* MPEG-1 */
r = 6;
while(pes_packet->data[r] == 0xff){
r += 1;
}
if( (pes_packet->data[r] & 0xc0) == 0x40 ){
r += 2;
}
if( (pes_packet->data[r] & 0xf0) == 0x20 ) {
r += 5;
}else if( (pes_packet->data[r] & 0xf0) == 0x30 ){
r += 10;
}else{
r += 1;
}
}
return r;
}
static int ps_proc_video_picture(BLOCK *b1, BLOCK *b2, int old_offset, int new_offset, PS_PROC_VIDEO_OPTION *opt)
{
int code,n;
if(ps_check_fill_zero_video(opt)){
ps_fill_zero_video(b1, b2, old_offset, new_offset);
}
if(opt->level == PS_LEVEL_FIELD){
return new_offset+2;
}else{
opt->level = PS_LEVEL_PICTURE;
code = (get_byte_block(b1, b2, new_offset+5) >> 3) & 3;
opt->picture = code;
opt->padding = 0;
if(code == 1){ /* I picture */
if(opt->step == PS_STEP_START){
opt->step = PS_STEP_SEEK;
opt->input_field = 2;
code = get_byte_block(b1, b2, new_offset+4) << 2;
code += (get_byte_block(b1, b2, new_offset+5) >> 6) & 3;
opt->temporal_reference = code;
if(opt->closed_gop == 0){
opt->broken_link = 1;
}else{
opt->closed_gop = 2;
}
n = subtract_temporal_reference(opt->temporal_reference, 0);
if( opt->in <= n ){
opt->step = PS_STEP_OUTPUT;
opt->output = PS_OUTPUT_PACK;
opt->output_field = 2;
if(opt->closed_gop){
opt->temporal_reference -= (n-opt->in);
}
code -= opt->temporal_reference;
set_byte_block(b1, b2, new_offset+4, (unsigned char)((code >> 2) & 0xff));
code = ((code & 3) << 6) + (get_byte_block(b1, b2, new_offset+5) & 0x3f);
set_byte_block(b1, b2, new_offset+5, (unsigned char)code);
return new_offset+6;
}
return new_offset+2;
}else if(opt->step == PS_STEP_SEEK){
if(opt->broken_link == 1){
opt->broken_link = 2;
}else{
opt->broken_link = 0;
}
if(opt->closed_gop == 1){
opt->closed_gop = 2;
}else{
opt->closed_gop = 0;
}
code = get_byte_block(b1, b2, new_offset+4) << 2;
code += (get_byte_block(b1, b2, new_offset+5) >> 6) & 3;
n = (opt->input_field+subtract_temporal_reference(code, opt->temporal_reference)*2+1)/2;
opt->input_field +=2;
if( opt->in <= n ){
opt->output = PS_OUTPUT_PACK;
opt->output_field = 2;
opt->step = PS_STEP_OUTPUT;
if(opt->closed_gop){
opt->temporal_reference = code - (n-opt->in);
}else{
opt->temporal_reference = code;
}
code -= opt->temporal_reference;
set_byte_block(b1, b2, new_offset+4, (unsigned char)((code >> 2) & 0xff));
code = ((code & 3) << 6) + (get_byte_block(b1, b2, new_offset+5) & 0x3f);
set_byte_block(b1, b2, new_offset+5, (unsigned char)code);
return new_offset+6;
}
opt->temporal_reference = code;
return new_offset+2;
}else if(opt->step == PS_STEP_OUTPUT){
if( (opt->input_field+1)/2 >= opt->out ){
opt->step = PS_STEP_END;
set_byte_block(b1, b2, new_offset+3, 0xb7);
return new_offset+4;
}
code = get_byte_block(b1, b2, new_offset+4) << 2;
code += (get_byte_block(b1, b2, new_offset+5) >> 6) & 3;
if(opt->broken_link == 1){
opt->broken_link = 2;
opt->temporal_reference = code;
}else{
opt->broken_link = 0;
}
code -= opt->temporal_reference;
set_byte_block(b1, b2, new_offset+4, (unsigned char)((code >> 2) & 0xff));
code = ((code & 3) << 6) + (get_byte_block(b1, b2, new_offset+5) & 0x3f);
set_byte_block(b1, b2, new_offset+5, (unsigned char)code);
opt->input_field += 2;
opt->output_field += 2;
return new_offset+6;
}else{
return new_offset+2;
}
}else if(code == 2){/* P picture */
if(opt->step == PS_STEP_SEEK){
opt->broken_link = 0;
opt->closed_gop = 0;
code = get_byte_block(b1, b2, new_offset+4) << 2;
code += (get_byte_block(b1, b2, new_offset+5) >> 6) & 3;
opt->temporal_reference = code;
opt->input_field += 2;
return new_offset+2;
}else if(opt->step == PS_STEP_OUTPUT){
if( (opt->input_field+1)/2 >= opt->out ){
opt->step = PS_STEP_END;
set_byte_block(b1, b2, new_offset+3, 0xb7);
return new_offset+4;
}
opt->broken_link = 0;
opt->closed_gop = 0;
code = get_byte_block(b1, b2, new_offset+4) << 2;
code += (get_byte_block(b1, b2, new_offset+5) >> 6) & 3;
code -= opt->temporal_reference;
set_byte_block(b1, b2, new_offset+4, (unsigned char)((code >> 2) & 0xff));
code = ((code & 3) << 6) + (get_byte_block(b1, b2, new_offset+5) & 0x3f);
set_byte_block(b1, b2, new_offset+5, (unsigned char)code);
opt->input_field += 2;
opt->output_field += 2;
return new_offset+6;
}else{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -