181typedef struct plm_t plm_t;
182typedef struct plm_buffer_t plm_buffer_t;
183typedef struct plm_demux_t plm_demux_t;
184typedef struct plm_video_t plm_video_t;
185typedef struct plm_audio_t plm_audio_t;
192#define PLM_PACKET_INVALID_TS -1
231typedef void (*plm_video_decode_callback)(plm_t *self, plm_frame_t *frame,
void *user);
239#define PLM_AUDIO_SAMPLES_PER_FRAME 1152
244#ifdef PLM_AUDIO_SEPARATE_CHANNELS
245 float left[PLM_AUDIO_SAMPLES_PER_FRAME];
246 float right[PLM_AUDIO_SAMPLES_PER_FRAME];
248 float interleaved[PLM_AUDIO_SAMPLES_PER_FRAME * 2];
255typedef void (*plm_audio_decode_callback)(plm_t *self, plm_samples_t *samples,
void *user);
259typedef void (*plm_buffer_load_callback)(plm_buffer_t *self,
void *user);
268plm_t *plm_create_with_filename(
const char *filename);
273plm_t *plm_create_with_file(FIL *fh,
int close_when_done);
280plm_t *plm_create_with_memory(uint8_t *bytes,
size_t length,
int free_when_done);
286plm_t *plm_create_with_buffer(plm_buffer_t *buffer,
int destroy_when_done);
290void plm_destroy(plm_t *self);
298int plm_has_headers(plm_t *self);
302int plm_get_video_enabled(plm_t *self);
303void plm_set_video_enabled(plm_t *self,
int enabled);
307int plm_get_num_video_streams(plm_t *self);
311int plm_get_width(plm_t *self);
312int plm_get_height(plm_t *self);
316double plm_get_framerate(plm_t *self);
320int plm_get_audio_enabled(plm_t *self);
321void plm_set_audio_enabled(plm_t *self,
int enabled);
325int plm_get_num_audio_streams(plm_t *self);
329void plm_set_audio_stream(plm_t *self,
int stream_index);
333int plm_get_samplerate(plm_t *self);
340double plm_get_audio_lead_time(plm_t *self);
341void plm_set_audio_lead_time(plm_t *self,
double lead_time);
345double plm_get_time(plm_t *self);
349double plm_get_duration(plm_t *self);
353void plm_rewind(plm_t *self);
357int plm_get_loop(plm_t *self);
358void plm_set_loop(plm_t *self,
int loop);
363int plm_has_ended(plm_t *self);
369void plm_set_video_decode_callback(plm_t *self, plm_video_decode_callback fp,
void *user);
375void plm_set_audio_decode_callback(plm_t *self, plm_audio_decode_callback fp,
void *user);
382void plm_decode(plm_t *self,
double seconds);
390plm_frame_t *plm_decode_video(plm_t *self);
398plm_samples_t *plm_decode_audio(plm_t *self);
413int plm_seek(plm_t *self,
double time,
int seek_exact);
419plm_frame_t *plm_seek_frame(plm_t *self,
double time,
int seek_exact);
427#ifndef PLM_BUFFER_DEFAULT_SIZE
428#define PLM_BUFFER_DEFAULT_SIZE (128 * 1024)
434plm_buffer_t *plm_buffer_create_with_filename(
const char *filename);
439plm_buffer_t *plm_buffer_create_with_file(FIL *fh,
int close_when_done);
446plm_buffer_t *plm_buffer_create_with_memory(uint8_t *bytes,
size_t length,
int free_when_done);
451plm_buffer_t *plm_buffer_create_with_capacity(
size_t capacity);
458plm_buffer_t *plm_buffer_create_for_appending(
size_t initial_capacity);
462void plm_buffer_destroy(plm_buffer_t *self);
470size_t plm_buffer_write(plm_buffer_t *self, uint8_t *bytes,
size_t length);
477void plm_buffer_signal_end(plm_buffer_t *self);
481void plm_buffer_set_load_callback(plm_buffer_t *self, plm_buffer_load_callback fp,
void *user);
486void plm_buffer_rewind(plm_buffer_t *self);
491size_t plm_buffer_get_size(plm_buffer_t *self);
496size_t plm_buffer_get_remaining(plm_buffer_t *self);
501int plm_buffer_has_ended(plm_buffer_t *self);
509static const int PLM_DEMUX_PACKET_PRIVATE = 0xBD;
510static const int PLM_DEMUX_PACKET_AUDIO_1 = 0xC0;
511static const int PLM_DEMUX_PACKET_AUDIO_2 = 0xC1;
512static const int PLM_DEMUX_PACKET_AUDIO_3 = 0xC2;
513static const int PLM_DEMUX_PACKET_AUDIO_4 = 0xC2;
514static const int PLM_DEMUX_PACKET_VIDEO_1 = 0xE0;
519plm_demux_t *plm_demux_create(plm_buffer_t *buffer,
int destroy_when_done);
523void plm_demux_destroy(plm_demux_t *self);
528int plm_demux_has_headers(plm_demux_t *self);
533int plm_demux_get_num_video_streams(plm_demux_t *self);
538int plm_demux_get_num_audio_streams(plm_demux_t *self);
542void plm_demux_rewind(plm_demux_t *self);
546int plm_demux_has_ended(plm_demux_t *self);
554plm_packet_t *plm_demux_seek(plm_demux_t *self,
double time,
int type,
int force_intra);
559double plm_demux_get_start_time(plm_demux_t *self,
int type);
565double plm_demux_get_duration(plm_demux_t *self,
int type);
570plm_packet_t *plm_demux_decode(plm_demux_t *self);
578plm_video_t *plm_video_create_with_buffer(plm_buffer_t *buffer,
int destroy_when_done);
582void plm_video_destroy(plm_video_t *self);
587int plm_video_has_header(plm_video_t *self);
591double plm_video_get_framerate(plm_video_t *self);
595int plm_video_get_width(plm_video_t *self);
596int plm_video_get_height(plm_video_t *self);
602void plm_video_set_no_delay(plm_video_t *self,
int no_delay);
606double plm_video_get_time(plm_video_t *self);
612void plm_video_set_time(plm_video_t *self,
double time);
616void plm_video_rewind(plm_video_t *self);
620int plm_video_has_ended(plm_video_t *self);
626plm_frame_t *plm_video_decode(plm_video_t *self);
635void plm_frame_to_rgb(plm_frame_t *frame, uint8_t *dest,
int stride);
636void plm_frame_to_bgr(plm_frame_t *frame, uint8_t *dest,
int stride);
637void plm_frame_to_rgba(plm_frame_t *frame, uint8_t *dest,
int stride);
638void plm_frame_to_bgra(plm_frame_t *frame, uint8_t *dest,
int stride);
639void plm_frame_to_argb(plm_frame_t *frame, uint8_t *dest,
int stride);
640void plm_frame_to_abgr(plm_frame_t *frame, uint8_t *dest,
int stride);
648plm_audio_t *plm_audio_create_with_buffer(plm_buffer_t *buffer,
int destroy_when_done);
652void plm_audio_destroy(plm_audio_t *self);
657int plm_audio_has_header(plm_audio_t *self);
661int plm_audio_get_samplerate(plm_audio_t *self);
665double plm_audio_get_time(plm_audio_t *self);
671void plm_audio_set_time(plm_audio_t *self,
double time);
675void plm_audio_rewind(plm_audio_t *self);
679int plm_audio_has_ended(plm_audio_t *self);
686plm_samples_t *plm_audio_decode(plm_audio_t *self);
698#ifdef PL_MPEG_IMPLEMENTATION
709#define PLM_MALLOC(sz) malloc(sz)
710#define PLM_FREE(p) free(p)
711#define PLM_REALLOC(p, sz) realloc(p, sz)
714#define PLM_UNUSED(expr) (void)(expr)
727 int video_packet_type;
728 plm_buffer_t *video_buffer;
729 plm_video_t *video_decoder;
732 int audio_stream_index;
733 int audio_packet_type;
734 double audio_lead_time;
735 plm_buffer_t *audio_buffer;
736 plm_audio_t *audio_decoder;
738 plm_video_decode_callback video_decode_callback;
739 void *video_decode_callback_user_data;
741 plm_audio_decode_callback audio_decode_callback;
742 void *audio_decode_callback_user_data;
745int plm_init_decoders(plm_t *self);
746void plm_handle_end(plm_t *self);
747void plm_read_video_packet(plm_buffer_t *buffer,
void *user);
748void plm_read_audio_packet(plm_buffer_t *buffer,
void *user);
749void plm_read_packets(plm_t *self,
int requested_type);
751plm_t *plm_create_with_filename(
const char *filename) {
752 plm_buffer_t *buffer = plm_buffer_create_with_filename(filename);
756 return plm_create_with_buffer(buffer, TRUE);
759plm_t *plm_create_with_file(FIL *fh,
int close_when_done) {
760 plm_buffer_t *buffer = plm_buffer_create_with_file(fh, close_when_done);
761 return plm_create_with_buffer(buffer, TRUE);
764plm_t *plm_create_with_memory(uint8_t *bytes,
size_t length,
int free_when_done) {
765 plm_buffer_t *buffer = plm_buffer_create_with_memory(bytes, length, free_when_done);
766 return plm_create_with_buffer(buffer, TRUE);
769plm_t *plm_create_with_buffer(plm_buffer_t *buffer,
int destroy_when_done) {
770 plm_t *self = (plm_t *)PLM_MALLOC(
sizeof(plm_t));
771 memset(self, 0,
sizeof(plm_t));
773 self->demux = plm_demux_create(buffer, destroy_when_done);
774 self->video_enabled = TRUE;
775 self->audio_enabled = TRUE;
776 plm_init_decoders(self);
781int plm_init_decoders(plm_t *self) {
782 if (self->has_decoders) {
786 if (!plm_demux_has_headers(self->demux)) {
790 if (plm_demux_get_num_video_streams(self->demux) > 0) {
791 if (self->video_enabled) {
792 self->video_packet_type = PLM_DEMUX_PACKET_VIDEO_1;
794 self->video_buffer = plm_buffer_create_with_capacity(PLM_BUFFER_DEFAULT_SIZE);
795 plm_buffer_set_load_callback(self->video_buffer, plm_read_video_packet, self);
798 if (plm_demux_get_num_audio_streams(self->demux) > 0) {
799 if (self->audio_enabled) {
800 self->audio_packet_type = PLM_DEMUX_PACKET_AUDIO_1 + self->audio_stream_index;
802 self->audio_buffer = plm_buffer_create_with_capacity(PLM_BUFFER_DEFAULT_SIZE);
803 plm_buffer_set_load_callback(self->audio_buffer, plm_read_audio_packet, self);
806 if (self->video_buffer) {
807 self->video_decoder = plm_video_create_with_buffer(self->video_buffer, TRUE);
810 if (self->audio_buffer) {
811 self->audio_decoder = plm_audio_create_with_buffer(self->audio_buffer, TRUE);
814 self->has_decoders = TRUE;
818void plm_destroy(plm_t *self) {
819 if (self->video_decoder) {
820 plm_video_destroy(self->video_decoder);
822 if (self->audio_decoder) {
823 plm_audio_destroy(self->audio_decoder);
826 plm_demux_destroy(self->demux);
830int plm_get_audio_enabled(plm_t *self) {
return self->audio_enabled; }
832int plm_has_headers(plm_t *self) {
833 if (!plm_demux_has_headers(self->demux)) {
837 if (!plm_init_decoders(self)) {
841 if ((self->video_decoder && !plm_video_has_header(self->video_decoder)) ||
842 (self->audio_decoder && !plm_audio_has_header(self->audio_decoder))) {
849void plm_set_audio_enabled(plm_t *self,
int enabled) {
850 self->audio_enabled = enabled;
853 self->audio_packet_type = 0;
857 self->audio_packet_type =
858 (plm_init_decoders(self) && self->audio_decoder) ? PLM_DEMUX_PACKET_AUDIO_1 + self->audio_stream_index : 0;
861void plm_set_audio_stream(plm_t *self,
int stream_index) {
862 if (stream_index < 0 || stream_index > 3) {
865 self->audio_stream_index = stream_index;
868 plm_set_audio_enabled(self, self->audio_enabled);
871int plm_get_video_enabled(plm_t *self) {
return self->video_enabled; }
873void plm_set_video_enabled(plm_t *self,
int enabled) {
874 self->video_enabled = enabled;
877 self->video_packet_type = 0;
881 self->video_packet_type = (plm_init_decoders(self) && self->video_decoder) ? PLM_DEMUX_PACKET_VIDEO_1 : 0;
884int plm_get_num_video_streams(plm_t *self) {
return plm_demux_get_num_video_streams(self->demux); }
886int plm_get_width(plm_t *self) {
887 return (plm_init_decoders(self) && self->video_decoder) ? plm_video_get_width(self->video_decoder) : 0;
890int plm_get_height(plm_t *self) {
891 return (plm_init_decoders(self) && self->video_decoder) ? plm_video_get_height(self->video_decoder) : 0;
894double plm_get_framerate(plm_t *self) {
895 return (plm_init_decoders(self) && self->video_decoder) ? plm_video_get_framerate(self->video_decoder) : 0;
898int plm_get_num_audio_streams(plm_t *self) {
return plm_demux_get_num_audio_streams(self->demux); }
900int plm_get_samplerate(plm_t *self) {
901 return (plm_init_decoders(self) && self->audio_decoder) ? plm_audio_get_samplerate(self->audio_decoder) : 0;
904double plm_get_audio_lead_time(plm_t *self) {
return self->audio_lead_time; }
906void plm_set_audio_lead_time(plm_t *self,
double lead_time) { self->audio_lead_time = lead_time; }
908double plm_get_time(plm_t *self) {
return self->time; }
910double plm_get_duration(plm_t *self) {
return plm_demux_get_duration(self->demux, PLM_DEMUX_PACKET_VIDEO_1); }
912void plm_rewind(plm_t *self) {
913 if (self->video_decoder) {
914 plm_video_rewind(self->video_decoder);
917 if (self->audio_decoder) {
918 plm_audio_rewind(self->audio_decoder);
921 plm_demux_rewind(self->demux);
925int plm_get_loop(plm_t *self) {
return self->loop; }
927void plm_set_loop(plm_t *self,
int loop) { self->loop = loop; }
929int plm_has_ended(plm_t *self) {
return self->has_ended; }
931void plm_set_video_decode_callback(plm_t *self, plm_video_decode_callback fp,
void *user) {
932 self->video_decode_callback = fp;
933 self->video_decode_callback_user_data = user;
936void plm_set_audio_decode_callback(plm_t *self, plm_audio_decode_callback fp,
void *user) {
937 self->audio_decode_callback = fp;
938 self->audio_decode_callback_user_data = user;
941void plm_decode(plm_t *self,
double tick) {
942 if (!plm_init_decoders(self)) {
946 int decode_video = (self->video_decode_callback && self->video_packet_type);
947 int decode_audio = (self->audio_decode_callback && self->audio_packet_type);
949 if (!decode_video && !decode_audio) {
954 int did_decode = FALSE;
955 int decode_video_failed = FALSE;
956 int decode_audio_failed = FALSE;
958 double video_target_time = self->time + tick;
959 double audio_target_time = self->time + tick + self->audio_lead_time;
964 if (decode_video && plm_video_get_time(self->video_decoder) < video_target_time) {
965 plm_frame_t *frame = plm_video_decode(self->video_decoder);
967 self->video_decode_callback(self, frame, self->video_decode_callback_user_data);
970 decode_video_failed = TRUE;
974 if (decode_audio && plm_audio_get_time(self->audio_decoder) < audio_target_time) {
975 plm_samples_t *samples = plm_audio_decode(self->audio_decoder);
977 self->audio_decode_callback(self, samples, self->audio_decode_callback_user_data);
980 decode_audio_failed = TRUE;
983 }
while (did_decode);
986 if ((!decode_video || decode_video_failed) && (!decode_audio || decode_audio_failed) &&
987 plm_demux_has_ended(self->demux)) {
988 plm_handle_end(self);
995plm_frame_t *plm_decode_video(plm_t *self) {
996 if (!plm_init_decoders(self)) {
1000 if (!self->video_packet_type) {
1004 plm_frame_t *frame = plm_video_decode(self->video_decoder);
1006 self->time = frame->time;
1007 }
else if (plm_demux_has_ended(self->demux)) {
1008 plm_handle_end(self);
1013plm_samples_t *plm_decode_audio(plm_t *self) {
1014 if (!plm_init_decoders(self)) {
1018 if (!self->audio_packet_type) {
1022 plm_samples_t *samples = plm_audio_decode(self->audio_decoder);
1024 self->time = samples->time;
1025 }
else if (plm_demux_has_ended(self->demux)) {
1026 plm_handle_end(self);
1031void plm_handle_end(plm_t *self) {
1035 self->has_ended = TRUE;
1039void plm_read_video_packet(plm_buffer_t *buffer,
void *user) {
1041 plm_t *self = (plm_t *)user;
1042 plm_read_packets(self, self->video_packet_type);
1045void plm_read_audio_packet(plm_buffer_t *buffer,
void *user) {
1047 plm_t *self = (plm_t *)user;
1048 plm_read_packets(self, self->audio_packet_type);
1051void plm_read_packets(plm_t *self,
int requested_type) {
1052 plm_packet_t *packet;
1053 while ((packet = plm_demux_decode(self->demux))) {
1054 if (packet->type == self->video_packet_type) {
1055 plm_buffer_write(self->video_buffer, packet->data, packet->length);
1056 }
else if (packet->type == self->audio_packet_type) {
1057 plm_buffer_write(self->audio_buffer, packet->data, packet->length);
1060 if (packet->type == requested_type) {
1065 if (plm_demux_has_ended(self->demux)) {
1066 if (self->video_buffer) {
1067 plm_buffer_signal_end(self->video_buffer);
1069 if (self->audio_buffer) {
1070 plm_buffer_signal_end(self->audio_buffer);
1075plm_frame_t *plm_seek_frame(plm_t *self,
double time,
int seek_exact) {
1076 if (!plm_init_decoders(self)) {
1080 if (!self->video_packet_type) {
1084 int type = self->video_packet_type;
1086 double start_time = plm_demux_get_start_time(self->demux, type);
1087 double duration = plm_demux_get_duration(self->demux, type);
1091 }
else if (time > duration) {
1095 plm_packet_t *packet = plm_demux_seek(self->demux, time, type, TRUE);
1101 int previous_audio_packet_type = self->audio_packet_type;
1102 self->audio_packet_type = 0;
1105 plm_video_rewind(self->video_decoder);
1106 plm_video_set_time(self->video_decoder, packet->pts - start_time);
1107 plm_buffer_write(self->video_buffer, packet->data, packet->length);
1108 plm_frame_t *frame = plm_video_decode(self->video_decoder);
1113 while (frame && frame->time < time) {
1114 frame = plm_video_decode(self->video_decoder);
1119 self->audio_packet_type = previous_audio_packet_type;
1122 self->time = frame->time;
1125 self->has_ended = FALSE;
1129int plm_seek(plm_t *self,
double time,
int seek_exact) {
1130 plm_frame_t *frame = plm_seek_frame(self, time, seek_exact);
1136 if (self->video_decode_callback) {
1137 self->video_decode_callback(self, frame, self->video_decode_callback_user_data);
1141 if (!self->audio_packet_type) {
1149 double start_time = plm_demux_get_start_time(self->demux, self->video_packet_type);
1150 plm_audio_rewind(self->audio_decoder);
1152 plm_packet_t *packet = NULL;
1153 while ((packet = plm_demux_decode(self->demux))) {
1154 if (packet->type == self->video_packet_type) {
1155 plm_buffer_write(self->video_buffer, packet->data, packet->length);
1156 }
else if (packet->type == self->audio_packet_type && packet->pts - start_time > self->time) {
1157 plm_audio_set_time(self->audio_decoder, packet->pts - start_time);
1158 plm_buffer_write(self->audio_buffer, packet->data, packet->length);
1159 plm_decode(self, 0);
1170enum plm_buffer_mode { PLM_BUFFER_MODE_FILE, PLM_BUFFER_MODE_FIXED_MEM, PLM_BUFFER_MODE_RING, PLM_BUFFER_MODE_APPEND };
1172struct plm_buffer_t {
1177 int discard_read_bytes;
1180 int close_when_done;
1182 plm_buffer_load_callback load_callback;
1183 void *load_callback_user_data;
1185 enum plm_buffer_mode mode;
1198void plm_buffer_seek(plm_buffer_t *self,
size_t pos);
1199size_t plm_buffer_tell(plm_buffer_t *self);
1200void plm_buffer_discard_read_bytes(plm_buffer_t *self);
1201void plm_buffer_load_file_callback(plm_buffer_t *self,
void *user);
1203int plm_buffer_has(plm_buffer_t *self,
size_t count);
1204int plm_buffer_read(plm_buffer_t *self,
int count);
1205void plm_buffer_align(plm_buffer_t *self);
1206void plm_buffer_skip(plm_buffer_t *self,
size_t count);
1207int plm_buffer_skip_bytes(plm_buffer_t *self, uint8_t v);
1208int plm_buffer_next_start_code(plm_buffer_t *self);
1209int plm_buffer_find_start_code(plm_buffer_t *self,
int code);
1210int plm_buffer_no_start_code(plm_buffer_t *self);
1211int16_t plm_buffer_read_vlc(plm_buffer_t *self,
const plm_vlc_t *table);
1212uint16_t plm_buffer_read_vlc_uint(plm_buffer_t *self,
const plm_vlc_uint_t *table);
1214plm_buffer_t *plm_buffer_create_with_filename(
const char *filename) {
1215 FIL *fh = vexFileOpen(filename,
"rb");
1219 return plm_buffer_create_with_file(fh, TRUE);
1222plm_buffer_t *plm_buffer_create_with_file(FIL *fh,
int close_when_done) {
1223 plm_buffer_t *self = plm_buffer_create_with_capacity(PLM_BUFFER_DEFAULT_SIZE);
1225 self->close_when_done = close_when_done;
1226 self->mode = PLM_BUFFER_MODE_FILE;
1227 self->discard_read_bytes = TRUE;
1229 vexFileSeek(self->fh, 0, SEEK_END);
1230 self->total_size = vexFileTell(self->fh);
1231 vexFileSeek(self->fh, 0, SEEK_SET);
1233 plm_buffer_set_load_callback(self, plm_buffer_load_file_callback, NULL);
1237plm_buffer_t *plm_buffer_create_with_memory(uint8_t *bytes,
size_t length,
int free_when_done) {
1238 plm_buffer_t *self = (plm_buffer_t *)PLM_MALLOC(
sizeof(plm_buffer_t));
1239 memset(self, 0,
sizeof(plm_buffer_t));
1240 self->capacity = length;
1241 self->length = length;
1242 self->total_size = length;
1243 self->free_when_done = free_when_done;
1244 self->bytes = bytes;
1245 self->mode = PLM_BUFFER_MODE_FIXED_MEM;
1246 self->discard_read_bytes = FALSE;
1250plm_buffer_t *plm_buffer_create_with_capacity(
size_t capacity) {
1251 plm_buffer_t *self = (plm_buffer_t *)PLM_MALLOC(
sizeof(plm_buffer_t));
1252 memset(self, 0,
sizeof(plm_buffer_t));
1253 self->capacity = capacity;
1254 self->free_when_done = TRUE;
1255 self->bytes = (uint8_t *)PLM_MALLOC(capacity);
1256 self->mode = PLM_BUFFER_MODE_RING;
1257 self->discard_read_bytes = TRUE;
1261plm_buffer_t *plm_buffer_create_for_appending(
size_t initial_capacity) {
1262 plm_buffer_t *self = plm_buffer_create_with_capacity(initial_capacity);
1263 self->mode = PLM_BUFFER_MODE_APPEND;
1264 self->discard_read_bytes = FALSE;
1268void plm_buffer_destroy(plm_buffer_t *self) {
1269 if (self->fh && self->close_when_done) {
1270 vexFileClose(self->fh);
1272 if (self->free_when_done) {
1273 PLM_FREE(self->bytes);
1278size_t plm_buffer_get_size(plm_buffer_t *self) {
1279 return (self->mode == PLM_BUFFER_MODE_FILE) ? self->total_size : self->length;
1282size_t plm_buffer_get_remaining(plm_buffer_t *self) {
return self->length - (self->bit_index >> 3); }
1284size_t plm_buffer_write(plm_buffer_t *self, uint8_t *bytes,
size_t length) {
1285 if (self->mode == PLM_BUFFER_MODE_FIXED_MEM) {
1289 if (self->discard_read_bytes) {
1294 plm_buffer_discard_read_bytes(self);
1295 if (self->mode == PLM_BUFFER_MODE_RING) {
1296 self->total_size = 0;
1301 size_t bytes_available = self->capacity - self->length;
1302 if (bytes_available < length) {
1303 size_t new_size = self->capacity;
1306 }
while (new_size - self->length < length);
1307 self->bytes = (uint8_t *)PLM_REALLOC(self->bytes, new_size);
1308 self->capacity = new_size;
1311 memcpy(self->bytes + self->length, bytes, length);
1312 self->length += length;
1313 self->has_ended = FALSE;
1317void plm_buffer_signal_end(plm_buffer_t *self) { self->total_size = self->length; }
1319void plm_buffer_set_load_callback(plm_buffer_t *self, plm_buffer_load_callback fp,
void *user) {
1320 self->load_callback = fp;
1321 self->load_callback_user_data = user;
1324void plm_buffer_rewind(plm_buffer_t *self) { plm_buffer_seek(self, 0); }
1326void plm_buffer_seek(plm_buffer_t *self,
size_t pos) {
1327 self->has_ended = FALSE;
1329 if (self->mode == PLM_BUFFER_MODE_FILE) {
1330 vexFileSeek(self->fh, pos, SEEK_SET);
1331 self->bit_index = 0;
1333 }
else if (self->mode == PLM_BUFFER_MODE_RING) {
1338 self->bit_index = 0;
1340 self->total_size = 0;
1341 }
else if (pos < self->length) {
1342 self->bit_index = pos << 3;
1346size_t plm_buffer_tell(plm_buffer_t *self) {
1347 return self->mode == PLM_BUFFER_MODE_FILE ? vexFileTell(self->fh) + (self->bit_index >> 3) - self->length
1348 : self->bit_index >> 3;
1351void plm_buffer_discard_read_bytes(plm_buffer_t *self) {
1352 size_t byte_pos = self->bit_index >> 3;
1353 if (byte_pos == self->length) {
1354 self->bit_index = 0;
1356 }
else if (byte_pos > 0) {
1357 memmove(self->bytes, self->bytes + byte_pos, self->length - byte_pos);
1358 self->bit_index -= byte_pos << 3;
1359 self->length -= byte_pos;
1363void plm_buffer_load_file_callback(plm_buffer_t *self,
void *user) {
1366 if (self->discard_read_bytes) {
1367 plm_buffer_discard_read_bytes(self);
1370 size_t bytes_available = self->capacity - self->length;
1371 size_t bytes_read = vexFileRead((
char *)self->bytes + self->length, 1, bytes_available, self->fh);
1372 self->length += bytes_read;
1374 if (bytes_read == 0) {
1375 self->has_ended = TRUE;
1379int plm_buffer_has_ended(plm_buffer_t *self) {
return self->has_ended; }
1381int plm_buffer_has(plm_buffer_t *self,
size_t count) {
1382 if (((self->length << 3) - self->bit_index) >= count) {
1386 if (self->load_callback) {
1387 self->load_callback(self, self->load_callback_user_data);
1389 if (((self->length << 3) - self->bit_index) >= count) {
1394 if (self->total_size != 0 && self->length == self->total_size) {
1395 self->has_ended = TRUE;
1400int plm_buffer_read(plm_buffer_t *self,
int count) {
1401 if (!plm_buffer_has(self, count)) {
1407 int current_byte = self->bytes[self->bit_index >> 3];
1409 int remaining = 8 - (self->bit_index & 7);
1410 int read = remaining < count ? remaining : count;
1411 int shift = remaining - read;
1412 int mask = (0xff >> (8 - read));
1414 value = (value << read) | ((current_byte & (mask << shift)) >> shift);
1416 self->bit_index += read;
1423void plm_buffer_align(plm_buffer_t *self) {
1424 self->bit_index = ((self->bit_index + 7) >> 3) << 3;
1427void plm_buffer_skip(plm_buffer_t *self,
size_t count) {
1428 if (plm_buffer_has(self, count)) {
1429 self->bit_index += count;
1433int plm_buffer_skip_bytes(plm_buffer_t *self, uint8_t v) {
1434 plm_buffer_align(self);
1436 while (plm_buffer_has(self, 8) && self->bytes[self->bit_index >> 3] == v) {
1437 self->bit_index += 8;
1443int plm_buffer_next_start_code(plm_buffer_t *self) {
1444 plm_buffer_align(self);
1446 while (plm_buffer_has(self, (5 << 3))) {
1447 size_t byte_index = (self->bit_index) >> 3;
1448 if (self->bytes[byte_index] == 0x00 && self->bytes[byte_index + 1] == 0x00 && self->bytes[byte_index + 2] == 0x01) {
1449 self->bit_index = (byte_index + 4) << 3;
1450 return self->bytes[byte_index + 3];
1452 self->bit_index += 8;
1457int plm_buffer_find_start_code(plm_buffer_t *self,
int code) {
1460 current = plm_buffer_next_start_code(self);
1461 if (current == code || current == -1) {
1468int plm_buffer_has_start_code(plm_buffer_t *self,
int code) {
1469 size_t previous_bit_index = self->bit_index;
1470 int previous_discard_read_bytes = self->discard_read_bytes;
1472 self->discard_read_bytes = FALSE;
1473 int current = plm_buffer_find_start_code(self, code);
1475 self->bit_index = previous_bit_index;
1476 self->discard_read_bytes = previous_discard_read_bytes;
1480int plm_buffer_peek_non_zero(plm_buffer_t *self,
int bit_count) {
1481 if (!plm_buffer_has(self, bit_count)) {
1485 int val = plm_buffer_read(self, bit_count);
1486 self->bit_index -= bit_count;
1490int16_t plm_buffer_read_vlc(plm_buffer_t *self,
const plm_vlc_t *table) {
1491 plm_vlc_t state = {0, 0};
1493 state = table[state.index + plm_buffer_read(self, 1)];
1494 }
while (state.index > 0);
1498uint16_t plm_buffer_read_vlc_uint(plm_buffer_t *self,
const plm_vlc_uint_t *table) {
1499 return (uint16_t)plm_buffer_read_vlc(self, (
const plm_vlc_t *)table);
1505static const int PLM_START_PACK = 0xBA;
1506static const int PLM_START_END = 0xB9;
1507static const int PLM_START_SYSTEM = 0xBB;
1510 plm_buffer_t *buffer;
1511 int destroy_buffer_when_done;
1512 double system_clock_ref;
1514 size_t last_file_size;
1515 double last_decoded_pts;
1520 int has_pack_header;
1521 int has_system_header;
1524 int num_audio_streams;
1525 int num_video_streams;
1526 plm_packet_t current_packet;
1527 plm_packet_t next_packet;
1530void plm_demux_buffer_seek(plm_demux_t *self,
size_t pos);
1531double plm_demux_decode_time(plm_demux_t *self);
1532plm_packet_t *plm_demux_decode_packet(plm_demux_t *self,
int type);
1533plm_packet_t *plm_demux_get_packet(plm_demux_t *self);
1535plm_demux_t *plm_demux_create(plm_buffer_t *buffer,
int destroy_when_done) {
1536 plm_demux_t *self = (plm_demux_t *)PLM_MALLOC(
sizeof(plm_demux_t));
1537 memset(self, 0,
sizeof(plm_demux_t));
1539 self->buffer = buffer;
1540 self->destroy_buffer_when_done = destroy_when_done;
1542 self->start_time = PLM_PACKET_INVALID_TS;
1543 self->duration = PLM_PACKET_INVALID_TS;
1544 self->start_code = -1;
1546 plm_demux_has_headers(self);
1550void plm_demux_destroy(plm_demux_t *self) {
1551 if (self->destroy_buffer_when_done) {
1552 plm_buffer_destroy(self->buffer);
1557int plm_demux_has_headers(plm_demux_t *self) {
1558 if (self->has_headers) {
1563 if (!self->has_pack_header) {
1564 if (self->start_code != PLM_START_PACK && plm_buffer_find_start_code(self->buffer, PLM_START_PACK) == -1) {
1568 self->start_code = PLM_START_PACK;
1569 if (!plm_buffer_has(self->buffer, 64)) {
1572 self->start_code = -1;
1574 if (plm_buffer_read(self->buffer, 4) != 0x02) {
1578 self->system_clock_ref = plm_demux_decode_time(self);
1579 plm_buffer_skip(self->buffer, 1);
1580 plm_buffer_skip(self->buffer, 22);
1581 plm_buffer_skip(self->buffer, 1);
1583 self->has_pack_header = TRUE;
1587 if (!self->has_system_header) {
1588 if (self->start_code != PLM_START_SYSTEM && plm_buffer_find_start_code(self->buffer, PLM_START_SYSTEM) == -1) {
1592 self->start_code = PLM_START_SYSTEM;
1593 if (!plm_buffer_has(self->buffer, 56)) {
1596 self->start_code = -1;
1598 plm_buffer_skip(self->buffer, 16);
1599 plm_buffer_skip(self->buffer, 24);
1600 self->num_audio_streams = plm_buffer_read(self->buffer, 6);
1601 plm_buffer_skip(self->buffer, 5);
1602 self->num_video_streams = plm_buffer_read(self->buffer, 5);
1604 self->has_system_header = TRUE;
1607 self->has_headers = TRUE;
1611int plm_demux_get_num_video_streams(plm_demux_t *self) {
1612 return plm_demux_has_headers(self) ? self->num_video_streams : 0;
1615int plm_demux_get_num_audio_streams(plm_demux_t *self) {
1616 return plm_demux_has_headers(self) ? self->num_audio_streams : 0;
1619void plm_demux_rewind(plm_demux_t *self) {
1620 plm_buffer_rewind(self->buffer);
1621 self->current_packet.length = 0;
1622 self->next_packet.length = 0;
1623 self->start_code = -1;
1626int plm_demux_has_ended(plm_demux_t *self) {
return plm_buffer_has_ended(self->buffer); }
1628void plm_demux_buffer_seek(plm_demux_t *self,
size_t pos) {
1629 plm_buffer_seek(self->buffer, pos);
1630 self->current_packet.length = 0;
1631 self->next_packet.length = 0;
1632 self->start_code = -1;
1635double plm_demux_get_start_time(plm_demux_t *self,
int type) {
1636 if (self->start_time != PLM_PACKET_INVALID_TS) {
1637 return self->start_time;
1640 int previous_pos = plm_buffer_tell(self->buffer);
1641 int previous_start_code = self->start_code;
1644 plm_demux_rewind(self);
1646 plm_packet_t *packet = plm_demux_decode(self);
1650 if (packet->type == type) {
1651 self->start_time = packet->pts;
1653 }
while (self->start_time == PLM_PACKET_INVALID_TS);
1655 plm_demux_buffer_seek(self, previous_pos);
1656 self->start_code = previous_start_code;
1657 return self->start_time;
1660double plm_demux_get_duration(plm_demux_t *self,
int type) {
1661 size_t file_size = plm_buffer_get_size(self->buffer);
1663 if (self->duration != PLM_PACKET_INVALID_TS && self->last_file_size == file_size) {
1664 return self->duration;
1667 size_t previous_pos = plm_buffer_tell(self->buffer);
1668 int previous_start_code = self->start_code;
1672 long start_range = 64 * 1024;
1673 long max_range = 4096 * 1024;
1674 for (
long range = start_range; range <= max_range; range *= 2) {
1675 long seek_pos = file_size - range;
1680 plm_demux_buffer_seek(self, seek_pos);
1681 self->current_packet.length = 0;
1683 double last_pts = PLM_PACKET_INVALID_TS;
1684 plm_packet_t *packet = NULL;
1685 while ((packet = plm_demux_decode(self))) {
1686 if (packet->pts != PLM_PACKET_INVALID_TS && packet->type == type) {
1687 last_pts = packet->pts;
1690 if (last_pts != PLM_PACKET_INVALID_TS) {
1691 self->duration = last_pts - plm_demux_get_start_time(self, type);
1696 plm_demux_buffer_seek(self, previous_pos);
1697 self->start_code = previous_start_code;
1698 self->last_file_size = file_size;
1699 return self->duration;
1702plm_packet_t *plm_demux_seek(plm_demux_t *self,
double seek_time,
int type,
int force_intra) {
1703 if (!plm_demux_has_headers(self)) {
1723 double duration = plm_demux_get_duration(self, type);
1724 long file_size = plm_buffer_get_size(self->buffer);
1725 long byterate = file_size / duration;
1727 double cur_time = self->last_decoded_pts;
1728 double scan_span = 1;
1730 if (seek_time > duration) {
1731 seek_time = duration;
1732 }
else if (seek_time < 0) {
1735 seek_time += self->start_time;
1737 for (
int retry = 0; retry < 32; retry++) {
1738 int found_packet_with_pts = FALSE;
1739 int found_packet_in_range = FALSE;
1740 long last_valid_packet_start = -1;
1741 double first_packet_time = PLM_PACKET_INVALID_TS;
1743 long cur_pos = plm_buffer_tell(self->buffer);
1746 long offset = (seek_time - cur_time - scan_span) * byterate;
1747 long seek_pos = cur_pos + offset;
1750 }
else if (seek_pos > file_size - 256) {
1751 seek_pos = file_size - 256;
1754 plm_demux_buffer_seek(self, seek_pos);
1758 while (plm_buffer_find_start_code(self->buffer, type) != -1) {
1759 long packet_start = plm_buffer_tell(self->buffer);
1760 plm_packet_t *packet = plm_demux_decode_packet(self, type);
1763 if (!packet || packet->pts == PLM_PACKET_INVALID_TS) {
1771 if (packet->pts > seek_time || packet->pts < seek_time - scan_span) {
1772 found_packet_with_pts = TRUE;
1773 byterate = (seek_pos - cur_pos) / (packet->pts - cur_time);
1774 cur_time = packet->pts;
1783 if (!found_packet_in_range) {
1784 found_packet_in_range = TRUE;
1785 first_packet_time = packet->pts;
1793 for (
size_t i = 0; i < packet->length - 6; i++) {
1795 if (packet->data[i] == 0x00 && packet->data[i + 1] == 0x00 && packet->data[i + 2] == 0x01 &&
1796 packet->data[i + 3] == 0x00) {
1799 if ((packet->data[i + 5] & 0x38) == 8) {
1800 last_valid_packet_start = packet_start;
1809 last_valid_packet_start = packet_start;
1815 if (last_valid_packet_start != -1) {
1816 plm_demux_buffer_seek(self, last_valid_packet_start);
1817 return plm_demux_decode_packet(self, type);
1823 else if (found_packet_in_range) {
1825 seek_time = first_packet_time;
1830 else if (!found_packet_with_pts) {
1831 byterate = (seek_pos - cur_pos) / (duration - cur_time);
1832 cur_time = duration;
1839plm_packet_t *plm_demux_decode(plm_demux_t *self) {
1840 if (!plm_demux_has_headers(self)) {
1844 if (self->current_packet.length) {
1845 size_t bits_till_next_packet = self->current_packet.length << 3;
1846 if (!plm_buffer_has(self->buffer, bits_till_next_packet)) {
1849 plm_buffer_skip(self->buffer, bits_till_next_packet);
1850 self->current_packet.length = 0;
1854 if (self->next_packet.length) {
1855 return plm_demux_get_packet(self);
1859 if (self->start_code != -1) {
1860 return plm_demux_decode_packet(self, self->start_code);
1864 self->start_code = plm_buffer_next_start_code(self->buffer);
1865 if (self->start_code == PLM_DEMUX_PACKET_VIDEO_1 || self->start_code == PLM_DEMUX_PACKET_PRIVATE ||
1866 (self->start_code >= PLM_DEMUX_PACKET_AUDIO_1 && self->start_code <= PLM_DEMUX_PACKET_AUDIO_4)) {
1867 return plm_demux_decode_packet(self, self->start_code);
1869 }
while (self->start_code != -1);
1874double plm_demux_decode_time(plm_demux_t *self) {
1875 int64_t clock = plm_buffer_read(self->buffer, 3) << 30;
1876 plm_buffer_skip(self->buffer, 1);
1877 clock |= plm_buffer_read(self->buffer, 15) << 15;
1878 plm_buffer_skip(self->buffer, 1);
1879 clock |= plm_buffer_read(self->buffer, 15);
1880 plm_buffer_skip(self->buffer, 1);
1881 return (
double)clock / 90000.0;
1884plm_packet_t *plm_demux_decode_packet(plm_demux_t *self,
int type) {
1885 if (!plm_buffer_has(self->buffer, 16 << 3)) {
1889 self->start_code = -1;
1891 self->next_packet.type = type;
1892 self->next_packet.length = plm_buffer_read(self->buffer, 16);
1893 self->next_packet.length -= plm_buffer_skip_bytes(self->buffer, 0xff);
1896 if (plm_buffer_read(self->buffer, 2) == 0x01) {
1897 plm_buffer_skip(self->buffer, 16);
1898 self->next_packet.length -= 2;
1901 int pts_dts_marker = plm_buffer_read(self->buffer, 2);
1902 if (pts_dts_marker == 0x03) {
1903 self->next_packet.pts = plm_demux_decode_time(self);
1904 self->last_decoded_pts = self->next_packet.pts;
1905 plm_buffer_skip(self->buffer, 40);
1906 self->next_packet.length -= 10;
1907 }
else if (pts_dts_marker == 0x02) {
1908 self->next_packet.pts = plm_demux_decode_time(self);
1909 self->last_decoded_pts = self->next_packet.pts;
1910 self->next_packet.length -= 5;
1911 }
else if (pts_dts_marker == 0x00) {
1912 self->next_packet.pts = PLM_PACKET_INVALID_TS;
1913 plm_buffer_skip(self->buffer, 4);
1914 self->next_packet.length -= 1;
1919 return plm_demux_get_packet(self);
1922plm_packet_t *plm_demux_get_packet(plm_demux_t *self) {
1923 if (!plm_buffer_has(self->buffer, self->next_packet.length << 3)) {
1927 self->current_packet.data = self->buffer->bytes + (self->buffer->bit_index >> 3);
1928 self->current_packet.length = self->next_packet.length;
1929 self->current_packet.type = self->next_packet.type;
1930 self->current_packet.pts = self->next_packet.pts;
1932 self->next_packet.length = 0;
1933 return &self->current_packet;
1942static const int PLM_VIDEO_PICTURE_TYPE_INTRA = 1;
1943static const int PLM_VIDEO_PICTURE_TYPE_PREDICTIVE = 2;
1944static const int PLM_VIDEO_PICTURE_TYPE_B = 3;
1946static const int PLM_START_SEQUENCE = 0xB3;
1947static const int PLM_START_SLICE_FIRST = 0x01;
1948static const int PLM_START_SLICE_LAST = 0xAF;
1949static const int PLM_START_PICTURE = 0x00;
1950static const int PLM_START_EXTENSION = 0xB5;
1951static const int PLM_START_USER_DATA = 0xB2;
1953#define PLM_START_IS_SLICE(c) (c >= PLM_START_SLICE_FIRST && c <= PLM_START_SLICE_LAST)
1955static const double PLM_VIDEO_PICTURE_RATE[] = {0.000, 23.976, 24.000, 25.000, 29.970, 30.000, 50.000, 59.940,
1956 60.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000};
1958static const uint8_t PLM_VIDEO_ZIG_ZAG[] = {0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
1959 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
1960 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
1961 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63};
1963static const uint8_t PLM_VIDEO_INTRA_QUANT_MATRIX[] = {8, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37,
1964 19, 22, 26, 27, 29, 34, 34, 38, 22, 22, 26, 27, 29, 34, 37, 40,
1965 22, 26, 27, 29, 32, 35, 40, 48, 26, 27, 29, 32, 35, 40, 48, 58,
1966 26, 27, 29, 34, 38, 46, 56, 69, 27, 29, 35, 38, 46, 56, 69, 83};
1968static const uint8_t PLM_VIDEO_NON_INTRA_QUANT_MATRIX[] = {
1969 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
1970 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
1971 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16};
1973static const uint8_t PLM_VIDEO_PREMULTIPLIER_MATRIX[] = {32, 44, 42, 38, 32, 25, 17, 9, 44, 62, 58, 52, 44, 35, 24, 12,
1974 42, 58, 55, 49, 42, 33, 23, 12, 38, 52, 49, 44, 38, 30, 20, 10,
1975 32, 44, 42, 38, 32, 25, 17, 9, 25, 35, 33, 30, 25, 20, 14, 7,
1976 17, 24, 23, 20, 17, 14, 9, 5, 9, 12, 12, 10, 9, 7, 5, 2};
1978static const plm_vlc_t PLM_VIDEO_MACROBLOCK_ADDRESS_INCREMENT[] = {
1979 {1 << 1, 0}, {0, 1},
1980 {2 << 1, 0}, {3 << 1, 0},
1981 {4 << 1, 0}, {5 << 1, 0},
1983 {6 << 1, 0}, {7 << 1, 0},
1985 {8 << 1, 0}, {9 << 1, 0},
1987 {10 << 1, 0}, {11 << 1, 0},
1988 {12 << 1, 0}, {13 << 1, 0},
1989 {14 << 1, 0}, {15 << 1, 0},
1990 {16 << 1, 0}, {17 << 1, 0},
1991 {18 << 1, 0}, {19 << 1, 0},
1993 {-1, 0}, {20 << 1, 0},
1994 {-1, 0}, {21 << 1, 0},
1995 {22 << 1, 0}, {23 << 1, 0},
1999 {24 << 1, 0}, {25 << 1, 0},
2000 {26 << 1, 0}, {27 << 1, 0},
2001 {28 << 1, 0}, {29 << 1, 0},
2002 {30 << 1, 0}, {31 << 1, 0},
2003 {32 << 1, 0}, {-1, 0},
2004 {-1, 0}, {33 << 1, 0},
2005 {34 << 1, 0}, {35 << 1, 0},
2006 {36 << 1, 0}, {37 << 1, 0},
2007 {38 << 1, 0}, {39 << 1, 0},
2021static const plm_vlc_t PLM_VIDEO_MACROBLOCK_TYPE_INTRA[] = {
2028static const plm_vlc_t PLM_VIDEO_MACROBLOCK_TYPE_PREDICTIVE[] = {
2029 {1 << 1, 0}, {0, 0x0a},
2030 {2 << 1, 0}, {0, 0x02},
2031 {3 << 1, 0}, {0, 0x08},
2032 {4 << 1, 0}, {5 << 1, 0},
2033 {6 << 1, 0}, {0, 0x12},
2034 {0, 0x1a}, {0, 0x01},
2038static const plm_vlc_t PLM_VIDEO_MACROBLOCK_TYPE_B[] = {
2039 {1 << 1, 0}, {2 << 1, 0},
2040 {3 << 1, 0}, {4 << 1, 0},
2041 {0, 0x0c}, {0, 0x0e},
2042 {5 << 1, 0}, {6 << 1, 0},
2043 {0, 0x04}, {0, 0x06},
2044 {7 << 1, 0}, {8 << 1, 0},
2045 {0, 0x08}, {0, 0x0a},
2046 {9 << 1, 0}, {10 << 1, 0},
2047 {0, 0x1e}, {0, 0x01},
2049 {0, 0x16}, {0, 0x1a},
2052static const plm_vlc_t *PLM_VIDEO_MACROBLOCK_TYPE[] = {
2053 NULL, PLM_VIDEO_MACROBLOCK_TYPE_INTRA, PLM_VIDEO_MACROBLOCK_TYPE_PREDICTIVE, PLM_VIDEO_MACROBLOCK_TYPE_B};
2055static const plm_vlc_t PLM_VIDEO_CODE_BLOCK_PATTERN[] = {
2056 {1 << 1, 0}, {2 << 1, 0},
2057 {3 << 1, 0}, {4 << 1, 0},
2058 {5 << 1, 0}, {6 << 1, 0},
2059 {7 << 1, 0}, {8 << 1, 0},
2060 {9 << 1, 0}, {10 << 1, 0},
2061 {11 << 1, 0}, {12 << 1, 0},
2062 {13 << 1, 0}, {0, 60},
2063 {14 << 1, 0}, {15 << 1, 0},
2064 {16 << 1, 0}, {17 << 1, 0},
2065 {18 << 1, 0}, {19 << 1, 0},
2066 {20 << 1, 0}, {21 << 1, 0},
2067 {22 << 1, 0}, {23 << 1, 0},
2070 {24 << 1, 0}, {25 << 1, 0},
2071 {26 << 1, 0}, {27 << 1, 0},
2072 {28 << 1, 0}, {29 << 1, 0},
2073 {30 << 1, 0}, {31 << 1, 0},
2080 {32 << 1, 0}, {33 << 1, 0},
2081 {34 << 1, 0}, {35 << 1, 0},
2082 {36 << 1, 0}, {37 << 1, 0},
2083 {38 << 1, 0}, {39 << 1, 0},
2084 {40 << 1, 0}, {41 << 1, 0},
2085 {42 << 1, 0}, {43 << 1, 0},
2088 {44 << 1, 0}, {45 << 1, 0},
2089 {46 << 1, 0}, {47 << 1, 0},
2090 {48 << 1, 0}, {49 << 1, 0},
2091 {50 << 1, 0}, {51 << 1, 0},
2092 {52 << 1, 0}, {53 << 1, 0},
2093 {54 << 1, 0}, {55 << 1, 0},
2094 {56 << 1, 0}, {57 << 1, 0},
2095 {58 << 1, 0}, {59 << 1, 0},
2100 {-1, 0}, {60 << 1, 0},
2101 {61 << 1, 0}, {62 << 1, 0},
2121static const plm_vlc_t PLM_VIDEO_MOTION[] = {
2122 {1 << 1, 0}, {0, 0},
2123 {2 << 1, 0}, {3 << 1, 0},
2124 {4 << 1, 0}, {5 << 1, 0},
2126 {6 << 1, 0}, {7 << 1, 0},
2128 {8 << 1, 0}, {9 << 1, 0},
2130 {10 << 1, 0}, {11 << 1, 0},
2131 {12 << 1, 0}, {13 << 1, 0},
2132 {-1, 0}, {14 << 1, 0},
2133 {15 << 1, 0}, {16 << 1, 0},
2134 {17 << 1, 0}, {18 << 1, 0},
2136 {-1, 0}, {19 << 1, 0},
2137 {20 << 1, 0}, {21 << 1, 0},
2141 {22 << 1, 0}, {23 << 1, 0},
2142 {24 << 1, 0}, {25 << 1, 0},
2143 {26 << 1, 0}, {27 << 1, 0},
2144 {28 << 1, 0}, {29 << 1, 0},
2145 {30 << 1, 0}, {31 << 1, 0},
2146 {32 << 1, 0}, {33 << 1, 0},
2158static const plm_vlc_t PLM_VIDEO_DCT_SIZE_LUMINANCE[] = {
2159 {1 << 1, 0}, {2 << 1, 0},
2161 {3 << 1, 0}, {4 << 1, 0},
2163 {0, 4}, {5 << 1, 0},
2164 {0, 5}, {6 << 1, 0},
2165 {0, 6}, {7 << 1, 0},
2166 {0, 7}, {8 << 1, 0},
2170static const plm_vlc_t PLM_VIDEO_DCT_SIZE_CHROMINANCE[] = {
2171 {1 << 1, 0}, {2 << 1, 0},
2173 {0, 2}, {3 << 1, 0},
2174 {0, 3}, {4 << 1, 0},
2175 {0, 4}, {5 << 1, 0},
2176 {0, 5}, {6 << 1, 0},
2177 {0, 6}, {7 << 1, 0},
2178 {0, 7}, {8 << 1, 0},
2182static const plm_vlc_t *PLM_VIDEO_DCT_SIZE[] = {PLM_VIDEO_DCT_SIZE_LUMINANCE, PLM_VIDEO_DCT_SIZE_CHROMINANCE,
2183 PLM_VIDEO_DCT_SIZE_CHROMINANCE};
2191static const plm_vlc_uint_t PLM_VIDEO_DCT_COEFF[] = {
2192 {1 << 1, 0}, {0, 0x0001},
2193 {2 << 1, 0}, {3 << 1, 0},
2194 {4 << 1, 0}, {5 << 1, 0},
2195 {6 << 1, 0}, {0, 0x0101},
2196 {7 << 1, 0}, {8 << 1, 0},
2197 {9 << 1, 0}, {10 << 1, 0},
2198 {0, 0x0002}, {0, 0x0201},
2199 {11 << 1, 0}, {12 << 1, 0},
2200 {13 << 1, 0}, {14 << 1, 0},
2201 {15 << 1, 0}, {0, 0x0003},
2202 {0, 0x0401}, {0, 0x0301},
2203 {16 << 1, 0}, {0, 0xffff},
2204 {17 << 1, 0}, {18 << 1, 0},
2205 {0, 0x0701}, {0, 0x0601},
2206 {0, 0x0102}, {0, 0x0501},
2207 {19 << 1, 0}, {20 << 1, 0},
2208 {21 << 1, 0}, {22 << 1, 0},
2209 {0, 0x0202}, {0, 0x0901},
2210 {0, 0x0004}, {0, 0x0801},
2211 {23 << 1, 0}, {24 << 1, 0},
2212 {25 << 1, 0}, {26 << 1, 0},
2213 {27 << 1, 0}, {28 << 1, 0},
2214 {29 << 1, 0}, {30 << 1, 0},
2215 {0, 0x0d01}, {0, 0x0006},
2216 {0, 0x0c01}, {0, 0x0b01},
2217 {0, 0x0302}, {0, 0x0103},
2218 {0, 0x0005}, {0, 0x0a01},
2219 {31 << 1, 0}, {32 << 1, 0},
2220 {33 << 1, 0}, {34 << 1, 0},
2221 {35 << 1, 0}, {36 << 1, 0},
2222 {37 << 1, 0}, {38 << 1, 0},
2223 {39 << 1, 0}, {40 << 1, 0},
2224 {41 << 1, 0}, {42 << 1, 0},
2225 {43 << 1, 0}, {44 << 1, 0},
2226 {45 << 1, 0}, {46 << 1, 0},
2227 {0, 0x1001}, {0, 0x0502},
2228 {0, 0x0007}, {0, 0x0203},
2229 {0, 0x0104}, {0, 0x0f01},
2230 {0, 0x0e01}, {0, 0x0402},
2231 {47 << 1, 0}, {48 << 1, 0},
2232 {49 << 1, 0}, {50 << 1, 0},
2233 {51 << 1, 0}, {52 << 1, 0},
2234 {53 << 1, 0}, {54 << 1, 0},
2235 {55 << 1, 0}, {56 << 1, 0},
2236 {57 << 1, 0}, {58 << 1, 0},
2237 {59 << 1, 0}, {60 << 1, 0},
2238 {61 << 1, 0}, {62 << 1, 0},
2239 {-1, 0}, {63 << 1, 0},
2240 {64 << 1, 0}, {65 << 1, 0},
2241 {66 << 1, 0}, {67 << 1, 0},
2242 {68 << 1, 0}, {69 << 1, 0},
2243 {70 << 1, 0}, {71 << 1, 0},
2244 {72 << 1, 0}, {73 << 1, 0},
2245 {74 << 1, 0}, {75 << 1, 0},
2246 {76 << 1, 0}, {77 << 1, 0},
2247 {0, 0x000b}, {0, 0x0802},
2248 {0, 0x0403}, {0, 0x000a},
2249 {0, 0x0204}, {0, 0x0702},
2250 {0, 0x1501}, {0, 0x1401},
2251 {0, 0x0009}, {0, 0x1301},
2252 {0, 0x1201}, {0, 0x0105},
2253 {0, 0x0303}, {0, 0x0008},
2254 {0, 0x0602}, {0, 0x1101},
2255 {78 << 1, 0}, {79 << 1, 0},
2256 {80 << 1, 0}, {81 << 1, 0},
2257 {82 << 1, 0}, {83 << 1, 0},
2258 {84 << 1, 0}, {85 << 1, 0},
2259 {86 << 1, 0}, {87 << 1, 0},
2260 {88 << 1, 0}, {89 << 1, 0},
2261 {90 << 1, 0}, {91 << 1, 0},
2262 {0, 0x0a02}, {0, 0x0902},
2263 {0, 0x0503}, {0, 0x0304},
2264 {0, 0x0205}, {0, 0x0107},
2265 {0, 0x0106}, {0, 0x000f},
2266 {0, 0x000e}, {0, 0x000d},
2267 {0, 0x000c}, {0, 0x1a01},
2268 {0, 0x1901}, {0, 0x1801},
2269 {0, 0x1701}, {0, 0x1601},
2270 {92 << 1, 0}, {93 << 1, 0},
2271 {94 << 1, 0}, {95 << 1, 0},
2272 {96 << 1, 0}, {97 << 1, 0},
2273 {98 << 1, 0}, {99 << 1, 0},
2274 {100 << 1, 0}, {101 << 1, 0},
2275 {102 << 1, 0}, {103 << 1, 0},
2276 {0, 0x001f}, {0, 0x001e},
2277 {0, 0x001d}, {0, 0x001c},
2278 {0, 0x001b}, {0, 0x001a},
2279 {0, 0x0019}, {0, 0x0018},
2280 {0, 0x0017}, {0, 0x0016},
2281 {0, 0x0015}, {0, 0x0014},
2282 {0, 0x0013}, {0, 0x0012},
2283 {0, 0x0011}, {0, 0x0010},
2284 {104 << 1, 0}, {105 << 1, 0},
2285 {106 << 1, 0}, {107 << 1, 0},
2286 {108 << 1, 0}, {109 << 1, 0},
2287 {110 << 1, 0}, {111 << 1, 0},
2288 {0, 0x0028}, {0, 0x0027},
2289 {0, 0x0026}, {0, 0x0025},
2290 {0, 0x0024}, {0, 0x0023},
2291 {0, 0x0022}, {0, 0x0021},
2292 {0, 0x0020}, {0, 0x010e},
2293 {0, 0x010d}, {0, 0x010c},
2294 {0, 0x010b}, {0, 0x010a},
2295 {0, 0x0109}, {0, 0x0108},
2296 {0, 0x0112}, {0, 0x0111},
2297 {0, 0x0110}, {0, 0x010f},
2298 {0, 0x0603}, {0, 0x1002},
2299 {0, 0x0f02}, {0, 0x0e02},
2300 {0, 0x0d02}, {0, 0x0c02},
2301 {0, 0x0b02}, {0, 0x1f01},
2302 {0, 0x1e01}, {0, 0x1d01},
2303 {0, 0x1c01}, {0, 0x1b01},
2312} plm_video_motion_t;
2333 plm_video_motion_t motion_forward;
2334 plm_video_motion_t motion_backward;
2336 int has_sequence_header;
2338 int quantizer_scale;
2340 int macroblock_address;
2345 int macroblock_type;
2346 int macroblock_intra;
2348 int dc_predictor[3];
2350 plm_buffer_t *buffer;
2351 int destroy_buffer_when_done;
2353 plm_frame_t frame_current;
2354 plm_frame_t frame_forward;
2355 plm_frame_t frame_backward;
2357 uint8_t *frames_data;
2360 uint8_t intra_quant_matrix[64];
2361 uint8_t non_intra_quant_matrix[64];
2363 int has_reference_frame;
2364 int assume_no_b_frames;
2367static inline uint8_t plm_clamp(
int n) {
2376int plm_video_decode_sequence_header(plm_video_t *self);
2377void plm_video_init_frame(plm_video_t *self, plm_frame_t *frame, uint8_t *base);
2378void plm_video_decode_picture(plm_video_t *self);
2379void plm_video_decode_slice(plm_video_t *self,
int slice);
2380void plm_video_decode_macroblock(plm_video_t *self);
2381void plm_video_decode_motion_vectors(plm_video_t *self);
2382int plm_video_decode_motion_vector(plm_video_t *self,
int r_size,
int motion);
2383void plm_video_predict_macroblock(plm_video_t *self);
2384void plm_video_copy_macroblock(plm_video_t *self, plm_frame_t *s,
int motion_h,
int motion_v);
2385void plm_video_interpolate_macroblock(plm_video_t *self, plm_frame_t *s,
int motion_h,
int motion_v);
2386void plm_video_process_macroblock(plm_video_t *self, uint8_t *s, uint8_t *d,
int mh,
int mb,
int bs,
int interp);
2387void plm_video_decode_block(plm_video_t *self,
int block);
2388void plm_video_idct(
int *block);
2390plm_video_t *plm_video_create_with_buffer(plm_buffer_t *buffer,
int destroy_when_done) {
2391 plm_video_t *self = (plm_video_t *)PLM_MALLOC(
sizeof(plm_video_t));
2392 memset(self, 0,
sizeof(plm_video_t));
2394 self->buffer = buffer;
2395 self->destroy_buffer_when_done = destroy_when_done;
2398 self->start_code = plm_buffer_find_start_code(self->buffer, PLM_START_SEQUENCE);
2399 if (self->start_code != -1) {
2400 plm_video_decode_sequence_header(self);
2405void plm_video_destroy(plm_video_t *self) {
2406 if (self->destroy_buffer_when_done) {
2407 plm_buffer_destroy(self->buffer);
2410 if (self->has_sequence_header) {
2411 PLM_FREE(self->frames_data);
2417double plm_video_get_framerate(plm_video_t *self) {
return plm_video_has_header(self) ? self->framerate : 0; }
2419int plm_video_get_width(plm_video_t *self) {
return plm_video_has_header(self) ? self->width : 0; }
2421int plm_video_get_height(plm_video_t *self) {
return plm_video_has_header(self) ? self->height : 0; }
2423void plm_video_set_no_delay(plm_video_t *self,
int no_delay) { self->assume_no_b_frames = no_delay; }
2425double plm_video_get_time(plm_video_t *self) {
return self->time; }
2427void plm_video_set_time(plm_video_t *self,
double time) {
2428 self->frames_decoded = self->framerate * time;
2432void plm_video_rewind(plm_video_t *self) {
2433 plm_buffer_rewind(self->buffer);
2435 self->frames_decoded = 0;
2436 self->has_reference_frame = FALSE;
2437 self->start_code = -1;
2440int plm_video_has_ended(plm_video_t *self) {
return plm_buffer_has_ended(self->buffer); }
2442plm_frame_t *plm_video_decode(plm_video_t *self) {
2443 if (!plm_video_has_header(self)) {
2447 plm_frame_t *frame = NULL;
2449 if (self->start_code != PLM_START_PICTURE) {
2450 self->start_code = plm_buffer_find_start_code(self->buffer, PLM_START_PICTURE);
2452 if (self->start_code == -1) {
2455 if (self->has_reference_frame && !self->assume_no_b_frames && plm_buffer_has_ended(self->buffer) &&
2456 (self->picture_type == PLM_VIDEO_PICTURE_TYPE_INTRA ||
2457 self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE)) {
2458 self->has_reference_frame = FALSE;
2459 frame = &self->frame_backward;
2472 if (plm_buffer_has_start_code(self->buffer, PLM_START_PICTURE) == -1 && !plm_buffer_has_ended(self->buffer)) {
2475 plm_buffer_discard_read_bytes(self->buffer);
2477 plm_video_decode_picture(self);
2479 if (self->assume_no_b_frames) {
2480 frame = &self->frame_backward;
2481 }
else if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_B) {
2482 frame = &self->frame_current;
2483 }
else if (self->has_reference_frame) {
2484 frame = &self->frame_forward;
2486 self->has_reference_frame = TRUE;
2490 frame->time = self->time;
2491 self->frames_decoded++;
2492 self->time = (double)self->frames_decoded / self->framerate;
2497int plm_video_has_header(plm_video_t *self) {
2498 if (self->has_sequence_header) {
2502 if (self->start_code != PLM_START_SEQUENCE) {
2503 self->start_code = plm_buffer_find_start_code(self->buffer, PLM_START_SEQUENCE);
2505 if (self->start_code == -1) {
2509 if (!plm_video_decode_sequence_header(self)) {
2516int plm_video_decode_sequence_header(plm_video_t *self) {
2517 int max_header_size = 64 + 2 * 64 * 8;
2518 if (!plm_buffer_has(self->buffer, max_header_size)) {
2522 self->width = plm_buffer_read(self->buffer, 12);
2523 self->height = plm_buffer_read(self->buffer, 12);
2525 if (self->width <= 0 || self->height <= 0) {
2530 plm_buffer_skip(self->buffer, 4);
2532 self->framerate = PLM_VIDEO_PICTURE_RATE[plm_buffer_read(self->buffer, 4)];
2535 plm_buffer_skip(self->buffer, 18 + 1 + 10 + 1);
2538 if (plm_buffer_read(self->buffer, 1)) {
2539 for (
int i = 0; i < 64; i++) {
2540 int idx = PLM_VIDEO_ZIG_ZAG[i];
2541 self->intra_quant_matrix[idx] = plm_buffer_read(self->buffer, 8);
2544 memcpy(self->intra_quant_matrix, PLM_VIDEO_INTRA_QUANT_MATRIX, 64);
2548 if (plm_buffer_read(self->buffer, 1)) {
2549 for (
int i = 0; i < 64; i++) {
2550 int idx = PLM_VIDEO_ZIG_ZAG[i];
2551 self->non_intra_quant_matrix[idx] = plm_buffer_read(self->buffer, 8);
2554 memcpy(self->non_intra_quant_matrix, PLM_VIDEO_NON_INTRA_QUANT_MATRIX, 64);
2557 self->mb_width = (self->width + 15) >> 4;
2558 self->mb_height = (self->height + 15) >> 4;
2559 self->mb_size = self->mb_width * self->mb_height;
2561 self->luma_width = self->mb_width << 4;
2562 self->luma_height = self->mb_height << 4;
2564 self->chroma_width = self->mb_width << 3;
2565 self->chroma_height = self->mb_height << 3;
2568 size_t luma_plane_size = self->luma_width * self->luma_height;
2569 size_t chroma_plane_size = self->chroma_width * self->chroma_height;
2570 size_t frame_data_size = (luma_plane_size + 2 * chroma_plane_size);
2572 self->frames_data = (uint8_t *)PLM_MALLOC(frame_data_size * 3);
2573 plm_video_init_frame(self, &self->frame_current, self->frames_data + frame_data_size * 0);
2574 plm_video_init_frame(self, &self->frame_forward, self->frames_data + frame_data_size * 1);
2575 plm_video_init_frame(self, &self->frame_backward, self->frames_data + frame_data_size * 2);
2577 self->has_sequence_header = TRUE;
2581void plm_video_init_frame(plm_video_t *self, plm_frame_t *frame, uint8_t *base) {
2582 size_t luma_plane_size = self->luma_width * self->luma_height;
2583 size_t chroma_plane_size = self->chroma_width * self->chroma_height;
2585 frame->width = self->width;
2586 frame->height = self->height;
2587 frame->y.width = self->luma_width;
2588 frame->y.height = self->luma_height;
2589 frame->y.data = base;
2591 frame->cr.width = self->chroma_width;
2592 frame->cr.height = self->chroma_height;
2593 frame->cr.data = base + luma_plane_size;
2595 frame->cb.width = self->chroma_width;
2596 frame->cb.height = self->chroma_height;
2597 frame->cb.data = base + luma_plane_size + chroma_plane_size;
2600void plm_video_decode_picture(plm_video_t *self) {
2601 plm_buffer_skip(self->buffer, 10);
2602 self->picture_type = plm_buffer_read(self->buffer, 3);
2603 plm_buffer_skip(self->buffer, 16);
2606 if (self->picture_type <= 0 || self->picture_type > PLM_VIDEO_PICTURE_TYPE_B) {
2611 if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE || self->picture_type == PLM_VIDEO_PICTURE_TYPE_B) {
2612 self->motion_forward.full_px = plm_buffer_read(self->buffer, 1);
2613 int f_code = plm_buffer_read(self->buffer, 3);
2618 self->motion_forward.r_size = f_code - 1;
2622 if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_B) {
2623 self->motion_backward.full_px = plm_buffer_read(self->buffer, 1);
2624 int f_code = plm_buffer_read(self->buffer, 3);
2629 self->motion_backward.r_size = f_code - 1;
2632 plm_frame_t frame_temp = self->frame_forward;
2633 if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_INTRA || self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE) {
2634 self->frame_forward = self->frame_backward;
2639 self->start_code = plm_buffer_next_start_code(self->buffer);
2640 }
while (self->start_code == PLM_START_EXTENSION || self->start_code == PLM_START_USER_DATA);
2643 while (PLM_START_IS_SLICE(self->start_code)) {
2644 plm_video_decode_slice(self, self->start_code & 0x000000FF);
2645 if (self->macroblock_address >= self->mb_size - 2) {
2648 self->start_code = plm_buffer_next_start_code(self->buffer);
2652 if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_INTRA || self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE) {
2653 self->frame_backward = self->frame_current;
2654 self->frame_current = frame_temp;
2658void plm_video_decode_slice(plm_video_t *self,
int slice) {
2659 self->slice_begin = TRUE;
2660 self->macroblock_address = (slice - 1) * self->mb_width - 1;
2663 self->motion_backward.h = self->motion_forward.h = 0;
2664 self->motion_backward.v = self->motion_forward.v = 0;
2665 self->dc_predictor[0] = 128;
2666 self->dc_predictor[1] = 128;
2667 self->dc_predictor[2] = 128;
2669 self->quantizer_scale = plm_buffer_read(self->buffer, 5);
2672 while (plm_buffer_read(self->buffer, 1)) {
2673 plm_buffer_skip(self->buffer, 8);
2677 plm_video_decode_macroblock(self);
2678 }
while (self->macroblock_address < self->mb_size - 1 && plm_buffer_peek_non_zero(self->buffer, 23));
2681void plm_video_decode_macroblock(plm_video_t *self) {
2684 int t = plm_buffer_read_vlc(self->buffer, PLM_VIDEO_MACROBLOCK_ADDRESS_INCREMENT);
2688 t = plm_buffer_read_vlc(self->buffer, PLM_VIDEO_MACROBLOCK_ADDRESS_INCREMENT);
2693 t = plm_buffer_read_vlc(self->buffer, PLM_VIDEO_MACROBLOCK_ADDRESS_INCREMENT);
2698 if (self->slice_begin) {
2701 self->slice_begin = FALSE;
2702 self->macroblock_address += increment;
2704 if (self->macroblock_address + increment >= self->mb_size) {
2707 if (increment > 1) {
2709 self->dc_predictor[0] = 128;
2710 self->dc_predictor[1] = 128;
2711 self->dc_predictor[2] = 128;
2714 if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE) {
2715 self->motion_forward.h = 0;
2716 self->motion_forward.v = 0;
2721 while (increment > 1) {
2722 self->macroblock_address++;
2723 self->mb_row = self->macroblock_address / self->mb_width;
2724 self->mb_col = self->macroblock_address % self->mb_width;
2726 plm_video_predict_macroblock(self);
2729 self->macroblock_address++;
2732 self->mb_row = self->macroblock_address / self->mb_width;
2733 self->mb_col = self->macroblock_address % self->mb_width;
2735 if (self->mb_col >= self->mb_width || self->mb_row >= self->mb_height) {
2740 const plm_vlc_t *table = PLM_VIDEO_MACROBLOCK_TYPE[self->picture_type];
2741 self->macroblock_type = plm_buffer_read_vlc(self->buffer, table);
2743 self->macroblock_intra = (self->macroblock_type & 0x01);
2744 self->motion_forward.is_set = (self->macroblock_type & 0x08);
2745 self->motion_backward.is_set = (self->macroblock_type & 0x04);
2748 if ((self->macroblock_type & 0x10) != 0) {
2749 self->quantizer_scale = plm_buffer_read(self->buffer, 5);
2752 if (self->macroblock_intra) {
2754 self->motion_backward.h = self->motion_forward.h = 0;
2755 self->motion_backward.v = self->motion_forward.v = 0;
2758 self->dc_predictor[0] = 128;
2759 self->dc_predictor[1] = 128;
2760 self->dc_predictor[2] = 128;
2762 plm_video_decode_motion_vectors(self);
2763 plm_video_predict_macroblock(self);
2767 int cbp = ((self->macroblock_type & 0x02) != 0) ? plm_buffer_read_vlc(self->buffer, PLM_VIDEO_CODE_BLOCK_PATTERN)
2768 : (self->macroblock_intra ? 0x3f : 0);
2770 for (
int block = 0, mask = 0x20; block < 6; block++) {
2771 if ((cbp & mask) != 0) {
2772 plm_video_decode_block(self, block);
2778void plm_video_decode_motion_vectors(plm_video_t *self) {
2781 if (self->motion_forward.is_set) {
2782 int r_size = self->motion_forward.r_size;
2783 self->motion_forward.h = plm_video_decode_motion_vector(self, r_size, self->motion_forward.h);
2784 self->motion_forward.v = plm_video_decode_motion_vector(self, r_size, self->motion_forward.v);
2785 }
else if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE) {
2787 self->motion_forward.h = 0;
2788 self->motion_forward.v = 0;
2791 if (self->motion_backward.is_set) {
2792 int r_size = self->motion_backward.r_size;
2793 self->motion_backward.h = plm_video_decode_motion_vector(self, r_size, self->motion_backward.h);
2794 self->motion_backward.v = plm_video_decode_motion_vector(self, r_size, self->motion_backward.v);
2798int plm_video_decode_motion_vector(plm_video_t *self,
int r_size,
int motion) {
2799 int fscale = 1 << r_size;
2800 int m_code = plm_buffer_read_vlc(self->buffer, PLM_VIDEO_MOTION);
2804 if ((m_code != 0) && (fscale != 1)) {
2805 r = plm_buffer_read(self->buffer, r_size);
2806 d = ((abs(m_code) - 1) << r_size) + r + 1;
2815 if (motion > (fscale << 4) - 1) {
2816 motion -= fscale << 5;
2817 }
else if (motion < ((-fscale) << 4)) {
2818 motion += fscale << 5;
2824void plm_video_predict_macroblock(plm_video_t *self) {
2825 int fw_h = self->motion_forward.h;
2826 int fw_v = self->motion_forward.v;
2828 if (self->motion_forward.full_px) {
2833 if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_B) {
2834 int bw_h = self->motion_backward.h;
2835 int bw_v = self->motion_backward.v;
2837 if (self->motion_backward.full_px) {
2842 if (self->motion_forward.is_set) {
2843 plm_video_copy_macroblock(self, &self->frame_forward, fw_h, fw_v);
2844 if (self->motion_backward.is_set) {
2845 plm_video_interpolate_macroblock(self, &self->frame_backward, bw_h, bw_v);
2848 plm_video_copy_macroblock(self, &self->frame_backward, bw_h, bw_v);
2851 plm_video_copy_macroblock(self, &self->frame_forward, fw_h, fw_v);
2855void plm_video_copy_macroblock(plm_video_t *self, plm_frame_t *s,
int motion_h,
int motion_v) {
2856 plm_frame_t *d = &self->frame_current;
2857 plm_video_process_macroblock(self, s->y.data, d->y.data, motion_h, motion_v, 16, FALSE);
2858 plm_video_process_macroblock(self, s->cr.data, d->cr.data, motion_h / 2, motion_v / 2, 8, FALSE);
2859 plm_video_process_macroblock(self, s->cb.data, d->cb.data, motion_h / 2, motion_v / 2, 8, FALSE);
2862void plm_video_interpolate_macroblock(plm_video_t *self, plm_frame_t *s,
int motion_h,
int motion_v) {
2863 plm_frame_t *d = &self->frame_current;
2864 plm_video_process_macroblock(self, s->y.data, d->y.data, motion_h, motion_v, 16, TRUE);
2865 plm_video_process_macroblock(self, s->cr.data, d->cr.data, motion_h / 2, motion_v / 2, 8, TRUE);
2866 plm_video_process_macroblock(self, s->cb.data, d->cb.data, motion_h / 2, motion_v / 2, 8, TRUE);
2869#define PLM_BLOCK_SET(DEST, DEST_INDEX, DEST_WIDTH, SOURCE_INDEX, SOURCE_WIDTH, BLOCK_SIZE, OP) \
2871 int dest_scan = DEST_WIDTH - BLOCK_SIZE; \
2872 int source_scan = SOURCE_WIDTH - BLOCK_SIZE; \
2873 for (int y = 0; y < BLOCK_SIZE; y++) { \
2874 for (int x = 0; x < BLOCK_SIZE; x++) { \
2875 DEST[DEST_INDEX] = OP; \
2879 SOURCE_INDEX += source_scan; \
2880 DEST_INDEX += dest_scan; \
2884void plm_video_process_macroblock(plm_video_t *self, uint8_t *s, uint8_t *d,
int motion_h,
int motion_v,
int block_size,
2886 int dw = self->mb_width * block_size;
2888 int hp = motion_h >> 1;
2889 int vp = motion_v >> 1;
2890 int odd_h = (motion_h & 1) == 1;
2891 int odd_v = (motion_v & 1) == 1;
2893 unsigned int si = ((self->mb_row * block_size) + vp) * dw + (self->mb_col * block_size) + hp;
2894 unsigned int di = (self->mb_row * dw + self->mb_col) * block_size;
2896 unsigned int max_address = (dw * (self->mb_height * block_size - block_size + 1) - block_size);
2897 if (si > max_address || di > max_address) {
2901#define PLM_MB_CASE(INTERPOLATE, ODD_H, ODD_V, OP) \
2902 case ((INTERPOLATE << 2) | (ODD_H << 1) | (ODD_V)): \
2903 PLM_BLOCK_SET(d, di, dw, si, dw, block_size, OP); \
2906 switch ((interpolate << 2) | (odd_h << 1) | (odd_v)) {
2907 PLM_MB_CASE(0, 0, 0, (s[si]));
2908 PLM_MB_CASE(0, 0, 1, (s[si] + s[si + dw] + 1) >> 1);
2909 PLM_MB_CASE(0, 1, 0, (s[si] + s[si + 1] + 1) >> 1);
2910 PLM_MB_CASE(0, 1, 1, (s[si] + s[si + 1] + s[si + dw] + s[si + dw + 1] + 2) >> 2);
2912 PLM_MB_CASE(1, 0, 0, (d[di] + (s[si]) + 1) >> 1);
2913 PLM_MB_CASE(1, 0, 1, (d[di] + ((s[si] + s[si + dw] + 1) >> 1) + 1) >> 1);
2914 PLM_MB_CASE(1, 1, 0, (d[di] + ((s[si] + s[si + 1] + 1) >> 1) + 1) >> 1);
2915 PLM_MB_CASE(1, 1, 1, (d[di] + ((s[si] + s[si + 1] + s[si + dw] + s[si + dw + 1] + 2) >> 2) + 1) >> 1);
2921void plm_video_decode_block(plm_video_t *self,
int block) {
2924 uint8_t *quant_matrix;
2927 if (self->macroblock_intra) {
2932 int plane_index = block > 3 ? block - 3 : 0;
2933 predictor = self->dc_predictor[plane_index];
2934 dct_size = plm_buffer_read_vlc(self->buffer, PLM_VIDEO_DCT_SIZE[plane_index]);
2938 int differential = plm_buffer_read(self->buffer, dct_size);
2939 if ((differential & (1 << (dct_size - 1))) != 0) {
2940 self->block_data[0] = predictor + differential;
2942 self->block_data[0] = predictor + (-(1 << dct_size) | (differential + 1));
2945 self->block_data[0] = predictor;
2949 self->dc_predictor[plane_index] = self->block_data[0];
2952 self->block_data[0] <<= (3 + 5);
2954 quant_matrix = self->intra_quant_matrix;
2957 quant_matrix = self->non_intra_quant_matrix;
2964 uint16_t coeff = plm_buffer_read_vlc_uint(self->buffer, PLM_VIDEO_DCT_COEFF);
2966 if ((coeff == 0x0001) && (n > 0) && (plm_buffer_read(self->buffer, 1) == 0)) {
2970 if (coeff == 0xffff) {
2972 run = plm_buffer_read(self->buffer, 6);
2973 level = plm_buffer_read(self->buffer, 8);
2975 level = plm_buffer_read(self->buffer, 8);
2976 }
else if (level == 128) {
2977 level = plm_buffer_read(self->buffer, 8) - 256;
2978 }
else if (level > 128) {
2979 level = level - 256;
2983 level = coeff & 0xff;
2984 if (plm_buffer_read(self->buffer, 1)) {
2990 if (n < 0 || n >= 64) {
2994 int de_zig_zagged = PLM_VIDEO_ZIG_ZAG[n];
2999 if (!self->macroblock_intra) {
3000 level += (level < 0 ? -1 : 1);
3002 level = (level * self->quantizer_scale * quant_matrix[de_zig_zagged]) >> 4;
3003 if ((level & 1) == 0) {
3004 level -= level > 0 ? 1 : -1;
3008 }
else if (level < -2048) {
3013 self->block_data[de_zig_zagged] = level * PLM_VIDEO_PREMULTIPLIER_MATRIX[de_zig_zagged];
3022 d = self->frame_current.y.data;
3023 dw = self->luma_width;
3024 di = (self->mb_row * self->luma_width + self->mb_col) << 4;
3025 if ((block & 1) != 0) {
3028 if ((block & 2) != 0) {
3029 di += self->luma_width << 3;
3032 d = (block == 4) ? self->frame_current.cb.data : self->frame_current.cr.data;
3033 dw = self->chroma_width;
3034 di = ((self->mb_row * self->luma_width) << 2) + (self->mb_col << 3);
3037 int *s = self->block_data;
3039 if (self->macroblock_intra) {
3042 int clamped = plm_clamp((s[0] + 128) >> 8);
3043 PLM_BLOCK_SET(d, di, dw, si, 8, 8, clamped);
3047 PLM_BLOCK_SET(d, di, dw, si, 8, 8, plm_clamp(s[si]));
3048 memset(self->block_data, 0,
sizeof(self->block_data));
3053 int value = (s[0] + 128) >> 8;
3054 PLM_BLOCK_SET(d, di, dw, si, 8, 8, plm_clamp(d[di] + value));
3058 PLM_BLOCK_SET(d, di, dw, si, 8, 8, plm_clamp(d[di] + s[si]));
3059 memset(self->block_data, 0,
sizeof(self->block_data));
3064void plm_video_idct(
int *block) {
3065 int b1, b3, b4, b6, b7, tmp1, tmp2, m0, x0, x1, x2, x3, x4, y3, y4, y5, y6, y7;
3068 for (
int i = 0; i < 8; ++i) {
3069 b1 = block[4 * 8 + i];
3070 b3 = block[2 * 8 + i] + block[6 * 8 + i];
3071 b4 = block[5 * 8 + i] - block[3 * 8 + i];
3072 tmp1 = block[1 * 8 + i] + block[7 * 8 + i];
3073 tmp2 = block[3 * 8 + i] + block[5 * 8 + i];
3074 b6 = block[1 * 8 + i] - block[7 * 8 + i];
3076 m0 = block[0 * 8 + i];
3077 x4 = ((b6 * 473 - b4 * 196 + 128) >> 8) - b7;
3078 x0 = x4 - (((tmp1 - tmp2) * 362 + 128) >> 8);
3080 x2 = (((block[2 * 8 + i] - block[6 * 8 + i]) * 362 + 128) >> 8) - b3;
3086 y7 = -x0 - ((b4 * 473 + b6 * 196 + 128) >> 8);
3087 block[0 * 8 + i] = b7 + y4;
3088 block[1 * 8 + i] = x4 + y3;
3089 block[2 * 8 + i] = y5 - x0;
3090 block[3 * 8 + i] = y6 - y7;
3091 block[4 * 8 + i] = y6 + y7;
3092 block[5 * 8 + i] = x0 + y5;
3093 block[6 * 8 + i] = y3 - x4;
3094 block[7 * 8 + i] = y4 - b7;
3098 for (
int i = 0; i < 64; i += 8) {
3100 b3 = block[2 + i] + block[6 + i];
3101 b4 = block[5 + i] - block[3 + i];
3102 tmp1 = block[1 + i] + block[7 + i];
3103 tmp2 = block[3 + i] + block[5 + i];
3104 b6 = block[1 + i] - block[7 + i];
3107 x4 = ((b6 * 473 - b4 * 196 + 128) >> 8) - b7;
3108 x0 = x4 - (((tmp1 - tmp2) * 362 + 128) >> 8);
3110 x2 = (((block[2 + i] - block[6 + i]) * 362 + 128) >> 8) - b3;
3116 y7 = -x0 - ((b4 * 473 + b6 * 196 + 128) >> 8);
3117 block[0 + i] = (b7 + y4 + 128) >> 8;
3118 block[1 + i] = (x4 + y3 + 128) >> 8;
3119 block[2 + i] = (y5 - x0 + 128) >> 8;
3120 block[3 + i] = (y6 - y7 + 128) >> 8;
3121 block[4 + i] = (y6 + y7 + 128) >> 8;
3122 block[5 + i] = (x0 + y5 + 128) >> 8;
3123 block[6 + i] = (y3 - x4 + 128) >> 8;
3124 block[7 + i] = (y4 - b7 + 128) >> 8;
3131#define PLM_PUT_PIXEL(RI, GI, BI, Y_OFFSET, DEST_OFFSET) \
3132 y = ((frame->y.data[y_index + Y_OFFSET] - 16) * 76309) >> 16; \
3133 dest[d_index + DEST_OFFSET + RI] = plm_clamp(y + r); \
3134 dest[d_index + DEST_OFFSET + GI] = plm_clamp(y - g); \
3135 dest[d_index + DEST_OFFSET + BI] = plm_clamp(y + b);
3137#define PLM_DEFINE_FRAME_CONVERT_FUNCTION(NAME, BYTES_PER_PIXEL, RI, GI, BI) \
3138 void NAME(plm_frame_t *frame, uint8_t *dest, int stride) { \
3139 int cols = frame->width >> 1; \
3140 int rows = frame->height >> 1; \
3141 int yw = frame->y.width; \
3142 int cw = frame->cb.width; \
3143 for (int row = 0; row < rows; row++) { \
3144 int c_index = row * cw; \
3145 int y_index = row * 2 * yw; \
3146 int d_index = row * 2 * stride; \
3147 for (int col = 0; col < cols; col++) { \
3149 int cr = frame->cr.data[c_index] - 128; \
3150 int cb = frame->cb.data[c_index] - 128; \
3151 int r = (cr * 104597) >> 16; \
3152 int g = (cb * 25674 + cr * 53278) >> 16; \
3153 int b = (cb * 132201) >> 16; \
3154 PLM_PUT_PIXEL(RI, GI, BI, 0, 0); \
3155 PLM_PUT_PIXEL(RI, GI, BI, 1, BYTES_PER_PIXEL); \
3156 PLM_PUT_PIXEL(RI, GI, BI, yw, stride); \
3157 PLM_PUT_PIXEL(RI, GI, BI, yw + 1, stride + BYTES_PER_PIXEL); \
3160 d_index += 2 * BYTES_PER_PIXEL; \
3165PLM_DEFINE_FRAME_CONVERT_FUNCTION(plm_frame_to_rgb, 3, 0, 1, 2)
3166PLM_DEFINE_FRAME_CONVERT_FUNCTION(plm_frame_to_bgr, 3, 2, 1, 0)
3167PLM_DEFINE_FRAME_CONVERT_FUNCTION(plm_frame_to_rgba, 4, 0, 1, 2)
3168PLM_DEFINE_FRAME_CONVERT_FUNCTION(plm_frame_to_bgra, 4, 2, 1, 0)
3169PLM_DEFINE_FRAME_CONVERT_FUNCTION(plm_frame_to_argb, 4, 1, 2, 3)
3170PLM_DEFINE_FRAME_CONVERT_FUNCTION(plm_frame_to_abgr, 4, 3, 2, 1)
3173#undef PLM_DEFINE_FRAME_CONVERT_FUNCTION
3181static const int PLM_AUDIO_FRAME_SYNC = 0x7ff;
3183static const int PLM_AUDIO_MPEG_2_5 = 0x0;
3184static const int PLM_AUDIO_MPEG_2 = 0x2;
3185static const int PLM_AUDIO_MPEG_1 = 0x3;
3187static const int PLM_AUDIO_LAYER_III = 0x1;
3188static const int PLM_AUDIO_LAYER_II = 0x2;
3189static const int PLM_AUDIO_LAYER_I = 0x3;
3191static const int PLM_AUDIO_MODE_STEREO = 0x0;
3192static const int PLM_AUDIO_MODE_JOINT_STEREO = 0x1;
3193static const int PLM_AUDIO_MODE_DUAL_CHANNEL = 0x2;
3194static const int PLM_AUDIO_MODE_MONO = 0x3;
3196static const unsigned short PLM_AUDIO_SAMPLE_RATE[] = {
3197 44100, 48000, 32000, 0,
3198 22050, 24000, 16000, 0
3201static const short PLM_AUDIO_BIT_RATE[] = {
3202 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,
3203 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160
3206static const int PLM_AUDIO_SCALEFACTOR_BASE[] = {0x02000000, 0x01965FEA, 0x01428A30};
3208static const float PLM_AUDIO_SYNTHESIS_WINDOW[] = {
3209 0.0, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -1.0, -1.0, -1.0, -1.0,
3210 -1.5, -1.5, -2.0, -2.0, -2.5, -2.5, -3.0, -3.5, -3.5, -4.0, -4.5,
3211 -5.0, -5.5, -6.5, -7.0, -8.0, -8.5, -9.5, -10.5, -12.0, -13.0, -14.5,
3212 -15.5, -17.5, -19.0, -20.5, -22.5, -24.5, -26.5, -29.0, -31.5, -34.0, -36.5,
3213 -39.5, -42.5, -45.5, -48.5, -52.0, -55.5, -58.5, -62.5, -66.0, -69.5, -73.5,
3214 -77.0, -80.5, -84.5, -88.0, -91.5, -95.0, -98.0, -101.0, -104.0, 106.5, 109.0,
3215 111.0, 112.5, 113.5, 114.0, 114.0, 113.5, 112.0, 110.5, 107.5, 104.0, 100.0,
3216 94.5, 88.5, 81.5, 73.0, 63.5, 53.0, 41.5, 28.5, 14.5, -1.0, -18.0,
3217 -36.0, -55.5, -76.5, -98.5, -122.0, -147.0, -173.5, -200.5, -229.5, -259.5, -290.5,
3218 -322.5, -355.5, -389.5, -424.0, -459.5, -495.5, -532.0, -568.5, -605.0, -641.5, -678.0,
3219 -714.0, -749.0, -783.5, -817.0, -849.0, -879.5, -908.5, -935.0, -959.5, -981.0, -1000.5,
3220 -1016.0, -1028.5, -1037.5, -1042.5, -1043.5, -1040.0, -1031.5, 1018.5, 1000.0, 976.0, 946.5,
3221 911.0, 869.5, 822.0, 767.5, 707.0, 640.0, 565.5, 485.0, 397.0, 302.5, 201.0,
3222 92.5, -22.5, -144.0, -272.5, -407.0, -547.5, -694.0, -846.0, -1003.0, -1165.0, -1331.5,
3223 -1502.0, -1675.5, -1852.5, -2031.5, -2212.5, -2394.0, -2576.5, -2758.5, -2939.5, -3118.5, -3294.5,
3224 -3467.5, -3635.5, -3798.5, -3955.0, -4104.5, -4245.5, -4377.5, -4499.0, -4609.5, -4708.0, -4792.5,
3225 -4863.5, -4919.0, -4958.0, -4979.5, -4983.0, -4967.5, -4931.5, -4875.0, -4796.0, -4694.5, -4569.5,
3226 -4420.0, -4246.0, -4046.0, -3820.0, -3567.0, 3287.0, 2979.5, 2644.0, 2280.5, 1888.0, 1467.5,
3227 1018.5, 541.0, 35.0, -499.0, -1061.0, -1650.0, -2266.5, -2909.0, -3577.0, -4270.0, -4987.5,
3228 -5727.5, -6490.0, -7274.0, -8077.5, -8899.5, -9739.0, -10594.5, -11464.5, -12347.0, -13241.0, -14144.5,
3229 -15056.0, -15973.5, -16895.5, -17820.0, -18744.5, -19668.0, -20588.0, -21503.0, -22410.5, -23308.5, -24195.0,
3230 -25068.5, -25926.5, -26767.0, -27589.0, -28389.0, -29166.5, -29919.0, -30644.5, -31342.0, -32009.5, -32645.0,
3231 -33247.0, -33814.5, -34346.0, -34839.5, -35295.0, -35710.0, -36084.5, -36417.5, -36707.5, -36954.0, -37156.5,
3232 -37315.0, -37428.0, -37496.0, 37519.0, 37496.0, 37428.0, 37315.0, 37156.5, 36954.0, 36707.5, 36417.5,
3233 36084.5, 35710.0, 35295.0, 34839.5, 34346.0, 33814.5, 33247.0, 32645.0, 32009.5, 31342.0, 30644.5,
3234 29919.0, 29166.5, 28389.0, 27589.0, 26767.0, 25926.5, 25068.5, 24195.0, 23308.5, 22410.5, 21503.0,
3235 20588.0, 19668.0, 18744.5, 17820.0, 16895.5, 15973.5, 15056.0, 14144.5, 13241.0, 12347.0, 11464.5,
3236 10594.5, 9739.0, 8899.5, 8077.5, 7274.0, 6490.0, 5727.5, 4987.5, 4270.0, 3577.0, 2909.0,
3237 2266.5, 1650.0, 1061.0, 499.0, -35.0, -541.0, -1018.5, -1467.5, -1888.0, -2280.5, -2644.0,
3238 -2979.5, 3287.0, 3567.0, 3820.0, 4046.0, 4246.0, 4420.0, 4569.5, 4694.5, 4796.0, 4875.0,
3239 4931.5, 4967.5, 4983.0, 4979.5, 4958.0, 4919.0, 4863.5, 4792.5, 4708.0, 4609.5, 4499.0,
3240 4377.5, 4245.5, 4104.5, 3955.0, 3798.5, 3635.5, 3467.5, 3294.5, 3118.5, 2939.5, 2758.5,
3241 2576.5, 2394.0, 2212.5, 2031.5, 1852.5, 1675.5, 1502.0, 1331.5, 1165.0, 1003.0, 846.0,
3242 694.0, 547.5, 407.0, 272.5, 144.0, 22.5, -92.5, -201.0, -302.5, -397.0, -485.0,
3243 -565.5, -640.0, -707.0, -767.5, -822.0, -869.5, -911.0, -946.5, -976.0, -1000.0, 1018.5,
3244 1031.5, 1040.0, 1043.5, 1042.5, 1037.5, 1028.5, 1016.0, 1000.5, 981.0, 959.5, 935.0,
3245 908.5, 879.5, 849.0, 817.0, 783.5, 749.0, 714.0, 678.0, 641.5, 605.0, 568.5,
3246 532.0, 495.5, 459.5, 424.0, 389.5, 355.5, 322.5, 290.5, 259.5, 229.5, 200.5,
3247 173.5, 147.0, 122.0, 98.5, 76.5, 55.5, 36.0, 18.0, 1.0, -14.5, -28.5,
3248 -41.5, -53.0, -63.5, -73.0, -81.5, -88.5, -94.5, -100.0, -104.0, -107.5, -110.5,
3249 -112.0, -113.5, -114.0, -114.0, -113.5, -112.5, -111.0, -109.0, 106.5, 104.0, 101.0,
3250 98.0, 95.0, 91.5, 88.0, 84.5, 80.5, 77.0, 73.5, 69.5, 66.0, 62.5,
3251 58.5, 55.5, 52.0, 48.5, 45.5, 42.5, 39.5, 36.5, 34.0, 31.5, 29.0,
3252 26.5, 24.5, 22.5, 20.5, 19.0, 17.5, 15.5, 14.5, 13.0, 12.0, 10.5,
3253 9.5, 8.5, 8.0, 7.0, 6.5, 5.5, 5.0, 4.5, 4.0, 3.5, 3.5,
3254 3.0, 2.5, 2.5, 2.0, 2.0, 1.5, 1.5, 1.0, 1.0, 1.0, 1.0,
3255 0.5, 0.5, 0.5, 0.5, 0.5, 0.5};
3258static const uint8_t PLM_AUDIO_QUANT_LUT_STEP_1[2][16] = {
3260 {0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2},
3262 {0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2}
3266#define PLM_AUDIO_QUANT_TAB_A (27 | 64)
3267#define PLM_AUDIO_QUANT_TAB_B (30 | 64)
3268#define PLM_AUDIO_QUANT_TAB_C 8
3269#define PLM_AUDIO_QUANT_TAB_D 12
3271static const uint8_t QUANT_LUT_STEP_2[3][3] = {
3273 {PLM_AUDIO_QUANT_TAB_C, PLM_AUDIO_QUANT_TAB_C, PLM_AUDIO_QUANT_TAB_D},
3274 {PLM_AUDIO_QUANT_TAB_A, PLM_AUDIO_QUANT_TAB_A, PLM_AUDIO_QUANT_TAB_A},
3275 {PLM_AUDIO_QUANT_TAB_B, PLM_AUDIO_QUANT_TAB_A, PLM_AUDIO_QUANT_TAB_B}
3280static const uint8_t PLM_AUDIO_QUANT_LUT_STEP_3[3][32] = {
3282 {0x44, 0x44, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34},
3284 {0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x31, 0x31, 0x31, 0x31,
3285 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20},
3287 {0x45, 0x45, 0x45, 0x45, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x24, 0x24, 0x24, 0x24,
3288 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24}};
3291static const uint8_t PLM_AUDIO_QUANT_LUT_STEP_4[6][16] = {{0, 1, 2, 17},
3292 {0, 1, 2, 3, 4, 5, 6, 17},
3293 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17},
3294 {0, 1, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17},
3295 {0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17},
3296 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
3298typedef struct plm_quantizer_spec_t {
3299 unsigned short levels;
3300 unsigned char group;
3302} plm_quantizer_spec_t;
3304static const plm_quantizer_spec_t PLM_AUDIO_QUANT_TAB[] = {
3326 int samples_decoded;
3327 int samplerate_index;
3334 int next_frame_data_size;
3337 plm_buffer_t *buffer;
3338 int destroy_buffer_when_done;
3340 const plm_quantizer_spec_t *allocation[2][32];
3341 uint8_t scale_factor_info[2][32];
3342 int scale_factor[2][32][3];
3343 int sample[2][32][3];
3345 plm_samples_t samples;
3351int plm_audio_find_frame_sync(plm_audio_t *self);
3352int plm_audio_decode_header(plm_audio_t *self);
3353void plm_audio_decode_frame(plm_audio_t *self);
3354const plm_quantizer_spec_t *plm_audio_read_allocation(plm_audio_t *self,
int sb,
int tab3);
3355void plm_audio_read_samples(plm_audio_t *self,
int ch,
int sb,
int part);
3356void plm_audio_idct36(
int s[32][3],
int ss,
float *d,
int dp);
3358plm_audio_t *plm_audio_create_with_buffer(plm_buffer_t *buffer,
int destroy_when_done) {
3359 plm_audio_t *self = (plm_audio_t *)PLM_MALLOC(
sizeof(plm_audio_t));
3360 memset(self, 0,
sizeof(plm_audio_t));
3362 self->samples.count = PLM_AUDIO_SAMPLES_PER_FRAME;
3363 self->buffer = buffer;
3364 self->destroy_buffer_when_done = destroy_when_done;
3365 self->samplerate_index = 3;
3367 memcpy(self->D, PLM_AUDIO_SYNTHESIS_WINDOW, 512 *
sizeof(
float));
3368 memcpy(self->D + 512, PLM_AUDIO_SYNTHESIS_WINDOW, 512 *
sizeof(
float));
3371 self->next_frame_data_size = plm_audio_decode_header(self);
3376void plm_audio_destroy(plm_audio_t *self) {
3377 if (self->destroy_buffer_when_done) {
3378 plm_buffer_destroy(self->buffer);
3383int plm_audio_has_header(plm_audio_t *self) {
3384 if (self->has_header) {
3388 self->next_frame_data_size = plm_audio_decode_header(self);
3389 return self->has_header;
3392int plm_audio_get_samplerate(plm_audio_t *self) {
3393 return plm_audio_has_header(self) ? PLM_AUDIO_SAMPLE_RATE[self->samplerate_index] : 0;
3396double plm_audio_get_time(plm_audio_t *self) {
return self->time; }
3398void plm_audio_set_time(plm_audio_t *self,
double time) {
3399 self->samples_decoded = time * (double)PLM_AUDIO_SAMPLE_RATE[self->samplerate_index];
3403void plm_audio_rewind(plm_audio_t *self) {
3404 plm_buffer_rewind(self->buffer);
3406 self->samples_decoded = 0;
3407 self->next_frame_data_size = 0;
3410int plm_audio_has_ended(plm_audio_t *self) {
return plm_buffer_has_ended(self->buffer); }
3412plm_samples_t *plm_audio_decode(plm_audio_t *self) {
3414 if (!self->next_frame_data_size) {
3415 if (!plm_buffer_has(self->buffer, 48)) {
3418 self->next_frame_data_size = plm_audio_decode_header(self);
3421 if (self->next_frame_data_size == 0 || !plm_buffer_has(self->buffer, self->next_frame_data_size << 3)) {
3425 plm_audio_decode_frame(self);
3426 self->next_frame_data_size = 0;
3428 self->samples.time = self->time;
3430 self->samples_decoded += PLM_AUDIO_SAMPLES_PER_FRAME;
3431 self->time = (double)self->samples_decoded / (
double)PLM_AUDIO_SAMPLE_RATE[self->samplerate_index];
3433 return &self->samples;
3436int plm_audio_find_frame_sync(plm_audio_t *self) {
3438 for (i = self->buffer->bit_index >> 3; i < self->buffer->length - 1; i++) {
3439 if (self->buffer->bytes[i] == 0xFF && (self->buffer->bytes[i + 1] & 0xFE) == 0xFC) {
3440 self->buffer->bit_index = ((i + 1) << 3) + 3;
3444 self->buffer->bit_index = (i + 1) << 3;
3448int plm_audio_decode_header(plm_audio_t *self) {
3449 if (!plm_buffer_has(self->buffer, 48)) {
3453 plm_buffer_skip_bytes(self->buffer, 0x00);
3454 int sync = plm_buffer_read(self->buffer, 11);
3463 if (sync != PLM_AUDIO_FRAME_SYNC && !plm_audio_find_frame_sync(self)) {
3467 self->version = plm_buffer_read(self->buffer, 2);
3468 self->layer = plm_buffer_read(self->buffer, 2);
3469 int hasCRC = !plm_buffer_read(self->buffer, 1);
3471 if (self->version != PLM_AUDIO_MPEG_1 || self->layer != PLM_AUDIO_LAYER_II) {
3475 int bitrate_index = plm_buffer_read(self->buffer, 4) - 1;
3476 if (bitrate_index > 13) {
3480 int samplerate_index = plm_buffer_read(self->buffer, 2);
3481 if (samplerate_index == 3) {
3485 int padding = plm_buffer_read(self->buffer, 1);
3486 plm_buffer_skip(self->buffer, 1);
3487 int mode = plm_buffer_read(self->buffer, 2);
3491 if (self->has_header &&
3492 (self->bitrate_index != bitrate_index || self->samplerate_index != samplerate_index || self->mode != mode)) {
3496 self->bitrate_index = bitrate_index;
3497 self->samplerate_index = samplerate_index;
3499 self->has_header = TRUE;
3502 if (mode == PLM_AUDIO_MODE_JOINT_STEREO) {
3503 self->bound = (plm_buffer_read(self->buffer, 2) + 1) << 2;
3505 plm_buffer_skip(self->buffer, 2);
3506 self->bound = (mode == PLM_AUDIO_MODE_MONO) ? 0 : 32;
3510 plm_buffer_skip(self->buffer, 4);
3512 plm_buffer_skip(self->buffer, 16);
3517 int bitrate = PLM_AUDIO_BIT_RATE[self->bitrate_index];
3518 int samplerate = PLM_AUDIO_SAMPLE_RATE[self->samplerate_index];
3519 int frame_size = (144000 * bitrate / samplerate) + padding;
3520 return frame_size - (hasCRC ? 6 : 4);
3523void plm_audio_decode_frame(plm_audio_t *self) {
3528 int tab1 = (self->mode == PLM_AUDIO_MODE_MONO) ? 0 : 1;
3529 int tab2 = PLM_AUDIO_QUANT_LUT_STEP_1[tab1][self->bitrate_index];
3530 tab3 = QUANT_LUT_STEP_2[tab2][self->samplerate_index];
3531 sblimit = tab3 & 63;
3534 if (self->bound > sblimit) {
3535 self->bound = sblimit;
3539 for (
int sb = 0; sb < self->bound; sb++) {
3540 self->allocation[0][sb] = plm_audio_read_allocation(self, sb, tab3);
3541 self->allocation[1][sb] = plm_audio_read_allocation(self, sb, tab3);
3544 for (
int sb = self->bound; sb < sblimit; sb++) {
3545 self->allocation[0][sb] = self->allocation[1][sb] = plm_audio_read_allocation(self, sb, tab3);
3549 int channels = (self->mode == PLM_AUDIO_MODE_MONO) ? 1 : 2;
3550 for (
int sb = 0; sb < sblimit; sb++) {
3551 for (
int ch = 0; ch < channels; ch++) {
3552 if (self->allocation[ch][sb]) {
3553 self->scale_factor_info[ch][sb] = plm_buffer_read(self->buffer, 2);
3556 if (self->mode == PLM_AUDIO_MODE_MONO) {
3557 self->scale_factor_info[1][sb] = self->scale_factor_info[0][sb];
3562 for (
int sb = 0; sb < sblimit; sb++) {
3563 for (
int ch = 0; ch < channels; ch++) {
3564 if (self->allocation[ch][sb]) {
3565 int *sf = self->scale_factor[ch][sb];
3566 switch (self->scale_factor_info[ch][sb]) {
3568 sf[0] = plm_buffer_read(self->buffer, 6);
3569 sf[1] = plm_buffer_read(self->buffer, 6);
3570 sf[2] = plm_buffer_read(self->buffer, 6);
3573 sf[0] = sf[1] = plm_buffer_read(self->buffer, 6);
3574 sf[2] = plm_buffer_read(self->buffer, 6);
3577 sf[0] = sf[1] = sf[2] = plm_buffer_read(self->buffer, 6);
3580 sf[0] = plm_buffer_read(self->buffer, 6);
3581 sf[1] = sf[2] = plm_buffer_read(self->buffer, 6);
3586 if (self->mode == PLM_AUDIO_MODE_MONO) {
3587 self->scale_factor[1][sb][0] = self->scale_factor[0][sb][0];
3588 self->scale_factor[1][sb][1] = self->scale_factor[0][sb][1];
3589 self->scale_factor[1][sb][2] = self->scale_factor[0][sb][2];
3595 for (
int part = 0; part < 3; part++) {
3596 for (
int granule = 0; granule < 4; granule++) {
3599 for (
int sb = 0; sb < self->bound; sb++) {
3600 plm_audio_read_samples(self, 0, sb, part);
3601 plm_audio_read_samples(self, 1, sb, part);
3603 for (
int sb = self->bound; sb < sblimit; sb++) {
3604 plm_audio_read_samples(self, 0, sb, part);
3605 self->sample[1][sb][0] = self->sample[0][sb][0];
3606 self->sample[1][sb][1] = self->sample[0][sb][1];
3607 self->sample[1][sb][2] = self->sample[0][sb][2];
3609 for (
int sb = sblimit; sb < 32; sb++) {
3610 self->sample[0][sb][0] = 0;
3611 self->sample[0][sb][1] = 0;
3612 self->sample[0][sb][2] = 0;
3613 self->sample[1][sb][0] = 0;
3614 self->sample[1][sb][1] = 0;
3615 self->sample[1][sb][2] = 0;
3619 for (
int p = 0; p < 3; p++) {
3621 self->v_pos = (self->v_pos - 64) & 1023;
3623 for (
int ch = 0; ch < 2; ch++) {
3624 plm_audio_idct36(self->sample[ch], p, self->V[ch], self->v_pos);
3627 memset(self->U, 0,
sizeof(self->U));
3629 int d_index = 512 - (self->v_pos >> 1);
3630 int v_index = (self->v_pos % 128) >> 1;
3631 while (v_index < 1024) {
3632 for (
int i = 0; i < 32; ++i) {
3633 self->U[i] += self->D[d_index++] * self->V[ch][v_index++];
3636 v_index += 128 - 32;
3640 d_index -= (512 - 32);
3641 v_index = (128 - 32 + 1024) - v_index;
3642 while (v_index < 1024) {
3643 for (
int i = 0; i < 32; ++i) {
3644 self->U[i] += self->D[d_index++] * self->V[ch][v_index++];
3647 v_index += 128 - 32;
3652#ifdef PLM_AUDIO_SEPARATE_CHANNELS
3653 float *out_channel = ch == 0 ? self->samples.left : self->samples.right;
3654 for (
int j = 0; j < 32; j++) {
3655 out_channel[out_pos + j] = self->U[j] / 2147418112.0f;
3658 for (
int j = 0; j < 32; j++) {
3659 self->samples.interleaved[((out_pos + j) << 1) + ch] = self->U[j] / 2147418112.0f;
3669 plm_buffer_align(self->buffer);
3672const plm_quantizer_spec_t *plm_audio_read_allocation(plm_audio_t *self,
int sb,
int tab3) {
3673 int tab4 = PLM_AUDIO_QUANT_LUT_STEP_3[tab3][sb];
3674 int qtab = PLM_AUDIO_QUANT_LUT_STEP_4[tab4 & 15][plm_buffer_read(self->buffer, tab4 >> 4)];
3675 return qtab ? (&PLM_AUDIO_QUANT_TAB[qtab - 1]) : 0;
3678void plm_audio_read_samples(plm_audio_t *self,
int ch,
int sb,
int part) {
3679 const plm_quantizer_spec_t *q = self->allocation[ch][sb];
3680 int sf = self->scale_factor[ch][sb][part];
3681 int *sample = self->sample[ch][sb];
3686 sample[0] = sample[1] = sample[2] = 0;
3694 int shift = (sf / 3) | 0;
3695 sf = (PLM_AUDIO_SCALEFACTOR_BASE[sf % 3] + ((1 << shift) >> 1)) >> shift;
3699 int adj = q->levels;
3702 val = plm_buffer_read(self->buffer, q->bits);
3703 sample[0] = val % adj;
3705 sample[1] = val % adj;
3706 sample[2] = val / adj;
3709 sample[0] = plm_buffer_read(self->buffer, q->bits);
3710 sample[1] = plm_buffer_read(self->buffer, q->bits);
3711 sample[2] = plm_buffer_read(self->buffer, q->bits);
3715 int scale = 65536 / (adj + 1);
3716 adj = ((adj + 1) >> 1) - 1;
3718 val = (adj - sample[0]) * scale;
3719 sample[0] = (val * (sf >> 12) + ((val * (sf & 4095) + 2048) >> 12)) >> 12;
3721 val = (adj - sample[1]) * scale;
3722 sample[1] = (val * (sf >> 12) + ((val * (sf & 4095) + 2048) >> 12)) >> 12;
3724 val = (adj - sample[2]) * scale;
3725 sample[2] = (val * (sf >> 12) + ((val * (sf & 4095) + 2048) >> 12)) >> 12;
3728void plm_audio_idct36(
int s[32][3],
int ss,
float *d,
int dp) {
3729 float t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22,
3730 t23, t24, t25, t26, t27, t28, t29, t30, t31, t32, t33;
3732 t01 = (float)(s[0][ss] + s[31][ss]);
3733 t02 = (float)(s[0][ss] - s[31][ss]) * 0.500602998235f;
3734 t03 = (float)(s[1][ss] + s[30][ss]);
3735 t04 = (float)(s[1][ss] - s[30][ss]) * 0.505470959898f;
3736 t05 = (float)(s[2][ss] + s[29][ss]);
3737 t06 = (float)(s[2][ss] - s[29][ss]) * 0.515447309923f;
3738 t07 = (float)(s[3][ss] + s[28][ss]);
3739 t08 = (float)(s[3][ss] - s[28][ss]) * 0.53104259109f;
3740 t09 = (float)(s[4][ss] + s[27][ss]);
3741 t10 = (float)(s[4][ss] - s[27][ss]) * 0.553103896034f;
3742 t11 = (float)(s[5][ss] + s[26][ss]);
3743 t12 = (float)(s[5][ss] - s[26][ss]) * 0.582934968206f;
3744 t13 = (float)(s[6][ss] + s[25][ss]);
3745 t14 = (float)(s[6][ss] - s[25][ss]) * 0.622504123036f;
3746 t15 = (float)(s[7][ss] + s[24][ss]);
3747 t16 = (float)(s[7][ss] - s[24][ss]) * 0.674808341455f;
3748 t17 = (float)(s[8][ss] + s[23][ss]);
3749 t18 = (float)(s[8][ss] - s[23][ss]) * 0.744536271002f;
3750 t19 = (float)(s[9][ss] + s[22][ss]);
3751 t20 = (float)(s[9][ss] - s[22][ss]) * 0.839349645416f;
3752 t21 = (float)(s[10][ss] + s[21][ss]);
3753 t22 = (float)(s[10][ss] - s[21][ss]) * 0.972568237862f;
3754 t23 = (float)(s[11][ss] + s[20][ss]);
3755 t24 = (float)(s[11][ss] - s[20][ss]) * 1.16943993343f;
3756 t25 = (float)(s[12][ss] + s[19][ss]);
3757 t26 = (float)(s[12][ss] - s[19][ss]) * 1.48416461631f;
3758 t27 = (float)(s[13][ss] + s[18][ss]);
3759 t28 = (float)(s[13][ss] - s[18][ss]) * 2.05778100995f;
3760 t29 = (float)(s[14][ss] + s[17][ss]);
3761 t30 = (float)(s[14][ss] - s[17][ss]) * 3.40760841847f;
3762 t31 = (float)(s[15][ss] + s[16][ss]);
3763 t32 = (float)(s[15][ss] - s[16][ss]) * 10.1900081235f;
3766 t31 = (t01 - t31) * 0.502419286188f;
3768 t29 = (t03 - t29) * 0.52249861494f;
3770 t27 = (t05 - t27) * 0.566944034816f;
3772 t25 = (t07 - t25) * 0.64682178336f;
3774 t23 = (t09 - t23) * 0.788154623451f;
3776 t21 = (t11 - t21) * 1.06067768599f;
3778 t19 = (t13 - t19) * 1.72244709824f;
3780 t17 = (t15 - t17) * 5.10114861869f;
3782 t13 = (t33 - t13) * 0.509795579104f;
3784 t01 = (t01 - t11) * 0.601344886935f;
3786 t09 = (t03 - t09) * 0.899976223136f;
3788 t07 = (t05 - t07) * 2.56291544774f;
3790 t15 = (t15 - t03) * 0.541196100146f;
3792 t11 = (t33 - t11) * 1.30656296488f;
3794 t05 = (t05 - t03) * 0.707106781187f;
3796 t15 = (t15 - t11) * 0.707106781187f;
3799 t13 = (t13 - t07) * 0.541196100146f;
3801 t09 = (t01 - t09) * 1.30656296488f;
3803 t07 = (t11 - t07) * 0.707106781187f;
3805 t13 = (t13 - t09) * 0.707106781187f;
3811 t31 = (t31 - t17) * 0.509795579104f;
3813 t29 = (t29 - t19) * 0.601344886935f;
3815 t21 = (t27 - t21) * 0.899976223136f;
3817 t23 = (t25 - t23) * 2.56291544774f;
3819 t09 = (t09 - t27) * 0.541196100146f;
3821 t19 = (t17 - t19) * 1.30656296488f;
3823 t27 = (t25 - t27) * 0.707106781187f;
3825 t19 = (t09 - t19) * 0.707106781187f;
3828 t31 = (t31 - t23) * 0.541196100146f;
3830 t21 = (t29 - t21) * 1.30656296488f;
3832 t23 = (t09 - t23) * 0.707106781187f;
3834 t31 = (t31 - t21) * 0.707106781187f;
3847 t02 = (t02 - t32) * 0.502419286188f;
3849 t04 = (t04 - t30) * 0.52249861494f;
3851 t28 = (t06 - t28) * 0.566944034816f;
3853 t08 = (t08 - t26) * 0.64682178336f;
3855 t10 = (t10 - t24) * 0.788154623451f;
3857 t22 = (t12 - t22) * 1.06067768599f;
3859 t20 = (t14 - t20) * 1.72244709824f;
3861 t16 = (t16 - t18) * 5.10114861869f;
3863 t14 = (t21 - t14) * 0.509795579104f;
3865 t32 = (t32 - t12) * 0.601344886935f;
3867 t24 = (t30 - t24) * 0.899976223136f;
3869 t26 = (t06 - t26) * 2.56291544774f;
3871 t18 = (t18 - t30) * 0.541196100146f;
3873 t12 = (t21 - t12) * 1.30656296488f;
3875 t30 = (t06 - t30) * 0.707106781187f;
3877 t12 = (t18 - t12) * 0.707106781187f;
3880 t26 = (t14 - t26) * 0.541196100146f;
3882 t24 = (t32 - t24) * 1.30656296488f;
3884 t14 = (t18 - t14) * 0.707106781187f;
3886 t24 = (t26 - t24) * 0.707106781187f;
3892 t02 = (t02 - t16) * 0.509795579104f;
3894 t04 = (t04 - t20) * 0.601344886935f;
3896 t22 = (t28 - t22) * 0.899976223136f;
3898 t10 = (t08 - t10) * 2.56291544774f;
3900 t14 = (t14 - t28) * 0.541196100146f;
3902 t20 = (t16 - t20) * 1.30656296488f;
3904 t28 = (t08 - t28) * 0.707106781187f;
3906 t20 = (t14 - t20) * 0.707106781187f;
3909 t02 = (t02 - t10) * 0.541196100146f;
3911 t22 = (t04 - t22) * 1.30656296488f;
3913 t10 = (t14 - t10) * 0.707106781187f;
3915 t02 = (t02 - t22) * 0.707106781187f;
3944 d[dp + 49] = d[dp + 47] = -t21;
3945 d[dp + 50] = d[dp + 46] = -t17;
3946 d[dp + 51] = d[dp + 45] = -t16;
3947 d[dp + 52] = d[dp + 44] = -t01;
3948 d[dp + 53] = d[dp + 43] = -t32;
3949 d[dp + 54] = d[dp + 42] = -t29;
3950 d[dp + 55] = d[dp + 41] = -t04;
3951 d[dp + 56] = d[dp + 40] = -t03;
3952 d[dp + 57] = d[dp + 39] = -t06;
3953 d[dp + 58] = d[dp + 38] = -t25;
3954 d[dp + 59] = d[dp + 37] = -t08;
3955 d[dp + 60] = d[dp + 36] = -t11;
3956 d[dp + 61] = d[dp + 35] = -t18;
3957 d[dp + 62] = d[dp + 34] = -t09;
3958 d[dp + 63] = d[dp + 33] = -t14;