/unsupported/trunk/first-official/test.c |
---|
0,0 → 1,327 |
/* |
* Project: S.Ha.R.K. |
* |
* Coordinators: |
* Giorgio Buttazzo <giorgio@sssup.it> |
* Paolo Gai <pj@gandalf.sssup.it> |
* |
* Authors : |
* Giacomo Guidi <giacomo@gandalf.sssup.it> |
* (see the web pages for full authors list) |
* |
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy) |
* |
* http://www.sssup.it |
* http://retis.sssup.it |
* http://shark.sssup.it |
*/ |
/* |
* Copyright (C) 2002 Paolo Gai |
* |
* This program is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; either version 2 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
* |
*/ |
#include "kernel/kern.h" |
#include "edf/edf/edf.h" |
#include "cbs/cbs/cbs.h" |
#include "pthread.h" |
#include "posix/posix/posix.h" |
#include "fsf.h" |
#include "fsf_server.h" |
#include "dummy/dummy/dummy.h" |
#include "sem/sem/sem.h" |
#include "pi/pi/pi.h" |
#include "pc/pc/pc.h" |
#include "hartport/hartport/hartport.h" |
#include "cabs/cabs/cabs.h" |
#include "drivers/keyb.h" |
#include <stdlib.h> |
// -------------------------------------------------- |
// -------------------------------------------------- |
// Init Part |
// -------------------------------------------------- |
// -------------------------------------------------- |
/*+ sysyem tick in us +*/ |
#define TICK 0 |
/*+ RR tick in us +*/ |
#define RRTICK 10000 |
int grubstar_level; |
int posix_level; |
//fsf_shared_object_t obj; |
//fsf_shared_operation_t op; |
TIME __kernel_register_levels__(void *arg) |
{ |
struct multiboot_info *mb = (struct multiboot_info *)arg; |
EDF_register_level(EDF_ENABLE_ALL); |
posix_level=POSIX_register_level(RRTICK, 1, mb, 32); |
grubstar_level = GRUBSTAR_register_level(5, 0); |
FSF_register_module(posix_level,grubstar_level, (int)(MAX_BANDWIDTH * 0.9)); |
dummy_register_level(); |
// for the keyboard... |
CBS_register_level(CBS_ENABLE_ALL, 0); |
PI_register_module(); |
PC_register_module(); |
SEM_register_module(); |
PTHREAD_register_module(1, 0, 1); |
return TICK; |
} |
TASK __init__(void *arg) |
{ |
struct multiboot_info *mb = (struct multiboot_info *)arg; |
HARTPORT_init(); |
KEYB_init(NULL); |
__call_main__(mb); |
return (void *)0; |
} |
// -------------------------------------------------- |
// -------------------------------------------------- |
// The Test |
// -------------------------------------------------- |
// -------------------------------------------------- |
pthread_t jposix = -1; |
pthread_t j1 = -1; |
pthread_t j2 = -1; |
fsf_server_id_t server1 = -1; |
fsf_server_id_t server2 = -1; |
fsf_contract_parameters_t contract; |
void *star(void *arg) |
{ |
struct timespec actual,end; |
int actpersecond,act; |
int cycle,rec; |
act = 0; |
actpersecond = 0; |
cycle = 0; |
rec = 0; |
for (;;) { |
cycle++; |
kern_gettime(&actual); |
rec = SERVER_get_last_reclaiming(grubstar_level,exec_shadow); |
if (act == 0) { |
TIMESPEC_ASSIGN(&end,&actual); |
end.tv_sec++; |
} |
if (TIMESPEC_A_LT_B(&actual,&end)) { |
act++; |
} else { |
actpersecond = act; |
act = 0; |
} |
//pthread_mutex_lock(&mux); |
printf_xy(0,exec_shadow,WHITE,"Thread %3d Act_per_Second = %8d cycle = %8d rec = %8d", |
exec_shadow,actpersecond,cycle,rec); |
//pthread_mutex_unlock(&mux); |
} |
return NULL; |
} |
void *periodic_star(void *arg) |
{ |
struct timespec actual,end; |
int actpersecond,act; |
int cycle,rec; |
act = 0; |
actpersecond = 0; |
cycle = 0; |
rec = 0; |
for (;;) { |
cycle++; |
kern_gettime(&actual); |
rec = SERVER_get_last_reclaiming(grubstar_level,exec_shadow); |
if (act == 0) { |
TIMESPEC_ASSIGN(&end,&actual); |
end.tv_sec++; |
} |
if (TIMESPEC_A_LT_B(&actual,&end)) { |
act++; |
} else { |
actpersecond = act; |
act = 0; |
} |
//fsf_lock_object(&op); |
printf_xy(0,exec_shadow,RED,"Thread %3d Act_per_Second = %8d cycle = %8d rec = %8d", |
exec_shadow,actpersecond,cycle,rec); |
//fsf_unlock_object(&op); |
task_endcycle(); |
} |
return NULL; |
} |
int keyinc = 5; |
void *edftask(void *arg) |
{ |
long long j; |
while(1) { |
for (j=0; j<10000*keyinc; j++); |
task_endcycle(); |
} |
return NULL; |
} |
void create() |
{ |
struct timespec period1 = {0,90000000}; //30% |
struct timespec period2 = {0,75000000}; //80% |
struct timespec budget1 = {0,30000000}; |
struct timespec budget2 = {0,60000000}; |
FSF_start_service_task(); |
kern_printf("(Start Create)"); |
fsf_initialize_contract(&contract); |
fsf_set_contract_basic_parameters(&contract,&budget1,&period1,FSF_DEFAULT_WORKLOAD); |
fsf_set_contract_scheduling_policy(&contract, FSF_EDF); |
fsf_set_contract_reclamation_parameters(&contract,&budget2, &period2, FSF_DEFAULT_GRANULARITY, NULL, 1, 0); |
fsf_negotiate_contract(&contract,&server1); |
fsf_set_contract_basic_parameters(&contract,&budget1,&period1,FSF_DEFAULT_WORKLOAD); |
fsf_set_contract_scheduling_policy(&contract, FSF_EDF); |
fsf_set_contract_reclamation_parameters(&contract,&budget2, &period2,FSF_DEFAULT_GRANULARITY, NULL, 1, 1); |
fsf_negotiate_contract(&contract,&server2); |
kern_printf("(End Create)"); |
} |
void renegotiate(void) { |
struct timespec period2 = {0,75000000}; |
struct timespec budget2 = {0,60000000}; |
struct timespec budget1 = {0,60000000}; |
union sigval sval; |
for (;;) { |
fsf_set_contract_basic_parameters(&contract,&budget2,&period2,FSF_DEFAULT_WORKLOAD); |
fsf_set_contract_reclamation_parameters(&contract,&budget1, &period2,FSF_DEFAULT_GRANULARITY, NULL, 20, 0); |
//fsf_request_contract_renegotiation(&contract,server2, 0, sval); |
fsf_renegotiate_contract(&contract, server2); |
budget2.tv_nsec -=60000; |
task_endcycle(); |
} |
} |
int main(int argc, char **argv) |
{ |
int err; |
HARD_TASK_MODEL ht; |
struct timespec endtimer; |
//fsf_init_shared_object(&obj,1); |
//op.op_id=1; |
//op.wcet.tv_sec=0; |
//op.wcet.tv_nsec=100000; |
//fsf_declare_shared_object_operation(&obj, &op); |
srand(kern_gettime(NULL)); |
create(); |
kern_gettime(&endtimer); |
endtimer.tv_sec += 20; |
kern_event_post(&endtimer, (void (*)(void *))(exit), NULL); |
hard_task_default_model(ht); |
hard_task_def_mit(ht,200000); |
hard_task_def_wcet(ht,5000); |
err = fsf_create_thread(server1,&j1,NULL,periodic_star,NULL,&ht); |
kern_printf("(%d)",err); |
task_activate(j1); |
hard_task_default_model(ht); |
hard_task_def_mit(ht,1000000); |
hard_task_def_wcet(ht,50000); |
err = fsf_create_thread(server1,&j1,NULL,renegotiate,NULL,&ht); |
kern_printf("(%d)",err); |
task_activate(j1); |
hard_task_default_model(ht); |
hard_task_def_mit(ht,159000); |
hard_task_def_wcet(ht,5000); |
err = fsf_create_thread(server2,&j2,NULL,periodic_star,NULL,&ht); |
kern_printf("(%d)",err); |
task_activate(j2); |
hard_task_default_model(ht); |
hard_task_def_mit(ht,159000); |
hard_task_def_wcet(ht,5000); |
err = fsf_create_thread(server2,&j2,NULL,periodic_star,NULL,&ht); |
kern_printf("(%d)",err); |
task_activate(j2); |
return 0; |
} |
/unsupported/trunk/first-official/test1.c |
---|
0,0 → 1,385 |
/* |
* Project: S.Ha.R.K. |
* |
* Coordinators: |
* Giorgio Buttazzo <giorgio@sssup.it> |
* Paolo Gai <pj@gandalf.sssup.it> |
* |
* Authors : |
* Giacomo Guidi <giacomo@gandalf.sssup.it> |
* (see the web pages for full authors list) |
* |
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy) |
* |
* http://www.sssup.it |
* http://retis.sssup.it |
* http://shark.sssup.it |
*/ |
/* |
* Copyright (C) 2002 Paolo Gai |
* |
* This program is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; either version 2 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
* |
*/ |
#include "kernel/kern.h" |
#include "edf/edf/edf.h" |
#include "cbs/cbs/cbs.h" |
#include "pthread.h" |
#include "posix/posix/posix.h" |
#include "fsf.h" |
#include "fsf_server.h" |
#include "dummy/dummy/dummy.h" |
#include "sem/sem/sem.h" |
#include "pi/pi/pi.h" |
#include "pc/pc/pc.h" |
#include "hartport/hartport/hartport.h" |
#include "cabs/cabs/cabs.h" |
#include "drivers/keyb.h" |
#include <stdlib.h> |
// -------------------------------------------------- |
// -------------------------------------------------- |
// Init Part |
// -------------------------------------------------- |
// -------------------------------------------------- |
/*+ sysyem tick in us +*/ |
#define TICK 0 |
/*+ RR tick in us +*/ |
#define RRTICK 10000 |
int grubstar_level; |
int posix_level; |
TIME __kernel_register_levels__(void *arg) |
{ |
struct multiboot_info *mb = (struct multiboot_info *)arg; |
EDF_register_level(EDF_ENABLE_ALL); |
posix_level=POSIX_register_level(RRTICK, 1, mb, 32); |
grubstar_level = GRUBSTAR_register_level(5, 0); |
FSF_register_module(posix_level,grubstar_level, (int)(MAX_BANDWIDTH * 0.9)); |
dummy_register_level(); |
// for the keyboard... |
CBS_register_level(CBS_ENABLE_ALL, 0); |
PI_register_module(); |
PC_register_module(); |
SEM_register_module(); |
PTHREAD_register_module(1, 0, 1); |
return TICK; |
} |
TASK __init__(void *arg) |
{ |
struct multiboot_info *mb = (struct multiboot_info *)arg; |
HARTPORT_init(); |
KEYB_init(NULL); |
__call_main__(mb); |
return (void *)0; |
} |
// -------------------------------------------------- |
// -------------------------------------------------- |
// The Test |
// -------------------------------------------------- |
// -------------------------------------------------- |
pthread_t j1 = -1; |
pthread_t j2 = -1; |
pthread_t j3 = -1; |
pthread_t j4 = -1; |
fsf_server_id_t server1 = -1; |
fsf_server_id_t server2 = -1; |
fsf_server_id_t server3 = -1; |
fsf_server_id_t server4 = -1; |
fsf_contract_parameters_t contract1, contract2; |
#define TASK_PERIOD 1000000 |
void *periodic_star(void *arg) |
{ |
struct timespec actual,end,next_time; |
int actpersecond,act,cycle; |
int mean,nmean; |
bool was_deadline_missed, was_budget_overran; |
act = 0; |
actpersecond = 0; |
mean = 0; |
nmean = 0; |
cycle = 0; |
for (;;) { |
kern_gettime(&actual); |
cycle++; |
if (act == 0) { |
TIMESPEC_ASSIGN(&end,&actual); |
end.tv_sec++; |
} |
if (TIMESPEC_A_LT_B(&actual,&end)) { |
act++; |
} else { |
actpersecond = act; |
act = 0; |
mean = (mean * nmean + actpersecond) / (nmean+1); |
nmean++; |
} |
printf_xy(0,exec_shadow,WHITE,"Thread %3d Act_per_Second = %8d Mean = %8d Cycle = %8d", |
exec_shadow,actpersecond,mean,cycle); |
kern_gettime(&next_time); |
ADDUSEC2TIMESPEC(TASK_PERIOD, &next_time); |
fsf_schedule_timed_job(&next_time, NULL, NULL, &was_deadline_missed, &was_budget_overran); |
} |
return NULL; |
} |
void *star(void *arg) |
{ |
struct timespec actual,end; |
int actpersecond,act; |
int mean,nmean,cycle; |
act = 0; |
actpersecond = 0; |
mean = 0; |
nmean = 0; |
cycle = 0; |
for (;;) { |
cycle++; |
kern_gettime(&actual); |
if (act == 0) { |
TIMESPEC_ASSIGN(&end,&actual); |
end.tv_sec++; |
} |
if (TIMESPEC_A_LT_B(&actual,&end)) { |
act++; |
} else { |
actpersecond = act; |
act = 0; |
mean = (mean * nmean + actpersecond) / (nmean+1); |
nmean++; |
} |
printf_xy(0,exec_shadow,WHITE,"Thread %3d Act_per_Second = %8d Mean = %8d Cycle = %8d", |
exec_shadow,actpersecond,mean,cycle); |
} |
return NULL; |
} |
void *edftask(void *arg) |
{ |
int i,j; |
while(1) { |
for (i=0;i<5; i++) { |
for (j=0; j<10; j++); |
//cputc('#'); |
//cputs((char *)(arg)); |
} |
task_endcycle(); |
} |
return NULL; |
} |
void create() |
{ |
HARD_TASK_MODEL mhard; |
struct timespec period1 = {0,100000000}; |
struct timespec period2 = {0,100000000}; |
struct timespec budget1 = {0,30000000}; |
struct timespec budget2 = {0,30000000}; |
PID t1, t2; |
int err; |
FSF_start_service_task(); |
kern_printf("(Start Create)"); |
hard_task_default_model(mhard); |
hard_task_def_ctrl_jet(mhard); |
hard_task_def_mit(mhard,32000); |
hard_task_def_wcet(mhard,3000); |
hard_task_def_arg(mhard,(void *)"X"); |
hard_task_def_group(mhard,1); |
hard_task_def_periodic(mhard); |
//t1 = task_create("X", edftask, &mhard, NULL); |
//if (t1 == NIL) { |
// perror("Could not create task X ..."); |
// exit(1); |
//} |
hard_task_def_mit(mhard,32000); |
hard_task_def_wcet(mhard,3000); |
hard_task_def_arg(mhard,(void *)"Y"); |
//t2 = task_create("Y", edftask, &mhard, NULL); |
//if (t2 == NIL) { |
// perror("Could not create task Y ..."); |
// exit(1); |
//} |
//group_activate(1); |
err = pthread_create(&j1, NULL, star, (void *)"A"); |
if (err) { |
perror("Could not create task A ..."); |
exit(1); |
} |
err = pthread_create(&j2, NULL, periodic_star, (void *)"B"); |
if (err) { |
perror("Could not create task B ..."); |
exit(1); |
} |
err = pthread_create(&j3, NULL, star, (void *)"C"); |
if (err) { |
perror("Could not create task C ..."); |
exit(1); |
} |
err = pthread_create(&j4, NULL, periodic_star, (void *)"D"); |
if (err) { |
perror("Could not create task D ..."); |
exit(1); |
} |
fsf_initialize_contract(&contract1); |
fsf_set_contract_basic_parameters(&contract1,&budget1,&period1,FSF_DEFAULT_WORKLOAD); |
fsf_initialize_contract(&contract2); |
fsf_set_contract_basic_parameters(&contract2,&budget2,&period2,FSF_DEFAULT_WORKLOAD); |
kern_printf("(End Create)"); |
} |
int main(int argc, char **argv) |
{ |
char ch = 0; |
int err; |
create(); |
do { |
ch = keyb_getch(BLOCK); |
switch(ch) { |
case '1': |
err = fsf_bind_thread_to_server(server1,j1); |
kern_printf("(%d)",err); |
break; |
case '2': |
err = fsf_bind_thread_to_server(server2,j2); |
kern_printf("(%d)",err); |
break; |
case '3': |
err = fsf_bind_thread_to_server(server1,j3); |
kern_printf("(%d)",err); |
break; |
case '4': |
err = fsf_bind_thread_to_server(server2,j4); |
kern_printf("(%d)",err); |
break; |
case '5': |
err = fsf_unbind_thread_from_server(j1); |
kern_printf("(%d)",err); |
break; |
case '6': |
err = fsf_unbind_thread_from_server(j2); |
kern_printf("(%d)",err); |
break; |
case '7': |
err = fsf_unbind_thread_from_server(j3); |
kern_printf("(%d)",err); |
break; |
case '8': |
err = fsf_unbind_thread_from_server(j4); |
kern_printf("(%d)",err); |
break; |
case 'q': |
err = fsf_negotiate_contract(&contract1,&server1); |
cprintf("(%d)",err); |
break; |
case 'w': |
err = fsf_negotiate_contract(&contract2,&server2); |
kern_printf("(%d)",err); |
break; |
case 'e': |
err = fsf_negotiate_contract(&contract1,&server3); |
kern_printf("(%d)",err); |
break; |
case 'r': |
err = fsf_cancel_contract(server1); |
kern_printf("(%d)",err); |
break; |
case 't': |
err = fsf_cancel_contract(server2); |
kern_printf("(%d)",err); |
break; |
case 'y': |
err = fsf_cancel_contract(server3); |
kern_printf("(%d)",err); |
break; |
} |
} while(ch != ESC); |
exit(1); |
return 0; |
} |
/unsupported/trunk/first-official/test2.c |
---|
0,0 → 1,431 |
/* |
* Project: S.Ha.R.K. |
* |
* Coordinators: |
* Giorgio Buttazzo <giorgio@sssup.it> |
* Paolo Gai <pj@gandalf.sssup.it> |
* |
* Authors : |
* Giacomo Guidi <giacomo@gandalf.sssup.it> |
* |
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy) |
* |
* http://www.sssup.it |
* http://retis.sssup.it |
* http://shark.sssup.it |
*/ |
/* |
* Copyright (C) 2000 Paolo Gai |
* |
* This program is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; either version 2 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
*/ |
#include "kernel/kern.h" |
#include "fsf.h" |
#include "fsf_server.h" |
#include "stdlib.h" |
#include "unistd.h" |
#include "string.h" |
#include "pistar.h" |
#include "pthread.h" |
#include "drivers/glib.h" |
#include <tracer.h> |
#include "FTrace_udp.h" |
#include "FTrace_chunk.h" |
#include <drivers/shark_keyb26.h> |
#define TEST_PERIOD 50000 |
mutex_t mux; |
int main_chunk; |
TASK finish_task() { |
#ifdef __NEW_TRACER__ |
group_kill(1); |
group_kill(2); |
FTrace_OSD_init_udp(1,"192.168.82.43","192.168.82.41"); |
FTrace_send_chunk(main_chunk, 0, FTRACE_CHUNK_FLAG_FREE | FTRACE_CHUNK_FLAG_CYC); |
exit(0); |
#else |
exit(0); |
#endif |
return NULL; |
} |
void print_timer(int x, int y) |
{ |
long nsec,sec,min,hrs,day; |
struct timespec actual_timer; |
char tmp[100]; |
sys_gettime(&actual_timer); |
nsec = actual_timer.tv_nsec; |
sec = actual_timer.tv_sec; |
min = sec / 60; |
sec %= 60; |
hrs = min / 60; |
min %= 60; |
day = hrs / 24; |
hrs %= 24; |
sprintf(tmp,"Time: %2ld d %2ld h %2ld m %2ld s %12ld ns",day,hrs,min,sec,(long)nsec); |
mutex_lock(&mux); |
grx_text(tmp,x,y,rgb16(255,255,255),0); |
mutex_unlock(&mux); |
} |
#define LOAD_VARIATION 10 |
#define MAX_V_QOS 30 |
#define MIN_V_QOS 2 |
void *test_task_variable(void *arg) { |
struct timespec next_time; |
bool was_deadline_missed = false, was_budget_overran = false; |
char tmp[100]; |
long long i; |
int task_qos; |
int var_load, rd_per; |
TIME exectime; |
task_qos = 7; |
var_load = 5; |
rd_per = 0; |
while(1) { |
print_timer(307,10+30*exec_shadow); |
sprintf(tmp,"Test Thread V QOS = %5d PID = %3d VLOAD = %3d",task_qos,exec_shadow,var_load); |
mutex_lock(&mux); |
if (!was_deadline_missed) |
grx_text(tmp,307,20+30*exec_shadow,rgb16(255,255,255),0); |
else |
grx_text(tmp,307,20+30*exec_shadow,rgb16(255,0,0),0); |
mutex_unlock(&mux); |
//jet_gettable(exec_shadow, &exectime, 1); |
//sprintf(tmp,"Thread Exec Timer = %10d us",(int)exectime); |
//grx_text(tmp,307,30+30*exec_shadow,rgb16(255,255,255),0); |
if (rd_per > LOAD_VARIATION) { |
var_load += rand()%3-1; |
if (var_load > 20) var_load = 20; |
if (var_load < 0) var_load = 0; |
rd_per = 0; |
} else { |
rd_per++; |
} |
for(i = 0; i < 10000*(task_qos+var_load); i++); |
} |
return NULL; |
} |
#define MAX_C_QOS 30 |
#define MIN_C_QOS 2 |
void *test_task_constant(void *arg) { |
struct timespec next_time; |
bool was_deadline_missed = false, was_budget_overran = false; |
char tmp[100]; |
long long i; |
int task_qos; |
task_qos = 7; |
while(1) { |
print_timer(307,10+20*exec_shadow); |
sprintf(tmp,"Test Task C QOS = %5d PID = %3d",task_qos,exec_shadow); |
mutex_lock(&mux); |
if (!was_deadline_missed) |
grx_text(tmp,307,20+20*exec_shadow,rgb16(255,255,255),0); |
else |
grx_text(tmp,307,20+20*exec_shadow,rgb16(255,0,0),0); |
mutex_unlock(&mux); |
for(i = 0; i < 10000*task_qos; i++); |
} |
return NULL; |
} |
void draw_box(int x1, int y1, int x2, int y2) |
{ |
grx_rect(x1,y1,x2,y2,rgb16(160,160,160)); |
grx_rect(x1+2,y1+2,x2-2,y2-2,rgb16(210,210,210)); |
} |
void layout_screen() |
{ |
draw_box(0,0,300,500); |
grx_text("Application Task List",5,5,rgb16(255,255,255),0); |
draw_box(303,0,799,500); |
grx_text("Task Output",305,5,rgb16(255,255,255),0); |
draw_box(0,503,799,599); |
grx_line(140,505,140,597,rgb16(255,255,255)); |
grx_line(140,583,797,583,rgb16(255,255,255)); |
grx_text("Application Statistics",142,507,rgb16(255,255,255),0); |
} |
void program_end() |
{ |
grx_close(); |
} |
void *mpeg2decoder(void *arg); |
void add_posixstar_thread(fsf_server_id_t server) |
{ |
int err; |
pthread_t j = -1; |
static fsf_sched_params_t pr; |
NRT_TASK_MODEL nrt; |
pr.policy=FSF_RR; |
pr.params=&nrt; |
nrt_task_default_model(nrt); |
nrt_task_def_save_arrivals(nrt); |
nrt_task_def_group(nrt,1); |
err = pthread_create(&j, NULL, test_task_variable, NULL); |
if (err) { |
perror("Could not create task..."); |
exit(1); |
} |
err=fsf_bind_local_thread_to_server(server, j, (fsf_sched_params_t *)(&pr)); |
if (err) { |
grx_close(); |
kern_printf("Could not bind task.. %d", err); |
exit(1); |
} |
} |
void add_edfstar_thread(fsf_server_id_t server) |
{ |
int err; |
pthread_t j = -1; |
HARD_TASK_MODEL ht; |
static fsf_sched_params_t pr; |
pr.policy=FSF_EDF; |
pr.params=&ht; |
hard_task_default_model(ht); |
hard_task_def_mit(ht,100000); |
hard_task_def_wcet(ht,90000); |
nrt_task_def_group(ht,2); |
err = pthread_create(&j, NULL, mpeg2decoder, NULL); |
if (err) { |
grx_close(); |
perror("Could not create task..."); |
exit(1); |
} |
err=fsf_bind_local_thread_to_server(server, j,(fsf_sched_params_t *)(&pr)); |
if (err) { |
grx_close(); |
perror("Could not bind task.."); |
exit(1); |
} |
} |
void ending_system(KEY_EVT *e) { |
grx_close(); |
#ifdef __NEW_TRACER__ |
NRT_TASK_MODEL nrt; |
TRACER_LOGEVENT(FTrace_EVT_trace_stop,0,0); |
FTrace_disable(); |
//group_kill(l->group); |
nrt_task_default_model(nrt); |
task_activate(task_create("Finish",finish_task,&nrt,NULL)); |
#else |
exit(0); |
#endif |
} |
int main(int argc, char **argv) |
{ |
char ch; |
int err; |
//KEY_EVT k; |
PI_mutexattr_t a; |
KEY_EVT ev; |
union sigval no_sigval = {0}; |
struct timespec period = {0,10000000}; |
struct timespec budget = {0,1000000}; |
struct timespec period1 = {0,10000000}; |
struct timespec period2 = {0,10000000}; |
struct timespec budget1 = {0,3000000}; |
struct timespec budget2 = {0,3000000}; |
fsf_server_id_t server1, server2; |
fsf_contract_parameters_t contract1, contract2; |
union sigval sval; |
ev.ascii = 'c'; |
ev.scan = KEY_C; |
ev.status = KEY_PRESSED; |
ev.flag = CNTR_BIT; |
keyb_hook(ev, ending_system, FALSE); |
#ifdef __NEW_TRACER__ |
main_chunk = FTrace_chunk_create(10000000, 1000, FTRACE_CHUNK_FLAG_FREE | FTRACE_CHUNK_FLAG_CYC); |
FTrace_actual_chunk_select(main_chunk); |
FTrace_enable(); |
#endif |
TRACER_LOGEVENT(FTrace_EVT_trace_start,0,0); |
PI_mutexattr_default(a); |
FSF_start_service_task(); |
mutex_init(&mux,&a); |
fsf_initialize_contract(&contract1); |
fsf_set_contract_basic_parameters(&contract1,&budget1,&period1,FSF_DEFAULT_WORKLOAD); |
fsf_set_contract_timing_requirements(&contract1,true,NULL,0,no_sigval,0,no_sigval); |
fsf_initialize_contract(&contract2); |
fsf_set_contract_scheduling_policy(&contract1, FSF_RR); |
fsf_set_contract_basic_parameters(&contract2,&budget2,&period2,FSF_DEFAULT_WORKLOAD); |
fsf_set_contract_timing_requirements(&contract2,true,NULL,0,no_sigval,0,no_sigval); |
fsf_set_contract_scheduling_policy(&contract2, FSF_EDF); |
err = fsf_negotiate_contract(&contract1,&server1); |
if (err) cprintf("(FSF ERROR %d)",err); |
err = fsf_negotiate_contract(&contract2,&server2); |
if (err) cprintf("(FSF ERROR %d)",err); |
//graphic card Initialization |
if (grx_init() < 1) { |
exit(1); |
} |
if (grx_open(800, 600, 16) < 0) { |
cprintf("GRX Err\n"); |
exit(0); |
} |
layout_screen(); |
ch = keyb_getch(BLOCK); |
while(ch != ESC) { |
switch (ch) { |
case '1': |
add_posixstar_thread(server1); |
break; |
case '2': |
add_edfstar_thread(server2); |
break; |
case '3': |
fsf_set_contract_basic_parameters(&contract2,&budget,&period,FSF_DEFAULT_WORKLOAD); |
fsf_request_contract_renegotiation(&contract2,server2, 0, sval); |
break; |
case '4': |
ending_system(NULL); |
break; |
case '5': |
break; |
} |
ch = keyb_getch(BLOCK); |
} |
ending_system(NULL); |
return 0; |
} |
/unsupported/trunk/first-official/initfile.c |
---|
0,0 → 1,204 |
/* |
* Project: S.Ha.R.K. |
* |
* Coordinators: |
* Giorgio Buttazzo <giorgio@sssup.it> |
* Paolo Gai <pj@gandalf.sssup.it> |
* |
* Authors : |
* Giacomo Guidi <giacomo@gandalf.sssup.it> |
* Tullio Facchinetti <tullio.facchinetti@unipv.it> |
* (see the web pages for full authors list) |
* |
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy) |
* |
* http://www.sssup.it |
* http://retis.sssup.it |
* http://shark.sssup.it |
*/ |
/* |
* Copyright (C) 2000 Paolo Gai |
* |
* This program is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; either version 2 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
* |
*/ |
#include "kernel/kern.h" |
#include "edf/edf/edf.h" |
#include "cbs/cbs/cbs.h" |
#include "posix/posix/posix.h" |
#include "pthread.h" |
#include "sem/sem/sem.h" |
#include "dummy/dummy/dummy.h" |
#include "hartport/hartport/hartport.h" |
#include "fsf.h" |
#include "pi/pi/pi.h" |
#include "pc/pc/pc.h" |
#include "intdrive/intdrive/intdrive.h" |
#include <drivers/shark_linuxc26.h> |
#include <drivers/shark_input26.h> |
#include <drivers/shark_keyb26.h> |
#include <drivers/shark_pci26.h> |
#define TICK 0 |
#define RRTICK 10000 |
/*+ Interrupt Server +*/ |
#define INTDRIVE_Q 1000 |
#define INTDRIVE_U 0.1*MAX_BANDWIDTH |
#define INTDRIVE_FLAG 0 |
void call_shutdown_task(void *arg); |
int device_drivers_init(); |
int device_drivers_close(); |
void set_shutdown_task(); |
TASK shutdown_task_body(void *arg); |
PID shutdown_task_PID = 1; |
void load_file(); |
int device_drivers_close() { |
KEYB26_close(); |
INPUT26_close(); |
return 0; |
} |
int device_drivers_init() { |
KEYB_PARMS kparms = BASE_KEYB; |
LINUXC26_register_module(TRUE); |
PCI26_init(); |
INPUT26_init(); |
/*keyb_def_map(kparms, KEYMAP_IT);*/ |
keyb_def_ctrlC(kparms, NULL); |
KEYB26_init(&kparms); |
return 0; |
} |
TASK shutdown_task_body(void *arg) { |
device_drivers_close(); |
sys_shutdown_message("-- S.Ha.R.K. Closed --\n"); |
return NULL; |
} |
#define SHUTDOWN_TIMEOUT_SEC 3 |
void set_shutdown_task() { |
NRT_TASK_MODEL nrt; |
nrt_task_default_model(nrt); |
nrt_task_def_system(nrt); |
shutdown_task_PID = task_create("Shutdown Task", shutdown_task_body, &nrt, NULL); |
if (shutdown_task_PID == NIL) { |
sys_shutdown_message("Error: Cannot create shutdown task\n"); |
exit(1); |
} |
} |
void call_shutdown_task(void *arg) { |
struct timespec t; |
sys_gettime(&t); |
t.tv_sec += SHUTDOWN_TIMEOUT_SEC; |
/* Emergency timeout to exit from RUNLEVEL_SHUTDOWN */ |
kern_event_post(&t,(void *)((void *)sys_abort_shutdown),(void *)0); |
task_activate(shutdown_task_PID); |
} |
TIME __kernel_register_levels__(void *arg) |
{ |
struct multiboot_info *mb = (struct multiboot_info *)arg; |
int edf_level; |
int grubstar_level; |
int posix_level; |
int pi_level; |
int pc_level; |
INTDRIVE_register_level(INTDRIVE_Q, INTDRIVE_Q, INTDRIVE_U, INTDRIVE_FLAG); |
edf_level=EDF_register_level(EDF_ENABLE_ALL); |
posix_level=POSIX_register_level(RRTICK, edf_level, mb, 32); |
grubstar_level = GRUBSTAR_register_level(FSF_MAX_N_SERVERS, edf_level); |
FSF_register_module(posix_level,grubstar_level, (int)(MAX_BANDWIDTH*0.8)); |
dummy_register_level(); |
CBS_register_level(CBS_ENABLE_ALL,edf_level); |
SEM_register_module(); |
pi_level=PI_register_module(); |
pc_level=PC_register_module(); |
PTHREAD_register_module(posix_level, pi_level, pc_level); |
load_file(); |
return TICK; |
} |
TASK __init__(void *arg) |
{ |
struct multiboot_info *mb = (struct multiboot_info *)arg; |
HARTPORT_init(); |
set_shutdown_task(); |
device_drivers_init(); |
sys_atrunlevel(call_shutdown_task, NULL, RUNLEVEL_SHUTDOWN); |
__call_main__(mb); |
return (void *)0; |
} |
int dos_video_preload(void *filename, long max_size, void **start, void **end); |
void *start_file; |
void *end_file; |
void load_file() |
{ |
start_file = NULL; |
end_file = NULL; |
dos_video_preload("test.m2v",5000000,&start_file,&end_file); |
cprintf("Start file ptr = %08lx\n",(long)(start_file)); |
cprintf("End file ptr = %08lx\n",(long)(end_file)); |
cprintf("Size = %8ld\n",(long)(end_file - start_file)); |
} |
/unsupported/trunk/first-official/demos.txt |
---|
0,0 → 1,48 |
FSF demo for S.Ha.R.K |
test1.c: |
This demo shows the main feature of service contract implementation. |
A set of 4 threads is created using the pthread standard functions. |
At the beginning, these threads run without temporal restrictions |
and they don't respect any deadline. |
Two service contracts are initialized and set |
fsf_initialize_contract(&contract1); |
fsf_initialize_contract(&contract2); |
fsf_set_contract_basic_parameters(&contract1,&budget1,&period1,NULL,NULL,FSF_DEFAULT_WORKLOAD); |
fsf_set_contract_basic_parameters(&contract2,&budget2,&period2,NULL,NULL,FSF_DEFAULT_WORKLOAD); |
whit the button 'q','w','e' you can respectively |
negotiate contract for a server |
[err = fsf_negotiate_contract(&contractX,&serverY);] |
'q' -> negotiate contract1 for server1 |
'w' -> negotiate contract2 for server2 |
'e' -> negotiate contract1 for server3 |
now with button '1','2','3','4' you can bind the thread to a server |
[err = fsf_bind_thread_to_server(serverY,jZ);] |
'1' -> bind thread1 to server1 |
'2' -> bind thread2 to server2 |
'3' -> bind thread3 to server3 |
'4' -> bind thread4 to server2 |
threads will start to respect the assigned budget. It's possible |
to bind more threads to one server. The local scheduler specified in the |
contract define how the threads will get the server resources. |
With '5','6','7','8' the thread is unbind from the server |
[err = fsf_unbind_thread_from_server(jZ);] |
With 'r','t','y' a server is removed |
[err = fsf_cancel_contract(&server2);] |
/unsupported/trunk/first-official/mpeg2/getbits.c |
---|
0,0 → 1,217 |
/* getbits.c, bit level routines */ |
/* |
* All modifications (mpeg2decode -> mpeg2play) are |
* Copyright (C) 1996, Stefan Eckart. All Rights Reserved. |
*/ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
#include <stdlib.h> |
#include "drivers/glib.h" |
#include "config.h" |
#include "global.h" |
/* initialize buffer, call once before first getbits or showbits */ |
void Initialize_Buffer() |
{ |
ld->Incnt = 0; |
ld->Rdptr = ld->Rdbfr + 2048; |
ld->Rdmax = ld->Rdptr; |
#ifdef VERIFY |
/* only the verifier uses this particular bit counter |
* Bitcnt keeps track of the current parser position with respect |
* to the video elementary stream being decoded, regardless |
* of whether or not it is wrapped within a systems layer stream |
*/ |
ld->Bitcnt = 0; |
#endif |
ld->Bfr = 0; |
Flush_Buffer(0); /* fills valid data into bfr */ |
} |
int read(int Infile, void *Rdbfr, int rdsize) { |
if (ld->actual_file_ptr + 2048 > ld->end_file_ptr) |
rdsize = (int)(ld->end_file_ptr - ld->actual_file_ptr); |
if (rdsize < 0) return 0; |
memcpy(Rdbfr,ld->actual_file_ptr,rdsize); |
ld->actual_file_ptr += rdsize; |
return rdsize; |
} |
void Fill_Buffer() |
{ |
int Buffer_Level; |
Buffer_Level = read(ld->Infile,ld->Rdbfr,2048); |
ld->Rdptr = ld->Rdbfr; |
if (System_Stream_Flag) |
ld->Rdmax -= 2048; |
/* end of the bitstream file */ |
if (Buffer_Level < 2048) |
{ |
/* just to be safe */ |
if (Buffer_Level < 0) |
Buffer_Level = 0; |
/* pad until the next to the next 32-bit word boundary */ |
while (Buffer_Level & 3) |
ld->Rdbfr[Buffer_Level++] = 0; |
/* pad the buffer with sequence end codes */ |
while (Buffer_Level < 2048) |
{ |
ld->Rdbfr[Buffer_Level++] = SEQUENCE_END_CODE>>24; |
ld->Rdbfr[Buffer_Level++] = SEQUENCE_END_CODE>>16; |
ld->Rdbfr[Buffer_Level++] = SEQUENCE_END_CODE>>8; |
ld->Rdbfr[Buffer_Level++] = SEQUENCE_END_CODE&0xff; |
} |
} |
} |
/* MPEG-1 system layer demultiplexer */ |
int Get_Byte() |
{ |
while(ld->Rdptr >= ld->Rdbfr+2048) |
{ |
read(ld->Infile,ld->Rdbfr,2048); |
ld->Rdptr -= 2048; |
ld->Rdmax -= 2048; |
} |
return *ld->Rdptr++; |
} |
/* extract a 16-bit word from the bitstream buffer */ |
int Get_Word() |
{ |
int Val; |
Val = Get_Byte(); |
return (Val<<8) | Get_Byte(); |
} |
/* return next n bits (right adjusted) without advancing */ |
unsigned int Show_Bits(N) |
int N; |
{ |
return ld->Bfr >> (32-N); |
} |
/* return next bit (could be made faster than Get_Bits(1)) */ |
unsigned int Get_Bits1() |
{ |
return Get_Bits(1); |
} |
/* advance by n bits */ |
void Flush_Buffer(N) |
int N; |
{ |
int Incnt; |
ld->Bfr <<= N; |
Incnt = ld->Incnt -= N; |
if (Incnt <= 24) |
{ |
if (System_Stream_Flag && (ld->Rdptr >= ld->Rdmax-4)) |
{ |
do |
{ |
if (ld->Rdptr >= ld->Rdmax) |
Next_Packet(); |
ld->Bfr |= Get_Byte() << (24 - Incnt); |
Incnt += 8; |
} |
while (Incnt <= 24); |
} |
else if (ld->Rdptr < ld->Rdbfr+2044) |
{ |
do |
{ |
ld->Bfr |= *ld->Rdptr++ << (24 - Incnt); |
Incnt += 8; |
} |
while (Incnt <= 24); |
} |
else |
{ |
do |
{ |
if (ld->Rdptr >= ld->Rdbfr+2048) |
Fill_Buffer(); |
ld->Bfr |= *ld->Rdptr++ << (24 - Incnt); |
Incnt += 8; |
} |
while (Incnt <= 24); |
} |
ld->Incnt = Incnt; |
} |
#ifdef VERIFY |
ld->Bitcnt += N; |
#endif /* VERIFY */ |
} |
/* return next n bits (right adjusted) */ |
unsigned int Get_Bits(N) |
int N; |
{ |
unsigned int Val; |
Val = Show_Bits(N); |
Flush_Buffer(N); |
return Val; |
} |
/unsupported/trunk/first-official/mpeg2/verify.c |
---|
0,0 → 1,300 |
/* verify.c |
* |
* Bitstream verification routines |
* |
* |
*/ |
#ifdef VERIFY |
#include <stdlib.h> |
#include <math.h> /* needed for ceil() */ |
#include "config.h" |
#include "global.h" |
/* #define DEBUG */ |
#ifdef DEBUG |
#define PC |
#endif |
#ifdef PC |
#include <conio.h> /* needed for getch() */ |
#endif /* PC */ |
/* |
Check picture headers: due to the VBV definition of picture data, |
this routine must be called immediately before any picture data |
is parsed. (before the first slice start code, including any slice |
start code stuffing). |
*/ |
static void Check_VBV_Delay _ANSI_ARGS_((int Bitstream_Framenum, int Sequence_Framenum)); |
void Check_Headers(Bitstream_Framenum, Sequence_Framenum) |
int Bitstream_Framenum; |
int Sequence_Framenum; |
{ |
if((!low_delay)&&(vbv_delay!=0)&&(vbv_delay!=0xFFFF)) |
Check_VBV_Delay(Bitstream_Framenum, Sequence_Framenum); |
/* clear out the header tracking variables so we have an accurate |
count next time */ |
Clear_Verify_Headers(); |
} |
/* |
* Verify vbv_delay value in picture header |
* (low_delay==1 checks not implemented. this does not exhaustively test all |
* possibilities suggested in ISO/IEC 13818-2 Annex C. It only checks |
* for constant rate streams) |
* |
* Q:how do we tell a variable rate stream from a constant rate stream anyway? |
* it's not as simple as vbv_delay==0xFFFF, since we need meaningful |
* vbv_delay values to calculate the piecewise rate in the first place! |
* |
* Also: no special provisions at the beginning or end of a sequence |
*/ |
static void Check_VBV_Delay(Bitstream_Framenum, Sequence_Framenum) |
int Bitstream_Framenum; |
int Sequence_Framenum; |
{ |
double B; /* buffer size */ |
double Bn; /* buffer fullness for picture n */ |
double R; /* bitrate */ |
double I; /* time interval (t[n+1] - t[n]) */ |
double T; /* inverse of the frame rate (frame period) */ |
int d; |
int internal_vbv_delay; |
static int previous_IorP_picture_structure; |
static int previous_IorP_repeat_first_field; |
static int previous_IorP_top_field_first; |
static int previous_vbv_delay; |
static int previous_bitstream_position; |
static double previous_Bn; |
static double E; /* maximum quantization error or mismatch */ |
if((Sequence_Framenum==0)&&(!Second_Field)) |
{ /* first coded picture of sequence */ |
R = bit_rate; |
/* the initial buffer occupancy is taken on faith |
that is, we believe what is transmitted in the first coded picture header |
to be the true/actual buffer occupancy */ |
Bn = (R * (double) vbv_delay) / 90000.0; |
B = 16 * 1024 * vbv_buffer_size; |
/* maximum quantization error in bitrate (bit_rate_value is quantized/ |
rounded-up to units of 400 bits/sec as per ISO/IEC 13818-2 |
section 6.3.3 */ |
E = (400.0/frame_rate) + 400; |
#ifdef DEBUG |
cprintf("vbv_buffer_size (B) = %.0f, Bn=%f, E=%f, \nbitrate=%f, vbv_delay=%d frame_rate=%f\n", |
B, Bn, E, bit_rate, vbv_delay, frame_rate); |
#endif |
} |
else /* not the first coded picture of sequence */ |
{ |
/* derive the interval (I). The interval tells us how many constant rate bits |
* will have been downloaded to the buffer during the current picture period |
* |
* interval assumes that: |
* 1. whilst we are decoding the current I or P picture, we are displaying |
* the previous I or P picture which was stored in the reorder |
* buffer (pointed to by forward_reference_frame in this implementation) |
* |
* 2. B pictures are output ("displayed") at the time when they are decoded |
* |
*/ |
if(progressive_sequence) /* Annex C.9 (progressive_sequence==1, low_delay==0) */ |
{ |
T = 1/frame_rate; /* inverse of the frame rate (frame period) */ |
if(picture_coding_type==B_TYPE) |
{ |
if(repeat_first_field==1) |
{ |
if(top_field_first==1) |
I = T*3; /* three frame periods */ |
else |
I = T*2; /* two frame periods */ |
} |
else |
I = T; /* one frame period */ |
} |
else /* P or I frame */ |
{ |
if(previous_IorP_repeat_first_field==1) |
{ |
if(previous_IorP_top_field_first==1) |
I = 3*T; |
else |
I = 2*T; |
} |
else |
I = T; |
} |
} |
else /* Annex C.11 (progressive_sequence==0, low_delay==0) */ |
{ |
T = 1/(2*frame_rate); /* inverse of two times the frame rate (field period) */ |
if(picture_coding_type==B_TYPE) |
{ |
if(picture_structure==FRAME_PICTURE) |
{ |
if(repeat_first_field==0) |
I = 2*T; /* two field periods */ |
else |
I = 3*T; /* three field periods */ |
} |
else /* B field */ |
{ |
I = T; /* one field period */ |
} |
} |
else /* I or P picture */ |
{ |
if(picture_structure==FRAME_PICTURE) |
{ |
if(previous_IorP_repeat_first_field==0) |
I = 2*T; |
else |
I = 3*T; |
} |
else |
{ |
if(Second_Field==0) /* first field of current frame */ |
I = T; |
else /* second field of current frame */ |
{ |
/* formula: previous I or P display period (2*T or 3*T) minus the |
very recent decode period (T) of the first field of the current |
frame */ |
if(previous_IorP_picture_structure!=FRAME_PICTURE |
|| previous_IorP_repeat_first_field==0) |
I = 2*T - T; /* a net of one field period */ |
else if(previous_IorP_picture_structure==FRAME_PICTURE |
&& previous_IorP_repeat_first_field==1) |
I = 3*T - T; /* a net of two field periods */ |
} |
} |
} |
} |
/* derive coded size of previous picture */ |
d = ld->Bitcnt - previous_bitstream_position; |
/* Rate = Distance/Time */ |
/* piecewise constant rate (variable rate stream) calculation |
* R = ((double) d /((previous_vbv_delay - vbv_delay)/90000 + I)); |
*/ |
R = bit_rate; |
/* compute buffer fullness just before removing picture n |
* |
* Bn = previous_Bn + (I*R) - d; (recursive formula) |
* |
* where: |
* |
* n is the current picture |
* |
* Bn is the buffer fullness for the current picture |
* |
* previous_Bn is the buffer fullness of the previous picture |
* |
* (I*R ) is the bits accumulated during the current picture |
* period |
* |
* d is the number of bits removed during the decoding of the |
* previous picture |
*/ |
Bn = previous_Bn + (I*R) - d; |
/* compute internally derived vbv_delay (rouding up with ceil()) */ |
internal_vbv_delay = (int) ceil((90000 * Bn / bit_rate)); |
#ifdef DEBUG |
cprintf("\nvbv_delay: internal=%d, bitstream=%d\n", internal_vbv_delay, vbv_delay); |
cprintf("Bn=%f, prevBn=%f, I=%f, R=%f, d=%d\n", Bn, previous_Bn, I, R, d); |
cprintf("frame(%d), pictstruct(%d), picttype(%d)\n", Sequence_Framenum, |
picture_structure, picture_coding_type); |
/* report error */ |
if(internal_vbv_delay != vbv_delay) |
{ |
cprintf("WARNING: internal_vbv_delay(%d) != vbv_delay(%d)\n", |
internal_vbv_delay, vbv_delay); |
} |
#endif |
} /* not the first coded picture of sequence */ |
#ifdef PC |
getch(); |
#endif /* PC */ |
/* update generic tracking variables */ |
previous_bitstream_position = ld->Bitcnt ; |
previous_vbv_delay = vbv_delay; |
previous_Bn = Bn; |
/* reference picture: reordered/delayed output picture */ |
if(picture_coding_type!=B_TYPE) |
{ |
previous_IorP_repeat_first_field = repeat_first_field; |
previous_IorP_top_field_first = top_field_first; |
previous_IorP_picture_structure = picture_structure; |
} |
} |
/* variables to keep track of the occurance of redundant headers between pictures */ |
void Clear_Verify_Headers() |
{ |
verify_sequence_header = 0; |
verify_group_of_pictures_header = 0; |
verify_picture_header = 0; |
verify_slice_header = 0; |
verify_sequence_extension = 0; |
verify_sequence_display_extension = 0; |
verify_quant_matrix_extension = 0; |
verify_sequence_scalable_extension = 0; |
verify_picture_display_extension = 0; |
verify_picture_coding_extension = 0; |
verify_picture_spatial_scalable_extension = 0; |
verify_picture_temporal_scalable_extension = 0; |
verify_copyright_extension = 0; |
} |
#endif /* VERIFY */ |
/unsupported/trunk/first-official/mpeg2/motion.c |
---|
0,0 → 1,234 |
/* motion.c, motion vector decoding */ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
#include "config.h" |
#include "global.h" |
/* private prototypes */ |
static void decode_motion_vector _ANSI_ARGS_((int *pred, int r_size, int motion_code, |
int motion_residualesidual, int full_pel_vector)); |
/* ISO/IEC 13818-2 sections 6.2.5.2, 6.3.17.2, and 7.6.3: Motion vectors */ |
void motion_vectors(PMV,dmvector, |
motion_vertical_field_select,s,motion_vector_count,mv_format,h_r_size,v_r_size,dmv,mvscale) |
int PMV[2][2][2]; |
int dmvector[2]; |
int motion_vertical_field_select[2][2]; |
int s, motion_vector_count, mv_format, h_r_size, v_r_size, dmv, mvscale; |
{ |
if (motion_vector_count==1) |
{ |
if (mv_format==MV_FIELD && !dmv) |
{ |
motion_vertical_field_select[1][s] = motion_vertical_field_select[0][s] = Get_Bits(1); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
cprintf("motion_vertical_field_select[][%d] (%d): %d\n",s, |
motion_vertical_field_select[0][s],motion_vertical_field_select[0][s]); |
} |
#endif /* TRACE */ |
} |
motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0); |
/* update other motion vector predictors */ |
PMV[1][s][0] = PMV[0][s][0]; |
PMV[1][s][1] = PMV[0][s][1]; |
} |
else |
{ |
motion_vertical_field_select[0][s] = Get_Bits(1); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
cprintf("motion_vertical_field_select[0][%d] (%d): %d\n",s, |
motion_vertical_field_select[0][s],motion_vertical_field_select[0][s]); |
} |
#endif /* TRACE */ |
motion_vector(PMV[0][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0); |
motion_vertical_field_select[1][s] = Get_Bits(1); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
cprintf("motion_vertical_field_select[1][%d] (%d): %d\n",s, |
motion_vertical_field_select[1][s],motion_vertical_field_select[1][s]); |
} |
#endif /* TRACE */ |
motion_vector(PMV[1][s],dmvector,h_r_size,v_r_size,dmv,mvscale,0); |
} |
} |
/* get and decode motion vector and differential motion vector |
for one prediction */ |
void motion_vector(PMV,dmvector, |
h_r_size,v_r_size,dmv,mvscale,full_pel_vector) |
int *PMV; |
int *dmvector; |
int h_r_size; |
int v_r_size; |
int dmv; /* MPEG-2 only: get differential motion vectors */ |
int mvscale; /* MPEG-2 only: field vector in frame pic */ |
int full_pel_vector; /* MPEG-1 only */ |
{ |
int motion_code, motion_residual; |
/* horizontal component */ |
/* ISO/IEC 13818-2 Table B-10 */ |
motion_code = Get_motion_code(); |
motion_residual = (h_r_size!=0 && motion_code!=0) ? Get_Bits(h_r_size) : 0; |
#ifdef TRACE |
if (Trace_Flag) |
{ |
if (h_r_size!=0 && motion_code!=0) |
{ |
cprintf("motion_residual ("); |
Print_Bits(motion_residual,h_r_size,h_r_size); |
cprintf("): %d\n",motion_residual); |
} |
} |
#endif /* TRACE */ |
decode_motion_vector(&PMV[0],h_r_size,motion_code,motion_residual,full_pel_vector); |
if (dmv) |
dmvector[0] = Get_dmvector(); |
/* vertical component */ |
motion_code = Get_motion_code(); |
motion_residual = (v_r_size!=0 && motion_code!=0) ? Get_Bits(v_r_size) : 0; |
#ifdef TRACE |
if (Trace_Flag) |
{ |
if (v_r_size!=0 && motion_code!=0) |
{ |
cprintf("motion_residual ("); |
Print_Bits(motion_residual,v_r_size,v_r_size); |
cprintf("): %d\n",motion_residual); |
} |
} |
#endif /* TRACE */ |
if (mvscale) |
PMV[1] >>= 1; /* DIV 2 */ |
decode_motion_vector(&PMV[1],v_r_size,motion_code,motion_residual,full_pel_vector); |
if (mvscale) |
PMV[1] <<= 1; |
if (dmv) |
dmvector[1] = Get_dmvector(); |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("PMV = %d,%d\n",PMV[0],PMV[1]); |
#endif /* TRACE */ |
} |
/* calculate motion vector component */ |
/* ISO/IEC 13818-2 section 7.6.3.1: Decoding the motion vectors */ |
/* Note: the arithmetic here is more elegant than that which is shown |
in 7.6.3.1. The end results (PMV[][][]) should, however, be the same. */ |
static void decode_motion_vector(pred,r_size,motion_code,motion_residual,full_pel_vector) |
int *pred; |
int r_size, motion_code, motion_residual; |
int full_pel_vector; /* MPEG-1 (ISO/IEC 11172-1) support */ |
{ |
int lim, vec; |
lim = 16<<r_size; |
vec = full_pel_vector ? (*pred >> 1) : (*pred); |
if (motion_code>0) |
{ |
vec+= ((motion_code-1)<<r_size) + motion_residual + 1; |
if (vec>=lim) |
vec-= lim + lim; |
} |
else if (motion_code<0) |
{ |
vec-= ((-motion_code-1)<<r_size) + motion_residual + 1; |
if (vec<-lim) |
vec+= lim + lim; |
} |
*pred = full_pel_vector ? (vec<<1) : vec; |
} |
/* ISO/IEC 13818-2 section 7.6.3.6: Dual prime additional arithmetic */ |
void Dual_Prime_Arithmetic(DMV,dmvector,mvx,mvy) |
int DMV[][2]; |
int *dmvector; /* differential motion vector */ |
int mvx, mvy; /* decoded mv components (always in field format) */ |
{ |
if (picture_structure==FRAME_PICTURE) |
{ |
if (top_field_first) |
{ |
/* vector for prediction of top field from bottom field */ |
DMV[0][0] = ((mvx +(mvx>0))>>1) + dmvector[0]; |
DMV[0][1] = ((mvy +(mvy>0))>>1) + dmvector[1] - 1; |
/* vector for prediction of bottom field from top field */ |
DMV[1][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0]; |
DMV[1][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] + 1; |
} |
else |
{ |
/* vector for prediction of top field from bottom field */ |
DMV[0][0] = ((3*mvx+(mvx>0))>>1) + dmvector[0]; |
DMV[0][1] = ((3*mvy+(mvy>0))>>1) + dmvector[1] - 1; |
/* vector for prediction of bottom field from top field */ |
DMV[1][0] = ((mvx +(mvx>0))>>1) + dmvector[0]; |
DMV[1][1] = ((mvy +(mvy>0))>>1) + dmvector[1] + 1; |
} |
} |
else |
{ |
/* vector for prediction from field of opposite 'parity' */ |
DMV[0][0] = ((mvx+(mvx>0))>>1) + dmvector[0]; |
DMV[0][1] = ((mvy+(mvy>0))>>1) + dmvector[1]; |
/* correct for vertical field shift */ |
if (picture_structure==TOP_FIELD) |
DMV[0][1]--; |
else |
DMV[0][1]++; |
} |
} |
/unsupported/trunk/first-official/mpeg2/global.h |
---|
0,0 → 1,497 |
/* global.h, global variables */ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
#include "ll/sys/types.h" |
#include "kernel/kern.h" |
#include "mpeg2dec.h" |
/* choose between declaration (GLOBAL undefined) |
* and definition (GLOBAL defined) |
* GLOBAL is defined in exactly one file mpeg2dec.c) |
*/ |
#ifndef GLOBAL |
#define EXTERN extern |
#else |
#define EXTERN |
#endif |
/* prototypes of global functions */ |
/* readpic.c */ |
void Substitute_Frame_Buffer _ANSI_ARGS_ ((int bitstream_framenum, |
int sequence_framenum)); |
/* Get_Bits.c */ |
void Initialize_Buffer _ANSI_ARGS_((void)); |
void Fill_Buffer _ANSI_ARGS_((void)); |
unsigned int Show_Bits _ANSI_ARGS_((int n)); |
unsigned int Get_Bits1 _ANSI_ARGS_((void)); |
void Flush_Buffer _ANSI_ARGS_((int n)); |
unsigned int Get_Bits _ANSI_ARGS_((int n)); |
int Get_Byte _ANSI_ARGS_((void)); |
int Get_Word _ANSI_ARGS_((void)); |
/* systems.c */ |
void Next_Packet _ANSI_ARGS_((void)); |
int Get_Long _ANSI_ARGS_((void)); |
void Flush_Buffer32 _ANSI_ARGS_((void)); |
unsigned int Get_Bits32 _ANSI_ARGS_((void)); |
/* getblk.c */ |
void Decode_MPEG1_Intra_Block _ANSI_ARGS_((int comp, int dc_dct_pred[])); |
void Decode_MPEG1_Non_Intra_Block _ANSI_ARGS_((int comp)); |
void Decode_MPEG2_Intra_Block _ANSI_ARGS_((int comp, int dc_dct_pred[])); |
void Decode_MPEG2_Non_Intra_Block _ANSI_ARGS_((int comp)); |
/* gethdr.c */ |
int Get_Hdr _ANSI_ARGS_((void)); |
void next_start_code _ANSI_ARGS_((void)); |
int slice_header _ANSI_ARGS_((void)); |
void marker_bit _ANSI_ARGS_((char *text)); |
/* getpic.c */ |
void Decode_Picture _ANSI_ARGS_((int bitstream_framenum, |
int sequence_framenum)); |
void Output_Last_Frame_of_Sequence _ANSI_ARGS_((int framenum)); |
/* getvlc.c */ |
int Get_macroblock_type _ANSI_ARGS_((void)); |
int Get_motion_code _ANSI_ARGS_((void)); |
int Get_dmvector _ANSI_ARGS_((void)); |
int Get_coded_block_pattern _ANSI_ARGS_((void)); |
int Get_macroblock_address_increment _ANSI_ARGS_((void)); |
int Get_Luma_DC_dct_diff _ANSI_ARGS_((void)); |
int Get_Chroma_DC_dct_diff _ANSI_ARGS_((void)); |
/* idct.c */ |
void Fast_IDCT _ANSI_ARGS_((short *block)); |
void Initialize_Fast_IDCT _ANSI_ARGS_((void)); |
/* Reference_IDCT.c */ |
void Initialize_Reference_IDCT _ANSI_ARGS_((void)); |
void Reference_IDCT _ANSI_ARGS_((short *block)); |
/* motion.c */ |
void motion_vectors _ANSI_ARGS_((int PMV[2][2][2], int dmvector[2], |
int motion_vertical_field_select[2][2], int s, int motion_vector_count, |
int mv_format, int h_r_size, int v_r_size, int dmv, int mvscale)); |
void motion_vector _ANSI_ARGS_((int *PMV, int *dmvector, |
int h_r_size, int v_r_size, int dmv, int mvscale, int full_pel_vector)); |
void Dual_Prime_Arithmetic _ANSI_ARGS_((int DMV[][2], int *dmvector, int mvx, int mvy)); |
/* mpeg2dec.c */ |
void Error _ANSI_ARGS_((char *text)); |
void Warning _ANSI_ARGS_((char *text)); |
void Print_Bits _ANSI_ARGS_((int code, int bits, int len)); |
/* recon.c */ |
void form_predictions _ANSI_ARGS_((int bx, int by, int macroblock_type, |
int motion_type, int PMV[2][2][2], int motion_vertical_field_select[2][2], |
int dmvector[2], int stwtype)); |
/* spatscal.c */ |
void Spatial_Prediction _ANSI_ARGS_((void)); |
/* store.c */ |
void Write_Frame _ANSI_ARGS_((unsigned char *src[], int frame)); |
#ifdef DISPLAY |
/* display.c */ |
void Initialize_Display_Process _ANSI_ARGS_((char *name)); |
void Terminate_Display_Process _ANSI_ARGS_((void)); |
void Display_Second_Field _ANSI_ARGS_((void)); |
void dither _ANSI_ARGS_((unsigned char *src[])); |
void Initialize_Dither_Matrix _ANSI_ARGS_((void)); |
#endif |
/* global variables */ |
EXTERN char Version[] |
#ifdef GLOBAL |
="mpeg2decode V1.2a, 96/07/19" |
#endif |
; |
EXTERN char Author[] |
#ifdef GLOBAL |
="(C) 1996, MPEG Software Simulation Group" |
#endif |
; |
/* zig-zag and alternate scan patterns */ |
EXTERN unsigned char scan[2][64] |
#ifdef GLOBAL |
= |
{ |
{ /* Zig-Zag scan pattern */ |
0,1,8,16,9,2,3,10,17,24,32,25,18,11,4,5, |
12,19,26,33,40,48,41,34,27,20,13,6,7,14,21,28, |
35,42,49,56,57,50,43,36,29,22,15,23,30,37,44,51, |
58,59,52,45,38,31,39,46,53,60,61,54,47,55,62,63 |
}, |
{ /* Alternate scan pattern */ |
0,8,16,24,1,9,2,10,17,25,32,40,48,56,57,49, |
41,33,26,18,3,11,4,12,19,27,34,42,50,58,35,43, |
51,59,20,28,5,13,6,14,21,29,36,44,52,60,37,45, |
53,61,22,30,7,15,23,31,38,46,54,62,39,47,55,63 |
} |
} |
#endif |
; |
/* default intra quantization matrix */ |
EXTERN unsigned char default_intra_quantizer_matrix[64] |
#ifdef GLOBAL |
= |
{ |
8, 16, 19, 22, 26, 27, 29, 34, |
16, 16, 22, 24, 27, 29, 34, 37, |
19, 22, 26, 27, 29, 34, 34, 38, |
22, 22, 26, 27, 29, 34, 37, 40, |
22, 26, 27, 29, 32, 35, 40, 48, |
26, 27, 29, 32, 35, 40, 48, 58, |
26, 27, 29, 34, 38, 46, 56, 69, |
27, 29, 35, 38, 46, 56, 69, 83 |
} |
#endif |
; |
/* non-linear quantization coefficient table */ |
EXTERN unsigned char Non_Linear_quantizer_scale[32] |
#ifdef GLOBAL |
= |
{ |
0, 1, 2, 3, 4, 5, 6, 7, |
8,10,12,14,16,18,20,22, |
24,28,32,36,40,44,48,52, |
56,64,72,80,88,96,104,112 |
} |
#endif |
; |
/* color space conversion coefficients |
* for YCbCr -> RGB mapping |
* |
* entries are {crv,cbu,cgu,cgv} |
* |
* crv=(255/224)*65536*(1-cr)/0.5 |
* cbu=(255/224)*65536*(1-cb)/0.5 |
* cgu=(255/224)*65536*(cb/cg)*(1-cb)/0.5 |
* cgv=(255/224)*65536*(cr/cg)*(1-cr)/0.5 |
* |
* where Y=cr*R+cg*G+cb*B (cr+cg+cb=1) |
*/ |
/* ISO/IEC 13818-2 section 6.3.6 sequence_display_extension() */ |
EXTERN int Inverse_Table_6_9[8][4] |
#ifdef GLOBAL |
= |
{ |
{117504, 138453, 13954, 34903}, /* no sequence_display_extension */ |
{117504, 138453, 13954, 34903}, /* ITU-R Rec. 709 (1990) */ |
{104597, 132201, 25675, 53279}, /* unspecified */ |
{104597, 132201, 25675, 53279}, /* reserved */ |
{104448, 132798, 24759, 53109}, /* FCC */ |
{104597, 132201, 25675, 53279}, /* ITU-R Rec. 624-4 System B, G */ |
{104597, 132201, 25675, 53279}, /* SMPTE 170M */ |
{117579, 136230, 16907, 35559} /* SMPTE 240M (1987) */ |
} |
#endif |
; |
/* output types (Output_Type) */ |
#define T_YUV 0 |
#define T_SIF 1 |
#define T_TGA 2 |
#define T_PPM 3 |
#define T_X11 4 |
#define T_X11HIQ 5 |
/* decoder operation control variables */ |
EXTERN int Output_Type; |
EXTERN int hiQdither; |
/* decoder operation control flags */ |
EXTERN int Quiet_Flag; |
EXTERN int Trace_Flag; |
EXTERN int Fault_Flag; |
EXTERN int Verbose_Flag; |
EXTERN int Two_Streams; |
EXTERN int Spatial_Flag; |
EXTERN int Reference_IDCT_Flag; |
EXTERN int Frame_Store_Flag; |
EXTERN int System_Stream_Flag; |
EXTERN int Display_Progressive_Flag; |
EXTERN int Ersatz_Flag; |
EXTERN int Big_Picture_Flag; |
EXTERN int Verify_Flag; |
EXTERN int Stats_Flag; |
EXTERN int User_Data_Flag; |
EXTERN int Main_Bitstream_Flag; |
/* filenames */ |
EXTERN char *Output_Picture_Filename; |
EXTERN char *Substitute_Picture_Filename; |
EXTERN char *Main_Bitstream_Filename; |
EXTERN char *Enhancement_Layer_Bitstream_Filename; |
/* buffers for multiuse purposes */ |
EXTERN char Error_Text[256]; |
EXTERN unsigned char *Clip; |
/* pointers to generic picture buffers */ |
EXTERN unsigned char *backward_reference_frame[3]; |
EXTERN unsigned char *forward_reference_frame[3]; |
EXTERN unsigned char *auxframe[3]; |
EXTERN unsigned char *current_frame[3]; |
EXTERN unsigned char *substitute_frame[3]; |
/* pointers to scalability picture buffers */ |
EXTERN unsigned char *llframe0[3]; |
EXTERN unsigned char *llframe1[3]; |
EXTERN short *lltmp; |
EXTERN char *Lower_Layer_Picture_Filename; |
/* non-normative variables derived from normative elements */ |
EXTERN int Coded_Picture_Width; |
EXTERN int Coded_Picture_Height; |
EXTERN int Chroma_Width; |
EXTERN int Chroma_Height; |
EXTERN int block_count; |
EXTERN int Second_Field; |
EXTERN int profile, level; |
/* normative derived variables (as per ISO/IEC 13818-2) */ |
EXTERN int horizontal_size; |
EXTERN int vertical_size; |
EXTERN int mb_width; |
EXTERN int mb_height; |
EXTERN double bit_rate; |
EXTERN double frame_rate; |
/* headers */ |
/* ISO/IEC 13818-2 section 6.2.2.1: sequence_header() */ |
EXTERN int aspect_ratio_information; |
EXTERN int frame_rate_code; |
EXTERN int bit_rate_value; |
EXTERN int vbv_buffer_size; |
EXTERN int constrained_parameters_flag; |
/* ISO/IEC 13818-2 section 6.2.2.3: sequence_extension() */ |
EXTERN int profile_and_level_indication; |
EXTERN int progressive_sequence; |
EXTERN int chroma_format; |
EXTERN int low_delay; |
EXTERN int frame_rate_extension_n; |
EXTERN int frame_rate_extension_d; |
/* ISO/IEC 13818-2 section 6.2.2.4: sequence_display_extension() */ |
EXTERN int video_format; |
EXTERN int color_description; |
EXTERN int color_primaries; |
EXTERN int transfer_characteristics; |
EXTERN int matrix_coefficients; |
EXTERN int display_horizontal_size; |
EXTERN int display_vertical_size; |
/* ISO/IEC 13818-2 section 6.2.3: picture_header() */ |
EXTERN int temporal_reference; |
EXTERN int picture_coding_type; |
EXTERN int vbv_delay; |
EXTERN int full_pel_forward_vector; |
EXTERN int forward_f_code; |
EXTERN int full_pel_backward_vector; |
EXTERN int backward_f_code; |
/* ISO/IEC 13818-2 section 6.2.3.1: picture_coding_extension() header */ |
EXTERN int f_code[2][2]; |
EXTERN int intra_dc_precision; |
EXTERN int picture_structure; |
EXTERN int top_field_first; |
EXTERN int frame_pred_frame_dct; |
EXTERN int concealment_motion_vectors; |
EXTERN int intra_vlc_format; |
EXTERN int repeat_first_field; |
EXTERN int chroma_420_type; |
EXTERN int progressive_frame; |
EXTERN int composite_display_flag; |
EXTERN int v_axis; |
EXTERN int field_sequence; |
EXTERN int sub_carrier; |
EXTERN int burst_amplitude; |
EXTERN int sub_carrier_phase; |
/* ISO/IEC 13818-2 section 6.2.3.3: picture_display_extension() header */ |
EXTERN int frame_center_horizontal_offset[3]; |
EXTERN int frame_center_vertical_offset[3]; |
/* ISO/IEC 13818-2 section 6.2.2.5: sequence_scalable_extension() header */ |
EXTERN int layer_id; |
EXTERN int lower_layer_prediction_horizontal_size; |
EXTERN int lower_layer_prediction_vertical_size; |
EXTERN int horizontal_subsampling_factor_m; |
EXTERN int horizontal_subsampling_factor_n; |
EXTERN int vertical_subsampling_factor_m; |
EXTERN int vertical_subsampling_factor_n; |
/* ISO/IEC 13818-2 section 6.2.3.5: picture_spatial_scalable_extension() header */ |
EXTERN int lower_layer_temporal_reference; |
EXTERN int lower_layer_horizontal_offset; |
EXTERN int lower_layer_vertical_offset; |
EXTERN int spatial_temporal_weight_code_table_index; |
EXTERN int lower_layer_progressive_frame; |
EXTERN int lower_layer_deinterlaced_field_select; |
/* ISO/IEC 13818-2 section 6.2.3.6: copyright_extension() header */ |
EXTERN int copyright_flag; |
EXTERN int copyright_identifier; |
EXTERN int original_or_copy; |
EXTERN int copyright_number_1; |
EXTERN int copyright_number_2; |
EXTERN int copyright_number_3; |
/* ISO/IEC 13818-2 section 6.2.2.6: group_of_pictures_header() */ |
EXTERN int drop_flag; |
EXTERN int hour; |
EXTERN int minute; |
EXTERN int sec; |
EXTERN int frame; |
EXTERN int closed_gop; |
EXTERN int broken_link; |
/* layer specific variables (needed for SNR and DP scalability) */ |
EXTERN struct layer_data { |
/* bit input */ |
int Infile; |
void *start_file_ptr; |
void *actual_file_ptr; |
void *end_file_ptr; |
int px; |
int py; |
unsigned char Rdbfr[2048]; |
unsigned char *Rdptr; |
unsigned char Inbfr[16]; |
/* from mpeg2play */ |
unsigned int Bfr; |
unsigned char *Rdmax; |
int Incnt; |
int Bitcnt; |
/* sequence header and quant_matrix_extension() */ |
int intra_quantizer_matrix[64]; |
int non_intra_quantizer_matrix[64]; |
int chroma_intra_quantizer_matrix[64]; |
int chroma_non_intra_quantizer_matrix[64]; |
int load_intra_quantizer_matrix; |
int load_non_intra_quantizer_matrix; |
int load_chroma_intra_quantizer_matrix; |
int load_chroma_non_intra_quantizer_matrix; |
int MPEG2_Flag; |
/* sequence scalable extension */ |
int scalable_mode; |
/* picture coding extension */ |
int q_scale_type; |
int alternate_scan; |
/* picture spatial scalable extension */ |
int pict_scal; |
/* slice/macroblock */ |
int priority_breakpoint; |
int quantizer_scale; |
int intra_slice; |
short block[12][64]; |
} base, enhan, *ld; |
#ifdef VERIFY |
EXTERN int verify_sequence_header; |
EXTERN int verify_group_of_pictures_header; |
EXTERN int verify_picture_header; |
EXTERN int verify_slice_header; |
EXTERN int verify_sequence_extension; |
EXTERN int verify_sequence_display_extension; |
EXTERN int verify_quant_matrix_extension; |
EXTERN int verify_sequence_scalable_extension; |
EXTERN int verify_picture_display_extension; |
EXTERN int verify_picture_coding_extension; |
EXTERN int verify_picture_spatial_scalable_extension; |
EXTERN int verify_picture_temporal_scalable_extension; |
EXTERN int verify_copyright_extension; |
#endif /* VERIFY */ |
EXTERN int Decode_Layer; |
/* verify.c */ |
#ifdef VERIFY |
void Check_Headers _ANSI_ARGS_((int Bitstream_Framenum, int Sequence_Framenum)); |
void Clear_Verify_Headers _ANSI_ARGS_((void)); |
#endif /* VERIFY */ |
EXTERN int global_MBA; |
EXTERN int global_pic; |
EXTERN int True_Framenum; |
/unsupported/trunk/first-official/mpeg2/recon.c |
---|
0,0 → 1,465 |
/* Predict.c, motion compensation routines */ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
#include "config.h" |
#include "global.h" |
/* private prototypes */ |
static void form_prediction _ANSI_ARGS_((unsigned char *src[], int sfield, |
unsigned char *dst[], int dfield, |
int lx, int lx2, int w, int h, int x, int y, int dx, int dy, |
int average_flag)); |
static void form_component_prediction _ANSI_ARGS_((unsigned char *src, unsigned char *dst, |
int lx, int lx2, int w, int h, int x, int y, int dx, int dy, int average_flag)); |
void form_predictions(bx,by,macroblock_type,motion_type,PMV,motion_vertical_field_select,dmvector,stwtype) |
int bx, by; |
int macroblock_type; |
int motion_type; |
int PMV[2][2][2], motion_vertical_field_select[2][2], dmvector[2]; |
int stwtype; |
{ |
int currentfield; |
unsigned char **predframe; |
int DMV[2][2]; |
int stwtop, stwbot; |
stwtop = stwtype%3; /* 0:temporal, 1:(spat+temp)/2, 2:spatial */ |
stwbot = stwtype/3; |
if ((macroblock_type & MACROBLOCK_MOTION_FORWARD) |
|| (picture_coding_type==P_TYPE)) |
{ |
if (picture_structure==FRAME_PICTURE) |
{ |
if ((motion_type==MC_FRAME) |
|| !(macroblock_type & MACROBLOCK_MOTION_FORWARD)) |
{ |
/* frame-based prediction (broken into top and bottom halves |
for spatial scalability prediction purposes) */ |
if (stwtop<2) |
form_prediction(forward_reference_frame,0,current_frame,0, |
Coded_Picture_Width,Coded_Picture_Width<<1,16,8,bx,by, |
PMV[0][0][0],PMV[0][0][1],stwtop); |
if (stwbot<2) |
form_prediction(forward_reference_frame,1,current_frame,1, |
Coded_Picture_Width,Coded_Picture_Width<<1,16,8,bx,by, |
PMV[0][0][0],PMV[0][0][1],stwbot); |
} |
else if (motion_type==MC_FIELD) /* field-based prediction */ |
{ |
/* top field prediction */ |
if (stwtop<2) |
form_prediction(forward_reference_frame,motion_vertical_field_select[0][0], |
current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8, |
bx,by>>1,PMV[0][0][0],PMV[0][0][1]>>1,stwtop); |
/* bottom field prediction */ |
if (stwbot<2) |
form_prediction(forward_reference_frame,motion_vertical_field_select[1][0], |
current_frame,1,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8, |
bx,by>>1,PMV[1][0][0],PMV[1][0][1]>>1,stwbot); |
} |
else if (motion_type==MC_DMV) /* dual prime prediction */ |
{ |
/* calculate derived motion vectors */ |
Dual_Prime_Arithmetic(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]>>1); |
if (stwtop<2) |
{ |
/* predict top field from top field */ |
form_prediction(forward_reference_frame,0,current_frame,0, |
Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by>>1, |
PMV[0][0][0],PMV[0][0][1]>>1,0); |
/* predict and add to top field from bottom field */ |
form_prediction(forward_reference_frame,1,current_frame,0, |
Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by>>1, |
DMV[0][0],DMV[0][1],1); |
} |
if (stwbot<2) |
{ |
/* predict bottom field from bottom field */ |
form_prediction(forward_reference_frame,1,current_frame,1, |
Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by>>1, |
PMV[0][0][0],PMV[0][0][1]>>1,0); |
/* predict and add to bottom field from top field */ |
form_prediction(forward_reference_frame,0,current_frame,1, |
Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by>>1, |
DMV[1][0],DMV[1][1],1); |
} |
} |
else |
/* invalid motion_type */ |
cprintf("invalid motion_type\n"); |
} |
else /* TOP_FIELD or BOTTOM_FIELD */ |
{ |
/* field picture */ |
currentfield = (picture_structure==BOTTOM_FIELD); |
/* determine which frame to use for prediction */ |
if ((picture_coding_type==P_TYPE) && Second_Field |
&& (currentfield!=motion_vertical_field_select[0][0])) |
predframe = backward_reference_frame; /* same frame */ |
else |
predframe = forward_reference_frame; /* previous frame */ |
if ((motion_type==MC_FIELD) |
|| !(macroblock_type & MACROBLOCK_MOTION_FORWARD)) |
{ |
/* field-based prediction */ |
if (stwtop<2) |
form_prediction(predframe,motion_vertical_field_select[0][0],current_frame,0, |
Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,16,bx,by, |
PMV[0][0][0],PMV[0][0][1],stwtop); |
} |
else if (motion_type==MC_16X8) |
{ |
if (stwtop<2) |
{ |
form_prediction(predframe,motion_vertical_field_select[0][0],current_frame,0, |
Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by, |
PMV[0][0][0],PMV[0][0][1],stwtop); |
/* determine which frame to use for lower half prediction */ |
if ((picture_coding_type==P_TYPE) && Second_Field |
&& (currentfield!=motion_vertical_field_select[1][0])) |
predframe = backward_reference_frame; /* same frame */ |
else |
predframe = forward_reference_frame; /* previous frame */ |
form_prediction(predframe,motion_vertical_field_select[1][0],current_frame,0, |
Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8,bx,by+8, |
PMV[1][0][0],PMV[1][0][1],stwtop); |
} |
} |
else if (motion_type==MC_DMV) /* dual prime prediction */ |
{ |
if (Second_Field) |
predframe = backward_reference_frame; /* same frame */ |
else |
predframe = forward_reference_frame; /* previous frame */ |
/* calculate derived motion vectors */ |
Dual_Prime_Arithmetic(DMV,dmvector,PMV[0][0][0],PMV[0][0][1]); |
/* predict from field of same parity */ |
form_prediction(forward_reference_frame,currentfield,current_frame,0, |
Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,16,bx,by, |
PMV[0][0][0],PMV[0][0][1],0); |
/* predict from field of opposite parity */ |
form_prediction(predframe,!currentfield,current_frame,0, |
Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,16,bx,by, |
DMV[0][0],DMV[0][1],1); |
} |
else |
/* invalid motion_type */ |
cprintf("invalid motion_type\n"); |
} |
stwtop = stwbot = 1; |
} |
if (macroblock_type & MACROBLOCK_MOTION_BACKWARD) |
{ |
if (picture_structure==FRAME_PICTURE) |
{ |
if (motion_type==MC_FRAME) |
{ |
/* frame-based prediction */ |
if (stwtop<2) |
form_prediction(backward_reference_frame,0,current_frame,0, |
Coded_Picture_Width,Coded_Picture_Width<<1,16,8,bx,by, |
PMV[0][1][0],PMV[0][1][1],stwtop); |
if (stwbot<2) |
form_prediction(backward_reference_frame,1,current_frame,1, |
Coded_Picture_Width,Coded_Picture_Width<<1,16,8,bx,by, |
PMV[0][1][0],PMV[0][1][1],stwbot); |
} |
else /* field-based prediction */ |
{ |
/* top field prediction */ |
if (stwtop<2) |
form_prediction(backward_reference_frame,motion_vertical_field_select[0][1], |
current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8, |
bx,by>>1,PMV[0][1][0],PMV[0][1][1]>>1,stwtop); |
/* bottom field prediction */ |
if (stwbot<2) |
form_prediction(backward_reference_frame,motion_vertical_field_select[1][1], |
current_frame,1,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8, |
bx,by>>1,PMV[1][1][0],PMV[1][1][1]>>1,stwbot); |
} |
} |
else /* TOP_FIELD or BOTTOM_FIELD */ |
{ |
/* field picture */ |
if (motion_type==MC_FIELD) |
{ |
/* field-based prediction */ |
form_prediction(backward_reference_frame,motion_vertical_field_select[0][1], |
current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,16, |
bx,by,PMV[0][1][0],PMV[0][1][1],stwtop); |
} |
else if (motion_type==MC_16X8) |
{ |
form_prediction(backward_reference_frame,motion_vertical_field_select[0][1], |
current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8, |
bx,by,PMV[0][1][0],PMV[0][1][1],stwtop); |
form_prediction(backward_reference_frame,motion_vertical_field_select[1][1], |
current_frame,0,Coded_Picture_Width<<1,Coded_Picture_Width<<1,16,8, |
bx,by+8,PMV[1][1][0],PMV[1][1][1],stwtop); |
} |
else |
/* invalid motion_type */ |
cprintf("invalid motion_type\n"); |
} |
} |
} |
static void form_prediction(src,sfield,dst,dfield,lx,lx2,w,h,x,y,dx,dy,average_flag) |
unsigned char *src[]; /* prediction source buffer */ |
int sfield; /* prediction source field number (0 or 1) */ |
unsigned char *dst[]; /* prediction destination buffer */ |
int dfield; /* prediction destination field number (0 or 1)*/ |
int lx,lx2; /* line strides */ |
int w,h; /* prediction block/sub-block width, height */ |
int x,y; /* pixel co-ordinates of top-left sample in current MB */ |
int dx,dy; /* horizontal, vertical prediction address */ |
int average_flag; /* add prediction error to prediction ? */ |
{ |
/* Y */ |
form_component_prediction(src[0]+(sfield?lx2>>1:0),dst[0]+(dfield?lx2>>1:0), |
lx,lx2,w,h,x,y,dx,dy,average_flag); |
if (chroma_format!=CHROMA444) |
{ |
lx>>=1; lx2>>=1; w>>=1; x>>=1; dx/=2; |
} |
if (chroma_format==CHROMA420) |
{ |
h>>=1; y>>=1; dy/=2; |
} |
/* Cb */ |
form_component_prediction(src[1]+(sfield?lx2>>1:0),dst[1]+(dfield?lx2>>1:0), |
lx,lx2,w,h,x,y,dx,dy,average_flag); |
/* Cr */ |
form_component_prediction(src[2]+(sfield?lx2>>1:0),dst[2]+(dfield?lx2>>1:0), |
lx,lx2,w,h,x,y,dx,dy,average_flag); |
} |
/* ISO/IEC 13818-2 section 7.6.4: Forming predictions */ |
/* NOTE: the arithmetic below produces numerically equivalent results |
* to 7.6.4, yet is more elegant. It differs in the following ways: |
* |
* 1. the vectors (dx, dy) are based on cartesian frame |
* coordiantes along a half-pel grid (always positive numbers) |
* In contrast, vector[r][s][t] are differential (with positive and |
* negative values). As a result, deriving the integer vectors |
* (int_vec[t]) from dx, dy is accomplished by a simple right shift. |
* |
* 2. Half pel flags (xh, yh) are equivalent to the LSB (Least |
* Significant Bit) of the half-pel coordinates (dx,dy). |
* |
* |
* NOTE: the work of combining predictions (ISO/IEC 13818-2 section 7.6.7) |
* is distributed among several other stages. This is accomplished by |
* folding line offsets into the source and destination (src,dst) |
* addresses (note the call arguments to form_prediction() in Predict()), |
* line stride variables lx and lx2, the block dimension variables (w,h), |
* average_flag, and by the very order in which Predict() is called. |
* This implementation design (implicitly different than the spec) |
* was chosen for its elegance. |
*/ |
static void form_component_prediction(src,dst,lx,lx2,w,h,x,y,dx,dy,average_flag) |
unsigned char *src; |
unsigned char *dst; |
int lx; /* raster line increment */ |
int lx2; |
int w,h; |
int x,y; |
int dx,dy; |
int average_flag; /* flag that signals bi-directional or Dual-Prime |
averaging (7.6.7.1 and 7.6.7.4). if average_flag==1, |
a previously formed prediction has been stored in |
pel_pred[] */ |
{ |
int xint; /* horizontal integer sample vector: analogous to int_vec[0] */ |
int yint; /* vertical integer sample vectors: analogous to int_vec[1] */ |
int xh; /* horizontal half sample flag: analogous to half_flag[0] */ |
int yh; /* vertical half sample flag: analogous to half_flag[1] */ |
int i, j, v; |
unsigned char *s; /* source pointer: analogous to pel_ref[][] */ |
unsigned char *d; /* destination pointer: analogous to pel_pred[][] */ |
/* half pel scaling for integer vectors */ |
xint = dx>>1; |
yint = dy>>1; |
/* derive half pel flags */ |
xh = dx & 1; |
yh = dy & 1; |
/* compute the linear address of pel_ref[][] and pel_pred[][] |
based on cartesian/raster cordinates provided */ |
s = src + lx*(y+yint) + x + xint; |
d = dst + lx*y + x; |
if (!xh && !yh) /* no horizontal nor vertical half-pel */ |
{ |
if (average_flag) |
{ |
for (j=0; j<h; j++) |
{ |
for (i=0; i<w; i++) |
{ |
v = d[i]+s[i]; |
d[i] = (v+(v>=0?1:0))>>1; |
} |
s+= lx2; |
d+= lx2; |
} |
} |
else |
{ |
for (j=0; j<h; j++) |
{ |
for (i=0; i<w; i++) |
{ |
d[i] = s[i]; |
} |
s+= lx2; |
d+= lx2; |
} |
} |
} |
else if (!xh && yh) /* no horizontal but vertical half-pel */ |
{ |
if (average_flag) |
{ |
for (j=0; j<h; j++) |
{ |
for (i=0; i<w; i++) |
{ |
v = d[i] + ((unsigned int)(s[i]+s[i+lx]+1)>>1); |
d[i]=(v+(v>=0?1:0))>>1; |
} |
s+= lx2; |
d+= lx2; |
} |
} |
else |
{ |
for (j=0; j<h; j++) |
{ |
for (i=0; i<w; i++) |
{ |
d[i] = (unsigned int)(s[i]+s[i+lx]+1)>>1; |
} |
s+= lx2; |
d+= lx2; |
} |
} |
} |
else if (xh && !yh) /* horizontal but no vertical half-pel */ |
{ |
if (average_flag) |
{ |
for (j=0; j<h; j++) |
{ |
for (i=0; i<w; i++) |
{ |
v = d[i] + ((unsigned int)(s[i]+s[i+1]+1)>>1); |
d[i] = (v+(v>=0?1:0))>>1; |
} |
s+= lx2; |
d+= lx2; |
} |
} |
else |
{ |
for (j=0; j<h; j++) |
{ |
for (i=0; i<w; i++) |
{ |
d[i] = (unsigned int)(s[i]+s[i+1]+1)>>1; |
} |
s+= lx2; |
d+= lx2; |
} |
} |
} |
else /* if (xh && yh) horizontal and vertical half-pel */ |
{ |
if (average_flag) |
{ |
for (j=0; j<h; j++) |
{ |
for (i=0; i<w; i++) |
{ |
v = d[i] + ((unsigned int)(s[i]+s[i+1]+s[i+lx]+s[i+lx+1]+2)>>2); |
d[i] = (v+(v>=0?1:0))>>1; |
} |
s+= lx2; |
d+= lx2; |
} |
} |
else |
{ |
for (j=0; j<h; j++) |
{ |
for (i=0; i<w; i++) |
{ |
d[i] = (unsigned int)(s[i]+s[i+1]+s[i+lx]+s[i+lx+1]+2)>>2; |
} |
s+= lx2; |
d+= lx2; |
} |
} |
} |
} |
/unsupported/trunk/first-official/mpeg2/systems.c |
---|
0,0 → 1,195 |
/* systems.c, systems-specific routines */ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
#include <stdlib.h> |
#include "config.h" |
#include "global.h" |
/* initialize buffer, call once before first getbits or showbits */ |
/* parse system layer, ignore everything we don't need */ |
void Next_Packet() |
{ |
unsigned int code; |
int l; |
for(;;) |
{ |
code = Get_Long(); |
/* remove system layer byte stuffing */ |
while ((code & 0xffffff00) != 0x100) |
code = (code<<8) | Get_Byte(); |
switch(code) |
{ |
case PACK_START_CODE: /* pack header */ |
/* skip pack header (system_clock_reference and mux_rate) */ |
ld->Rdptr += 8; |
break; |
case VIDEO_ELEMENTARY_STREAM: |
code = Get_Word(); /* packet_length */ |
ld->Rdmax = ld->Rdptr + code; |
code = Get_Byte(); |
if((code>>6)==0x02) |
{ |
ld->Rdptr++; |
code=Get_Byte(); /* parse PES_header_data_length */ |
ld->Rdptr+=code; /* advance pointer by PES_header_data_length */ |
cprintf("MPEG-2 PES packet\n"); |
return; |
} |
else if(code==0xff) |
{ |
/* parse MPEG-1 packet header */ |
while((code=Get_Byte())== 0xFF); |
} |
/* stuffing bytes */ |
if(code>=0x40) |
{ |
if(code>=0x80) |
{ |
cprintf("Error in packet header\n"); |
} |
/* skip STD_buffer_scale */ |
ld->Rdptr++; |
code = Get_Byte(); |
} |
if(code>=0x30) |
{ |
if(code>=0x40) |
{ |
cprintf("Error in packet header\n"); |
} |
/* skip presentation and decoding time stamps */ |
ld->Rdptr += 9; |
} |
else if(code>=0x20) |
{ |
/* skip presentation time stamps */ |
ld->Rdptr += 4; |
} |
else if(code!=0x0f) |
{ |
cprintf("Error in packet header\n"); |
} |
return; |
case ISO_END_CODE: /* end */ |
/* simulate a buffer full of sequence end codes */ |
l = 0; |
while (l<2048) |
{ |
ld->Rdbfr[l++] = SEQUENCE_END_CODE>>24; |
ld->Rdbfr[l++] = SEQUENCE_END_CODE>>16; |
ld->Rdbfr[l++] = SEQUENCE_END_CODE>>8; |
ld->Rdbfr[l++] = SEQUENCE_END_CODE&0xff; |
} |
ld->Rdptr = ld->Rdbfr; |
ld->Rdmax = ld->Rdbfr + 2048; |
return; |
default: |
if(code>=SYSTEM_START_CODE) |
{ |
/* skip system headers and non-video packets*/ |
code = Get_Word(); |
ld->Rdptr += code; |
} |
else |
{ |
cprintf("Unexpected startcode %08x in system layer\n",code); |
} |
break; |
} |
} |
} |
void Flush_Buffer32() |
{ |
int Incnt; |
ld->Bfr = 0; |
Incnt = ld->Incnt; |
Incnt -= 32; |
if (System_Stream_Flag && (ld->Rdptr >= ld->Rdmax-4)) |
{ |
while (Incnt <= 24) |
{ |
if (ld->Rdptr >= ld->Rdmax) |
Next_Packet(); |
ld->Bfr |= Get_Byte() << (24 - Incnt); |
Incnt += 8; |
} |
} |
else |
{ |
while (Incnt <= 24) |
{ |
if (ld->Rdptr >= ld->Rdbfr+2048) |
Fill_Buffer(); |
ld->Bfr |= *ld->Rdptr++ << (24 - Incnt); |
Incnt += 8; |
} |
} |
ld->Incnt = Incnt; |
#ifdef VERIFY |
ld->Bitcnt += 32; |
#endif /* VERIFY */ |
} |
unsigned int Get_Bits32() |
{ |
unsigned int l; |
l = Show_Bits(32); |
Flush_Buffer32(); |
return l; |
} |
int Get_Long() |
{ |
int i; |
i = Get_Word(); |
return (i<<16) | Get_Word(); |
} |
/unsupported/trunk/first-official/mpeg2/subspic.c |
---|
0,0 → 1,384 |
/* #define DEBUG */ |
/* subspic.c, Frame buffer substitution routines */ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
#include <stdlib.h> |
#include "config.h" |
#include "global.h" |
/* private prototypes*/ |
static void Read_Frame _ANSI_ARGS_((char *filename, |
unsigned char *frame_buffer[], int framenum)); |
static void Copy_Frame _ANSI_ARGS_((unsigned char *src, unsigned char *dst, |
int width, int height, int parity, int incr)); |
static int Read_Components _ANSI_ARGS_ ((char *filename, |
unsigned char *frame[3], int framenum)); |
static int Read_Component _ANSI_ARGS_ ((char *fname, unsigned char *frame, |
int width, int height)); |
static int Extract_Components _ANSI_ARGS_ ((char *filename, |
unsigned char *frame[3], int framenum)); |
extern int read(int Infile, void *Rdbfr, int rdsize); |
/* substitute frame buffer routine */ |
void Substitute_Frame_Buffer (bitstream_framenum, sequence_framenum) |
int bitstream_framenum; |
int sequence_framenum; |
{ |
/* static tracking variables */ |
static int previous_temporal_reference; |
static int previous_bitstream_framenum; |
static int previous_anchor_temporal_reference; |
static int previous_anchor_bitstream_framenum; |
static int previous_picture_coding_type; |
static int bgate; |
/* local temporary variables */ |
int substitute_display_framenum; |
#ifdef DEBUG |
cprintf("SUB: seq fn(%d) bitfn(%d) tempref(%d) picstr(%d) type(%d)\n", |
sequence_framenum, bitstream_framenum, temporal_reference, |
picture_structure, picture_coding_type); |
#endif |
/* we don't substitute at the first picture of a sequence */ |
if((sequence_framenum!=0)||(Second_Field)) |
{ |
/* only at the start of the frame */ |
if ((picture_structure==FRAME_PICTURE)||(!Second_Field)) |
{ |
if(picture_coding_type==P_TYPE) |
{ |
/* the most recently decoded reference frame needs substituting */ |
substitute_display_framenum = bitstream_framenum - 1; |
Read_Frame(Substitute_Picture_Filename, forward_reference_frame, |
substitute_display_framenum); |
} |
/* only the first B frame in a consequitve set of B pictures |
loads a substitute backward_reference_frame since all subsequent |
B frames predict from the same reference pictures */ |
else if((picture_coding_type==B_TYPE)&&(bgate!=1)) |
{ |
substitute_display_framenum = |
(previous_temporal_reference - temporal_reference) |
+ bitstream_framenum - 1; |
Read_Frame(Substitute_Picture_Filename, backward_reference_frame, |
substitute_display_framenum); |
} |
} /* P fields can predict from the two most recently decoded fields, even |
from the first field of the same frame being decoded */ |
else if(Second_Field && (picture_coding_type==P_TYPE)) |
{ |
/* our favourite case: the IP field picture pair */ |
if((previous_picture_coding_type==I_TYPE)&&(picture_coding_type==P_TYPE)) |
{ |
substitute_display_framenum = bitstream_framenum; |
} |
else /* our more generic P field picture pair */ |
{ |
substitute_display_framenum = |
(temporal_reference - previous_anchor_temporal_reference) |
+ bitstream_framenum - 1; |
} |
Read_Frame(Substitute_Picture_Filename, current_frame, substitute_display_framenum); |
} |
#ifdef DEBUG |
else if((picture_coding_type!=B_TYPE)||(picture_coding_type!=D_TYPE)) |
{ |
cprintf("NO SUBS FOR THIS PICTURE\n"); |
} |
#endif |
} |
/* set b gate so we don't redundantly load next time around */ |
if(picture_coding_type==B_TYPE) |
bgate = 1; |
else |
bgate = 0; |
/* update general tracking variables */ |
if((picture_structure==FRAME_PICTURE)||(!Second_Field)) |
{ |
previous_temporal_reference = temporal_reference; |
previous_bitstream_framenum = bitstream_framenum; |
} |
/* update reference frame tracking variables */ |
if((picture_coding_type!=B_TYPE) && |
((picture_structure==FRAME_PICTURE)||Second_Field)) |
{ |
previous_anchor_temporal_reference = temporal_reference; |
previous_anchor_bitstream_framenum = bitstream_framenum; |
} |
previous_picture_coding_type = picture_coding_type; |
} |
/* Note: fields are only read to serve as the same-frame reference for |
a second field */ |
static void Read_Frame(fname,frame,framenum) |
char *fname; |
unsigned char *frame[]; |
int framenum; |
{ |
int parity; |
int rerr = 0; |
int field_mode; |
if(framenum<0) |
cprintf("ERROR: framenum (%d) is less than zero\n", framenum); |
if(Big_Picture_Flag) |
rerr = Extract_Components(fname, substitute_frame, framenum); |
else |
rerr = Read_Components(fname, substitute_frame, framenum); |
if(rerr!=0) |
{ |
cprintf("was unable to substitute frame\n"); |
} |
/* now copy to the appropriate buffer */ |
/* first field (which we are attempting to substitute) must be |
of opposite field parity to the current one */ |
if((Second_Field)&&(picture_coding_type==P_TYPE)) |
{ |
parity = (picture_structure==TOP_FIELD ? 1:0); |
field_mode = (picture_structure==FRAME_PICTURE ? 0:1); |
} |
else |
{ |
/* Like frame structued pictures, B pictures only substitute an entire frame |
since both fields always predict from the same frame (with respect |
to forward/backwards directions) */ |
parity = 0; |
field_mode = 0; |
} |
Copy_Frame(substitute_frame[0], frame[0], Coded_Picture_Width, |
Coded_Picture_Height, parity, field_mode); |
Copy_Frame(substitute_frame[1], frame[1], Chroma_Width, Chroma_Height, |
parity, field_mode); |
Copy_Frame(substitute_frame[2], frame[2], Chroma_Width, Chroma_Height, |
parity, field_mode); |
#ifdef VERBOSE |
if(Verbose_Flag > NO_LAYER) |
cprintf("substituted %s %d\n", |
(field_mode ? (parity?"bottom field":"bottom field"):"frame"), framenum); |
#endif |
} |
static int Read_Components(filename, frame, framenum) |
char *filename; |
unsigned char *frame[3]; |
int framenum; |
{ |
int err = 0; |
char outname[FILENAME_LENGTH]; |
char name[FILENAME_LENGTH]; |
sprintf(outname,filename,framenum); |
sprintf(name,"%s.Y",outname); |
err += Read_Component(name, frame[0], Coded_Picture_Width, |
Coded_Picture_Height); |
sprintf(name,"%s.U",outname); |
err += Read_Component(name, frame[1], Chroma_Width, Chroma_Height); |
sprintf(name,"%s.V",outname); |
err += Read_Component(name, frame[2], Chroma_Width, Chroma_Height); |
return(err); |
} |
static int Read_Component(Filename, Frame, Width, Height) |
char *Filename; |
unsigned char *Frame; |
int Width; |
int Height; |
{ |
int Size; |
int Bytes_Read; |
int Infile; |
Size = Width*Height; |
#ifdef DEBUG |
cprintf("SUBS: reading %s\n", filename); |
#endif |
if(!(Infile=1)<0) |
{ |
cprintf("ERROR: unable to open reference filename (%s)\n", Filename); |
return(-1); |
} |
Bytes_Read = read(Infile, Frame, Size); |
if(Bytes_Read!=Size) |
{ |
cprintf("was able to read only %d bytes of %d of file %s\n", |
Bytes_Read, Size, Filename); |
} |
return(0); |
} |
/* optimization: do not open the big file each time. Open once at start |
of decoder, and close at the very last frame */ |
/* Note: "big" files were used in E-mail exchanges almost exclusively by the |
MPEG Committee's syntax validation and conformance ad-hoc groups from |
the year 1993 until 1995 */ |
static int Extract_Components(filename, frame, framenum) |
char *filename; |
unsigned char *frame[3]; |
int framenum; |
{ |
/* int err = 0; */ |
int line; |
int size, offset; |
cprintf("Extract_Components\n"); |
/* compute size of each frame (in bytes) */ |
size = (Coded_Picture_Width*Coded_Picture_Height); |
if(chroma_format==CHROMA444) |
size = (size * 3); |
else if(chroma_format==CHROMA422) |
size = (size * 2); |
else if(chroma_format==CHROMA420) |
size = ((size*3)>>1); |
else |
cprintf("ERROR: chroma_format (%d) not recognized\n", chroma_format); |
/* compute distance into "big" file */ |
offset = size*framenum; |
#ifdef DEBUG |
printf("EXTRACTING: frame(%d) offset(%d), size (%d) from %s\n", |
framenum, offset, size, filename); |
#endif |
/* seek to location in big file where desired frame begins */ |
/* note: this offset cannot exceed a few billion bytes due to the */ |
/* obvious limitations of 32-bit integers */ |
//fseek(fd, offset, 0); |
/* Y */ |
for (line=0; line<Coded_Picture_Height; line++) |
{ |
//fread(frame[0]+(line*Coded_Picture_Width),1,Coded_Picture_Width,fd); |
} |
/* Cb */ |
for (line=0; line<Chroma_Height; line++) |
{ |
//fread(frame[1]+(line*Chroma_Width),1,Chroma_Width,fd); |
} |
/* Cr */ |
for (line=0; line<Chroma_Height; line++) |
{ |
//fread(frame[2]+(line*Chroma_Width),1,Chroma_Width,fd); |
} |
//fclose(fd); |
return(0); |
} |
static void Copy_Frame(src, dst, width, height, parity, field_mode) |
unsigned char *src; |
unsigned char *dst; |
int width; |
int height; |
int parity; /* field parity (top or bottom) to overwrite */ |
int field_mode; /* 0 = frame, 1 = field */ |
{ |
int row, col; |
int s, d; |
int incr; |
s = d = 0; |
#ifdef DEBUG |
cprintf("COPYING (w=%d, h=%d, parity=%d, field_mode=%d)\n", |
width,height,parity,field_mode); |
#endif /* DEBUG */ |
if(field_mode) |
{ |
incr = 2; |
if(parity==0) |
s += width; |
} |
else |
{ |
incr = 1; |
} |
for(row=0; row<height; row+=incr) |
{ |
for(col=0; col<width; col++) |
{ |
dst[d+col] = src[s+col]; |
} |
d += (width*incr); |
s += (width*incr); |
} |
} |
/unsupported/trunk/first-official/mpeg2/getblk.c |
---|
0,0 → 1,571 |
/* getblk.c, DCT block decoding */ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
#include "config.h" |
#include "global.h" |
/* defined in getvlc.h */ |
typedef struct { |
char run, level, len; |
} DCTtab; |
extern DCTtab DCTtabfirst[],DCTtabnext[],DCTtab0[],DCTtab1[]; |
extern DCTtab DCTtab2[],DCTtab3[],DCTtab4[],DCTtab5[],DCTtab6[]; |
extern DCTtab DCTtab0a[],DCTtab1a[]; |
/* decode one intra coded MPEG-1 block */ |
void Decode_MPEG1_Intra_Block(comp,dc_dct_pred) |
int comp; |
int dc_dct_pred[]; |
{ |
int val, i, j, sign; |
unsigned int code; |
DCTtab *tab; |
short *bp; |
bp = ld->block[comp]; |
/* ISO/IEC 11172-2 section 2.4.3.7: Block layer. */ |
/* decode DC coefficients */ |
if (comp<4) |
bp[0] = (dc_dct_pred[0]+=Get_Luma_DC_dct_diff()) << 3; |
else if (comp==4) |
bp[0] = (dc_dct_pred[1]+=Get_Chroma_DC_dct_diff()) << 3; |
else |
bp[0] = (dc_dct_pred[2]+=Get_Chroma_DC_dct_diff()) << 3; |
if (Fault_Flag) return; |
/* D-pictures do not contain AC coefficients */ |
if(picture_coding_type == D_TYPE) |
return; |
/* decode AC coefficients */ |
for (i=1; ; i++) |
{ |
code = Show_Bits(16); |
if (code>=16384) |
tab = &DCTtabnext[(code>>12)-4]; |
else if (code>=1024) |
tab = &DCTtab0[(code>>8)-4]; |
else if (code>=512) |
tab = &DCTtab1[(code>>6)-8]; |
else if (code>=256) |
tab = &DCTtab2[(code>>4)-16]; |
else if (code>=128) |
tab = &DCTtab3[(code>>3)-16]; |
else if (code>=64) |
tab = &DCTtab4[(code>>2)-16]; |
else if (code>=32) |
tab = &DCTtab5[(code>>1)-16]; |
else if (code>=16) |
tab = &DCTtab6[code-16]; |
else |
{ |
if (!Quiet_Flag) |
cprintf("invalid Huffman code in Decode_MPEG1_Intra_Block()\n"); |
Fault_Flag = 1; |
return; |
} |
Flush_Buffer(tab->len); |
if (tab->run==64) /* end_of_block */ |
return; |
if (tab->run==65) /* escape */ |
{ |
i+= Get_Bits(6); |
val = Get_Bits(8); |
if (val==0) |
val = Get_Bits(8); |
else if (val==128) |
val = Get_Bits(8) - 256; |
else if (val>128) |
val -= 256; |
if((sign = (val<0))) |
val = -val; |
} |
else |
{ |
i+= tab->run; |
val = tab->level; |
sign = Get_Bits(1); |
} |
if (i>=64) |
{ |
if (!Quiet_Flag) |
cprintf("DCT coeff index (i) out of bounds (intra)\n"); |
Fault_Flag = 1; |
return; |
} |
j = scan[ZIG_ZAG][i]; |
val = (val*ld->quantizer_scale*ld->intra_quantizer_matrix[j]) >> 3; |
/* mismatch control ('oddification') */ |
if (val!=0) /* should always be true, but it's not guaranteed */ |
val = (val-1) | 1; /* equivalent to: if ((val&1)==0) val = val - 1; */ |
/* saturation */ |
if (!sign) |
bp[j] = (val>2047) ? 2047 : val; /* positive */ |
else |
bp[j] = (val>2048) ? -2048 : -val; /* negative */ |
} |
} |
/* decode one non-intra coded MPEG-1 block */ |
void Decode_MPEG1_Non_Intra_Block(comp) |
int comp; |
{ |
int val, i, j, sign; |
unsigned int code; |
DCTtab *tab; |
short *bp; |
bp = ld->block[comp]; |
/* decode AC coefficients */ |
for (i=0; ; i++) |
{ |
code = Show_Bits(16); |
if (code>=16384) |
{ |
if (i==0) |
tab = &DCTtabfirst[(code>>12)-4]; |
else |
tab = &DCTtabnext[(code>>12)-4]; |
} |
else if (code>=1024) |
tab = &DCTtab0[(code>>8)-4]; |
else if (code>=512) |
tab = &DCTtab1[(code>>6)-8]; |
else if (code>=256) |
tab = &DCTtab2[(code>>4)-16]; |
else if (code>=128) |
tab = &DCTtab3[(code>>3)-16]; |
else if (code>=64) |
tab = &DCTtab4[(code>>2)-16]; |
else if (code>=32) |
tab = &DCTtab5[(code>>1)-16]; |
else if (code>=16) |
tab = &DCTtab6[code-16]; |
else |
{ |
if (!Quiet_Flag) |
cprintf("invalid Huffman code in Decode_MPEG1_Non_Intra_Block()\n"); |
Fault_Flag = 1; |
return; |
} |
Flush_Buffer(tab->len); |
if (tab->run==64) /* end_of_block */ |
return; |
if (tab->run==65) /* escape */ |
{ |
i+= Get_Bits(6); |
val = Get_Bits(8); |
if (val==0) |
val = Get_Bits(8); |
else if (val==128) |
val = Get_Bits(8) - 256; |
else if (val>128) |
val -= 256; |
if((sign = (val<0))) |
val = -val; |
} |
else |
{ |
i+= tab->run; |
val = tab->level; |
sign = Get_Bits(1); |
} |
if (i>=64) |
{ |
if (!Quiet_Flag) |
cprintf("DCT coeff index (i) out of bounds (inter)\n"); |
Fault_Flag = 1; |
return; |
} |
j = scan[ZIG_ZAG][i]; |
val = (((val<<1)+1)*ld->quantizer_scale*ld->non_intra_quantizer_matrix[j]) >> 4; |
/* mismatch control ('oddification') */ |
if (val!=0) /* should always be true, but it's not guaranteed */ |
val = (val-1) | 1; /* equivalent to: if ((val&1)==0) val = val - 1; */ |
/* saturation */ |
if (!sign) |
bp[j] = (val>2047) ? 2047 : val; /* positive */ |
else |
bp[j] = (val>2048) ? -2048 : -val; /* negative */ |
} |
} |
/* decode one intra coded MPEG-2 block */ |
void Decode_MPEG2_Intra_Block(comp,dc_dct_pred) |
int comp; |
int dc_dct_pred[]; |
{ |
int val, i, j, sign, nc, cc, run; |
unsigned int code; |
DCTtab *tab; |
short *bp; |
int *qmat; |
struct layer_data *ld1; |
/* with data partitioning, data always goes to base layer */ |
ld1 = (ld->scalable_mode==SC_DP) ? &base : ld; |
bp = ld1->block[comp]; |
if (base.scalable_mode==SC_DP) { |
if (base.priority_breakpoint<64) |
ld = &enhan; |
else |
ld = &base; |
} |
cc = (comp<4) ? 0 : (comp&1)+1; |
qmat = (comp<4 || chroma_format==CHROMA420) |
? ld1->intra_quantizer_matrix |
: ld1->chroma_intra_quantizer_matrix; |
/* ISO/IEC 13818-2 section 7.2.1: decode DC coefficients */ |
if (cc==0) |
val = (dc_dct_pred[0]+= Get_Luma_DC_dct_diff()); |
else if (cc==1) |
val = (dc_dct_pred[1]+= Get_Chroma_DC_dct_diff()); |
else |
val = (dc_dct_pred[2]+= Get_Chroma_DC_dct_diff()); |
if (Fault_Flag) return; |
bp[0] = val << (3-intra_dc_precision); |
nc=0; |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("DCT(%d)i:",comp); |
#endif /* TRACE */ |
/* decode AC coefficients */ |
for (i=1; ; i++) |
{ |
code = Show_Bits(16); |
if (code>=16384 && !intra_vlc_format) |
tab = &DCTtabnext[(code>>12)-4]; |
else if (code>=1024) |
{ |
if (intra_vlc_format) |
tab = &DCTtab0a[(code>>8)-4]; |
else |
tab = &DCTtab0[(code>>8)-4]; |
} |
else if (code>=512) |
{ |
if (intra_vlc_format) |
tab = &DCTtab1a[(code>>6)-8]; |
else |
tab = &DCTtab1[(code>>6)-8]; |
} |
else if (code>=256) |
tab = &DCTtab2[(code>>4)-16]; |
else if (code>=128) |
tab = &DCTtab3[(code>>3)-16]; |
else if (code>=64) |
tab = &DCTtab4[(code>>2)-16]; |
else if (code>=32) |
tab = &DCTtab5[(code>>1)-16]; |
else if (code>=16) |
tab = &DCTtab6[code-16]; |
else |
{ |
if (!Quiet_Flag) |
cprintf("invalid Huffman code in Decode_MPEG2_Intra_Block()\n"); |
Fault_Flag = 1; |
return; |
} |
Flush_Buffer(tab->len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
printf(" ("); |
Print_Bits(code,16,tab->len); |
} |
#endif /* TRACE */ |
if (tab->run==64) /* end_of_block */ |
{ |
#ifdef TRACE |
if (Trace_Flag) |
printf("): EOB\n"); |
#endif /* TRACE */ |
return; |
} |
if (tab->run==65) /* escape */ |
{ |
#ifdef TRACE |
if (Trace_Flag) |
{ |
putchar(' '); |
Print_Bits(Show_Bits(6),6,6); |
} |
#endif /* TRACE */ |
i+= run = Get_Bits(6); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
putchar(' '); |
Print_Bits(Show_Bits(12),12,12); |
} |
#endif /* TRACE */ |
val = Get_Bits(12); |
if ((val&2047)==0) |
{ |
if (!Quiet_Flag) |
cprintf("invalid escape in Decode_MPEG2_Intra_Block()\n"); |
Fault_Flag = 1; |
return; |
} |
if((sign = (val>=2048))) |
val = 4096 - val; |
} |
else |
{ |
i+= run = tab->run; |
val = tab->level; |
sign = Get_Bits(1); |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("%d",sign); |
#endif /* TRACE */ |
} |
if (i>=64) |
{ |
if (!Quiet_Flag) |
cprintf("DCT coeff index (i) out of bounds (intra2)\n"); |
Fault_Flag = 1; |
return; |
} |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("): %d/%d",run,sign ? -val : val); |
#endif /* TRACE */ |
j = scan[ld1->alternate_scan][i]; |
val = (val * ld1->quantizer_scale * qmat[j]) >> 4; |
bp[j] = sign ? -val : val; |
nc++; |
if (base.scalable_mode==SC_DP && nc==base.priority_breakpoint-63) |
ld = &enhan; |
} |
} |
/* decode one non-intra coded MPEG-2 block */ |
void Decode_MPEG2_Non_Intra_Block(comp) |
int comp; |
{ |
int val, i, j, sign, nc, run; |
unsigned int code; |
DCTtab *tab; |
short *bp; |
int *qmat; |
struct layer_data *ld1; |
/* with data partitioning, data always goes to base layer */ |
ld1 = (ld->scalable_mode==SC_DP) ? &base : ld; |
bp = ld1->block[comp]; |
if (base.scalable_mode==SC_DP) { |
if (base.priority_breakpoint<64) |
ld = &enhan; |
else |
ld = &base; |
} |
qmat = (comp<4 || chroma_format==CHROMA420) |
? ld1->non_intra_quantizer_matrix |
: ld1->chroma_non_intra_quantizer_matrix; |
nc = 0; |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("DCT(%d)n:",comp); |
#endif /* TRACE */ |
/* decode AC coefficients */ |
for (i=0; ; i++) |
{ |
code = Show_Bits(16); |
if (code>=16384) |
{ |
if (i==0) |
tab = &DCTtabfirst[(code>>12)-4]; |
else |
tab = &DCTtabnext[(code>>12)-4]; |
} |
else if (code>=1024) |
tab = &DCTtab0[(code>>8)-4]; |
else if (code>=512) |
tab = &DCTtab1[(code>>6)-8]; |
else if (code>=256) |
tab = &DCTtab2[(code>>4)-16]; |
else if (code>=128) |
tab = &DCTtab3[(code>>3)-16]; |
else if (code>=64) |
tab = &DCTtab4[(code>>2)-16]; |
else if (code>=32) |
tab = &DCTtab5[(code>>1)-16]; |
else if (code>=16) |
tab = &DCTtab6[code-16]; |
else |
{ |
if (!Quiet_Flag) |
cprintf("invalid Huffman code in Decode_MPEG2_Non_Intra_Block()\n"); |
Fault_Flag = 1; |
return; |
} |
Flush_Buffer(tab->len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
cprintf(" ("); |
Print_Bits(code,16,tab->len); |
} |
#endif /* TRACE */ |
if (tab->run==64) /* end_of_block */ |
{ |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("): EOB\n"); |
#endif /* TRACE */ |
return; |
} |
if (tab->run==65) /* escape */ |
{ |
#ifdef TRACE |
if (Trace_Flag) |
{ |
cprintf(" "); |
Print_Bits(Show_Bits(6),6,6); |
} |
#endif /* TRACE */ |
i+= run = Get_Bits(6); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
cprintf(" "); |
Print_Bits(Show_Bits(12),12,12); |
} |
#endif /* TRACE */ |
val = Get_Bits(12); |
if ((val&2047)==0) |
{ |
if (!Quiet_Flag) |
cprintf("invalid escape in Decode_MPEG2_Intra_Block()\n"); |
Fault_Flag = 1; |
return; |
} |
if((sign = (val>=2048))) |
val = 4096 - val; |
} |
else |
{ |
i+= run = tab->run; |
val = tab->level; |
sign = Get_Bits(1); |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("%d",sign); |
#endif /* TRACE */ |
} |
if (i>=64) |
{ |
if (!Quiet_Flag) |
cprintf("DCT coeff index (i) out of bounds (inter2)\n"); |
Fault_Flag = 1; |
return; |
} |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("): %d/%d",run,sign?-val:val); |
#endif /* TRACE */ |
j = scan[ld1->alternate_scan][i]; |
val = (((val<<1)+1) * ld1->quantizer_scale * qmat[j]) >> 5; |
bp[j] = sign ? -val : val; |
nc++; |
if (base.scalable_mode==SC_DP && nc==base.priority_breakpoint-63) |
ld = &enhan; |
} |
} |
/unsupported/trunk/first-official/mpeg2/spatscal.c |
---|
0,0 → 1,275 |
#include "config.h" |
#include "global.h" |
/* private prototypes */ |
static void Read_Lower_Layer_Component_Framewise _ANSI_ARGS_((int comp, int lw, int lh)); |
static void Read_Lower_Layer_Component_Fieldwise _ANSI_ARGS_((int comp, int lw, int lh)); |
static void Make_Spatial_Prediction_Frame _ANSI_ARGS_((int progressive_frame, |
int llprogressive_frame, unsigned char *fld0, unsigned char *fld1, |
short *tmp, unsigned char *dst, int llx0, int lly0, int llw, int llh, |
int horizontal_size, int vertical_size, int vm, int vn, int hm, int hn, |
int aperture)); |
static void Deinterlace _ANSI_ARGS_((unsigned char *fld0, unsigned char *fld1, |
int j0, int lx, int ly, int aperture)); |
static void Subsample_Vertical _ANSI_ARGS_((unsigned char *s, short *d, |
int lx, int lys, int lyd, int m, int n, int j0, int dj)); |
static void Subsample_Horizontal _ANSI_ARGS_((short *s, unsigned char *d, |
int x0, int lx, int lxs, int lxd, int ly, int m, int n)); |
/* get reference frame */ |
void Spatial_Prediction() |
{ |
if(Frame_Store_Flag) |
{ |
Read_Lower_Layer_Component_Framewise(0,lower_layer_prediction_horizontal_size, |
lower_layer_prediction_vertical_size); /* Y */ |
Read_Lower_Layer_Component_Framewise(1,lower_layer_prediction_horizontal_size>>1, |
lower_layer_prediction_vertical_size>>1); /* Cb ("U") */ |
Read_Lower_Layer_Component_Framewise(2,lower_layer_prediction_horizontal_size>>1, |
lower_layer_prediction_vertical_size>>1); /* Cr ("V") */ |
} |
else |
{ |
Read_Lower_Layer_Component_Fieldwise(0,lower_layer_prediction_horizontal_size, |
lower_layer_prediction_vertical_size); /* Y */ |
Read_Lower_Layer_Component_Fieldwise(1,lower_layer_prediction_horizontal_size>>1, |
lower_layer_prediction_vertical_size>>1); /* Cb ("U") */ |
Read_Lower_Layer_Component_Fieldwise(2,lower_layer_prediction_horizontal_size>>1, |
lower_layer_prediction_vertical_size>>1); /* Cr ("V") */ |
} |
Make_Spatial_Prediction_Frame /* Y */ |
(progressive_frame,lower_layer_progressive_frame,llframe0[0],llframe1[0], |
lltmp,current_frame[0],lower_layer_horizontal_offset, |
lower_layer_vertical_offset, |
lower_layer_prediction_horizontal_size, |
lower_layer_prediction_vertical_size, |
horizontal_size,vertical_size,vertical_subsampling_factor_m, |
vertical_subsampling_factor_n,horizontal_subsampling_factor_m, |
horizontal_subsampling_factor_n, |
picture_structure!=FRAME_PICTURE); /* this changed from CD to DIS */ |
Make_Spatial_Prediction_Frame /* Cb */ |
(progressive_frame,lower_layer_progressive_frame,llframe0[1],llframe1[1], |
lltmp,current_frame[1],lower_layer_horizontal_offset/2, |
lower_layer_vertical_offset/2, |
lower_layer_prediction_horizontal_size>>1, |
lower_layer_prediction_vertical_size>>1, |
horizontal_size>>1,vertical_size>>1,vertical_subsampling_factor_m, |
vertical_subsampling_factor_n,horizontal_subsampling_factor_m, |
horizontal_subsampling_factor_n,1); |
Make_Spatial_Prediction_Frame /* Cr */ |
(progressive_frame,lower_layer_progressive_frame,llframe0[2],llframe1[2], |
lltmp,current_frame[2],lower_layer_horizontal_offset/2, |
lower_layer_vertical_offset/2, |
lower_layer_prediction_horizontal_size>>1, |
lower_layer_prediction_vertical_size>>1, |
horizontal_size>>1,vertical_size>>1,vertical_subsampling_factor_m, |
vertical_subsampling_factor_n,horizontal_subsampling_factor_m, |
horizontal_subsampling_factor_n,1); |
} |
static void Read_Lower_Layer_Component_Framewise(comp,lw,lh) |
int comp; |
int lw, lh; |
{ |
cprintf("Read_Lower_Layer_Component_Framewise\n"); |
} |
static void Read_Lower_Layer_Component_Fieldwise(comp,lw,lh) |
int comp; |
int lw, lh; |
{ |
cprintf("Read_Lower_Layer_Component_Fieldwise\n"); |
} |
/* form spatial prediction */ |
static void Make_Spatial_Prediction_Frame(progressive_frame, |
llprogressive_frame,fld0,fld1,tmp,dst,llx0,lly0,llw,llh,horizontal_size, |
vertical_size,vm,vn,hm,hn,aperture) |
int progressive_frame,llprogressive_frame; |
unsigned char *fld0,*fld1; |
short *tmp; |
unsigned char *dst; |
int llx0,lly0,llw,llh,horizontal_size,vertical_size,vm,vn,hm,hn,aperture; |
{ |
int w, h, x0, llw2, llh2; |
llw2 = (llw*hn)/hm; |
llh2 = (llh*vn)/vm; |
if (llprogressive_frame) |
{ |
/* progressive -> progressive / interlaced */ |
Subsample_Vertical(fld0,tmp,llw,llh,llh2,vm,vn,0,1); |
} |
else if (progressive_frame) |
{ |
/* interlaced -> progressive */ |
if (lower_layer_deinterlaced_field_select) |
{ |
Deinterlace(fld1,fld0,0,llw,llh,aperture); |
Subsample_Vertical(fld1,tmp,llw,llh,llh2,vm,vn,0,1); |
} |
else |
{ |
Deinterlace(fld0,fld1,1,llw,llh,aperture); |
Subsample_Vertical(fld0,tmp,llw,llh,llh2,vm,vn,0,1); |
} |
} |
else |
{ |
/* interlaced -> interlaced */ |
Deinterlace(fld0,fld1,1,llw,llh,aperture); |
Deinterlace(fld1,fld0,0,llw,llh,aperture); |
Subsample_Vertical(fld0,tmp,llw,llh,llh2,vm,vn,0,2); |
Subsample_Vertical(fld1,tmp,llw,llh,llh2,vm,vn,1,2); |
} |
/* vertical limits */ |
if (lly0<0) |
{ |
tmp-= llw*lly0; |
llh2+= lly0; |
if (llh2<0) |
llh2 = 0; |
h = (vertical_size<llh2) ? vertical_size : llh2; |
} |
else |
{ |
dst+= horizontal_size*lly0; |
h= vertical_size - lly0; |
if (h>llh2) |
h = llh2; |
} |
/* horizontal limits */ |
if (llx0<0) |
{ |
x0 = -llx0; |
llw2+= llx0; |
if (llw2<0) |
llw2 = 0; |
w = (horizontal_size<llw2) ? horizontal_size : llw2; |
} |
else |
{ |
dst+= llx0; |
x0 = 0; |
w = horizontal_size - llx0; |
if (w>llw2) |
w = llw2; |
} |
Subsample_Horizontal(tmp,dst,x0,w,llw,horizontal_size,h,hm,hn); |
} |
/* deinterlace one field (interpolate opposite parity samples) |
* |
* deinterlacing is done in-place: if j0=1, fld0 contains the input field in |
* its even lines and the odd lines are interpolated by this routine |
* if j0=0, the input field is in the odd lines and the even lines are |
* interpolated |
* |
* fld0: field to be deinterlaced |
* fld1: other field (referenced by the two field aperture filter) |
* j0: 0: interpolate even (top) lines, 1: interpolate odd (bottom) lines |
* lx: width of fld0 and fld1 |
* ly: height of the deinterlaced field (has to be even) |
* aperture: 1: use one field aperture filter (two field otherwise) |
*/ |
static void Deinterlace(fld0,fld1,j0,lx,ly,aperture) |
unsigned char *fld0,*fld1; |
int j0,lx,ly; /* ly has to be even */ |
int aperture; |
{ |
int i,j,v; |
unsigned char *p0, *p0m1, *p0p1, *p1, *p1m2, *p1p2; |
/* deinterlace one field */ |
for (j=j0; j<ly; j+=2) |
{ |
p0 = fld0+lx*j; |
p0m1 = (j==0) ? p0+lx : p0-lx; |
p0p1 = (j==ly-1) ? p0-lx : p0+lx; |
if (aperture) |
for (i=0; i<lx; i++) |
p0[i] = (unsigned int)(p0m1[i] + p0p1[i] + 1)>>1; |
else |
{ |
p1 = fld1 + lx*j; |
p1m2 = (j<2) ? p1 : p1-2*lx; |
p1p2 = (j>=ly-2) ? p1 : p1+2*lx; |
for (i=0; i<lx; i++) |
{ |
v = 8*(p0m1[i]+p0p1[i]) + 2*p1[i] - p1m2[i] - p1p2[i]; |
p0[i] = Clip[(v + ((v>=0) ? 8 : 7))>>4]; |
} |
} |
} |
} |
/* vertical resampling */ |
static void Subsample_Vertical(s,d,lx,lys,lyd,m,n,j0,dj) |
unsigned char *s; |
short *d; |
int lx, lys, lyd, m, n, j0, dj; |
{ |
int i, j, c1, c2, jd; |
unsigned char *s1, *s2; |
short *d1; |
for (j=j0; j<lyd; j+=dj) |
{ |
d1 = d + lx*j; |
jd = (j*m)/n; |
s1 = s + lx*jd; |
s2 = (jd<lys-1)? s1+lx : s1; |
c2 = (16*((j*m)%n) + (n>>1))/n; |
c1 = 16 - c2; |
for (i=0; i<lx; i++) |
d1[i] = c1*s1[i] + c2*s2[i]; |
} |
} |
/* horizontal resampling */ |
static void Subsample_Horizontal(s,d,x0,lx,lxs,lxd,ly,m,n) |
short *s; |
unsigned char *d; |
int x0, lx, lxs, lxd, ly, m, n; |
{ |
int i, i1, j, id, c1, c2, v; |
short *s1, *s2; |
unsigned char *d1; |
for (i1=0; i1<lx; i1++) |
{ |
d1 = d + i1; |
i = x0 + i1; |
id = (i*m)/n; |
s1 = s+id; |
s2 = (id<lxs-1) ? s1+1 : s1; |
c2 = (16*((i*m)%n) + (n>>1))/n; |
c1 = 16 - c2; |
for (j=0; j<ly; j++) |
{ |
v = c1*(*s1) + c2*(*s2); |
*d1 = (v + ((v>=0) ? 128 : 127))>>8; |
d1+= lxd; |
s1+= lxs; |
s2+= lxs; |
} |
} |
} |
/unsupported/trunk/first-official/mpeg2/config.h |
---|
0,0 → 1,45 |
/* config.h, configuration defines */ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
/* define NON_ANSI_COMPILER for compilers without function prototyping */ |
/* #define NON_ANSI_COMPILER */ |
#ifdef NON_ANSI_COMPILER |
#define _ANSI_ARGS_(x) () |
#else |
#define _ANSI_ARGS_(x) x |
#endif |
#define RB "rb" |
#define WB "wb" |
#ifndef O_BINARY |
#define O_BINARY 0 |
#endif |
/unsupported/trunk/first-official/mpeg2/getpic.c |
---|
0,0 → 1,1223 |
/* getpic.c, picture decoding */ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
#include "config.h" |
#include "global.h" |
/* private prototypes*/ |
static void picture_data _ANSI_ARGS_((int framenum)); |
static void macroblock_modes _ANSI_ARGS_((int *pmacroblock_type, int *pstwtype, |
int *pstwclass, int *pmotion_type, int *pmotion_vector_count, int *pmv_format, int *pdmv, |
int *pmvscale, int *pdct_type)); |
static void Clear_Block _ANSI_ARGS_((int comp)); |
static void Sum_Block _ANSI_ARGS_((int comp)); |
static void Saturate _ANSI_ARGS_((short *bp)); |
static void Add_Block _ANSI_ARGS_((int comp, int bx, int by, |
int dct_type, int addflag)); |
static void Update_Picture_Buffers _ANSI_ARGS_((void)); |
static void frame_reorder _ANSI_ARGS_((int bitstream_framenum, |
int sequence_framenum)); |
static void Decode_SNR_Macroblock _ANSI_ARGS_((int *SNRMBA, int *SNRMBAinc, |
int MBA, int MBAmax, int *dct_type)); |
static void motion_compensation _ANSI_ARGS_((int MBA, int macroblock_type, |
int motion_type, int PMV[2][2][2], int motion_vertical_field_select[2][2], |
int dmvector[2], int stwtype, int dct_type)); |
static void skipped_macroblock _ANSI_ARGS_((int dc_dct_pred[3], |
int PMV[2][2][2], int *motion_type, int motion_vertical_field_select[2][2], |
int *stwtype, int *macroblock_type)); |
static int slice _ANSI_ARGS_((int framenum, int MBAmax)); |
static int start_of_slice _ANSI_ARGS_ ((int MBAmax, int *MBA, |
int *MBAinc, int dc_dct_pred[3], int PMV[2][2][2])); |
static int decode_macroblock _ANSI_ARGS_((int *macroblock_type, |
int *stwtype, int *stwclass, int *motion_type, int *dct_type, |
int PMV[2][2][2], int dc_dct_pred[3], |
int motion_vertical_field_select[2][2], int dmvector[2])); |
/* decode one frame or field picture */ |
void Decode_Picture(bitstream_framenum, sequence_framenum) |
int bitstream_framenum, sequence_framenum; |
{ |
if (picture_structure==FRAME_PICTURE && Second_Field) |
{ |
/* recover from illegal number of field pictures */ |
cprintf("odd number of field pictures\n"); |
Second_Field = 0; |
} |
/* IMPLEMENTATION: update picture buffer pointers */ |
Update_Picture_Buffers(); |
#ifdef VERIFY |
Check_Headers(bitstream_framenum, sequence_framenum); |
#endif /* VERIFY */ |
/* ISO/IEC 13818-4 section 2.4.5.4 "frame buffer intercept method" */ |
/* (section number based on November 1995 (Dallas) draft of the |
conformance document) */ |
if(Ersatz_Flag) |
Substitute_Frame_Buffer(bitstream_framenum, sequence_framenum); |
/* form spatial scalable picture */ |
/* form spatial scalable picture */ |
/* ISO/IEC 13818-2 section 7.7: Spatial scalability */ |
if (base.pict_scal && !Second_Field) |
{ |
Spatial_Prediction(); |
} |
/* decode picture data ISO/IEC 13818-2 section 6.2.3.7 */ |
picture_data(bitstream_framenum); |
/* write or display current or previously decoded reference frame */ |
/* ISO/IEC 13818-2 section 6.1.1.11: Frame reordering */ |
frame_reorder(bitstream_framenum, sequence_framenum); |
if (picture_structure!=FRAME_PICTURE) |
Second_Field = !Second_Field; |
} |
/* decode all macroblocks of the current picture */ |
/* stages described in ISO/IEC 13818-2 section 7 */ |
static void picture_data(framenum) |
int framenum; |
{ |
int MBAmax; |
int ret; |
/* number of macroblocks per picture */ |
MBAmax = mb_width*mb_height; |
if (picture_structure!=FRAME_PICTURE) |
MBAmax>>=1; /* field picture has half as mnay macroblocks as frame */ |
for(;;) |
{ |
if((ret=slice(framenum, MBAmax))<0) |
return; |
} |
} |
/* decode all macroblocks of the current picture */ |
/* ISO/IEC 13818-2 section 6.3.16 */ |
static int slice(framenum, MBAmax) |
int framenum, MBAmax; |
{ |
int MBA; |
int MBAinc, macroblock_type, motion_type, dct_type; |
int dc_dct_pred[3]; |
int PMV[2][2][2], motion_vertical_field_select[2][2]; |
int dmvector[2]; |
int stwtype, stwclass; |
int SNRMBA, SNRMBAinc; |
int ret; |
MBA = 0; /* macroblock address */ |
MBAinc = 0; |
if((ret=start_of_slice(MBAmax, &MBA, &MBAinc, dc_dct_pred, PMV))!=1) |
return(ret); |
if (Two_Streams && enhan.scalable_mode==SC_SNR) |
{ |
SNRMBA=0; |
SNRMBAinc=0; |
} |
Fault_Flag=0; |
for (;;) |
{ |
/* this is how we properly exit out of picture */ |
if (MBA>=MBAmax) |
return(-1); /* all macroblocks decoded */ |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("frame %d, MB %d\n",framenum,MBA); |
#endif /* TRACE */ |
#ifdef DISPLAY |
if (!progressive_frame && picture_structure==FRAME_PICTURE |
&& MBA==(MBAmax>>1) && framenum!=0 && Output_Type==T_X11 |
&& !Display_Progressive_Flag) |
{ |
Display_Second_Field(); |
} |
#endif |
ld = &base; |
if (MBAinc==0) |
{ |
if (base.scalable_mode==SC_DP && base.priority_breakpoint==1) |
ld = &enhan; |
if (!Show_Bits(23) || Fault_Flag) /* next_start_code or fault */ |
{ |
resync: /* if Fault_Flag: resynchronize to next next_start_code */ |
Fault_Flag = 0; |
return(0); /* trigger: go to next slice */ |
} |
else /* neither next_start_code nor Fault_Flag */ |
{ |
if (base.scalable_mode==SC_DP && base.priority_breakpoint==1) |
ld = &enhan; |
/* decode macroblock address increment */ |
MBAinc = Get_macroblock_address_increment(); |
if (Fault_Flag) goto resync; |
} |
} |
if (MBA>=MBAmax) |
{ |
/* MBAinc points beyond picture dimensions */ |
if (!Quiet_Flag) |
cprintf("Too many macroblocks in picture\n"); |
return(-1); |
} |
if (MBAinc==1) /* not skipped */ |
{ |
ret = decode_macroblock(¯oblock_type, &stwtype, &stwclass, |
&motion_type, &dct_type, PMV, dc_dct_pred, |
motion_vertical_field_select, dmvector); |
if(ret==-1) |
return(-1); |
if(ret==0) |
goto resync; |
} |
else /* MBAinc!=1: skipped macroblock */ |
{ |
/* ISO/IEC 13818-2 section 7.6.6 */ |
skipped_macroblock(dc_dct_pred, PMV, &motion_type, |
motion_vertical_field_select, &stwtype, ¯oblock_type); |
} |
/* SCALABILITY: SNR */ |
/* ISO/IEC 13818-2 section 7.8 */ |
/* NOTE: we currently ignore faults encountered in this routine */ |
if (Two_Streams && enhan.scalable_mode==SC_SNR) |
Decode_SNR_Macroblock(&SNRMBA, &SNRMBAinc, MBA, MBAmax, &dct_type); |
/* ISO/IEC 13818-2 section 7.6 */ |
motion_compensation(MBA, macroblock_type, motion_type, PMV, |
motion_vertical_field_select, dmvector, stwtype, dct_type); |
/* advance to next macroblock */ |
MBA++; |
MBAinc--; |
/* SCALABILITY: SNR */ |
if (Two_Streams && enhan.scalable_mode==SC_SNR) |
{ |
SNRMBA++; |
SNRMBAinc--; |
} |
if (MBA>=MBAmax) |
return(-1); /* all macroblocks decoded */ |
} |
} |
/* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes */ |
static void macroblock_modes(pmacroblock_type,pstwtype,pstwclass, |
pmotion_type,pmotion_vector_count,pmv_format,pdmv,pmvscale,pdct_type) |
int *pmacroblock_type, *pstwtype, *pstwclass; |
int *pmotion_type, *pmotion_vector_count, *pmv_format, *pdmv, *pmvscale; |
int *pdct_type; |
{ |
int macroblock_type; |
int stwtype, stwcode, stwclass; |
int motion_type = 0; |
int motion_vector_count, mv_format, dmv, mvscale; |
int dct_type; |
static unsigned char stwc_table[3][4] |
= { {6,3,7,4}, {2,1,5,4}, {2,5,7,4} }; |
static unsigned char stwclass_table[9] |
= {0, 1, 2, 1, 1, 2, 3, 3, 4}; |
/* get macroblock_type */ |
macroblock_type = Get_macroblock_type(); |
if (Fault_Flag) return; |
/* get spatial_temporal_weight_code */ |
if (macroblock_type & MB_WEIGHT) |
{ |
if (spatial_temporal_weight_code_table_index==0) |
stwtype = 4; |
else |
{ |
stwcode = Get_Bits(2); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
cprintf("spatial_temporal_weight_code ("); |
Print_Bits(stwcode,2,2); |
cprintf("): %d\n",stwcode); |
} |
#endif /* TRACE */ |
stwtype = stwc_table[spatial_temporal_weight_code_table_index-1][stwcode]; |
} |
} |
else |
stwtype = (macroblock_type & MB_CLASS4) ? 8 : 0; |
/* SCALABILITY: derive spatial_temporal_weight_class (Table 7-18) */ |
stwclass = stwclass_table[stwtype]; |
/* get frame/field motion type */ |
if (macroblock_type & (MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD)) |
{ |
if (picture_structure==FRAME_PICTURE) /* frame_motion_type */ |
{ |
motion_type = frame_pred_frame_dct ? MC_FRAME : Get_Bits(2); |
#ifdef TRACE |
if (!frame_pred_frame_dct && Trace_Flag) |
{ |
cprintf("frame_motion_type ("); |
Print_Bits(motion_type,2,2); |
cprintf("): %s\n",motion_type==MC_FIELD?"Field": |
motion_type==MC_FRAME?"Frame": |
motion_type==MC_DMV?"Dual_Prime":"Invalid"); |
} |
#endif /* TRACE */ |
} |
else /* field_motion_type */ |
{ |
motion_type = Get_Bits(2); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
cprintf("field_motion_type ("); |
Print_Bits(motion_type,2,2); |
cprintf("): %s\n",motion_type==MC_FIELD?"Field": |
motion_type==MC_16X8?"16x8 MC": |
motion_type==MC_DMV?"Dual_Prime":"Invalid"); |
} |
#endif /* TRACE */ |
} |
} |
else if ((macroblock_type & MACROBLOCK_INTRA) && concealment_motion_vectors) |
{ |
/* concealment motion vectors */ |
motion_type = (picture_structure==FRAME_PICTURE) ? MC_FRAME : MC_FIELD; |
} |
#if 0 |
else |
{ |
printf("maroblock_modes(): unknown macroblock type\n"); |
motion_type = -1; |
} |
#endif |
/* derive motion_vector_count, mv_format and dmv, (table 6-17, 6-18) */ |
if (picture_structure==FRAME_PICTURE) |
{ |
motion_vector_count = (motion_type==MC_FIELD && stwclass<2) ? 2 : 1; |
mv_format = (motion_type==MC_FRAME) ? MV_FRAME : MV_FIELD; |
} |
else |
{ |
motion_vector_count = (motion_type==MC_16X8) ? 2 : 1; |
mv_format = MV_FIELD; |
} |
dmv = (motion_type==MC_DMV); /* dual prime */ |
/* field mv predictions in frame pictures have to be scaled |
* ISO/IEC 13818-2 section 7.6.3.1 Decoding the motion vectors |
* IMPLEMENTATION: mvscale is derived for later use in motion_vectors() |
* it displaces the stage: |
* |
* if((mv_format=="field")&&(t==1)&&(picture_structure=="Frame picture")) |
* prediction = PMV[r][s][t] DIV 2; |
*/ |
mvscale = ((mv_format==MV_FIELD) && (picture_structure==FRAME_PICTURE)); |
/* get dct_type (frame DCT / field DCT) */ |
dct_type = (picture_structure==FRAME_PICTURE) |
&& (!frame_pred_frame_dct) |
&& (macroblock_type & (MACROBLOCK_PATTERN|MACROBLOCK_INTRA)) |
? Get_Bits(1) |
: 0; |
#ifdef TRACE |
if (Trace_Flag && (picture_structure==FRAME_PICTURE) |
&& (!frame_pred_frame_dct) |
&& (macroblock_type & (MACROBLOCK_PATTERN|MACROBLOCK_INTRA))) |
cprintf("dct_type (%d): %s\n",dct_type,dct_type?"Field":"Frame"); |
#endif /* TRACE */ |
/* return values */ |
*pmacroblock_type = macroblock_type; |
*pstwtype = stwtype; |
*pstwclass = stwclass; |
*pmotion_type = motion_type; |
*pmotion_vector_count = motion_vector_count; |
*pmv_format = mv_format; |
*pdmv = dmv; |
*pmvscale = mvscale; |
*pdct_type = dct_type; |
} |
/* move/add 8x8-Block from block[comp] to backward_reference_frame */ |
/* copy reconstructed 8x8 block from block[comp] to current_frame[] |
* ISO/IEC 13818-2 section 7.6.8: Adding prediction and coefficient data |
* This stage also embodies some of the operations implied by: |
* - ISO/IEC 13818-2 section 7.6.7: Combining predictions |
* - ISO/IEC 13818-2 section 6.1.3: Macroblock |
*/ |
static void Add_Block(comp,bx,by,dct_type,addflag) |
int comp,bx,by,dct_type,addflag; |
{ |
int cc,i, j, iincr; |
unsigned char *rfp; |
short *bp; |
/* derive color component index */ |
/* equivalent to ISO/IEC 13818-2 Table 7-1 */ |
cc = (comp<4) ? 0 : (comp&1)+1; /* color component index */ |
if (cc==0) |
{ |
/* luminance */ |
if (picture_structure==FRAME_PICTURE) |
if (dct_type) |
{ |
/* field DCT coding */ |
rfp = current_frame[0] |
+ Coded_Picture_Width*(by+((comp&2)>>1)) + bx + ((comp&1)<<3); |
iincr = (Coded_Picture_Width<<1) - 8; |
} |
else |
{ |
/* frame DCT coding */ |
rfp = current_frame[0] |
+ Coded_Picture_Width*(by+((comp&2)<<2)) + bx + ((comp&1)<<3); |
iincr = Coded_Picture_Width - 8; |
} |
else |
{ |
/* field picture */ |
rfp = current_frame[0] |
+ (Coded_Picture_Width<<1)*(by+((comp&2)<<2)) + bx + ((comp&1)<<3); |
iincr = (Coded_Picture_Width<<1) - 8; |
} |
} |
else |
{ |
/* chrominance */ |
/* scale coordinates */ |
if (chroma_format!=CHROMA444) |
bx >>= 1; |
if (chroma_format==CHROMA420) |
by >>= 1; |
if (picture_structure==FRAME_PICTURE) |
{ |
if (dct_type && (chroma_format!=CHROMA420)) |
{ |
/* field DCT coding */ |
rfp = current_frame[cc] |
+ Chroma_Width*(by+((comp&2)>>1)) + bx + (comp&8); |
iincr = (Chroma_Width<<1) - 8; |
} |
else |
{ |
/* frame DCT coding */ |
rfp = current_frame[cc] |
+ Chroma_Width*(by+((comp&2)<<2)) + bx + (comp&8); |
iincr = Chroma_Width - 8; |
} |
} |
else |
{ |
/* field picture */ |
rfp = current_frame[cc] |
+ (Chroma_Width<<1)*(by+((comp&2)<<2)) + bx + (comp&8); |
iincr = (Chroma_Width<<1) - 8; |
} |
} |
bp = ld->block[comp]; |
if (addflag) |
{ |
for (i=0; i<8; i++) |
{ |
for (j=0; j<8; j++) |
{ |
*rfp = Clip[*bp++ + *rfp]; |
rfp++; |
} |
rfp+= iincr; |
} |
} |
else |
{ |
for (i=0; i<8; i++) |
{ |
for (j=0; j<8; j++) |
*rfp++ = Clip[*bp++ + 128]; |
rfp+= iincr; |
} |
} |
} |
/* ISO/IEC 13818-2 section 7.8 */ |
static void Decode_SNR_Macroblock(SNRMBA, SNRMBAinc, MBA, MBAmax, dct_type) |
int *SNRMBA, *SNRMBAinc; |
int MBA, MBAmax; |
int *dct_type; |
{ |
int SNRmacroblock_type, SNRcoded_block_pattern, SNRdct_type, dummy; |
int slice_vert_pos_ext, quantizer_scale_code, comp, code; |
ld = &enhan; |
if (*SNRMBAinc==0) |
{ |
if (!Show_Bits(23)) /* next_start_code */ |
{ |
next_start_code(); |
code = Show_Bits(32); |
if (code<SLICE_START_CODE_MIN || code>SLICE_START_CODE_MAX) |
{ |
/* only slice headers are allowed in picture_data */ |
if (!Quiet_Flag) |
cprintf("SNR: Premature end of picture\n"); |
return; |
} |
Flush_Buffer32(); |
/* decode slice header (may change quantizer_scale) */ |
slice_vert_pos_ext = slice_header(); |
/* decode macroblock address increment */ |
*SNRMBAinc = Get_macroblock_address_increment(); |
/* set current location */ |
*SNRMBA = |
((slice_vert_pos_ext<<7) + (code&255) - 1)*mb_width + *SNRMBAinc - 1; |
*SNRMBAinc = 1; /* first macroblock in slice: not skipped */ |
} |
else /* not next_start_code */ |
{ |
if (*SNRMBA>=MBAmax) |
{ |
if (!Quiet_Flag) |
cprintf("Too many macroblocks in picture\n"); |
return; |
} |
/* decode macroblock address increment */ |
*SNRMBAinc = Get_macroblock_address_increment(); |
} |
} |
if (*SNRMBA!=MBA) |
{ |
/* streams out of sync */ |
if (!Quiet_Flag) |
cprintf("Cant't synchronize streams\n"); |
return; |
} |
if (*SNRMBAinc==1) /* not skipped */ |
{ |
macroblock_modes(&SNRmacroblock_type, &dummy, &dummy, |
&dummy, &dummy, &dummy, &dummy, &dummy, |
&SNRdct_type); |
if (SNRmacroblock_type & MACROBLOCK_PATTERN) |
*dct_type = SNRdct_type; |
if (SNRmacroblock_type & MACROBLOCK_QUANT) |
{ |
quantizer_scale_code = Get_Bits(5); |
ld->quantizer_scale = |
ld->q_scale_type ? Non_Linear_quantizer_scale[quantizer_scale_code] : quantizer_scale_code<<1; |
} |
/* macroblock_pattern */ |
if (SNRmacroblock_type & MACROBLOCK_PATTERN) |
{ |
SNRcoded_block_pattern = Get_coded_block_pattern(); |
if (chroma_format==CHROMA422) |
SNRcoded_block_pattern = (SNRcoded_block_pattern<<2) | Get_Bits(2); /* coded_block_pattern_1 */ |
else if (chroma_format==CHROMA444) |
SNRcoded_block_pattern = (SNRcoded_block_pattern<<6) | Get_Bits(6); /* coded_block_pattern_2 */ |
} |
else |
SNRcoded_block_pattern = 0; |
/* decode blocks */ |
for (comp=0; comp<block_count; comp++) |
{ |
Clear_Block(comp); |
if (SNRcoded_block_pattern & (1<<(block_count-1-comp))) |
Decode_MPEG2_Non_Intra_Block(comp); |
} |
} |
else /* SNRMBAinc!=1: skipped macroblock */ |
{ |
for (comp=0; comp<block_count; comp++) |
Clear_Block(comp); |
} |
ld = &base; |
} |
/* IMPLEMENTATION: set scratch pad macroblock to zero */ |
static void Clear_Block(comp) |
int comp; |
{ |
short *Block_Ptr; |
int i; |
Block_Ptr = ld->block[comp]; |
for (i=0; i<64; i++) |
*Block_Ptr++ = 0; |
} |
/* SCALABILITY: add SNR enhancement layer block data to base layer */ |
/* ISO/IEC 13818-2 section 7.8.3.4: Addition of coefficients from the two layes */ |
static void Sum_Block(comp) |
int comp; |
{ |
short *Block_Ptr1, *Block_Ptr2; |
int i; |
Block_Ptr1 = base.block[comp]; |
Block_Ptr2 = enhan.block[comp]; |
for (i=0; i<64; i++) |
*Block_Ptr1++ += *Block_Ptr2++; |
} |
/* limit coefficients to -2048..2047 */ |
/* ISO/IEC 13818-2 section 7.4.3 and 7.4.4: Saturation and Mismatch control */ |
static void Saturate(Block_Ptr) |
short *Block_Ptr; |
{ |
int i, sum, val; |
sum = 0; |
/* ISO/IEC 13818-2 section 7.4.3: Saturation */ |
for (i=0; i<64; i++) |
{ |
val = Block_Ptr[i]; |
if (val>2047) |
val = 2047; |
else if (val<-2048) |
val = -2048; |
Block_Ptr[i] = val; |
sum+= val; |
} |
/* ISO/IEC 13818-2 section 7.4.4: Mismatch control */ |
if ((sum&1)==0) |
Block_Ptr[63]^= 1; |
} |
/* reuse old picture buffers as soon as they are no longer needed |
based on life-time axioms of MPEG */ |
static void Update_Picture_Buffers() |
{ |
int cc; /* color component index */ |
unsigned char *tmp; /* temporary swap pointer */ |
for (cc=0; cc<3; cc++) |
{ |
/* B pictures do not need to be save for future reference */ |
if (picture_coding_type==B_TYPE) |
{ |
current_frame[cc] = auxframe[cc]; |
} |
else |
{ |
/* only update at the beginning of the coded frame */ |
if (!Second_Field) |
{ |
tmp = forward_reference_frame[cc]; |
/* the previously decoded reference frame is stored |
coincident with the location where the backward |
reference frame is stored (backwards prediction is not |
needed in P pictures) */ |
forward_reference_frame[cc] = backward_reference_frame[cc]; |
/* update pointer for potential future B pictures */ |
backward_reference_frame[cc] = tmp; |
} |
/* can erase over old backward reference frame since it is not used |
in a P picture, and since any subsequent B pictures will use the |
previously decoded I or P frame as the backward_reference_frame */ |
current_frame[cc] = backward_reference_frame[cc]; |
} |
/* IMPLEMENTATION: |
one-time folding of a line offset into the pointer which stores the |
memory address of the current frame saves offsets and conditional |
branches throughout the remainder of the picture processing loop */ |
if (picture_structure==BOTTOM_FIELD) |
current_frame[cc]+= (cc==0) ? Coded_Picture_Width : Chroma_Width; |
} |
} |
/* store last frame */ |
void Output_Last_Frame_of_Sequence(Framenum) |
int Framenum; |
{ |
if (Second_Field) |
cprintf("last frame incomplete, not stored\n"); |
else |
Write_Frame(backward_reference_frame,Framenum-1); |
} |
static void frame_reorder(Bitstream_Framenum, Sequence_Framenum) |
int Bitstream_Framenum, Sequence_Framenum; |
{ |
/* tracking variables to insure proper output in spatial scalability */ |
static int Oldref_progressive_frame, Newref_progressive_frame; |
if (Sequence_Framenum!=0) |
{ |
if (picture_structure==FRAME_PICTURE || Second_Field) |
{ |
if (picture_coding_type==B_TYPE) |
Write_Frame(auxframe,Bitstream_Framenum-1); |
else |
{ |
Newref_progressive_frame = progressive_frame; |
progressive_frame = Oldref_progressive_frame; |
Write_Frame(forward_reference_frame,Bitstream_Framenum-1); |
Oldref_progressive_frame = progressive_frame = Newref_progressive_frame; |
} |
} |
#ifdef DISPLAY |
else if (Output_Type==T_X11) |
{ |
if(!Display_Progressive_Flag) |
Display_Second_Field(); |
} |
#endif |
} |
else |
Oldref_progressive_frame = progressive_frame; |
} |
/* ISO/IEC 13818-2 section 7.6 */ |
static void motion_compensation(MBA, macroblock_type, motion_type, PMV, |
motion_vertical_field_select, dmvector, stwtype, dct_type) |
int MBA; |
int macroblock_type; |
int motion_type; |
int PMV[2][2][2]; |
int motion_vertical_field_select[2][2]; |
int dmvector[2]; |
int stwtype; |
int dct_type; |
{ |
int bx, by; |
int comp; |
/* derive current macroblock position within picture */ |
/* ISO/IEC 13818-2 section 6.3.1.6 and 6.3.1.7 */ |
bx = 16*(MBA%mb_width); |
by = 16*(MBA/mb_width); |
/* motion compensation */ |
if (!(macroblock_type & MACROBLOCK_INTRA)) |
form_predictions(bx,by,macroblock_type,motion_type,PMV, |
motion_vertical_field_select,dmvector,stwtype); |
/* SCALABILITY: Data Partitioning */ |
if (base.scalable_mode==SC_DP) |
ld = &base; |
/* copy or add block data into picture */ |
for (comp=0; comp<block_count; comp++) |
{ |
/* SCALABILITY: SNR */ |
/* ISO/IEC 13818-2 section 7.8.3.4: Addition of coefficients from |
the two a layers */ |
if (Two_Streams && enhan.scalable_mode==SC_SNR) |
Sum_Block(comp); /* add SNR enhancement layer data to base layer */ |
/* MPEG-2 saturation and mismatch control */ |
/* base layer could be MPEG-1 stream, enhancement MPEG-2 SNR */ |
/* ISO/IEC 13818-2 section 7.4.3 and 7.4.4: Saturation and Mismatch control */ |
if ((Two_Streams && enhan.scalable_mode==SC_SNR) || ld->MPEG2_Flag) |
Saturate(ld->block[comp]); |
/* ISO/IEC 13818-2 section Annex A: inverse DCT */ |
if (Reference_IDCT_Flag) |
Reference_IDCT(ld->block[comp]); |
else |
Fast_IDCT(ld->block[comp]); |
/* ISO/IEC 13818-2 section 7.6.8: Adding prediction and coefficient data */ |
Add_Block(comp,bx,by,dct_type,(macroblock_type & MACROBLOCK_INTRA)==0); |
} |
} |
/* ISO/IEC 13818-2 section 7.6.6 */ |
static void skipped_macroblock(dc_dct_pred, PMV, motion_type, |
motion_vertical_field_select, stwtype, macroblock_type) |
int dc_dct_pred[3]; |
int PMV[2][2][2]; |
int *motion_type; |
int motion_vertical_field_select[2][2]; |
int *stwtype; |
int *macroblock_type; |
{ |
int comp; |
/* SCALABILITY: Data Paritioning */ |
if (base.scalable_mode==SC_DP) |
ld = &base; |
for (comp=0; comp<block_count; comp++) |
Clear_Block(comp); |
/* reset intra_dc predictors */ |
/* ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks */ |
dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0; |
/* reset motion vector predictors */ |
/* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */ |
if (picture_coding_type==P_TYPE) |
PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0; |
/* derive motion_type */ |
if (picture_structure==FRAME_PICTURE) |
*motion_type = MC_FRAME; |
else |
{ |
*motion_type = MC_FIELD; |
/* predict from field of same parity */ |
/* ISO/IEC 13818-2 section 7.6.6.1 and 7.6.6.3: P field picture and B field |
picture */ |
motion_vertical_field_select[0][0]=motion_vertical_field_select[0][1] = |
(picture_structure==BOTTOM_FIELD); |
} |
/* skipped I are spatial-only predicted, */ |
/* skipped P and B are temporal-only predicted */ |
/* ISO/IEC 13818-2 section 7.7.6: Skipped macroblocks */ |
*stwtype = (picture_coding_type==I_TYPE) ? 8 : 0; |
/* IMPLEMENTATION: clear MACROBLOCK_INTRA */ |
*macroblock_type&= ~MACROBLOCK_INTRA; |
} |
/* return==-1 means go to next picture */ |
/* the expression "start of slice" is used throughout the normative |
body of the MPEG specification */ |
static int start_of_slice(MBAmax, MBA, MBAinc, |
dc_dct_pred, PMV) |
int MBAmax; |
int *MBA; |
int *MBAinc; |
int dc_dct_pred[3]; |
int PMV[2][2][2]; |
{ |
unsigned int code; |
int slice_vert_pos_ext; |
ld = &base; |
Fault_Flag = 0; |
next_start_code(); |
code = Show_Bits(32); |
if (code<SLICE_START_CODE_MIN || code>SLICE_START_CODE_MAX) |
{ |
/* only slice headers are allowed in picture_data */ |
if (!Quiet_Flag) |
cprintf("start_of_slice(): Premature end of picture\n"); |
return(-1); /* trigger: go to next picture */ |
} |
Flush_Buffer32(); |
/* decode slice header (may change quantizer_scale) */ |
slice_vert_pos_ext = slice_header(); |
/* SCALABILITY: Data Partitioning */ |
if (base.scalable_mode==SC_DP) |
{ |
ld = &enhan; |
next_start_code(); |
code = Show_Bits(32); |
if (code<SLICE_START_CODE_MIN || code>SLICE_START_CODE_MAX) |
{ |
/* only slice headers are allowed in picture_data */ |
if (!Quiet_Flag) |
cprintf("DP: Premature end of picture\n"); |
return(-1); /* trigger: go to next picture */ |
} |
Flush_Buffer32(); |
/* decode slice header (may change quantizer_scale) */ |
slice_vert_pos_ext = slice_header(); |
if (base.priority_breakpoint!=1) |
ld = &base; |
} |
/* decode macroblock address increment */ |
*MBAinc = Get_macroblock_address_increment(); |
if (Fault_Flag) |
{ |
cprintf("start_of_slice(): MBAinc unsuccessful\n"); |
return(0); /* trigger: go to next slice */ |
} |
/* set current location */ |
/* NOTE: the arithmetic used to derive macroblock_address below is |
* equivalent to ISO/IEC 13818-2 section 6.3.17: Macroblock |
*/ |
*MBA = ((slice_vert_pos_ext<<7) + (code&255) - 1)*mb_width + *MBAinc - 1; |
*MBAinc = 1; /* first macroblock in slice: not skipped */ |
/* reset all DC coefficient and motion vector predictors */ |
/* reset all DC coefficient and motion vector predictors */ |
/* ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks */ |
dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0; |
/* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */ |
PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0; |
PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0; |
/* successfull: trigger decode macroblocks in slice */ |
return(1); |
} |
/* ISO/IEC 13818-2 sections 7.2 through 7.5 */ |
static int decode_macroblock(macroblock_type, stwtype, stwclass, |
motion_type, dct_type, PMV, dc_dct_pred, |
motion_vertical_field_select, dmvector) |
int *macroblock_type; |
int *stwtype; |
int *stwclass; |
int *motion_type; |
int *dct_type; |
int PMV[2][2][2]; |
int dc_dct_pred[3]; |
int motion_vertical_field_select[2][2]; |
int dmvector[2]; |
{ |
/* locals */ |
int quantizer_scale_code; |
int comp; |
int motion_vector_count; |
int mv_format; |
int dmv; |
int mvscale; |
int coded_block_pattern; |
/* SCALABILITY: Data Patitioning */ |
if (base.scalable_mode==SC_DP) |
{ |
if (base.priority_breakpoint<=2) |
ld = &enhan; |
else |
ld = &base; |
} |
/* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes */ |
macroblock_modes(macroblock_type, stwtype, stwclass, |
motion_type, &motion_vector_count, &mv_format, &dmv, &mvscale, |
dct_type); |
if (Fault_Flag) return(0); /* trigger: go to next slice */ |
if (*macroblock_type & MACROBLOCK_QUANT) |
{ |
quantizer_scale_code = Get_Bits(5); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
cprintf("quantiser_scale_code ("); |
Print_Bits(quantizer_scale_code,5,5); |
cprintf("): %d\n",quantizer_scale_code); |
} |
#endif /* TRACE */ |
/* ISO/IEC 13818-2 section 7.4.2.2: Quantizer scale factor */ |
if (ld->MPEG2_Flag) |
ld->quantizer_scale = |
ld->q_scale_type ? Non_Linear_quantizer_scale[quantizer_scale_code] |
: (quantizer_scale_code << 1); |
else |
ld->quantizer_scale = quantizer_scale_code; |
/* SCALABILITY: Data Partitioning */ |
if (base.scalable_mode==SC_DP) |
/* make sure base.quantizer_scale is valid */ |
base.quantizer_scale = ld->quantizer_scale; |
} |
/* motion vectors */ |
/* ISO/IEC 13818-2 section 6.3.17.2: Motion vectors */ |
/* decode forward motion vectors */ |
if ((*macroblock_type & MACROBLOCK_MOTION_FORWARD) |
|| ((*macroblock_type & MACROBLOCK_INTRA) |
&& concealment_motion_vectors)) |
{ |
if (ld->MPEG2_Flag) |
motion_vectors(PMV,dmvector,motion_vertical_field_select, |
0,motion_vector_count,mv_format,f_code[0][0]-1,f_code[0][1]-1, |
dmv,mvscale); |
else |
motion_vector(PMV[0][0],dmvector, |
forward_f_code-1,forward_f_code-1,0,0,full_pel_forward_vector); |
} |
if (Fault_Flag) return(0); /* trigger: go to next slice */ |
/* decode backward motion vectors */ |
if (*macroblock_type & MACROBLOCK_MOTION_BACKWARD) |
{ |
if (ld->MPEG2_Flag) |
motion_vectors(PMV,dmvector,motion_vertical_field_select, |
1,motion_vector_count,mv_format,f_code[1][0]-1,f_code[1][1]-1,0, |
mvscale); |
else |
motion_vector(PMV[0][1],dmvector, |
backward_f_code-1,backward_f_code-1,0,0,full_pel_backward_vector); |
} |
if (Fault_Flag) return(0); /* trigger: go to next slice */ |
if ((*macroblock_type & MACROBLOCK_INTRA) && concealment_motion_vectors) |
Flush_Buffer(1); /* remove marker_bit */ |
if (base.scalable_mode==SC_DP && base.priority_breakpoint==3) |
ld = &enhan; |
/* macroblock_pattern */ |
/* ISO/IEC 13818-2 section 6.3.17.4: Coded block pattern */ |
if (*macroblock_type & MACROBLOCK_PATTERN) |
{ |
coded_block_pattern = Get_coded_block_pattern(); |
if (chroma_format==CHROMA422) |
{ |
/* coded_block_pattern_1 */ |
coded_block_pattern = (coded_block_pattern<<2) | Get_Bits(2); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
cprintf("coded_block_pattern_1: "); |
Print_Bits(coded_block_pattern,2,2); |
cprintf(" (%d)\n",coded_block_pattern&3); |
} |
#endif /* TRACE */ |
} |
else if (chroma_format==CHROMA444) |
{ |
/* coded_block_pattern_2 */ |
coded_block_pattern = (coded_block_pattern<<6) | Get_Bits(6); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
cprintf("coded_block_pattern_2: "); |
Print_Bits(coded_block_pattern,6,6); |
cprintf(" (%d)\n",coded_block_pattern&63); |
} |
#endif /* TRACE */ |
} |
} |
else |
coded_block_pattern = (*macroblock_type & MACROBLOCK_INTRA) ? |
(1<<block_count)-1 : 0; |
if (Fault_Flag) return(0); /* trigger: go to next slice */ |
/* decode blocks */ |
for (comp=0; comp<block_count; comp++) |
{ |
/* SCALABILITY: Data Partitioning */ |
if (base.scalable_mode==SC_DP) |
ld = &base; |
Clear_Block(comp); |
if (coded_block_pattern & (1<<(block_count-1-comp))) |
{ |
if (*macroblock_type & MACROBLOCK_INTRA) |
{ |
if (ld->MPEG2_Flag) |
Decode_MPEG2_Intra_Block(comp,dc_dct_pred); |
else |
Decode_MPEG1_Intra_Block(comp,dc_dct_pred); |
} |
else |
{ |
if (ld->MPEG2_Flag) |
Decode_MPEG2_Non_Intra_Block(comp); |
else |
Decode_MPEG1_Non_Intra_Block(comp); |
} |
if (Fault_Flag) return(0); /* trigger: go to next slice */ |
} |
} |
if(picture_coding_type==D_TYPE) |
{ |
/* remove end_of_macroblock (always 1, prevents startcode emulation) */ |
/* ISO/IEC 11172-2 section 2.4.2.7 and 2.4.3.6 */ |
marker_bit("D picture end_of_macroblock bit"); |
} |
/* reset intra_dc predictors */ |
/* ISO/IEC 13818-2 section 7.2.1: DC coefficients in intra blocks */ |
if (!(*macroblock_type & MACROBLOCK_INTRA)) |
dc_dct_pred[0]=dc_dct_pred[1]=dc_dct_pred[2]=0; |
/* reset motion vector predictors */ |
if ((*macroblock_type & MACROBLOCK_INTRA) && !concealment_motion_vectors) |
{ |
/* intra mb without concealment motion vectors */ |
/* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */ |
PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0; |
PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0; |
} |
/* special "No_MC" macroblock_type case */ |
/* ISO/IEC 13818-2 section 7.6.3.5: Prediction in P pictures */ |
if ((picture_coding_type==P_TYPE) |
&& !(*macroblock_type & (MACROBLOCK_MOTION_FORWARD|MACROBLOCK_INTRA))) |
{ |
/* non-intra mb without forward mv in a P picture */ |
/* ISO/IEC 13818-2 section 7.6.3.4: Resetting motion vector predictors */ |
PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0; |
/* derive motion_type */ |
/* ISO/IEC 13818-2 section 6.3.17.1: Macroblock modes, frame_motion_type */ |
if (picture_structure==FRAME_PICTURE) |
*motion_type = MC_FRAME; |
else |
{ |
*motion_type = MC_FIELD; |
/* predict from field of same parity */ |
motion_vertical_field_select[0][0] = (picture_structure==BOTTOM_FIELD); |
} |
} |
if (*stwclass==4) |
{ |
/* purely spatially predicted macroblock */ |
/* ISO/IEC 13818-2 section 7.7.5.1: Resetting motion vector predictions */ |
PMV[0][0][0]=PMV[0][0][1]=PMV[1][0][0]=PMV[1][0][1]=0; |
PMV[0][1][0]=PMV[0][1][1]=PMV[1][1][0]=PMV[1][1][1]=0; |
} |
/* successfully decoded macroblock */ |
return(1); |
} /* decode_macroblock */ |
/unsupported/trunk/first-official/mpeg2/gvideo.c |
---|
0,0 → 1,50 |
/* |
* Project: S.Ha.R.K. |
* |
* Coordinators: |
* Giorgio Buttazzo <giorgio@sssup.it> |
* Paolo Gai <pj@gandalf.sssup.it> |
* |
* Authors : |
* Paolo Gai <pj@gandalf.sssup.it> |
* (see the web pages for full authors list) |
* |
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy) |
* |
* http://www.sssup.it |
* http://retis.sssup.it |
* http://shark.sssup.it |
*/ |
#include "drivers/glib.h" |
#include "fsf.h" |
#include "config.h" |
#include "global.h" |
extern void *start_file; |
extern void *end_file; |
int Init_Mpeg_Decoder(void *start,void *end); |
int Decode_Bitstream(); |
void *mpeg2decoder(void *arg) |
{ |
int init = 1; |
Init_Mpeg_Decoder(start_file,end_file); |
while(1) { |
if (init == 1) { |
Decode_Bitstream(); |
} |
} |
return 0; |
} |
/unsupported/trunk/first-official/mpeg2/gethdr.c |
---|
0,0 → 1,1074 |
/* gethdr.c, header decoding */ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
#include "config.h" |
#include "global.h" |
/* private prototypes */ |
static void sequence_header _ANSI_ARGS_((void)); |
static void group_of_pictures_header _ANSI_ARGS_((void)); |
static void picture_header _ANSI_ARGS_((void)); |
static void extension_and_user_data _ANSI_ARGS_((void)); |
static void sequence_extension _ANSI_ARGS_((void)); |
static void sequence_display_extension _ANSI_ARGS_((void)); |
static void quant_matrix_extension _ANSI_ARGS_((void)); |
static void sequence_scalable_extension _ANSI_ARGS_((void)); |
static void picture_display_extension _ANSI_ARGS_((void)); |
static void picture_coding_extension _ANSI_ARGS_((void)); |
static void picture_spatial_scalable_extension _ANSI_ARGS_((void)); |
static void picture_temporal_scalable_extension _ANSI_ARGS_((void)); |
static int extra_bit_information _ANSI_ARGS_((void)); |
static void copyright_extension _ANSI_ARGS_((void)); |
static void user_data _ANSI_ARGS_((void)); |
static void user_data _ANSI_ARGS_((void)); |
/* introduced in September 1995 to assist spatial scalable decoding */ |
static void Update_Temporal_Reference_Tacking_Data _ANSI_ARGS_((void)); |
/* private variables */ |
static int Temporal_Reference_Base = 0; |
static int True_Framenum_max = -1; |
static int Temporal_Reference_GOP_Reset = 0; |
#define RESERVED -1 |
static double frame_rate_Table[16] = |
{ |
0.0, |
((23.0*1000.0)/1001.0), |
24.0, |
25.0, |
((30.0*1000.0)/1001.0), |
30.0, |
50.0, |
((60.0*1000.0)/1001.0), |
60.0, |
RESERVED, |
RESERVED, |
RESERVED, |
RESERVED, |
RESERVED, |
RESERVED, |
RESERVED |
}; |
/* |
* decode headers from one input stream |
* until an End of Sequence or picture start code |
* is found |
*/ |
int Get_Hdr() |
{ |
unsigned int code; |
for (;;) |
{ |
/* look for next_start_code */ |
next_start_code(); |
code = Get_Bits32(); |
switch (code) |
{ |
case SEQUENCE_HEADER_CODE: |
sequence_header(); |
break; |
case GROUP_START_CODE: |
group_of_pictures_header(); |
break; |
case PICTURE_START_CODE: |
picture_header(); |
return 1; |
break; |
case SEQUENCE_END_CODE: |
return 0; |
break; |
default: |
if (!Quiet_Flag) |
cprintf("Unexpected next_start_code %08x (ignored)\n",code); |
break; |
} |
} |
} |
/* align to start of next next_start_code */ |
void next_start_code() |
{ |
/* byte align */ |
Flush_Buffer(ld->Incnt&7); |
while (Show_Bits(24)!=0x01L) |
Flush_Buffer(8); |
} |
/* decode sequence header */ |
static void sequence_header() |
{ |
int i; |
int pos; |
pos = ld->Bitcnt; |
horizontal_size = Get_Bits(12); |
vertical_size = Get_Bits(12); |
aspect_ratio_information = Get_Bits(4); |
frame_rate_code = Get_Bits(4); |
bit_rate_value = Get_Bits(18); |
marker_bit("sequence_header()"); |
vbv_buffer_size = Get_Bits(10); |
constrained_parameters_flag = Get_Bits(1); |
if((ld->load_intra_quantizer_matrix = Get_Bits(1))) |
{ |
for (i=0; i<64; i++) |
ld->intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8); |
} |
else |
{ |
for (i=0; i<64; i++) |
ld->intra_quantizer_matrix[i] = default_intra_quantizer_matrix[i]; |
} |
if((ld->load_non_intra_quantizer_matrix = Get_Bits(1))) |
{ |
for (i=0; i<64; i++) |
ld->non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8); |
} |
else |
{ |
for (i=0; i<64; i++) |
ld->non_intra_quantizer_matrix[i] = 16; |
} |
/* copy luminance to chrominance matrices */ |
for (i=0; i<64; i++) |
{ |
ld->chroma_intra_quantizer_matrix[i] = |
ld->intra_quantizer_matrix[i]; |
ld->chroma_non_intra_quantizer_matrix[i] = |
ld->non_intra_quantizer_matrix[i]; |
} |
#ifdef VERBOSE |
if (Verbose_Flag > NO_LAYER) |
{ |
cprintf("sequence header (byte %d)\n",(pos>>3)-4); |
if (Verbose_Flag > SEQUENCE_LAYER) |
{ |
cprintf(" horizontal_size=%d\n",horizontal_size); |
cprintf(" vertical_size=%d\n",vertical_size); |
cprintf(" aspect_ratio_information=%d\n",aspect_ratio_information); |
cprintf(" frame_rate_code=%d",frame_rate_code); |
cprintf(" bit_rate_value=%d\n",bit_rate_value); |
cprintf(" vbv_buffer_size=%d\n",vbv_buffer_size); |
cprintf(" constrained_parameters_flag=%d\n",constrained_parameters_flag); |
cprintf(" load_intra_quantizer_matrix=%d\n",ld->load_intra_quantizer_matrix); |
cprintf(" load_non_intra_quantizer_matrix=%d\n",ld->load_non_intra_quantizer_matrix); |
} |
} |
#endif /* VERBOSE */ |
#ifdef VERIFY |
verify_sequence_header++; |
#endif /* VERIFY */ |
extension_and_user_data(); |
} |
/* decode group of pictures header */ |
/* ISO/IEC 13818-2 section 6.2.2.6 */ |
static void group_of_pictures_header() |
{ |
int pos; |
if (ld == &base) |
{ |
Temporal_Reference_Base = True_Framenum_max + 1; /* *CH* */ |
Temporal_Reference_GOP_Reset = 1; |
} |
pos = ld->Bitcnt; |
drop_flag = Get_Bits(1); |
hour = Get_Bits(5); |
minute = Get_Bits(6); |
marker_bit("group_of_pictures_header()"); |
sec = Get_Bits(6); |
frame = Get_Bits(6); |
closed_gop = Get_Bits(1); |
broken_link = Get_Bits(1); |
#ifdef VERBOSE |
if (Verbose_Flag > NO_LAYER) |
{ |
cprintf("group of pictures (byte %d)\n",(pos>>3)-4); |
if (Verbose_Flag > SEQUENCE_LAYER) |
{ |
cprintf(" drop_flag=%d\n",drop_flag); |
cprintf(" timecode %d:%02d:%02d:%02d\n",hour,minute,sec,frame); |
cprintf(" closed_gop=%d\n",closed_gop); |
cprintf(" broken_link=%d\n",broken_link); |
} |
} |
#endif /* VERBOSE */ |
#ifdef VERIFY |
verify_group_of_pictures_header++; |
#endif /* VERIFY */ |
extension_and_user_data(); |
} |
/* decode picture header */ |
/* ISO/IEC 13818-2 section 6.2.3 */ |
static void picture_header() |
{ |
int pos; |
int Extra_Information_Byte_Count; |
/* unless later overwritten by picture_spatial_scalable_extension() */ |
ld->pict_scal = 0; |
pos = ld->Bitcnt; |
temporal_reference = Get_Bits(10); |
picture_coding_type = Get_Bits(3); |
vbv_delay = Get_Bits(16); |
if (picture_coding_type==P_TYPE || picture_coding_type==B_TYPE) |
{ |
full_pel_forward_vector = Get_Bits(1); |
forward_f_code = Get_Bits(3); |
} |
if (picture_coding_type==B_TYPE) |
{ |
full_pel_backward_vector = Get_Bits(1); |
backward_f_code = Get_Bits(3); |
} |
#ifdef VERBOSE |
if (Verbose_Flag>NO_LAYER) |
{ |
cprintf("picture header (byte %d)\n",(pos>>3)-4); |
if (Verbose_Flag>SEQUENCE_LAYER) |
{ |
cprintf(" temporal_reference=%d\n",temporal_reference); |
cprintf(" picture_coding_type=%d\n",picture_coding_type); |
cprintf(" vbv_delay=%d\n",vbv_delay); |
if (picture_coding_type==P_TYPE || picture_coding_type==B_TYPE) |
{ |
cprintf(" full_pel_forward_vector=%d\n",full_pel_forward_vector); |
cprintf(" forward_f_code =%d\n",forward_f_code); |
} |
if (picture_coding_type==B_TYPE) |
{ |
cprintf(" full_pel_backward_vector=%d\n",full_pel_backward_vector); |
cprintf(" backward_f_code =%d\n",backward_f_code); |
} |
} |
} |
#endif /* VERBOSE */ |
#ifdef VERIFY |
verify_picture_header++; |
#endif /* VERIFY */ |
Extra_Information_Byte_Count = |
extra_bit_information(); |
extension_and_user_data(); |
/* update tracking information used to assist spatial scalability */ |
Update_Temporal_Reference_Tacking_Data(); |
} |
/* decode slice header */ |
/* ISO/IEC 13818-2 section 6.2.4 */ |
int slice_header() |
{ |
int slice_vertical_position_extension; |
int quantizer_scale_code; |
int pos; |
int slice_picture_id_enable = 0; |
int slice_picture_id = 0; |
int extra_information_slice = 0; |
pos = ld->Bitcnt; |
slice_vertical_position_extension = |
(ld->MPEG2_Flag && vertical_size>2800) ? Get_Bits(3) : 0; |
if (ld->scalable_mode==SC_DP) |
ld->priority_breakpoint = Get_Bits(7); |
quantizer_scale_code = Get_Bits(5); |
ld->quantizer_scale = |
ld->MPEG2_Flag ? (ld->q_scale_type ? Non_Linear_quantizer_scale[quantizer_scale_code] : quantizer_scale_code<<1) : quantizer_scale_code; |
/* slice_id introduced in March 1995 as part of the video corridendum |
(after the IS was drafted in November 1994) */ |
if (Get_Bits(1)) |
{ |
ld->intra_slice = Get_Bits(1); |
slice_picture_id_enable = Get_Bits(1); |
slice_picture_id = Get_Bits(6); |
extra_information_slice = extra_bit_information(); |
} |
else |
ld->intra_slice = 0; |
#ifdef VERBOSE |
if (Verbose_Flag>PICTURE_LAYER) |
{ |
cprintf("slice header (byte %d)\n",(pos>>3)-4); |
if (Verbose_Flag>SLICE_LAYER) |
{ |
if (ld->MPEG2_Flag && vertical_size>2800) |
cprintf(" slice_vertical_position_extension=%d\n",slice_vertical_position_extension); |
if (ld->scalable_mode==SC_DP) |
cprintf(" priority_breakpoint=%d\n",ld->priority_breakpoint); |
cprintf(" quantizer_scale_code=%d\n",quantizer_scale_code); |
cprintf(" slice_picture_id_enable = %d\n", slice_picture_id_enable); |
if(slice_picture_id_enable) |
cprintf(" slice_picture_id = %d\n", slice_picture_id); |
} |
} |
#endif /* VERBOSE */ |
#ifdef VERIFY |
verify_slice_header++; |
#endif /* VERIFY */ |
return slice_vertical_position_extension; |
} |
/* decode extension and user data */ |
/* ISO/IEC 13818-2 section 6.2.2.2 */ |
static void extension_and_user_data() |
{ |
int code,ext_ID; |
next_start_code(); |
while ((code = Show_Bits(32))==EXTENSION_START_CODE || code==USER_DATA_START_CODE) |
{ |
if (code==EXTENSION_START_CODE) |
{ |
Flush_Buffer32(); |
ext_ID = Get_Bits(4); |
switch (ext_ID) |
{ |
case SEQUENCE_EXTENSION_ID: |
sequence_extension(); |
break; |
case SEQUENCE_DISPLAY_EXTENSION_ID: |
sequence_display_extension(); |
break; |
case QUANT_MATRIX_EXTENSION_ID: |
quant_matrix_extension(); |
break; |
case SEQUENCE_SCALABLE_EXTENSION_ID: |
sequence_scalable_extension(); |
break; |
case PICTURE_DISPLAY_EXTENSION_ID: |
picture_display_extension(); |
break; |
case PICTURE_CODING_EXTENSION_ID: |
picture_coding_extension(); |
break; |
case PICTURE_SPATIAL_SCALABLE_EXTENSION_ID: |
picture_spatial_scalable_extension(); |
break; |
case PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID: |
picture_temporal_scalable_extension(); |
break; |
case COPYRIGHT_EXTENSION_ID: |
copyright_extension(); |
break; |
default: |
cprintf("reserved extension start code ID %d\n",ext_ID); |
break; |
} |
next_start_code(); |
} |
else |
{ |
#ifdef VERBOSE |
if (Verbose_Flag>NO_LAYER) |
cprintf("user data\n"); |
#endif /* VERBOSE */ |
Flush_Buffer32(); |
user_data(); |
} |
} |
} |
/* decode sequence extension */ |
/* ISO/IEC 13818-2 section 6.2.2.3 */ |
static void sequence_extension() |
{ |
int horizontal_size_extension; |
int vertical_size_extension; |
int bit_rate_extension; |
int vbv_buffer_size_extension; |
/* derive bit position for trace */ |
#ifdef VERBOSE |
pos = ld->Bitcnt; |
#endif |
ld->MPEG2_Flag = 1; |
ld->scalable_mode = SC_NONE; /* unless overwritten by sequence_scalable_extension() */ |
layer_id = 0; /* unless overwritten by sequence_scalable_extension() */ |
profile_and_level_indication = Get_Bits(8); |
progressive_sequence = Get_Bits(1); |
chroma_format = Get_Bits(2); |
horizontal_size_extension = Get_Bits(2); |
vertical_size_extension = Get_Bits(2); |
bit_rate_extension = Get_Bits(12); |
marker_bit("sequence_extension"); |
vbv_buffer_size_extension = Get_Bits(8); |
low_delay = Get_Bits(1); |
frame_rate_extension_n = Get_Bits(2); |
frame_rate_extension_d = Get_Bits(5); |
frame_rate = frame_rate_Table[frame_rate_code] * |
((frame_rate_extension_n+1)/(frame_rate_extension_d+1)); |
/* special case for 422 profile & level must be made */ |
if((profile_and_level_indication>>7) & 1) |
{ /* escape bit of profile_and_level_indication set */ |
/* 4:2:2 Profile @ Main Level */ |
if((profile_and_level_indication&15)==5) |
{ |
profile = PROFILE_422; |
level = MAIN_LEVEL; |
} |
} |
else |
{ |
profile = profile_and_level_indication >> 4; /* Profile is upper nibble */ |
level = profile_and_level_indication & 0xF; /* Level is lower nibble */ |
} |
horizontal_size = (horizontal_size_extension<<12) | (horizontal_size&0x0fff); |
vertical_size = (vertical_size_extension<<12) | (vertical_size&0x0fff); |
/* ISO/IEC 13818-2 does not define bit_rate_value to be composed of |
* both the original bit_rate_value parsed in sequence_header() and |
* the optional bit_rate_extension in sequence_extension_header(). |
* However, we use it for bitstream verification purposes. |
*/ |
bit_rate_value += (bit_rate_extension << 18); |
bit_rate = ((double) bit_rate_value) * 400.0; |
vbv_buffer_size += (vbv_buffer_size_extension << 10); |
#ifdef VERBOSE |
if (Verbose_Flag>NO_LAYER) |
{ |
cprintf("sequence extension (byte %d)\n",(pos>>3)-4); |
if (Verbose_Flag>SEQUENCE_LAYER) |
{ |
cprintf(" profile_and_level_indication=%d\n",profile_and_level_indication); |
if (profile_and_level_indication<128) |
{ |
cprintf(" profile=%d, level=%d\n",profile,level); |
} |
cprintf(" progressive_sequence=%d\n",progressive_sequence); |
cprintf(" chroma_format=%d\n",chroma_format); |
cprintf(" horizontal_size_extension=%d\n",horizontal_size_extension); |
cprintf(" vertical_size_extension=%d\n",vertical_size_extension); |
cprintf(" bit_rate_extension=%d\n",bit_rate_extension); |
cprintf(" vbv_buffer_size_extension=%d\n",vbv_buffer_size_extension); |
cprintf(" low_delay=%d\n",low_delay); |
cprintf(" frame_rate_extension_n=%d\n",frame_rate_extension_n); |
cprintf(" frame_rate_extension_d=%d\n",frame_rate_extension_d); |
} |
} |
#endif /* VERBOSE */ |
#ifdef VERIFY |
verify_sequence_extension++; |
#endif /* VERIFY */ |
} |
/* decode sequence display extension */ |
static void sequence_display_extension() |
{ |
int pos; |
pos = ld->Bitcnt; |
video_format = Get_Bits(3); |
color_description = Get_Bits(1); |
if (color_description) |
{ |
color_primaries = Get_Bits(8); |
transfer_characteristics = Get_Bits(8); |
matrix_coefficients = Get_Bits(8); |
} |
display_horizontal_size = Get_Bits(14); |
marker_bit("sequence_display_extension"); |
display_vertical_size = Get_Bits(14); |
#ifdef VERBOSE |
if (Verbose_Flag>NO_LAYER) |
{ |
cprintf("sequence display extension (byte %d)\n",(pos>>3)-4); |
if (Verbose_Flag>SEQUENCE_LAYER) |
{ |
cprintf(" video_format=%d\n",video_format); |
cprintf(" color_description=%d\n",color_description); |
if (color_description) |
{ |
cprintf(" color_primaries=%d\n",color_primaries); |
cprintf(" transfer_characteristics=%d\n",transfer_characteristics); |
cprintf(" matrix_coefficients=%d\n",matrix_coefficients); |
} |
cprintf(" display_horizontal_size=%d\n",display_horizontal_size); |
cprintf(" display_vertical_size=%d\n",display_vertical_size); |
} |
} |
#endif /* VERBOSE */ |
#ifdef VERIFY |
verify_sequence_display_extension++; |
#endif /* VERIFY */ |
} |
/* decode quant matrix entension */ |
/* ISO/IEC 13818-2 section 6.2.3.2 */ |
static void quant_matrix_extension() |
{ |
int i; |
int pos; |
pos = ld->Bitcnt; |
if((ld->load_intra_quantizer_matrix = Get_Bits(1))) |
{ |
for (i=0; i<64; i++) |
{ |
ld->chroma_intra_quantizer_matrix[scan[ZIG_ZAG][i]] |
= ld->intra_quantizer_matrix[scan[ZIG_ZAG][i]] |
= Get_Bits(8); |
} |
} |
if((ld->load_non_intra_quantizer_matrix = Get_Bits(1))) |
{ |
for (i=0; i<64; i++) |
{ |
ld->chroma_non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] |
= ld->non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] |
= Get_Bits(8); |
} |
} |
if((ld->load_chroma_intra_quantizer_matrix = Get_Bits(1))) |
{ |
for (i=0; i<64; i++) |
ld->chroma_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8); |
} |
if((ld->load_chroma_non_intra_quantizer_matrix = Get_Bits(1))) |
{ |
for (i=0; i<64; i++) |
ld->chroma_non_intra_quantizer_matrix[scan[ZIG_ZAG][i]] = Get_Bits(8); |
} |
#ifdef VERBOSE |
if (Verbose_Flag>NO_LAYER) |
{ |
cprintf("quant matrix extension (byte %d)\n",(pos>>3)-4); |
cprintf(" load_intra_quantizer_matrix=%d\n", |
ld->load_intra_quantizer_matrix); |
cprintf(" load_non_intra_quantizer_matrix=%d\n", |
ld->load_non_intra_quantizer_matrix); |
cprintf(" load_chroma_intra_quantizer_matrix=%d\n", |
ld->load_chroma_intra_quantizer_matrix); |
cprintf(" load_chroma_non_intra_quantizer_matrix=%d\n", |
ld->load_chroma_non_intra_quantizer_matrix); |
} |
#endif /* VERBOSE */ |
#ifdef VERIFY |
verify_quant_matrix_extension++; |
#endif /* VERIFY */ |
} |
/* decode sequence scalable extension */ |
/* ISO/IEC 13818-2 section 6.2.2.5 */ |
static void sequence_scalable_extension() |
{ |
int pos; |
pos = ld->Bitcnt; |
/* values (without the +1 offset) of scalable_mode are defined in |
Table 6-10 of ISO/IEC 13818-2 */ |
ld->scalable_mode = Get_Bits(2) + 1; /* add 1 to make SC_DP != SC_NONE */ |
layer_id = Get_Bits(4); |
if (ld->scalable_mode==SC_SPAT) |
{ |
lower_layer_prediction_horizontal_size = Get_Bits(14); |
marker_bit("sequence_scalable_extension()"); |
lower_layer_prediction_vertical_size = Get_Bits(14); |
horizontal_subsampling_factor_m = Get_Bits(5); |
horizontal_subsampling_factor_n = Get_Bits(5); |
vertical_subsampling_factor_m = Get_Bits(5); |
vertical_subsampling_factor_n = Get_Bits(5); |
} |
if (ld->scalable_mode==SC_TEMP) |
Error("temporal scalability not implemented\n"); |
#ifdef VERBOSE |
if (Verbose_Flag>NO_LAYER) |
{ |
cprintf("sequence scalable extension (byte %d)\n",(pos>>3)-4); |
if (Verbose_Flag>SEQUENCE_LAYER) |
{ |
cprintf(" scalable_mode=%d\n",ld->scalable_mode-1); |
cprintf(" layer_id=%d\n",layer_id); |
if (ld->scalable_mode==SC_SPAT) |
{ |
cprintf(" lower_layer_prediction_horiontal_size=%d\n", |
lower_layer_prediction_horizontal_size); |
cprintf(" lower_layer_prediction_vertical_size=%d\n", |
lower_layer_prediction_vertical_size); |
cprintf(" horizontal_subsampling_factor_m=%d\n", |
horizontal_subsampling_factor_m); |
cprintf(" horizontal_subsampling_factor_n=%d\n", |
horizontal_subsampling_factor_n); |
cprintf(" vertical_subsampling_factor_m=%d\n", |
vertical_subsampling_factor_m); |
cprintf(" vertical_subsampling_factor_n=%d\n", |
vertical_subsampling_factor_n); |
} |
} |
} |
#endif /* VERBOSE */ |
#ifdef VERIFY |
verify_sequence_scalable_extension++; |
#endif /* VERIFY */ |
} |
/* decode picture display extension */ |
/* ISO/IEC 13818-2 section 6.2.3.3. */ |
static void picture_display_extension() |
{ |
int i; |
int number_of_frame_center_offsets; |
int pos; |
pos = ld->Bitcnt; |
/* based on ISO/IEC 13818-2 section 6.3.12 |
(November 1994) Picture display extensions */ |
/* derive number_of_frame_center_offsets */ |
if(progressive_sequence) |
{ |
if(repeat_first_field) |
{ |
if(top_field_first) |
number_of_frame_center_offsets = 3; |
else |
number_of_frame_center_offsets = 2; |
} |
else |
{ |
number_of_frame_center_offsets = 1; |
} |
} |
else |
{ |
if(picture_structure!=FRAME_PICTURE) |
{ |
number_of_frame_center_offsets = 1; |
} |
else |
{ |
if(repeat_first_field) |
number_of_frame_center_offsets = 3; |
else |
number_of_frame_center_offsets = 2; |
} |
} |
/* now parse */ |
for (i=0; i<number_of_frame_center_offsets; i++) |
{ |
frame_center_horizontal_offset[i] = Get_Bits(16); |
marker_bit("picture_display_extension, first marker bit"); |
frame_center_vertical_offset[i] = Get_Bits(16); |
marker_bit("picture_display_extension, second marker bit"); |
} |
#ifdef VERBOSE |
if (Verbose_Flag>NO_LAYER) |
{ |
cprintf("picture display extension (byte %d)\n",(pos>>3)-4); |
if (Verbose_Flag>SEQUENCE_LAYER) |
{ |
for (i=0; i<number_of_frame_center_offsets; i++) |
{ |
cprintf(" frame_center_horizontal_offset[%d]=%d\n",i, |
frame_center_horizontal_offset[i]); |
cprintf(" frame_center_vertical_offset[%d]=%d\n",i, |
frame_center_vertical_offset[i]); |
} |
} |
} |
#endif /* VERBOSE */ |
#ifdef VERIFY |
verify_picture_display_extension++; |
#endif /* VERIFY */ |
} |
/* decode picture coding extension */ |
static void picture_coding_extension() |
{ |
int pos; |
pos = ld->Bitcnt; |
f_code[0][0] = Get_Bits(4); |
f_code[0][1] = Get_Bits(4); |
f_code[1][0] = Get_Bits(4); |
f_code[1][1] = Get_Bits(4); |
intra_dc_precision = Get_Bits(2); |
picture_structure = Get_Bits(2); |
top_field_first = Get_Bits(1); |
frame_pred_frame_dct = Get_Bits(1); |
concealment_motion_vectors = Get_Bits(1); |
ld->q_scale_type = Get_Bits(1); |
intra_vlc_format = Get_Bits(1); |
ld->alternate_scan = Get_Bits(1); |
repeat_first_field = Get_Bits(1); |
chroma_420_type = Get_Bits(1); |
progressive_frame = Get_Bits(1); |
composite_display_flag = Get_Bits(1); |
if (composite_display_flag) |
{ |
v_axis = Get_Bits(1); |
field_sequence = Get_Bits(3); |
sub_carrier = Get_Bits(1); |
burst_amplitude = Get_Bits(7); |
sub_carrier_phase = Get_Bits(8); |
} |
#ifdef VERBOSE |
if (Verbose_Flag>NO_LAYER) |
{ |
cprintf("picture coding extension (byte %d)\n",(pos>>3)-4); |
if (Verbose_Flag>SEQUENCE_LAYER) |
{ |
cprintf(" forward horizontal f_code=%d\n", f_code[0][0]); |
cprintf(" forward vertical f_code=%d\n", f_code[0][1]); |
cprintf(" backward horizontal f_code=%d\n", f_code[1][0]); |
cprintf(" backward_vertical f_code=%d\n", f_code[1][1]); |
cprintf(" intra_dc_precision=%d\n",intra_dc_precision); |
cprintf(" picture_structure=%d\n",picture_structure); |
cprintf(" top_field_first=%d\n",top_field_first); |
cprintf(" frame_pred_frame_dct=%d\n",frame_pred_frame_dct); |
cprintf(" concealment_motion_vectors=%d\n",concealment_motion_vectors); |
cprintf(" q_scale_type=%d\n",ld->q_scale_type); |
cprintf(" intra_vlc_format=%d\n",intra_vlc_format); |
cprintf(" alternate_scan=%d\n",ld->alternate_scan); |
cprintf(" repeat_first_field=%d\n",repeat_first_field); |
cprintf(" chroma_420_type=%d\n",chroma_420_type); |
cprintf(" progressive_frame=%d\n",progressive_frame); |
cprintf(" composite_display_flag=%d\n",composite_display_flag); |
if (composite_display_flag) |
{ |
cprintf(" v_axis=%d\n",v_axis); |
cprintf(" field_sequence=%d\n",field_sequence); |
cprintf(" sub_carrier=%d\n",sub_carrier); |
cprintf(" burst_amplitude=%d\n",burst_amplitude); |
cprintf(" sub_carrier_phase=%d\n",sub_carrier_phase); |
} |
} |
} |
#endif /* VERBOSE */ |
#ifdef VERIFY |
verify_picture_coding_extension++; |
#endif /* VERIFY */ |
} |
/* decode picture spatial scalable extension */ |
/* ISO/IEC 13818-2 section 6.2.3.5. */ |
static void picture_spatial_scalable_extension() |
{ |
int pos; |
pos = ld->Bitcnt; |
ld->pict_scal = 1; /* use spatial scalability in this picture */ |
lower_layer_temporal_reference = Get_Bits(10); |
marker_bit("picture_spatial_scalable_extension(), first marker bit"); |
lower_layer_horizontal_offset = Get_Bits(15); |
if (lower_layer_horizontal_offset>=16384) |
lower_layer_horizontal_offset-= 32768; |
marker_bit("picture_spatial_scalable_extension(), second marker bit"); |
lower_layer_vertical_offset = Get_Bits(15); |
if (lower_layer_vertical_offset>=16384) |
lower_layer_vertical_offset-= 32768; |
spatial_temporal_weight_code_table_index = Get_Bits(2); |
lower_layer_progressive_frame = Get_Bits(1); |
lower_layer_deinterlaced_field_select = Get_Bits(1); |
#ifdef VERBOSE |
if (Verbose_Flag>NO_LAYER) |
{ |
cprintf("picture spatial scalable extension (byte %d)\n",(pos>>3)-4); |
if (Verbose_Flag>SEQUENCE_LAYER) |
{ |
cprintf(" lower_layer_temporal_reference=%d\n",lower_layer_temporal_reference); |
cprintf(" lower_layer_horizontal_offset=%d\n",lower_layer_horizontal_offset); |
cprintf(" lower_layer_vertical_offset=%d\n",lower_layer_vertical_offset); |
cprintf(" spatial_temporal_weight_code_table_index=%d\n", |
spatial_temporal_weight_code_table_index); |
cprintf(" lower_layer_progressive_frame=%d\n",lower_layer_progressive_frame); |
cprintf(" lower_layer_deinterlaced_field_select=%d\n",lower_layer_deinterlaced_field_select); |
} |
} |
#endif /* VERBOSE */ |
#ifdef VERIFY |
verify_picture_spatial_scalable_extension++; |
#endif /* VERIFY */ |
} |
/* decode picture temporal scalable extension |
* |
* not implemented |
*/ |
/* ISO/IEC 13818-2 section 6.2.3.4. */ |
static void picture_temporal_scalable_extension() |
{ |
Error("temporal scalability not supported\n"); |
#ifdef VERIFY |
verify_picture_temporal_scalable_extension++; |
#endif /* VERIFY */ |
} |
/* decode extra bit information */ |
/* ISO/IEC 13818-2 section 6.2.3.4. */ |
static int extra_bit_information() |
{ |
int Byte_Count = 0; |
while (Get_Bits1()) |
{ |
Flush_Buffer(8); |
Byte_Count++; |
} |
return(Byte_Count); |
} |
/* ISO/IEC 13818-2 section 5.3 */ |
/* Purpose: this function is mainly designed to aid in bitstream conformance |
testing. A simple Flush_Buffer(1) would do */ |
void marker_bit(text) |
char *text; |
{ |
int marker; |
marker = Get_Bits(1); |
#ifdef VERIFY |
if(!marker) |
cprintf("ERROR: %s--marker_bit set to 0",text); |
#endif |
} |
/* ISO/IEC 13818-2 sections 6.3.4.1 and 6.2.2.2.2 */ |
static void user_data() |
{ |
/* skip ahead to the next start code */ |
next_start_code(); |
} |
/* Copyright extension */ |
/* ISO/IEC 13818-2 section 6.2.3.6. */ |
/* (header added in November, 1994 to the IS document) */ |
static void copyright_extension() |
{ |
int pos; |
int reserved_data; |
pos = ld->Bitcnt; |
copyright_flag = Get_Bits(1); |
copyright_identifier = Get_Bits(8); |
original_or_copy = Get_Bits(1); |
/* reserved */ |
reserved_data = Get_Bits(7); |
marker_bit("copyright_extension(), first marker bit"); |
copyright_number_1 = Get_Bits(20); |
marker_bit("copyright_extension(), second marker bit"); |
copyright_number_2 = Get_Bits(22); |
marker_bit("copyright_extension(), third marker bit"); |
copyright_number_3 = Get_Bits(22); |
if(Verbose_Flag>NO_LAYER) |
{ |
cprintf("copyright_extension (byte %d)\n",(pos>>3)-4); |
if (Verbose_Flag>SEQUENCE_LAYER) |
{ |
cprintf(" copyright_flag =%d\n",copyright_flag); |
cprintf(" copyright_identifier=%d\n",copyright_identifier); |
cprintf(" original_or_copy = %d (original=1, copy=0)\n", |
original_or_copy); |
cprintf(" copyright_number_1=%d\n",copyright_number_1); |
cprintf(" copyright_number_2=%d\n",copyright_number_2); |
cprintf(" copyright_number_3=%d\n",copyright_number_3); |
} |
} |
#ifdef VERIFY |
verify_copyright_extension++; |
#endif /* VERIFY */ |
} |
/* introduced in September 1995 to assist Spatial Scalability */ |
static void Update_Temporal_Reference_Tacking_Data() |
{ |
static int temporal_reference_wrap = 0; |
static int temporal_reference_old = 0; |
if (ld == &base) /* *CH* */ |
{ |
if (picture_coding_type!=B_TYPE && temporal_reference!=temporal_reference_old) |
/* check first field of */ |
{ |
/* non-B-frame */ |
if (temporal_reference_wrap) |
{/* wrap occured at previous I- or P-frame */ |
/* now all intervening B-frames which could |
still have high temporal_reference values are done */ |
Temporal_Reference_Base += 1024; |
temporal_reference_wrap = 0; |
} |
/* distinguish from a reset */ |
if (temporal_reference<temporal_reference_old && !Temporal_Reference_GOP_Reset) |
temporal_reference_wrap = 1; /* we must have just passed a GOP-Header! */ |
temporal_reference_old = temporal_reference; |
Temporal_Reference_GOP_Reset = 0; |
} |
True_Framenum = Temporal_Reference_Base + temporal_reference; |
/* temporary wrap of TR at 1024 for M frames */ |
if (temporal_reference_wrap && temporal_reference <= temporal_reference_old) |
True_Framenum += 1024; |
True_Framenum_max = (True_Framenum > True_Framenum_max) ? |
True_Framenum : True_Framenum_max; |
} |
} |
/unsupported/trunk/first-official/mpeg2/idctref.c |
---|
0,0 → 1,108 |
/* Reference_IDCT.c, Inverse Discrete Fourier Transform, double precision */ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
/* Perform IEEE 1180 reference (64-bit floating point, separable 8x1 |
* direct matrix multiply) Inverse Discrete Cosine Transform |
*/ |
/* Here we use math.h to generate constants. Compiler results may |
vary a little */ |
#include <math.h> |
#include "config.h" |
#ifndef PI |
# ifdef M_PI |
# define PI M_PI |
# else |
# define PI 3.14159265358979323846 |
# endif |
#endif |
/* global declarations */ |
void Initialize_Fast_IDCTref _ANSI_ARGS_((void)); |
void Reference_IDCT _ANSI_ARGS_((short *block)); |
/* private data */ |
/* cosine transform matrix for 8x1 IDCT */ |
static double c[8][8]; |
/* initialize DCT coefficient matrix */ |
void Initialize_Reference_IDCT() |
{ |
int freq, time; |
double scale; |
for (freq=0; freq < 8; freq++) |
{ |
scale = (freq == 0) ? sqrt(0.125) : 0.5; |
for (time=0; time<8; time++) |
c[freq][time] = scale*cos((PI/8.0)*freq*(time + 0.5)); |
} |
} |
/* perform IDCT matrix multiply for 8x8 coefficient block */ |
void Reference_IDCT(block) |
short *block; |
{ |
int i, j, k, v; |
double partial_product; |
double tmp[64]; |
for (i=0; i<8; i++) |
for (j=0; j<8; j++) |
{ |
partial_product = 0.0; |
for (k=0; k<8; k++) |
partial_product+= c[k][j]*block[8*i+k]; |
tmp[8*i+j] = partial_product; |
} |
/* Transpose operation is integrated into address mapping by switching |
loop order of i and j */ |
for (j=0; j<8; j++) |
for (i=0; i<8; i++) |
{ |
partial_product = 0.0; |
for (k=0; k<8; k++) |
partial_product+= c[k][i]*tmp[8*k+j]; |
v = (int) floor(partial_product+0.5); |
block[8*i+j] = (v<-256) ? -256 : ((v>255) ? 255 : v); |
} |
} |
/unsupported/trunk/first-official/mpeg2/idct.c |
---|
0,0 → 1,211 |
/* idct.c, inverse fast discrete cosine transform */ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
/**********************************************************/ |
/* inverse two dimensional DCT, Chen-Wang algorithm */ |
/* (cf. IEEE ASSP-32, pp. 803-816, Aug. 1984) */ |
/* 32-bit integer arithmetic (8 bit coefficients) */ |
/* 11 mults, 29 adds per DCT */ |
/* sE, 18.8.91 */ |
/**********************************************************/ |
/* coefficients extended to 12 bit for IEEE1180-1990 */ |
/* compliance sE, 2.1.94 */ |
/**********************************************************/ |
/* this code assumes >> to be a two's-complement arithmetic */ |
/* right shift: (-2)>>1 == -1 , (-3)>>1 == -2 */ |
#include "config.h" |
#define W1 2841 /* 2048*sqrt(2)*cos(1*pi/16) */ |
#define W2 2676 /* 2048*sqrt(2)*cos(2*pi/16) */ |
#define W3 2408 /* 2048*sqrt(2)*cos(3*pi/16) */ |
#define W5 1609 /* 2048*sqrt(2)*cos(5*pi/16) */ |
#define W6 1108 /* 2048*sqrt(2)*cos(6*pi/16) */ |
#define W7 565 /* 2048*sqrt(2)*cos(7*pi/16) */ |
/* global declarations */ |
void Initialize_Fast_IDCT _ANSI_ARGS_((void)); |
void Fast_IDCT _ANSI_ARGS_((short *block)); |
/* private data */ |
static short iclip[1024]; /* clipping table */ |
static short *iclp; |
/* private prototypes */ |
static void idctrow _ANSI_ARGS_((short *blk)); |
static void idctcol _ANSI_ARGS_((short *blk)); |
/* row (horizontal) IDCT |
* |
* 7 pi 1 |
* dst[k] = sum c[l] * src[l] * cos( -- * ( k + - ) * l ) |
* l=0 8 2 |
* |
* where: c[0] = 128 |
* c[1..7] = 128*sqrt(2) |
*/ |
static void idctrow(blk) |
short *blk; |
{ |
int x0, x1, x2, x3, x4, x5, x6, x7, x8; |
/* shortcut */ |
if (!((x1 = blk[4]<<11) | (x2 = blk[6]) | (x3 = blk[2]) | |
(x4 = blk[1]) | (x5 = blk[7]) | (x6 = blk[5]) | (x7 = blk[3]))) |
{ |
blk[0]=blk[1]=blk[2]=blk[3]=blk[4]=blk[5]=blk[6]=blk[7]=blk[0]<<3; |
return; |
} |
x0 = (blk[0]<<11) + 128; /* for proper rounding in the fourth stage */ |
/* first stage */ |
x8 = W7*(x4+x5); |
x4 = x8 + (W1-W7)*x4; |
x5 = x8 - (W1+W7)*x5; |
x8 = W3*(x6+x7); |
x6 = x8 - (W3-W5)*x6; |
x7 = x8 - (W3+W5)*x7; |
/* second stage */ |
x8 = x0 + x1; |
x0 -= x1; |
x1 = W6*(x3+x2); |
x2 = x1 - (W2+W6)*x2; |
x3 = x1 + (W2-W6)*x3; |
x1 = x4 + x6; |
x4 -= x6; |
x6 = x5 + x7; |
x5 -= x7; |
/* third stage */ |
x7 = x8 + x3; |
x8 -= x3; |
x3 = x0 + x2; |
x0 -= x2; |
x2 = (181*(x4+x5)+128)>>8; |
x4 = (181*(x4-x5)+128)>>8; |
/* fourth stage */ |
blk[0] = (x7+x1)>>8; |
blk[1] = (x3+x2)>>8; |
blk[2] = (x0+x4)>>8; |
blk[3] = (x8+x6)>>8; |
blk[4] = (x8-x6)>>8; |
blk[5] = (x0-x4)>>8; |
blk[6] = (x3-x2)>>8; |
blk[7] = (x7-x1)>>8; |
} |
/* column (vertical) IDCT |
* |
* 7 pi 1 |
* dst[8*k] = sum c[l] * src[8*l] * cos( -- * ( k + - ) * l ) |
* l=0 8 2 |
* |
* where: c[0] = 1/1024 |
* c[1..7] = (1/1024)*sqrt(2) |
*/ |
static void idctcol(blk) |
short *blk; |
{ |
int x0, x1, x2, x3, x4, x5, x6, x7, x8; |
/* shortcut */ |
if (!((x1 = (blk[8*4]<<8)) | (x2 = blk[8*6]) | (x3 = blk[8*2]) | |
(x4 = blk[8*1]) | (x5 = blk[8*7]) | (x6 = blk[8*5]) | (x7 = blk[8*3]))) |
{ |
blk[8*0]=blk[8*1]=blk[8*2]=blk[8*3]=blk[8*4]=blk[8*5]=blk[8*6]=blk[8*7]= |
iclp[(blk[8*0]+32)>>6]; |
return; |
} |
x0 = (blk[8*0]<<8) + 8192; |
/* first stage */ |
x8 = W7*(x4+x5) + 4; |
x4 = (x8+(W1-W7)*x4)>>3; |
x5 = (x8-(W1+W7)*x5)>>3; |
x8 = W3*(x6+x7) + 4; |
x6 = (x8-(W3-W5)*x6)>>3; |
x7 = (x8-(W3+W5)*x7)>>3; |
/* second stage */ |
x8 = x0 + x1; |
x0 -= x1; |
x1 = W6*(x3+x2) + 4; |
x2 = (x1-(W2+W6)*x2)>>3; |
x3 = (x1+(W2-W6)*x3)>>3; |
x1 = x4 + x6; |
x4 -= x6; |
x6 = x5 + x7; |
x5 -= x7; |
/* third stage */ |
x7 = x8 + x3; |
x8 -= x3; |
x3 = x0 + x2; |
x0 -= x2; |
x2 = (181*(x4+x5)+128)>>8; |
x4 = (181*(x4-x5)+128)>>8; |
/* fourth stage */ |
blk[8*0] = iclp[(x7+x1)>>14]; |
blk[8*1] = iclp[(x3+x2)>>14]; |
blk[8*2] = iclp[(x0+x4)>>14]; |
blk[8*3] = iclp[(x8+x6)>>14]; |
blk[8*4] = iclp[(x8-x6)>>14]; |
blk[8*5] = iclp[(x0-x4)>>14]; |
blk[8*6] = iclp[(x3-x2)>>14]; |
blk[8*7] = iclp[(x7-x1)>>14]; |
} |
/* two dimensional inverse discrete cosine transform */ |
void Fast_IDCT(block) |
short *block; |
{ |
int i; |
for (i=0; i<8; i++) |
idctrow(block+8*i); |
for (i=0; i<8; i++) |
idctcol(block+i); |
} |
void Initialize_Fast_IDCT() |
{ |
int i; |
iclp = iclip+512; |
for (i= -512; i<512; i++) |
iclp[i] = (i<-256) ? -256 : ((i>255) ? 255 : i); |
} |
/unsupported/trunk/first-official/mpeg2/getvlc.c |
---|
0,0 → 1,797 |
/* getvlc.c, variable length decoding */ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
#include "config.h" |
#include "global.h" |
#include "getvlc.h" |
/* private prototypes */ |
/* generic picture macroblock type processing functions */ |
static int Get_I_macroblock_type _ANSI_ARGS_((void)); |
static int Get_P_macroblock_type _ANSI_ARGS_((void)); |
static int Get_B_macroblock_type _ANSI_ARGS_((void)); |
static int Get_D_macroblock_type _ANSI_ARGS_((void)); |
/* spatial picture macroblock type processing functions */ |
static int Get_I_Spatial_macroblock_type _ANSI_ARGS_((void)); |
static int Get_P_Spatial_macroblock_type _ANSI_ARGS_((void)); |
static int Get_B_Spatial_macroblock_type _ANSI_ARGS_((void)); |
static int Get_SNR_macroblock_type _ANSI_ARGS_((void)); |
int Get_macroblock_type() |
{ |
int macroblock_type = 0; |
if (ld->scalable_mode==SC_SNR) |
macroblock_type = Get_SNR_macroblock_type(); |
else |
{ |
switch (picture_coding_type) |
{ |
case I_TYPE: |
macroblock_type = ld->pict_scal ? Get_I_Spatial_macroblock_type() : Get_I_macroblock_type(); |
break; |
case P_TYPE: |
macroblock_type = ld->pict_scal ? Get_P_Spatial_macroblock_type() : Get_P_macroblock_type(); |
break; |
case B_TYPE: |
macroblock_type = ld->pict_scal ? Get_B_Spatial_macroblock_type() : Get_B_macroblock_type(); |
break; |
case D_TYPE: |
macroblock_type = Get_D_macroblock_type(); |
break; |
default: |
cprintf("Get_macroblock_type(): unrecognized picture coding type\n"); |
break; |
} |
} |
return macroblock_type; |
} |
static int Get_I_macroblock_type() |
{ |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("macroblock_type(I) "); |
#endif /* TRACE */ |
if (Get_Bits1()) |
{ |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("(1): Intra (1)\n"); |
#endif /* TRACE */ |
return 1; |
} |
if (!Get_Bits1()) |
{ |
if (!Quiet_Flag) |
cprintf("Invalid macroblock_type code\n"); |
Fault_Flag = 1; |
} |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("(01): Intra, Quant (17)\n"); |
#endif /* TRACE */ |
return 17; |
} |
static char *MBdescr[]={ |
"", "Intra", "No MC, Coded", "", |
"Bwd, Not Coded", "", "Bwd, Coded", "", |
"Fwd, Not Coded", "", "Fwd, Coded", "", |
"Interp, Not Coded", "", "Interp, Coded", "", |
"", "Intra, Quant", "No MC, Coded, Quant", "", |
"", "", "Bwd, Coded, Quant", "", |
"", "", "Fwd, Coded, Quant", "", |
"", "", "Interp, Coded, Quant", "" |
}; |
static int Get_P_macroblock_type() |
{ |
int code; |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("macroblock_type(P) ("); |
#endif /* TRACE */ |
if ((code = Show_Bits(6))>=8) |
{ |
code >>= 3; |
Flush_Buffer(PMBtab0[code].len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
Print_Bits(code,3,PMBtab0[code].len); |
cprintf("): %s (%d)\n",MBdescr[(int)PMBtab0[code].val],PMBtab0[code].val); |
} |
#endif /* TRACE */ |
return PMBtab0[code].val; |
} |
if (code==0) |
{ |
if (!Quiet_Flag) |
cprintf("Invalid macroblock_type code\n"); |
Fault_Flag = 1; |
return 0; |
} |
Flush_Buffer(PMBtab1[code].len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
Print_Bits(code,6,PMBtab1[code].len); |
cprintf("): %s (%d)\n",MBdescr[(int)PMBtab1[code].val],PMBtab1[code].val); |
} |
#endif /* TRACE */ |
return PMBtab1[code].val; |
} |
static int Get_B_macroblock_type() |
{ |
int code; |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("macroblock_type(B) ("); |
#endif /* TRACE */ |
if ((code = Show_Bits(6))>=8) |
{ |
code >>= 2; |
Flush_Buffer(BMBtab0[code].len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
Print_Bits(code,4,BMBtab0[code].len); |
cprintf("): %s (%d)\n",MBdescr[(int)BMBtab0[code].val],BMBtab0[code].val); |
} |
#endif /* TRACE */ |
return BMBtab0[code].val; |
} |
if (code==0) |
{ |
if (!Quiet_Flag) |
cprintf("Invalid macroblock_type code\n"); |
Fault_Flag = 1; |
return 0; |
} |
Flush_Buffer(BMBtab1[code].len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
Print_Bits(code,6,BMBtab1[code].len); |
cprintf("): %s (%d)\n",MBdescr[(int)BMBtab1[code].val],BMBtab1[code].val); |
} |
#endif /* TRACE */ |
return BMBtab1[code].val; |
} |
static int Get_D_macroblock_type() |
{ |
if (!Get_Bits1()) |
{ |
if (!Quiet_Flag) |
cprintf("Invalid macroblock_type code\n"); |
Fault_Flag=1; |
} |
return 1; |
} |
/* macroblock_type for pictures with spatial scalability */ |
static int Get_I_Spatial_macroblock_type() |
{ |
int code; |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("macroblock_type(I,spat) ("); |
#endif /* TRACE */ |
code = Show_Bits(4); |
if (code==0) |
{ |
if (!Quiet_Flag) |
cprintf("Invalid macroblock_type code\n"); |
Fault_Flag = 1; |
return 0; |
} |
#ifdef TRACE |
if (Trace_Flag) |
{ |
Print_Bits(code,4,spIMBtab[code].len); |
cprintf("): %02x\n",spIMBtab[code].val); |
} |
#endif /* TRACE */ |
Flush_Buffer(spIMBtab[code].len); |
return spIMBtab[code].val; |
} |
static int Get_P_Spatial_macroblock_type() |
{ |
int code; |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("macroblock_type(P,spat) ("); |
#endif /* TRACE */ |
code = Show_Bits(7); |
if (code<2) |
{ |
if (!Quiet_Flag) |
cprintf("Invalid macroblock_type code\n"); |
Fault_Flag = 1; |
return 0; |
} |
if (code>=16) |
{ |
code >>= 3; |
Flush_Buffer(spPMBtab0[code].len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
Print_Bits(code,4,spPMBtab0[code].len); |
cprintf("): %02x\n",spPMBtab0[code].val); |
} |
#endif /* TRACE */ |
return spPMBtab0[code].val; |
} |
Flush_Buffer(spPMBtab1[code].len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
Print_Bits(code,7,spPMBtab1[code].len); |
cprintf("): %02x\n",spPMBtab1[code].val); |
} |
#endif /* TRACE */ |
return spPMBtab1[code].val; |
} |
static int Get_B_Spatial_macroblock_type() |
{ |
int code; |
VLCtab *p; |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("macroblock_type(B,spat) ("); |
#endif /* TRACE */ |
code = Show_Bits(9); |
if (code>=64) |
p = &spBMBtab0[(code>>5)-2]; |
else if (code>=16) |
p = &spBMBtab1[(code>>2)-4]; |
else if (code>=8) |
p = &spBMBtab2[code-8]; |
else |
{ |
if (!Quiet_Flag) |
cprintf("Invalid macroblock_type code\n"); |
Fault_Flag = 1; |
return 0; |
} |
Flush_Buffer(p->len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
Print_Bits(code,9,p->len); |
printf("): %02x\n",p->val); |
} |
#endif /* TRACE */ |
return p->val; |
} |
static int Get_SNR_macroblock_type() |
{ |
int code; |
#ifdef TRACE /* *CH* */ |
if (Trace_Flag) |
cprintf("macroblock_type(SNR) ("); |
#endif |
code = Show_Bits(3); |
if (code==0) |
{ |
if (!Quiet_Flag) |
cprintf("Invalid macroblock_type code\n"); |
Fault_Flag = 1; |
return 0; |
} |
Flush_Buffer(SNRMBtab[code].len); |
#ifdef TRACE /* *CH* */ |
if (Trace_Flag) |
{ |
Print_Bits(code,3,SNRMBtab[code].len); |
cprintf("): %s (%d)\n",MBdescr[(int)SNRMBtab[code].val],SNRMBtab[code].val); |
} |
#endif |
return SNRMBtab[code].val; |
} |
int Get_motion_code() |
{ |
int code; |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("motion_code ("); |
#endif /* TRACE */ |
if (Get_Bits1()) |
{ |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("0): 0\n"); |
#endif /* TRACE */ |
return 0; |
} |
if ((code = Show_Bits(9))>=64) |
{ |
code >>= 6; |
Flush_Buffer(MVtab0[code].len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
Print_Bits(code,3,MVtab0[code].len); |
cprintf("%d): %d\n", |
Show_Bits(1),Show_Bits(1)?-MVtab0[code].val:MVtab0[code].val); |
} |
#endif /* TRACE */ |
return Get_Bits1()?-MVtab0[code].val:MVtab0[code].val; |
} |
if (code>=24) |
{ |
code >>= 3; |
Flush_Buffer(MVtab1[code].len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
Print_Bits(code,6,MVtab1[code].len); |
cprintf("%d): %d\n", |
Show_Bits(1),Show_Bits(1)?-MVtab1[code].val:MVtab1[code].val); |
} |
#endif /* TRACE */ |
return Get_Bits1()?-MVtab1[code].val:MVtab1[code].val; |
} |
if ((code-=12)<0) |
{ |
if (!Quiet_Flag) |
/* HACK */ |
cprintf("Invalid motion_vector code (MBA %d, pic %d)\n", global_MBA, global_pic); |
Fault_Flag=1; |
return 0; |
} |
Flush_Buffer(MVtab2[code].len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
Print_Bits(code+12,9,MVtab2[code].len); |
cprintf("%d): %d\n", |
Show_Bits(1),Show_Bits(1)?-MVtab2[code].val:MVtab2[code].val); |
} |
#endif /* TRACE */ |
return Get_Bits1() ? -MVtab2[code].val : MVtab2[code].val; |
} |
/* get differential motion vector (for dual prime prediction) */ |
int Get_dmvector() |
{ |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("dmvector ("); |
#endif /* TRACE */ |
if (Get_Bits(1)) |
{ |
#ifdef TRACE |
if (Trace_Flag) |
cprintf(Show_Bits(1) ? "11): -1\n" : "10): 1\n"); |
#endif /* TRACE */ |
return Get_Bits(1) ? -1 : 1; |
} |
else |
{ |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("0): 0\n"); |
#endif /* TRACE */ |
return 0; |
} |
} |
int Get_coded_block_pattern() |
{ |
int code; |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("coded_block_pattern_420 ("); |
#endif /* TRACE */ |
if ((code = Show_Bits(9))>=128) |
{ |
code >>= 4; |
Flush_Buffer(CBPtab0[code].len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
Print_Bits(code,5,CBPtab0[code].len); |
cprintf("): "); |
Print_Bits(CBPtab0[code].val,6,6); |
cprintf(" (%d)\n",CBPtab0[code].val); |
} |
#endif /* TRACE */ |
return CBPtab0[code].val; |
} |
if (code>=8) |
{ |
code >>= 1; |
Flush_Buffer(CBPtab1[code].len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
Print_Bits(code,8,CBPtab1[code].len); |
cprintf("): "); |
Print_Bits(CBPtab1[code].val,6,6); |
cprintf(" (%d)\n",CBPtab1[code].val); |
} |
#endif /* TRACE */ |
return CBPtab1[code].val; |
} |
if (code<1) |
{ |
if (!Quiet_Flag) |
cprintf("Invalid coded_block_pattern code\n"); |
Fault_Flag = 1; |
return 0; |
} |
Flush_Buffer(CBPtab2[code].len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
Print_Bits(code,9,CBPtab2[code].len); |
cprintf("): "); |
Print_Bits(CBPtab2[code].val,6,6); |
cprintf(" (%d)\n",CBPtab2[code].val); |
} |
#endif /* TRACE */ |
return CBPtab2[code].val; |
} |
int Get_macroblock_address_increment() |
{ |
int code, val; |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("macroblock_address_increment ("); |
#endif /* TRACE */ |
val = 0; |
while ((code = Show_Bits(11))<24) |
{ |
if (code!=15) /* if not macroblock_stuffing */ |
{ |
if (code==8) /* if macroblock_escape */ |
{ |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("00000001000 "); |
#endif /* TRACE */ |
val+= 33; |
} |
else |
{ |
if (!Quiet_Flag) |
cprintf("Invalid macroblock_address_increment code\n"); |
Fault_Flag = 1; |
return 1; |
} |
} |
else /* macroblock suffing */ |
{ |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("00000001111 "); |
#endif /* TRACE */ |
} |
Flush_Buffer(11); |
} |
/* macroblock_address_increment == 1 */ |
/* ('1' is in the MSB position of the lookahead) */ |
if (code>=1024) |
{ |
Flush_Buffer(1); |
#ifdef TRACE |
if (Trace_Flag) |
cprintf("1): %d\n",val+1); |
#endif /* TRACE */ |
return val + 1; |
} |
/* codes 00010 ... 011xx */ |
if (code>=128) |
{ |
/* remove leading zeros */ |
code >>= 6; |
Flush_Buffer(MBAtab1[code].len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
Print_Bits(code,5,MBAtab1[code].len); |
printf("): %d\n",val+MBAtab1[code].val); |
} |
#endif /* TRACE */ |
return val + MBAtab1[code].val; |
} |
/* codes 00000011000 ... 0000111xxxx */ |
code-= 24; /* remove common base */ |
Flush_Buffer(MBAtab2[code].len); |
#ifdef TRACE |
if (Trace_Flag) |
{ |
Print_Bits(code+24,11,MBAtab2[code].len); |
cprintf("): %d\n",val+MBAtab2[code].val); |
} |
#endif /* TRACE */ |
return val + MBAtab2[code].val; |
} |
/* combined MPEG-1 and MPEG-2 stage. parse VLC and |
perform dct_diff arithmetic. |
MPEG-1: ISO/IEC 11172-2 section |
MPEG-2: ISO/IEC 13818-2 section 7.2.1 |
Note: the arithmetic here is presented more elegantly than |
the spec, yet the results, dct_diff, are the same. |
*/ |
int Get_Luma_DC_dct_diff() |
{ |
int code, size, dct_diff; |
#ifdef TRACE |
/* |
if (Trace_Flag) |
printf("dct_dc_size_luminance: ("); |
*/ |
#endif /* TRACE */ |
/* decode length */ |
code = Show_Bits(5); |
if (code<31) |
{ |
size = DClumtab0[code].val; |
Flush_Buffer(DClumtab0[code].len); |
#ifdef TRACE |
/* |
if (Trace_Flag) |
{ |
Print_Bits(code,5,DClumtab0[code].len); |
printf("): %d",size); |
} |
*/ |
#endif /* TRACE */ |
} |
else |
{ |
code = Show_Bits(9) - 0x1f0; |
size = DClumtab1[code].val; |
Flush_Buffer(DClumtab1[code].len); |
#ifdef TRACE |
/* |
if (Trace_Flag) |
{ |
Print_Bits(code+0x1f0,9,DClumtab1[code].len); |
printf("): %d",size); |
} |
*/ |
#endif /* TRACE */ |
} |
#ifdef TRACE |
/* |
if (Trace_Flag) |
printf(", dct_dc_differential ("); |
*/ |
#endif /* TRACE */ |
if (size==0) |
dct_diff = 0; |
else |
{ |
dct_diff = Get_Bits(size); |
#ifdef TRACE |
/* |
if (Trace_Flag) |
Print_Bits(dct_diff,size,size); |
*/ |
#endif /* TRACE */ |
if ((dct_diff & (1<<(size-1)))==0) |
dct_diff-= (1<<size) - 1; |
} |
#ifdef TRACE |
/* |
if (Trace_Flag) |
printf("): %d\n",dct_diff); |
*/ |
#endif /* TRACE */ |
return dct_diff; |
} |
int Get_Chroma_DC_dct_diff() |
{ |
int code, size, dct_diff; |
#ifdef TRACE |
/* |
if (Trace_Flag) |
printf("dct_dc_size_chrominance: ("); |
*/ |
#endif /* TRACE */ |
/* decode length */ |
code = Show_Bits(5); |
if (code<31) |
{ |
size = DCchromtab0[code].val; |
Flush_Buffer(DCchromtab0[code].len); |
#ifdef TRACE |
/* |
if (Trace_Flag) |
{ |
Print_Bits(code,5,DCchromtab0[code].len); |
printf("): %d",size); |
} |
*/ |
#endif /* TRACE */ |
} |
else |
{ |
code = Show_Bits(10) - 0x3e0; |
size = DCchromtab1[code].val; |
Flush_Buffer(DCchromtab1[code].len); |
#ifdef TRACE |
/* |
if (Trace_Flag) |
{ |
Print_Bits(code+0x3e0,10,DCchromtab1[code].len); |
printf("): %d",size); |
} |
*/ |
#endif /* TRACE */ |
} |
#ifdef TRACE |
/* |
if (Trace_Flag) |
printf(", dct_dc_differential ("); |
*/ |
#endif /* TRACE */ |
if (size==0) |
dct_diff = 0; |
else |
{ |
dct_diff = Get_Bits(size); |
#ifdef TRACE |
/* |
if (Trace_Flag) |
Print_Bits(dct_diff,size,size); |
*/ |
#endif /* TRACE */ |
if ((dct_diff & (1<<(size-1)))==0) |
dct_diff-= (1<<size) - 1; |
} |
#ifdef TRACE |
/* |
if (Trace_Flag) |
printf("): %d\n",dct_diff); |
*/ |
#endif /* TRACE */ |
return dct_diff; |
} |
/unsupported/trunk/first-official/mpeg2/mpeg2dec.c |
---|
0,0 → 1,495 |
/* mpeg2dec.c, main(), initialization, option processing */ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
#include "stdlib.h" |
#include "drivers/glib.h" |
#include "fsf.h" |
#define GLOBAL |
#include "config.h" |
#include "global.h" |
/* private prototypes */ |
static int video_sequence _ANSI_ARGS_((int *framenum)); |
static int Headers _ANSI_ARGS_((void)); |
static void Initialize_Sequence _ANSI_ARGS_((void)); |
static void Initialize_Decoder _ANSI_ARGS_((void)); |
static void Deinitialize_Sequence _ANSI_ARGS_((void)); |
/* #define DEBUG */ |
static void Clear_Options(); |
#ifdef DEBUG |
static void Print_Options(); |
#endif |
#define MAX_M_QOS 0 |
#define MIN_M_QOS 0 |
int dos_video_preload(char *file_name, long max_size, void **start, void **end) |
{ |
DOS_FILE* file; |
void *buf; |
long rd; |
file = DOS_fopen(file_name,"r"); |
if (file == NULL) return -1; |
buf = malloc(max_size); |
*start = buf; |
while(((rd = DOS_fread(buf, sizeof(BYTE), 2048, file)) == 2048) && |
((buf - *start + rd) < (max_size-2048))) { |
buf += rd; |
} |
*end = buf + rd; |
DOS_fclose(file); |
return(0); |
} |
int Init_Mpeg_Decoder(void *start, void *end) |
{ |
int code; |
Clear_Options(); |
#ifdef DEBUG |
Print_Options(); |
#endif |
ld = &base; /* select base layer context */ |
ld->start_file_ptr = start; |
ld->end_file_ptr = end; |
ld->actual_file_ptr = ld->start_file_ptr; |
/* open MPEG base layer bitstream file(s) */ |
/* NOTE: this is either a base layer stream or a spatial enhancement stream */ |
if ((base.Infile=1)<0) |
{ |
cprintf("Base layer input file %s not found\n", Main_Bitstream_Filename); |
} |
if(base.Infile != 0) |
{ |
Initialize_Buffer(); |
if(Show_Bits(8)==0x47) |
{ |
sprintf(Error_Text,"Decoder currently does not parse transport streams\n"); |
Error(Error_Text); |
} |
next_start_code(); |
code = Show_Bits(32); |
switch(code) |
{ |
case SEQUENCE_HEADER_CODE: |
break; |
case PACK_START_CODE: |
System_Stream_Flag = 1; |
case VIDEO_ELEMENTARY_STREAM: |
System_Stream_Flag = 1; |
break; |
default: |
sprintf(Error_Text,"Unable to recognize stream type\n"); |
Error(Error_Text); |
break; |
} |
ld->actual_file_ptr = ld->start_file_ptr; |
Initialize_Buffer(); |
} |
if(base.Infile!=0) |
{ |
ld->actual_file_ptr = ld->start_file_ptr; |
} |
Initialize_Buffer(); |
if(Two_Streams) |
{ |
ld = &enhan; /* select enhancement layer context */ |
if ((enhan.Infile = 1)<0) |
{ |
sprintf(Error_Text,"enhancment layer bitstream file %s not found\n", |
Enhancement_Layer_Bitstream_Filename); |
Error(Error_Text); |
} |
Initialize_Buffer(); |
ld = &base; |
} |
Initialize_Decoder(); |
//Decode_Bitstream(); |
return 0; |
} |
/* IMPLEMENTAION specific rouintes */ |
static void Initialize_Decoder() |
{ |
int i; |
/* Clip table */ |
if (!(Clip=(unsigned char *)malloc(1024))) |
Error("Clip[] malloc failed\n"); |
Clip += 384; |
for (i=-384; i<640; i++) |
Clip[i] = (i<0) ? 0 : ((i>255) ? 255 : i); |
/* IDCT */ |
if (Reference_IDCT_Flag) |
Initialize_Reference_IDCT(); |
else |
Initialize_Fast_IDCT(); |
} |
/* mostly IMPLEMENTAION specific rouintes */ |
static void Initialize_Sequence() |
{ |
int cc, size; |
static int Table_6_20[3] = {6,8,12}; |
/* check scalability mode of enhancement layer */ |
if (Two_Streams && (enhan.scalable_mode!=SC_SNR) && (base.scalable_mode!=SC_DP)) |
Error("unsupported scalability mode\n"); |
/* force MPEG-1 parameters for proper decoder behavior */ |
/* see ISO/IEC 13818-2 section D.9.14 */ |
if (!base.MPEG2_Flag) |
{ |
progressive_sequence = 1; |
progressive_frame = 1; |
picture_structure = FRAME_PICTURE; |
frame_pred_frame_dct = 1; |
chroma_format = CHROMA420; |
matrix_coefficients = 5; |
} |
/* round to nearest multiple of coded macroblocks */ |
/* ISO/IEC 13818-2 section 6.3.3 sequence_header() */ |
mb_width = (horizontal_size+15)/16; |
mb_height = (base.MPEG2_Flag && !progressive_sequence) ? 2*((vertical_size+31)/32) |
: (vertical_size+15)/16; |
Coded_Picture_Width = 16*mb_width; |
Coded_Picture_Height = 16*mb_height; |
/* ISO/IEC 13818-2 sections 6.1.1.8, 6.1.1.9, and 6.1.1.10 */ |
Chroma_Width = (chroma_format==CHROMA444) ? Coded_Picture_Width |
: Coded_Picture_Width>>1; |
Chroma_Height = (chroma_format!=CHROMA420) ? Coded_Picture_Height |
: Coded_Picture_Height>>1; |
/* derived based on Table 6-20 in ISO/IEC 13818-2 section 6.3.17 */ |
block_count = Table_6_20[chroma_format-1]; |
for (cc=0; cc<3; cc++) |
{ |
if (cc==0) |
size = Coded_Picture_Width*Coded_Picture_Height; |
else |
size = Chroma_Width*Chroma_Height; |
if (!(backward_reference_frame[cc] = (unsigned char *)malloc(size))) |
Error("backward_reference_frame[] malloc failed\n"); |
if (!(forward_reference_frame[cc] = (unsigned char *)malloc(size))) |
Error("forward_reference_frame[] malloc failed\n"); |
if (!(auxframe[cc] = (unsigned char *)malloc(size))) |
Error("auxframe[] malloc failed\n"); |
if(Ersatz_Flag) |
if (!(substitute_frame[cc] = (unsigned char *)malloc(size))) |
Error("substitute_frame[] malloc failed\n"); |
if (base.scalable_mode==SC_SPAT) |
{ |
/* this assumes lower layer is 4:2:0 */ |
if (!(llframe0[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1)))) |
Error("llframe0 malloc failed\n"); |
if (!(llframe1[cc] = (unsigned char *)malloc((lower_layer_prediction_horizontal_size*lower_layer_prediction_vertical_size)/(cc?4:1)))) |
Error("llframe1 malloc failed\n"); |
} |
} |
/* SCALABILITY: Spatial */ |
if (base.scalable_mode==SC_SPAT) |
{ |
if (!(lltmp = (short *)malloc(lower_layer_prediction_horizontal_size*((lower_layer_prediction_vertical_size*vertical_subsampling_factor_n)/vertical_subsampling_factor_m)*sizeof(short)))) |
Error("lltmp malloc failed\n"); |
} |
#ifdef DISPLAY |
if (Output_Type==T_X11) |
{ |
Initialize_Display_Process(""); |
Initialize_Dither_Matrix(); |
} |
#endif /* DISPLAY */ |
} |
void Error(text) |
char *text; |
{ |
cprintf(text); |
} |
/* Trace_Flag output */ |
void Print_Bits(code,bits,len) |
int code,bits,len; |
{ |
int i; |
for (i=0; i<len; i++) |
cprintf("%d",(code>>(bits-1-i))&1); |
} |
static int Headers() |
{ |
int ret; |
ld = &base; |
/* return when end of sequence (0) or picture |
header has been parsed (1) */ |
ret = Get_Hdr(); |
if (Two_Streams) |
{ |
ld = &enhan; |
if (Get_Hdr()!=ret && !Quiet_Flag) |
cprintf("streams out of sync\n"); |
ld = &base; |
} |
return ret; |
} |
int Decode_Bitstream() |
{ |
int ret; |
int Bitstream_Framenum; |
Bitstream_Framenum = 0; |
for(;;) |
{ |
#ifdef VERIFY |
Clear_Verify_Headers(); |
#endif /* VERIFY */ |
ld->actual_file_ptr = ld->start_file_ptr; |
ret = Headers(); |
if(ret==1) |
{ |
ret = video_sequence(&Bitstream_Framenum); |
} |
else |
return(ret); |
} |
} |
static void Deinitialize_Sequence() |
{ |
int i; |
/* clear flags */ |
base.MPEG2_Flag=0; |
for(i=0;i<3;i++) |
{ |
free(backward_reference_frame[i]); |
free(forward_reference_frame[i]); |
free(auxframe[i]); |
if (base.scalable_mode==SC_SPAT) |
{ |
free(llframe0[i]); |
free(llframe1[i]); |
} |
} |
if (base.scalable_mode==SC_SPAT) |
free(lltmp); |
#ifdef DISPLAY |
if (Output_Type==T_X11) |
Terminate_Display_Process(); |
#endif |
} |
static int video_sequence(Bitstream_Framenumber) |
int *Bitstream_Framenumber; |
{ |
int Bitstream_Framenum; |
int Sequence_Framenum; |
int Return_Value; |
char tmp[100]; |
Bitstream_Framenum = *Bitstream_Framenumber; |
Sequence_Framenum=0; |
Initialize_Sequence(); |
/* decode picture whose header has already been parsed in |
Decode_Bitstream() */ |
ld->px = 310+(rand()%(500-Coded_Picture_Width)); |
ld->py = 100+(rand()%(400-Coded_Picture_Height)); |
sprintf(tmp,"Wx = %3d Wy = %3d",Coded_Picture_Width,Coded_Picture_Height); |
grx_text(tmp,ld->px,ld->py-10,rgb16(255,255,255),0); |
Decode_Picture(Bitstream_Framenum, Sequence_Framenum); |
/* update picture numbers */ |
if (!Second_Field) |
{ |
Bitstream_Framenum++; |
Sequence_Framenum++; |
} |
fsf_schedule_timed_job(NULL, NULL, NULL, NULL, NULL); |
/* loop through the rest of the pictures in the sequence */ |
while ((Return_Value=Headers())) |
{ |
Decode_Picture(Bitstream_Framenum, Sequence_Framenum); |
if (!Second_Field) |
{ |
Bitstream_Framenum++; |
Sequence_Framenum++; |
} |
fsf_schedule_timed_job(NULL, NULL, NULL, NULL, NULL); |
} |
/* put last frame */ |
if (Sequence_Framenum!=0) |
{ |
Output_Last_Frame_of_Sequence(Bitstream_Framenum); |
} |
Deinitialize_Sequence(); |
#ifdef VERIFY |
Clear_Verify_Headers(); |
#endif /* VERIFY */ |
*Bitstream_Framenumber = Bitstream_Framenum; |
return(Return_Value); |
} |
static void Clear_Options() |
{ |
Verbose_Flag = 0; |
Output_Type = 0; |
Output_Picture_Filename = " "; |
hiQdither = 0; |
Output_Type = 0; |
Frame_Store_Flag = 0; |
Spatial_Flag = 0; |
Lower_Layer_Picture_Filename = " "; |
Reference_IDCT_Flag = 0; |
Trace_Flag = 0; |
Quiet_Flag = 0; |
Ersatz_Flag = 0; |
Substitute_Picture_Filename = " "; |
Two_Streams = 0; |
Enhancement_Layer_Bitstream_Filename = " "; |
Big_Picture_Flag = 0; |
Main_Bitstream_Flag = 0; |
Main_Bitstream_Filename = " "; |
Verify_Flag = 0; |
Stats_Flag = 0; |
User_Data_Flag = 0; |
} |
#ifdef DEBUG |
static void Print_Options() |
{ |
printf("Verbose_Flag = %d\n", Verbose_Flag); |
printf("Output_Type = %d\n", Output_Type); |
printf("Output_Picture_Filename = %s\n", Output_Picture_Filename); |
printf("hiQdither = %d\n", hiQdither); |
printf("Output_Type = %d\n", Output_Type); |
printf("Frame_Store_Flag = %d\n", Frame_Store_Flag); |
printf("Spatial_Flag = %d\n", Spatial_Flag); |
printf("Lower_Layer_Picture_Filename = %s\n", Lower_Layer_Picture_Filename); |
printf("Reference_IDCT_Flag = %d\n", Reference_IDCT_Flag); |
printf("Trace_Flag = %d\n", Trace_Flag); |
printf("Quiet_Flag = %d\n", Quiet_Flag); |
printf("Ersatz_Flag = %d\n", Ersatz_Flag); |
printf("Substitute_Picture_Filename = %s\n", Substitute_Picture_Filename); |
printf("Two_Streams = %d\n", Two_Streams); |
printf("Enhancement_Layer_Bitstream_Filename = %s\n", Enhancement_Layer_Bitstream_Filename); |
printf("Big_Picture_Flag = %d\n", Big_Picture_Flag); |
printf("Main_Bitstream_Flag = %d\n", Main_Bitstream_Flag); |
printf("Main_Bitstream_Filename = %s\n", Main_Bitstream_Filename); |
printf("Verify_Flag = %d\n", Verify_Flag); |
printf("Stats_Flag = %d\n", Stats_Flag); |
printf("User_Data_Flag = %d\n", User_Data_Flag); |
} |
#endif |
/unsupported/trunk/first-official/mpeg2/getvlc.h |
---|
0,0 → 1,491 |
/* getvlc.h, variable length code tables */ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
/* NOTE: #define constants such as MACROBLOCK_QUANT are upper case |
as per C programming convention. However, the MPEG document |
(ISO/IEC 13818-2) lists them in all lower case (e.g. Annex B) */ |
/* NOTE: the VLC tables are in a flash format---a transformation |
of the tables in Annex B to a form more convenient towards |
parallel (more than one-bit-at-a-time) decoding */ |
typedef struct { |
char val, len; |
} VLCtab; |
typedef struct { |
char run, level, len; |
} DCTtab; |
/* Table B-3, macroblock_type in P-pictures, codes 001..1xx */ |
static VLCtab PMBtab0[8] = { |
{ERROR,0}, |
{MACROBLOCK_MOTION_FORWARD,3}, |
{MACROBLOCK_PATTERN,2}, {MACROBLOCK_PATTERN,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,1}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,1}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,1}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,1} |
}; |
/* Table B-3, macroblock_type in P-pictures, codes 000001..00011x */ |
static VLCtab PMBtab1[8] = { |
{ERROR,0}, |
{MACROBLOCK_QUANT|MACROBLOCK_INTRA,6}, |
{MACROBLOCK_QUANT|MACROBLOCK_PATTERN,5}, {MACROBLOCK_QUANT|MACROBLOCK_PATTERN,5}, |
{MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,5}, {MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,5}, |
{MACROBLOCK_INTRA,5}, {MACROBLOCK_INTRA,5} |
}; |
/* Table B-4, macroblock_type in B-pictures, codes 0010..11xx */ |
static VLCtab BMBtab0[16] = { |
{ERROR,0}, |
{ERROR,0}, |
{MACROBLOCK_MOTION_FORWARD,4}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,4}, |
{MACROBLOCK_MOTION_BACKWARD,3}, |
{MACROBLOCK_MOTION_BACKWARD,3}, |
{MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,3}, |
{MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,3}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2} |
}; |
/* Table B-4, macroblock_type in B-pictures, codes 000001..00011x */ |
static VLCtab BMBtab1[8] = { |
{ERROR,0}, |
{MACROBLOCK_QUANT|MACROBLOCK_INTRA,6}, |
{MACROBLOCK_QUANT|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,6}, |
{MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,6}, |
{MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,5}, |
{MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,5}, |
{MACROBLOCK_INTRA,5}, |
{MACROBLOCK_INTRA,5} |
}; |
/* Table B-5, macroblock_type in spat. scal. I-pictures, codes 0001..1xxx */ |
static VLCtab spIMBtab[16] = { |
{ERROR,0}, |
{PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS,4}, |
{MACROBLOCK_QUANT|MACROBLOCK_INTRA,4}, |
{MACROBLOCK_INTRA,4}, |
{PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS|MACROBLOCK_QUANT|MACROBLOCK_PATTERN,2}, {PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS|MACROBLOCK_QUANT|MACROBLOCK_PATTERN,2}, |
{PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS|MACROBLOCK_QUANT|MACROBLOCK_PATTERN,2}, {PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS|MACROBLOCK_QUANT|MACROBLOCK_PATTERN,2}, |
{PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS|MACROBLOCK_PATTERN,1}, {PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS|MACROBLOCK_PATTERN,1}, |
{PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS|MACROBLOCK_PATTERN,1}, {PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS|MACROBLOCK_PATTERN,1}, |
{PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS|MACROBLOCK_PATTERN,1}, {PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS|MACROBLOCK_PATTERN,1}, |
{PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS|MACROBLOCK_PATTERN,1}, {PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS|MACROBLOCK_PATTERN,1} |
}; |
/* Table B-6, macroblock_type in spat. scal. P-pictures, codes 0010..11xx */ |
static VLCtab spPMBtab0[16] = |
{ |
{ERROR,0}, |
{ERROR,0}, |
{MACROBLOCK_MOTION_FORWARD,4}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_MOTION_FORWARD,4}, |
{MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,3}, {MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,3}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,3}, {SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,3}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,2}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,2}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,2}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,2}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,2} |
}; |
/* Table B-6, macroblock_type in spat. scal. P-pictures, codes 0000010..000111x */ |
static VLCtab spPMBtab1[16] = { |
{ERROR,0}, |
{ERROR,0}, |
{PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS|MACROBLOCK_QUANT|MACROBLOCK_PATTERN,7}, |
{PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS,7}, |
{MACROBLOCK_PATTERN,7}, |
{PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS|MACROBLOCK_PATTERN,7}, |
{MACROBLOCK_QUANT|MACROBLOCK_INTRA,7}, |
{MACROBLOCK_INTRA,7}, |
{MACROBLOCK_QUANT|MACROBLOCK_PATTERN,6}, |
{MACROBLOCK_QUANT|MACROBLOCK_PATTERN,6}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_QUANT|MACROBLOCK_PATTERN,6}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_QUANT|MACROBLOCK_PATTERN,6}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG,6}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG,6}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_PATTERN,6}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_PATTERN,6} |
}; |
/* Table B-7, macroblock_type in spat. scal. B-pictures, codes 0010..11xx */ |
static VLCtab spBMBtab0[14] = { |
{MACROBLOCK_MOTION_FORWARD,4}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,4}, |
{MACROBLOCK_MOTION_BACKWARD,3}, |
{MACROBLOCK_MOTION_BACKWARD,3}, |
{MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,3}, |
{MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,3}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2}, |
{MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,2} |
}; |
/* Table B-7, macroblock_type in spat. scal. B-pictures, codes 0000100..000111x */ |
static VLCtab spBMBtab1[12] = { |
{MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,7}, |
{MACROBLOCK_QUANT|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,7}, |
{MACROBLOCK_INTRA,7}, |
{MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,7}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_MOTION_FORWARD,6}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_MOTION_FORWARD,6}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,6}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,6}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_MOTION_BACKWARD,6}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_MOTION_BACKWARD,6}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,6}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,6} |
}; |
/* Table B-7, macroblock_type in spat. scal. B-pictures, codes 00000100x..000001111 */ |
static VLCtab spBMBtab2[8] = { |
{MACROBLOCK_QUANT|MACROBLOCK_INTRA,8}, |
{MACROBLOCK_QUANT|MACROBLOCK_INTRA,8}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,8}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_QUANT|MACROBLOCK_MOTION_FORWARD|MACROBLOCK_PATTERN,8}, |
{SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG|MACROBLOCK_QUANT|MACROBLOCK_MOTION_BACKWARD|MACROBLOCK_PATTERN,9}, |
{PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS|MACROBLOCK_QUANT|MACROBLOCK_PATTERN,9}, |
{PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS,9}, |
{PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS|MACROBLOCK_PATTERN,9} |
}; |
/* Table B-8, macroblock_type in spat. scal. B-pictures, codes 001..1xx */ |
static VLCtab SNRMBtab[8] = { |
{ERROR,0}, |
{0,3}, |
{MACROBLOCK_QUANT|MACROBLOCK_PATTERN,2}, |
{MACROBLOCK_QUANT|MACROBLOCK_PATTERN,2}, |
{MACROBLOCK_PATTERN,1}, |
{MACROBLOCK_PATTERN,1}, |
{MACROBLOCK_PATTERN,1}, |
{MACROBLOCK_PATTERN,1} |
}; |
/* Table B-10, motion_code, codes 0001 ... 01xx */ |
static VLCtab MVtab0[8] = |
{ {ERROR,0}, {3,3}, {2,2}, {2,2}, {1,1}, {1,1}, {1,1}, {1,1} |
}; |
/* Table B-10, motion_code, codes 0000011 ... 000011x */ |
static VLCtab MVtab1[8] = |
{ {ERROR,0}, {ERROR,0}, {ERROR,0}, {7,6}, {6,6}, {5,6}, {4,5}, {4,5} |
}; |
/* Table B-10, motion_code, codes 0000001100 ... 000001011x */ |
static VLCtab MVtab2[12] = |
{ {16,9}, {15,9}, {14,9}, {13,9}, |
{12,9}, {11,9}, {10,8}, {10,8}, |
{9,8}, {9,8}, {8,8}, {8,8} |
}; |
/* Table B-9, coded_block_pattern, codes 01000 ... 111xx */ |
static VLCtab CBPtab0[32] = |
{ {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0}, |
{ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0}, |
{62,5}, {2,5}, {61,5}, {1,5}, {56,5}, {52,5}, {44,5}, {28,5}, |
{40,5}, {20,5}, {48,5}, {12,5}, {32,4}, {32,4}, {16,4}, {16,4}, |
{8,4}, {8,4}, {4,4}, {4,4}, {60,3}, {60,3}, {60,3}, {60,3} |
}; |
/* Table B-9, coded_block_pattern, codes 00000100 ... 001111xx */ |
static VLCtab CBPtab1[64] = |
{ {ERROR,0}, {ERROR,0}, {ERROR,0}, {ERROR,0}, |
{58,8}, {54,8}, {46,8}, {30,8}, |
{57,8}, {53,8}, {45,8}, {29,8}, {38,8}, {26,8}, {37,8}, {25,8}, |
{43,8}, {23,8}, {51,8}, {15,8}, {42,8}, {22,8}, {50,8}, {14,8}, |
{41,8}, {21,8}, {49,8}, {13,8}, {35,8}, {19,8}, {11,8}, {7,8}, |
{34,7}, {34,7}, {18,7}, {18,7}, {10,7}, {10,7}, {6,7}, {6,7}, |
{33,7}, {33,7}, {17,7}, {17,7}, {9,7}, {9,7}, {5,7}, {5,7}, |
{63,6}, {63,6}, {63,6}, {63,6}, {3,6}, {3,6}, {3,6}, {3,6}, |
{36,6}, {36,6}, {36,6}, {36,6}, {24,6}, {24,6}, {24,6}, {24,6} |
}; |
/* Table B-9, coded_block_pattern, codes 000000001 ... 000000111 */ |
static VLCtab CBPtab2[8] = |
{ {ERROR,0}, {0,9}, {39,9}, {27,9}, {59,9}, {55,9}, {47,9}, {31,9} |
}; |
/* Table B-1, macroblock_address_increment, codes 00010 ... 011xx */ |
static VLCtab MBAtab1[16] = |
{ {ERROR,0}, {ERROR,0}, {7,5}, {6,5}, {5,4}, {5,4}, {4,4}, {4,4}, |
{3,3}, {3,3}, {3,3}, {3,3}, {2,3}, {2,3}, {2,3}, {2,3} |
}; |
/* Table B-1, macroblock_address_increment, codes 00000011000 ... 0000111xxxx */ |
static VLCtab MBAtab2[104] = |
{ |
{33,11}, {32,11}, {31,11}, {30,11}, {29,11}, {28,11}, {27,11}, {26,11}, |
{25,11}, {24,11}, {23,11}, {22,11}, {21,10}, {21,10}, {20,10}, {20,10}, |
{19,10}, {19,10}, {18,10}, {18,10}, {17,10}, {17,10}, {16,10}, {16,10}, |
{15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, {15,8}, |
{14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, {14,8}, |
{13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, {13,8}, |
{12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, {12,8}, |
{11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, {11,8}, |
{10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, {10,8}, |
{9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, |
{9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, {9,7}, |
{8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, |
{8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7}, {8,7} |
}; |
/* Table B-12, dct_dc_size_luminance, codes 00xxx ... 11110 */ |
static VLCtab DClumtab0[32] = |
{ {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, |
{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, |
{0, 3}, {0, 3}, {0, 3}, {0, 3}, {3, 3}, {3, 3}, {3, 3}, {3, 3}, |
{4, 3}, {4, 3}, {4, 3}, {4, 3}, {5, 4}, {5, 4}, {6, 5}, {ERROR, 0} |
}; |
/* Table B-12, dct_dc_size_luminance, codes 111110xxx ... 111111111 */ |
static VLCtab DClumtab1[16] = |
{ {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, {7, 6}, |
{8, 7}, {8, 7}, {8, 7}, {8, 7}, {9, 8}, {9, 8}, {10,9}, {11,9} |
}; |
/* Table B-13, dct_dc_size_chrominance, codes 00xxx ... 11110 */ |
static VLCtab DCchromtab0[32] = |
{ {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, {0, 2}, |
{1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, {1, 2}, |
{2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, {2, 2}, |
{3, 3}, {3, 3}, {3, 3}, {3, 3}, {4, 4}, {4, 4}, {5, 5}, {ERROR, 0} |
}; |
/* Table B-13, dct_dc_size_chrominance, codes 111110xxxx ... 1111111111 */ |
static VLCtab DCchromtab1[32] = |
{ {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, |
{6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, {6, 6}, |
{7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, {7, 7}, |
{8, 8}, {8, 8}, {8, 8}, {8, 8}, {9, 9}, {9, 9}, {10,10}, {11,10} |
}; |
/* Table B-14, DCT coefficients table zero, |
* codes 0100 ... 1xxx (used for first (DC) coefficient) |
*/ |
DCTtab DCTtabfirst[12] = |
{ |
{0,2,4}, {2,1,4}, {1,1,3}, {1,1,3}, |
{0,1,1}, {0,1,1}, {0,1,1}, {0,1,1}, |
{0,1,1}, {0,1,1}, {0,1,1}, {0,1,1} |
}; |
/* Table B-14, DCT coefficients table zero, |
* codes 0100 ... 1xxx (used for all other coefficients) |
*/ |
DCTtab DCTtabnext[12] = |
{ |
{0,2,4}, {2,1,4}, {1,1,3}, {1,1,3}, |
{64,0,2}, {64,0,2}, {64,0,2}, {64,0,2}, /* EOB */ |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2} |
}; |
/* Table B-14, DCT coefficients table zero, |
* codes 000001xx ... 00111xxx |
*/ |
DCTtab DCTtab0[60] = |
{ |
{65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */ |
{2,2,7}, {2,2,7}, {9,1,7}, {9,1,7}, |
{0,4,7}, {0,4,7}, {8,1,7}, {8,1,7}, |
{7,1,6}, {7,1,6}, {7,1,6}, {7,1,6}, |
{6,1,6}, {6,1,6}, {6,1,6}, {6,1,6}, |
{1,2,6}, {1,2,6}, {1,2,6}, {1,2,6}, |
{5,1,6}, {5,1,6}, {5,1,6}, {5,1,6}, |
{13,1,8}, {0,6,8}, {12,1,8}, {11,1,8}, |
{3,2,8}, {1,3,8}, {0,5,8}, {10,1,8}, |
{0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, |
{0,3,5}, {0,3,5}, {0,3,5}, {0,3,5}, |
{4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, |
{4,1,5}, {4,1,5}, {4,1,5}, {4,1,5}, |
{3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, |
{3,1,5}, {3,1,5}, {3,1,5}, {3,1,5} |
}; |
/* Table B-15, DCT coefficients table one, |
* codes 000001xx ... 11111111 |
*/ |
DCTtab DCTtab0a[252] = |
{ |
{65,0,6}, {65,0,6}, {65,0,6}, {65,0,6}, /* Escape */ |
{7,1,7}, {7,1,7}, {8,1,7}, {8,1,7}, |
{6,1,7}, {6,1,7}, {2,2,7}, {2,2,7}, |
{0,7,6}, {0,7,6}, {0,7,6}, {0,7,6}, |
{0,6,6}, {0,6,6}, {0,6,6}, {0,6,6}, |
{4,1,6}, {4,1,6}, {4,1,6}, {4,1,6}, |
{5,1,6}, {5,1,6}, {5,1,6}, {5,1,6}, |
{1,5,8}, {11,1,8}, {0,11,8}, {0,10,8}, |
{13,1,8}, {12,1,8}, {3,2,8}, {1,4,8}, |
{2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, |
{2,1,5}, {2,1,5}, {2,1,5}, {2,1,5}, |
{1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, |
{1,2,5}, {1,2,5}, {1,2,5}, {1,2,5}, |
{3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, |
{3,1,5}, {3,1,5}, {3,1,5}, {3,1,5}, |
{1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, |
{1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, |
{1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, |
{1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, |
{1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, |
{1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, |
{1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, |
{1,1,3}, {1,1,3}, {1,1,3}, {1,1,3}, |
{64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, /* EOB */ |
{64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, |
{64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, |
{64,0,4}, {64,0,4}, {64,0,4}, {64,0,4}, |
{0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, |
{0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, |
{0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, |
{0,3,4}, {0,3,4}, {0,3,4}, {0,3,4}, |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, |
{0,1,2}, {0,1,2}, {0,1,2}, {0,1,2}, |
{0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, |
{0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, |
{0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, |
{0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, |
{0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, |
{0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, |
{0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, |
{0,2,3}, {0,2,3}, {0,2,3}, {0,2,3}, |
{0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, |
{0,4,5}, {0,4,5}, {0,4,5}, {0,4,5}, |
{0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, |
{0,5,5}, {0,5,5}, {0,5,5}, {0,5,5}, |
{9,1,7}, {9,1,7}, {1,3,7}, {1,3,7}, |
{10,1,7}, {10,1,7}, {0,8,7}, {0,8,7}, |
{0,9,7}, {0,9,7}, {0,12,8}, {0,13,8}, |
{2,3,8}, {4,2,8}, {0,14,8}, {0,15,8} |
}; |
/* Table B-14, DCT coefficients table zero, |
* codes 0000001000 ... 0000001111 |
*/ |
DCTtab DCTtab1[8] = |
{ |
{16,1,10}, {5,2,10}, {0,7,10}, {2,3,10}, |
{1,4,10}, {15,1,10}, {14,1,10}, {4,2,10} |
}; |
/* Table B-15, DCT coefficients table one, |
* codes 000000100x ... 000000111x |
*/ |
DCTtab DCTtab1a[8] = |
{ |
{5,2,9}, {5,2,9}, {14,1,9}, {14,1,9}, |
{2,4,10}, {16,1,10}, {15,1,9}, {15,1,9} |
}; |
/* Table B-14/15, DCT coefficients table zero / one, |
* codes 000000010000 ... 000000011111 |
*/ |
DCTtab DCTtab2[16] = |
{ |
{0,11,12}, {8,2,12}, {4,3,12}, {0,10,12}, |
{2,4,12}, {7,2,12}, {21,1,12}, {20,1,12}, |
{0,9,12}, {19,1,12}, {18,1,12}, {1,5,12}, |
{3,3,12}, {0,8,12}, {6,2,12}, {17,1,12} |
}; |
/* Table B-14/15, DCT coefficients table zero / one, |
* codes 0000000010000 ... 0000000011111 |
*/ |
DCTtab DCTtab3[16] = |
{ |
{10,2,13}, {9,2,13}, {5,3,13}, {3,4,13}, |
{2,5,13}, {1,7,13}, {1,6,13}, {0,15,13}, |
{0,14,13}, {0,13,13}, {0,12,13}, {26,1,13}, |
{25,1,13}, {24,1,13}, {23,1,13}, {22,1,13} |
}; |
/* Table B-14/15, DCT coefficients table zero / one, |
* codes 00000000010000 ... 00000000011111 |
*/ |
DCTtab DCTtab4[16] = |
{ |
{0,31,14}, {0,30,14}, {0,29,14}, {0,28,14}, |
{0,27,14}, {0,26,14}, {0,25,14}, {0,24,14}, |
{0,23,14}, {0,22,14}, {0,21,14}, {0,20,14}, |
{0,19,14}, {0,18,14}, {0,17,14}, {0,16,14} |
}; |
/* Table B-14/15, DCT coefficients table zero / one, |
* codes 000000000010000 ... 000000000011111 |
*/ |
DCTtab DCTtab5[16] = |
{ |
{0,40,15}, {0,39,15}, {0,38,15}, {0,37,15}, |
{0,36,15}, {0,35,15}, {0,34,15}, {0,33,15}, |
{0,32,15}, {1,14,15}, {1,13,15}, {1,12,15}, |
{1,11,15}, {1,10,15}, {1,9,15}, {1,8,15} |
}; |
/* Table B-14/15, DCT coefficients table zero / one, |
* codes 0000000000010000 ... 0000000000011111 |
*/ |
DCTtab DCTtab6[16] = |
{ |
{1,18,16}, {1,17,16}, {1,16,16}, {1,15,16}, |
{6,3,16}, {16,2,16}, {15,2,16}, {14,2,16}, |
{13,2,16}, {12,2,16}, {11,2,16}, {31,1,16}, |
{30,1,16}, {29,1,16}, {28,1,16}, {27,1,16} |
}; |
/unsupported/trunk/first-official/mpeg2/mpeg2dec.h |
---|
0,0 → 1,129 |
/* mpeg2dec.h, MPEG specific defines */ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
#define ERROR (-1) |
#define PICTURE_START_CODE 0x100 |
#define SLICE_START_CODE_MIN 0x101 |
#define SLICE_START_CODE_MAX 0x1AF |
#define USER_DATA_START_CODE 0x1B2 |
#define SEQUENCE_HEADER_CODE 0x1B3 |
#define SEQUENCE_ERROR_CODE 0x1B4 |
#define EXTENSION_START_CODE 0x1B5 |
#define SEQUENCE_END_CODE 0x1B7 |
#define GROUP_START_CODE 0x1B8 |
#define SYSTEM_START_CODE_MIN 0x1B9 |
#define SYSTEM_START_CODE_MAX 0x1FF |
#define ISO_END_CODE 0x1B9 |
#define PACK_START_CODE 0x1BA |
#define SYSTEM_START_CODE 0x1BB |
#define VIDEO_ELEMENTARY_STREAM 0x1e0 |
/* scalable_mode */ |
#define SC_NONE 0 |
#define SC_DP 1 |
#define SC_SPAT 2 |
#define SC_SNR 3 |
#define SC_TEMP 4 |
/* picture coding type */ |
#define I_TYPE 1 |
#define P_TYPE 2 |
#define B_TYPE 3 |
#define D_TYPE 4 |
/* picture structure */ |
#define TOP_FIELD 1 |
#define BOTTOM_FIELD 2 |
#define FRAME_PICTURE 3 |
/* macroblock type */ |
#define MACROBLOCK_INTRA 1 |
#define MACROBLOCK_PATTERN 2 |
#define MACROBLOCK_MOTION_BACKWARD 4 |
#define MACROBLOCK_MOTION_FORWARD 8 |
#define MACROBLOCK_QUANT 16 |
#define SPATIAL_TEMPORAL_WEIGHT_CODE_FLAG 32 |
#define PERMITTED_SPATIAL_TEMPORAL_WEIGHT_CLASS 64 |
/* motion_type */ |
#define MC_FIELD 1 |
#define MC_FRAME 2 |
#define MC_16X8 2 |
#define MC_DMV 3 |
/* mv_format */ |
#define MV_FIELD 0 |
#define MV_FRAME 1 |
/* chroma_format */ |
#define CHROMA420 1 |
#define CHROMA422 2 |
#define CHROMA444 3 |
/* extension start code IDs */ |
#define SEQUENCE_EXTENSION_ID 1 |
#define SEQUENCE_DISPLAY_EXTENSION_ID 2 |
#define QUANT_MATRIX_EXTENSION_ID 3 |
#define COPYRIGHT_EXTENSION_ID 4 |
#define SEQUENCE_SCALABLE_EXTENSION_ID 5 |
#define PICTURE_DISPLAY_EXTENSION_ID 7 |
#define PICTURE_CODING_EXTENSION_ID 8 |
#define PICTURE_SPATIAL_SCALABLE_EXTENSION_ID 9 |
#define PICTURE_TEMPORAL_SCALABLE_EXTENSION_ID 10 |
#define ZIG_ZAG 0 |
#define PROFILE_422 (128+5) |
#define MAIN_LEVEL 8 |
/* Layers: used by Verbose_Flag, Verifier_Flag, Stats_Flag, and Trace_Flag */ |
#define NO_LAYER 0 |
#define SEQUENCE_LAYER 1 |
#define PICTURE_LAYER 2 |
#define SLICE_LAYER 3 |
#define MACROBLOCK_LAYER 4 |
#define BLOCK_LAYER 5 |
#define EVENT_LAYER 6 |
#define ALL_LAYERS 7 |
#define FILENAME_LENGTH 256 |
#define MB_WEIGHT 32 |
#define MB_CLASS4 64 |
/unsupported/trunk/first-official/mpeg2/const.h |
---|
0,0 → 1,141 |
/* |
* Project: S.Ha.R.K. |
* |
* Coordinators: |
* Giorgio Buttazzo <giorgio@sssup.it> |
* Paolo Gai <pj@gandalf.sssup.it> |
* |
* Authors : |
* Paolo Gai <pj@gandalf.sssup.it> |
* Massimiliano Giorgi <massy@gandalf.sssup.it> |
* Luca Abeni <luca@gandalf.sssup.it> |
* (see the web pages for full authors list) |
* |
* ReTiS Lab (Scuola Superiore S.Anna - Pisa - Italy) |
* |
* http://www.sssup.it |
* http://retis.sssup.it |
* http://shark.sssup.it |
*/ |
/** |
------------ |
CVS : $Id: const.h,v 1.1 2007-01-17 14:48:24 tullio Exp $ |
File: $File$ |
Revision: $Revision: 1.1 $ |
Last update: $Date: 2007-01-17 14:48:24 $ |
------------ |
**/ |
/* |
* Copyright (C) 2000 Marco Dallera and Marco Fiocca |
* |
* This program is free software; you can redistribute it and/or modify |
* it under the terms of the GNU General Public License as published by |
* the Free Software Foundation; either version 2 of the License, or |
* (at your option) any later version. |
* |
* This program is distributed in the hope that it will be useful, |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
* GNU General Public License for more details. |
* |
* You should have received a copy of the GNU General Public License |
* along with this program; if not, write to the Free Software |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
* |
*/ |
/* |
* AUTO |
* |
* Another Unuseful Track simulatOr |
* |
* Authors: Marco Dallera |
* Marco Fiocca |
* |
*/ |
/* ------------------ */ |
/* Useful constants */ |
/* ------------------ */ |
#ifndef __CONST_H_ |
#define __CONST_H_ |
/* Screen dimensions */ |
#define SCREEN_WIDTH 800 |
#define SCREEN_HEIGHT 600 |
#define SCREEN_BIT_COLORS 8 |
/* Visible area */ |
#define TEL_WIDTH 50 |
#define TEL_HEIGHT 50 |
/* Car dimensions */ |
#define CAR_WIDTH 12 |
#define CAR_HEIGHT 12 |
#define CAR_W 8 |
#define CAR_H 10 |
/* Track dimensions */ |
#define TRACK_WIDTH 500 |
#define TRACK_HEIGHT 500 |
/* Track position */ |
#define TRACK_X1 0 |
#define TRACK_Y1 0 |
#define TRACK_X2 TRACK_X1+TRACK_WIDTH-1 |
#define TRACK_Y2 TRACK_Y1+TRACK_HEIGHT-1 |
/* Max number of car on track */ |
#define MAX_CAR_NUMBER 10 |
#define DRIVERS_NUMBER 20 |
#define MAX_DRIVER_NAME_LENGTH 20 |
#define MAX_TRACK_NAME_LENGTH 20 |
#define TRACK_NUMBER 4 |
/* Lap direction */ |
#define CLOCK 0 |
#define ANTICLOCK 1 |
/* Information display coords */ |
#define CMD_WIDTH TRACK_WIDTH |
#define CMD_HEIGHT (SCREEN_HEIGHT-TRACK_HEIGHT-3) |
/* Car position limits */ |
#define MIN_CAR_X (TRACK_X1 + CAR_WIDTH/2 + 4) |
#define MIN_CAR_Y (TRACK_Y1 + CAR_HEIGHT/2 + 4) |
#define MAX_CAR_X (TRACK_X2 - CAR_WIDTH/2 - 4) |
#define MAX_CAR_Y (TRACK_Y2 - CAR_HEIGHT/2 - 4) |
/* Road constants */ |
#define LEFT_ONLY 10 |
#define RIGHT_ONLY 11 |
#define ROAD_OK 12 |
#define NO_ROAD 13 |
/* Collision constants */ |
#define COLLISION_LEFT 20 |
#define COLLISION_RIGHT 21 |
#define COLLISION_BACK 22 |
#define NO_COLL 0 |
/* CAB constants */ |
#define ROAD_MSG_DIM sizeof(road_info) |
#define ROAD_MSG_READER 4 |
#define CAR_MSG_DIM sizeof(car_status) |
#define CAR_MSG_READER 5 |
/* Tasks parameters */ |
#define SENSOR_WCET 3000 |
#define SENSOR_PERIOD 40000 |
#define CONTROL_WCET 1000 |
#define CONTROL_PERIOD 40000 |
#endif |
/unsupported/trunk/first-official/mpeg2/store.c |
---|
0,0 → 1,319 |
/* store.c, picture output routines */ |
/* Copyright (C) 1996, MPEG Software Simulation Group. All Rights Reserved. */ |
/* |
* Disclaimer of Warranty |
* |
* These software programs are available to the user without any license fee or |
* royalty on an "as is" basis. The MPEG Software Simulation Group disclaims |
* any and all warranties, whether express, implied, or statuary, including any |
* implied warranties or merchantability or of fitness for a particular |
* purpose. In no event shall the copyright-holder be liable for any |
* incidental, punitive, or consequential damages of any kind whatsoever |
* arising from the use of these programs. |
* |
* This disclaimer of warranty extends to the user of these programs and user's |
* customers, employees, agents, transferees, successors, and assigns. |
* |
* The MPEG Software Simulation Group does not represent or warrant that the |
* programs furnished hereunder are free of infringement of any third-party |
* patents. |
* |
* Commercial implementations of MPEG-1 and MPEG-2 video, including shareware, |
* are subject to royalty fees to patent holders. Many of these patents are |
* general enough such that they are unavoidable regardless of implementation |
* design. |
* |
*/ |
#include <stdlib.h> |
#include "drivers/glib.h" |
#include "config.h" |
#include "global.h" |
extern DWORD flbaddr; |
static void conv422to444 _ANSI_ARGS_((unsigned char *src, unsigned char *dst)); |
static void conv420to422 _ANSI_ARGS_((unsigned char *src, unsigned char *dst)); |
__inline__ WORD down32to16(unsigned char r, unsigned char g, unsigned char b) |
{ |
return ((b&0xf8)>>3)|((g&0xfc)<<3)|((r&0xf8)<<8); |
} |
void Write_Frame _ANSI_ARGS_((unsigned char *src[], int frame)) |
{ |
int i, j; |
int y, u, v, r, g, b; |
// int rm=0,gm=0,bm=0; |
int crv, cbu, cgu, cgv; |
unsigned char *py, *pu, *pv; |
int height, width, incr; |
static unsigned char *u422, *v422, *u444, *v444; |
incr = width = Coded_Picture_Width ; |
height = Coded_Picture_Height; |
if (chroma_format==CHROMA444) |
{ |
u444 = src[1]; |
v444 = src[2]; |
} |
else |
{ |
if (!u444) |
{ |
if (chroma_format==CHROMA420) |
{ |
if (!(u422 = (unsigned char *)malloc((Coded_Picture_Width>>1) |
*Coded_Picture_Height))) |
Error("malloc failed"); |
if (!(v422 = (unsigned char *)malloc((Coded_Picture_Width>>1) |
*Coded_Picture_Height))) |
Error("malloc failed"); |
} |
if (!(u444 = (unsigned char *)malloc(Coded_Picture_Width |
*Coded_Picture_Height))) |
Error("malloc failed"); |
if (!(v444 = (unsigned char *)malloc(Coded_Picture_Width |
*Coded_Picture_Height))) |
Error("malloc failed"); |
} |
if (chroma_format==CHROMA420) |
{ |
conv420to422(src[1],u422); |
conv420to422(src[2],v422); |
conv422to444(u422,u444); |
conv422to444(v422,v444); |
} |
else |
{ |
conv422to444(src[1],u444); |
conv422to444(src[2],v444); |
} |
} |
/* matrix coefficients */ |
crv = Inverse_Table_6_9[matrix_coefficients][0]; |
cbu = Inverse_Table_6_9[matrix_coefficients][1]; |
cgu = Inverse_Table_6_9[matrix_coefficients][2]; |
cgv = Inverse_Table_6_9[matrix_coefficients][3]; |
for (i=0; i<height; i++) |
{ |
py = src[0] + incr*i; |
pu = u444 + incr*i; |
pv = v444 + incr*i; |
for (j=0; j<width; j++) |
{ |
u = *pu++ - 128; |
v = *pv++ - 128; |
y = 76309 * (*py++ - 16); /* (255/219)*65536 */ |
r = Clip[(y + crv*v + 32768)>>16]; |
g = Clip[(y - cgu*u - cgv*v + 32768)>>16]; |
b = Clip[(y + cbu*u + 32786)>>16]; |
*(WORD *)(flbaddr+((i+ld->py)*800+(j+ld->px))*2) = down32to16(r,g,b); |
} |
} |
} |
/* |
void Display_Image(Dithered_Image) |
unsigned char *Dithered_Image; |
{ |
/ * display dithered image */ |
//} |
/* horizontal 1:2 interpolation filter */ |
static void conv422to444(src,dst) |
unsigned char *src,*dst; |
{ |
int i, i2, w, j, im3, im2, im1, ip1, ip2, ip3; |
w = Coded_Picture_Width>>1; |
if (base.MPEG2_Flag) |
{ |
for (j=0; j<Coded_Picture_Height; j++) |
{ |
for (i=0; i<w; i++) |
{ |
i2 = i<<1; |
im2 = (i<2) ? 0 : i-2; |
im1 = (i<1) ? 0 : i-1; |
ip1 = (i<w-1) ? i+1 : w-1; |
ip2 = (i<w-2) ? i+2 : w-1; |
ip3 = (i<w-3) ? i+3 : w-1; |
/* FIR filter coefficients (*256): 21 0 -52 0 159 256 159 0 -52 0 21 */ |
/* even samples (0 0 256 0 0) */ |
dst[i2] = src[i]; |
/* odd samples (21 -52 159 159 -52 21) */ |
dst[i2+1] = Clip[(int)(21*(src[im2]+src[ip3]) |
-52*(src[im1]+src[ip2]) |
+159*(src[i]+src[ip1])+128)>>8]; |
} |
src+= w; |
dst+= Coded_Picture_Width; |
} |
} |
else |
{ |
for (j=0; j<Coded_Picture_Height; j++) |
{ |
for (i=0; i<w; i++) |
{ |
i2 = i<<1; |
im3 = (i<3) ? 0 : i-3; |
im2 = (i<2) ? 0 : i-2; |
im1 = (i<1) ? 0 : i-1; |
ip1 = (i<w-1) ? i+1 : w-1; |
ip2 = (i<w-2) ? i+2 : w-1; |
ip3 = (i<w-3) ? i+3 : w-1; |
/* FIR filter coefficients (*256): 5 -21 70 228 -37 11 */ |
dst[i2] = Clip[(int)( 5*src[im3] |
-21*src[im2] |
+70*src[im1] |
+228*src[i] |
-37*src[ip1] |
+11*src[ip2]+128)>>8]; |
dst[i2+1] = Clip[(int)( 5*src[ip3] |
-21*src[ip2] |
+70*src[ip1] |
+228*src[i] |
-37*src[im1] |
+11*src[im2]+128)>>8]; |
} |
src+= w; |
dst+= Coded_Picture_Width; |
} |
} |
} |
/* vertical 1:2 interpolation filter */ |
static void conv420to422(src,dst) |
unsigned char *src,*dst; |
{ |
int w, h, i, j, j2; |
int jm6, jm5, jm4, jm3, jm2, jm1, jp1, jp2, jp3, jp4, jp5, jp6, jp7; |
w = Coded_Picture_Width>>1; |
h = Coded_Picture_Height>>1; |
if (progressive_frame) |
{ |
/* intra frame */ |
for (i=0; i<w; i++) |
{ |
for (j=0; j<h; j++) |
{ |
j2 = j<<1; |
jm3 = (j<3) ? 0 : j-3; |
jm2 = (j<2) ? 0 : j-2; |
jm1 = (j<1) ? 0 : j-1; |
jp1 = (j<h-1) ? j+1 : h-1; |
jp2 = (j<h-2) ? j+2 : h-1; |
jp3 = (j<h-3) ? j+3 : h-1; |
/* FIR filter coefficients (*256): 5 -21 70 228 -37 11 */ |
/* New FIR filter coefficients (*256): 3 -16 67 227 -32 7 */ |
dst[w*j2] = Clip[(int)( 3*src[w*jm3] |
-16*src[w*jm2] |
+67*src[w*jm1] |
+227*src[w*j] |
-32*src[w*jp1] |
+7*src[w*jp2]+128)>>8]; |
dst[w*(j2+1)] = Clip[(int)( 3*src[w*jp3] |
-16*src[w*jp2] |
+67*src[w*jp1] |
+227*src[w*j] |
-32*src[w*jm1] |
+7*src[w*jm2]+128)>>8]; |
} |
src++; |
dst++; |
} |
} |
else |
{ |
/* intra field */ |
for (i=0; i<w; i++) |
{ |
for (j=0; j<h; j+=2) |
{ |
j2 = j<<1; |
/* top field */ |
jm6 = (j<6) ? 0 : j-6; |
jm4 = (j<4) ? 0 : j-4; |
jm2 = (j<2) ? 0 : j-2; |
jp2 = (j<h-2) ? j+2 : h-2; |
jp4 = (j<h-4) ? j+4 : h-2; |
jp6 = (j<h-6) ? j+6 : h-2; |
/* Polyphase FIR filter coefficients (*256): 2 -10 35 242 -18 5 */ |
/* New polyphase FIR filter coefficients (*256): 1 -7 30 248 -21 5 */ |
dst[w*j2] = Clip[(int)( 1*src[w*jm6] |
-7*src[w*jm4] |
+30*src[w*jm2] |
+248*src[w*j] |
-21*src[w*jp2] |
+5*src[w*jp4]+128)>>8]; |
/* Polyphase FIR filter coefficients (*256): 11 -38 192 113 -30 8 */ |
/* New polyphase FIR filter coefficients (*256):7 -35 194 110 -24 4 */ |
dst[w*(j2+2)] = Clip[(int)( 7*src[w*jm4] |
-35*src[w*jm2] |
+194*src[w*j] |
+110*src[w*jp2] |
-24*src[w*jp4] |
+4*src[w*jp6]+128)>>8]; |
/* bottom field */ |
jm5 = (j<5) ? 1 : j-5; |
jm3 = (j<3) ? 1 : j-3; |
jm1 = (j<1) ? 1 : j-1; |
jp1 = (j<h-1) ? j+1 : h-1; |
jp3 = (j<h-3) ? j+3 : h-1; |
jp5 = (j<h-5) ? j+5 : h-1; |
jp7 = (j<h-7) ? j+7 : h-1; |
/* Polyphase FIR filter coefficients (*256): 11 -38 192 113 -30 8 */ |
/* New polyphase FIR filter coefficients (*256):7 -35 194 110 -24 4 */ |
dst[w*(j2+1)] = Clip[(int)( 7*src[w*jp5] |
-35*src[w*jp3] |
+194*src[w*jp1] |
+110*src[w*jm1] |
-24*src[w*jm3] |
+4*src[w*jm5]+128)>>8]; |
dst[w*(j2+3)] = Clip[(int)( 1*src[w*jp7] |
-7*src[w*jp5] |
+30*src[w*jp3] |
+248*src[w*jp1] |
-21*src[w*jm1] |
+5*src[w*jm3]+128)>>8]; |
} |
src++; |
dst++; |
} |
} |
} |
/unsupported/trunk/first-official/makefile |
---|
0,0 → 1,24 |
# |
# |
BASE=../.. |
include $(BASE)/config/config.mk |
PROGS= test test1 test2 |
MPEG2 = ./mpeg2/getbits.o ./mpeg2/getblk.o ./mpeg2/gethdr.o ./mpeg2/getpic.o\ |
./mpeg2/getvlc.o ./mpeg2/idct.o ./mpeg2/idctref.o ./mpeg2/motion.o\ |
./mpeg2/mpeg2dec.o ./mpeg2/recon.o ./mpeg2/spatscal.o ./mpeg2/store.o\ |
./mpeg2/subspic.o ./mpeg2/systems.o ./mpeg2/verify.o ./mpeg2/gvideo.o |
include $(BASE)/config/example.mk |
#test: |
# make -f $(SUBMAKE) APP=test INIT= OTHEROBJS= OTHERINCL= SHARKOPT="__OLDCHAR__ __FIRST__ __NEW_TRACER__" |
test1: |
make -f $(SUBMAKE) APP=test1 INIT= OTHEROBJS= OTHERINCL= SHARKOPT="__OLDCHAR__ __FIRST__ __NEW_TRACER__" |
test2: |
make -f $(SUBMAKE) APP=test2 INIT= OTHEROBJS="initfile.o $(MPEG2)" OTHERINCL= SHARKOPT="__INPUT__ __FIRST__ __NEW_TRACER__ __LINUXC26__ __PCI__ __NET__ __GRX__" |