180typedef struct plm_t plm_t;
181typedef struct plm_buffer_t plm_buffer_t;
182typedef struct plm_demux_t plm_demux_t;
183typedef struct plm_video_t plm_video_t;
184typedef struct plm_audio_t plm_audio_t;
191#define PLM_PACKET_INVALID_TS -1
230typedef void (*plm_video_decode_callback)(plm_t *self, plm_frame_t *frame,
void *user);
238#define PLM_AUDIO_SAMPLES_PER_FRAME 1152
243#ifdef PLM_AUDIO_SEPARATE_CHANNELS
244 float left[PLM_AUDIO_SAMPLES_PER_FRAME];
245 float right[PLM_AUDIO_SAMPLES_PER_FRAME];
247 float interleaved[PLM_AUDIO_SAMPLES_PER_FRAME * 2];
254typedef void (*plm_audio_decode_callback)(plm_t *self, plm_samples_t *samples,
void *user);
258typedef void (*plm_buffer_load_callback)(plm_buffer_t *self,
void *user);
267plm_t *plm_create_with_filename(
const char *filename);
272plm_t *plm_create_with_file(FIL *fh,
int close_when_done);
279plm_t *plm_create_with_memory(uint8_t *bytes,
size_t length,
int free_when_done);
285plm_t *plm_create_with_buffer(plm_buffer_t *buffer,
int destroy_when_done);
289void plm_destroy(plm_t *self);
297int plm_has_headers(plm_t *self);
301int plm_get_video_enabled(plm_t *self);
302void plm_set_video_enabled(plm_t *self,
int enabled);
306int plm_get_num_video_streams(plm_t *self);
310int plm_get_width(plm_t *self);
311int plm_get_height(plm_t *self);
315double plm_get_framerate(plm_t *self);
319int plm_get_audio_enabled(plm_t *self);
320void plm_set_audio_enabled(plm_t *self,
int enabled);
324int plm_get_num_audio_streams(plm_t *self);
328void plm_set_audio_stream(plm_t *self,
int stream_index);
332int plm_get_samplerate(plm_t *self);
339double plm_get_audio_lead_time(plm_t *self);
340void plm_set_audio_lead_time(plm_t *self,
double lead_time);
344double plm_get_time(plm_t *self);
348double plm_get_duration(plm_t *self);
352void plm_rewind(plm_t *self);
356int plm_get_loop(plm_t *self);
357void plm_set_loop(plm_t *self,
int loop);
362int plm_has_ended(plm_t *self);
368void plm_set_video_decode_callback(plm_t *self, plm_video_decode_callback fp,
void *user);
374void plm_set_audio_decode_callback(plm_t *self, plm_audio_decode_callback fp,
void *user);
381void plm_decode(plm_t *self,
double seconds);
389plm_frame_t *plm_decode_video(plm_t *self);
397plm_samples_t *plm_decode_audio(plm_t *self);
412int plm_seek(plm_t *self,
double time,
int seek_exact);
418plm_frame_t *plm_seek_frame(plm_t *self,
double time,
int seek_exact);
426#ifndef PLM_BUFFER_DEFAULT_SIZE
427#define PLM_BUFFER_DEFAULT_SIZE (128 * 1024)
433plm_buffer_t *plm_buffer_create_with_filename(
const char *filename);
438plm_buffer_t *plm_buffer_create_with_file(FIL *fh,
int close_when_done);
445plm_buffer_t *plm_buffer_create_with_memory(uint8_t *bytes,
size_t length,
int free_when_done);
450plm_buffer_t *plm_buffer_create_with_capacity(
size_t capacity);
457plm_buffer_t *plm_buffer_create_for_appending(
size_t initial_capacity);
461void plm_buffer_destroy(plm_buffer_t *self);
469size_t plm_buffer_write(plm_buffer_t *self, uint8_t *bytes,
size_t length);
476void plm_buffer_signal_end(plm_buffer_t *self);
480void plm_buffer_set_load_callback(plm_buffer_t *self, plm_buffer_load_callback fp,
void *user);
485void plm_buffer_rewind(plm_buffer_t *self);
490size_t plm_buffer_get_size(plm_buffer_t *self);
495size_t plm_buffer_get_remaining(plm_buffer_t *self);
500int plm_buffer_has_ended(plm_buffer_t *self);
508static const int PLM_DEMUX_PACKET_PRIVATE = 0xBD;
509static const int PLM_DEMUX_PACKET_AUDIO_1 = 0xC0;
510static const int PLM_DEMUX_PACKET_AUDIO_2 = 0xC1;
511static const int PLM_DEMUX_PACKET_AUDIO_3 = 0xC2;
512static const int PLM_DEMUX_PACKET_AUDIO_4 = 0xC2;
513static const int PLM_DEMUX_PACKET_VIDEO_1 = 0xE0;
518plm_demux_t *plm_demux_create(plm_buffer_t *buffer,
int destroy_when_done);
522void plm_demux_destroy(plm_demux_t *self);
527int plm_demux_has_headers(plm_demux_t *self);
532int plm_demux_get_num_video_streams(plm_demux_t *self);
537int plm_demux_get_num_audio_streams(plm_demux_t *self);
541void plm_demux_rewind(plm_demux_t *self);
545int plm_demux_has_ended(plm_demux_t *self);
553plm_packet_t *plm_demux_seek(plm_demux_t *self,
double time,
int type,
int force_intra);
558double plm_demux_get_start_time(plm_demux_t *self,
int type);
564double plm_demux_get_duration(plm_demux_t *self,
int type);
569plm_packet_t *plm_demux_decode(plm_demux_t *self);
577plm_video_t *plm_video_create_with_buffer(plm_buffer_t *buffer,
int destroy_when_done);
581void plm_video_destroy(plm_video_t *self);
586int plm_video_has_header(plm_video_t *self);
590double plm_video_get_framerate(plm_video_t *self);
594int plm_video_get_width(plm_video_t *self);
595int plm_video_get_height(plm_video_t *self);
601void plm_video_set_no_delay(plm_video_t *self,
int no_delay);
605double plm_video_get_time(plm_video_t *self);
611void plm_video_set_time(plm_video_t *self,
double time);
615void plm_video_rewind(plm_video_t *self);
619int plm_video_has_ended(plm_video_t *self);
625plm_frame_t *plm_video_decode(plm_video_t *self);
634void plm_frame_to_rgb(plm_frame_t *frame, uint8_t *dest,
int stride);
635void plm_frame_to_bgr(plm_frame_t *frame, uint8_t *dest,
int stride);
636void plm_frame_to_rgba(plm_frame_t *frame, uint8_t *dest,
int stride);
637void plm_frame_to_bgra(plm_frame_t *frame, uint8_t *dest,
int stride);
638void plm_frame_to_argb(plm_frame_t *frame, uint8_t *dest,
int stride);
639void plm_frame_to_abgr(plm_frame_t *frame, uint8_t *dest,
int stride);
647plm_audio_t *plm_audio_create_with_buffer(plm_buffer_t *buffer,
int destroy_when_done);
651void plm_audio_destroy(plm_audio_t *self);
656int plm_audio_has_header(plm_audio_t *self);
660int plm_audio_get_samplerate(plm_audio_t *self);
664double plm_audio_get_time(plm_audio_t *self);
670void plm_audio_set_time(plm_audio_t *self,
double time);
674void plm_audio_rewind(plm_audio_t *self);
678int plm_audio_has_ended(plm_audio_t *self);
685plm_samples_t *plm_audio_decode(plm_audio_t *self);
697#ifdef PL_MPEG_IMPLEMENTATION
708#define PLM_MALLOC(sz) malloc(sz)
709#define PLM_FREE(p) free(p)
710#define PLM_REALLOC(p, sz) realloc(p, sz)
713#define PLM_UNUSED(expr) (void)(expr)
726 int video_packet_type;
727 plm_buffer_t *video_buffer;
728 plm_video_t *video_decoder;
731 int audio_stream_index;
732 int audio_packet_type;
733 double audio_lead_time;
734 plm_buffer_t *audio_buffer;
735 plm_audio_t *audio_decoder;
737 plm_video_decode_callback video_decode_callback;
738 void *video_decode_callback_user_data;
740 plm_audio_decode_callback audio_decode_callback;
741 void *audio_decode_callback_user_data;
744int plm_init_decoders(plm_t *self);
745void plm_handle_end(plm_t *self);
746void plm_read_video_packet(plm_buffer_t *buffer,
void *user);
747void plm_read_audio_packet(plm_buffer_t *buffer,
void *user);
748void plm_read_packets(plm_t *self,
int requested_type);
750plm_t *plm_create_with_filename(
const char *filename) {
751 plm_buffer_t *buffer = plm_buffer_create_with_filename(filename);
755 return plm_create_with_buffer(buffer, TRUE);
758plm_t *plm_create_with_file(FIL *fh,
int close_when_done) {
759 plm_buffer_t *buffer = plm_buffer_create_with_file(fh, close_when_done);
760 return plm_create_with_buffer(buffer, TRUE);
763plm_t *plm_create_with_memory(uint8_t *bytes,
size_t length,
int free_when_done) {
764 plm_buffer_t *buffer = plm_buffer_create_with_memory(bytes, length, free_when_done);
765 return plm_create_with_buffer(buffer, TRUE);
768plm_t *plm_create_with_buffer(plm_buffer_t *buffer,
int destroy_when_done) {
769 plm_t *self = (plm_t *)PLM_MALLOC(
sizeof(plm_t));
770 memset(self, 0,
sizeof(plm_t));
772 self->demux = plm_demux_create(buffer, destroy_when_done);
773 self->video_enabled = TRUE;
774 self->audio_enabled = TRUE;
775 plm_init_decoders(self);
780int plm_init_decoders(plm_t *self) {
781 if (self->has_decoders) {
785 if (!plm_demux_has_headers(self->demux)) {
789 if (plm_demux_get_num_video_streams(self->demux) > 0) {
790 if (self->video_enabled) {
791 self->video_packet_type = PLM_DEMUX_PACKET_VIDEO_1;
793 self->video_buffer = plm_buffer_create_with_capacity(PLM_BUFFER_DEFAULT_SIZE);
794 plm_buffer_set_load_callback(self->video_buffer, plm_read_video_packet, self);
797 if (plm_demux_get_num_audio_streams(self->demux) > 0) {
798 if (self->audio_enabled) {
799 self->audio_packet_type = PLM_DEMUX_PACKET_AUDIO_1 + self->audio_stream_index;
801 self->audio_buffer = plm_buffer_create_with_capacity(PLM_BUFFER_DEFAULT_SIZE);
802 plm_buffer_set_load_callback(self->audio_buffer, plm_read_audio_packet, self);
805 if (self->video_buffer) {
806 self->video_decoder = plm_video_create_with_buffer(self->video_buffer, TRUE);
809 if (self->audio_buffer) {
810 self->audio_decoder = plm_audio_create_with_buffer(self->audio_buffer, TRUE);
813 self->has_decoders = TRUE;
817void plm_destroy(plm_t *self) {
818 if (self->video_decoder) {
819 plm_video_destroy(self->video_decoder);
821 if (self->audio_decoder) {
822 plm_audio_destroy(self->audio_decoder);
825 plm_demux_destroy(self->demux);
829int plm_get_audio_enabled(plm_t *self) {
return self->audio_enabled; }
831int plm_has_headers(plm_t *self) {
832 if (!plm_demux_has_headers(self->demux)) {
836 if (!plm_init_decoders(self)) {
840 if ((self->video_decoder && !plm_video_has_header(self->video_decoder)) ||
841 (self->audio_decoder && !plm_audio_has_header(self->audio_decoder))) {
848void plm_set_audio_enabled(plm_t *self,
int enabled) {
849 self->audio_enabled = enabled;
852 self->audio_packet_type = 0;
856 self->audio_packet_type =
857 (plm_init_decoders(self) && self->audio_decoder) ? PLM_DEMUX_PACKET_AUDIO_1 + self->audio_stream_index : 0;
860void plm_set_audio_stream(plm_t *self,
int stream_index) {
861 if (stream_index < 0 || stream_index > 3) {
864 self->audio_stream_index = stream_index;
867 plm_set_audio_enabled(self, self->audio_enabled);
870int plm_get_video_enabled(plm_t *self) {
return self->video_enabled; }
872void plm_set_video_enabled(plm_t *self,
int enabled) {
873 self->video_enabled = enabled;
876 self->video_packet_type = 0;
880 self->video_packet_type = (plm_init_decoders(self) && self->video_decoder) ? PLM_DEMUX_PACKET_VIDEO_1 : 0;
883int plm_get_num_video_streams(plm_t *self) {
return plm_demux_get_num_video_streams(self->demux); }
885int plm_get_width(plm_t *self) {
886 return (plm_init_decoders(self) && self->video_decoder) ? plm_video_get_width(self->video_decoder) : 0;
889int plm_get_height(plm_t *self) {
890 return (plm_init_decoders(self) && self->video_decoder) ? plm_video_get_height(self->video_decoder) : 0;
893double plm_get_framerate(plm_t *self) {
894 return (plm_init_decoders(self) && self->video_decoder) ? plm_video_get_framerate(self->video_decoder) : 0;
897int plm_get_num_audio_streams(plm_t *self) {
return plm_demux_get_num_audio_streams(self->demux); }
899int plm_get_samplerate(plm_t *self) {
900 return (plm_init_decoders(self) && self->audio_decoder) ? plm_audio_get_samplerate(self->audio_decoder) : 0;
903double plm_get_audio_lead_time(plm_t *self) {
return self->audio_lead_time; }
905void plm_set_audio_lead_time(plm_t *self,
double lead_time) { self->audio_lead_time = lead_time; }
907double plm_get_time(plm_t *self) {
return self->time; }
909double plm_get_duration(plm_t *self) {
return plm_demux_get_duration(self->demux, PLM_DEMUX_PACKET_VIDEO_1); }
911void plm_rewind(plm_t *self) {
912 if (self->video_decoder) {
913 plm_video_rewind(self->video_decoder);
916 if (self->audio_decoder) {
917 plm_audio_rewind(self->audio_decoder);
920 plm_demux_rewind(self->demux);
924int plm_get_loop(plm_t *self) {
return self->loop; }
926void plm_set_loop(plm_t *self,
int loop) { self->loop = loop; }
928int plm_has_ended(plm_t *self) {
return self->has_ended; }
930void plm_set_video_decode_callback(plm_t *self, plm_video_decode_callback fp,
void *user) {
931 self->video_decode_callback = fp;
932 self->video_decode_callback_user_data = user;
935void plm_set_audio_decode_callback(plm_t *self, plm_audio_decode_callback fp,
void *user) {
936 self->audio_decode_callback = fp;
937 self->audio_decode_callback_user_data = user;
940void plm_decode(plm_t *self,
double tick) {
941 if (!plm_init_decoders(self)) {
945 int decode_video = (self->video_decode_callback && self->video_packet_type);
946 int decode_audio = (self->audio_decode_callback && self->audio_packet_type);
948 if (!decode_video && !decode_audio) {
953 int did_decode = FALSE;
954 int decode_video_failed = FALSE;
955 int decode_audio_failed = FALSE;
957 double video_target_time = self->time + tick;
958 double audio_target_time = self->time + tick + self->audio_lead_time;
963 if (decode_video && plm_video_get_time(self->video_decoder) < video_target_time) {
964 plm_frame_t *frame = plm_video_decode(self->video_decoder);
966 self->video_decode_callback(self, frame, self->video_decode_callback_user_data);
969 decode_video_failed = TRUE;
973 if (decode_audio && plm_audio_get_time(self->audio_decoder) < audio_target_time) {
974 plm_samples_t *samples = plm_audio_decode(self->audio_decoder);
976 self->audio_decode_callback(self, samples, self->audio_decode_callback_user_data);
979 decode_audio_failed = TRUE;
982 }
while (did_decode);
985 if ((!decode_video || decode_video_failed) && (!decode_audio || decode_audio_failed) &&
986 plm_demux_has_ended(self->demux)) {
987 plm_handle_end(self);
994plm_frame_t *plm_decode_video(plm_t *self) {
995 if (!plm_init_decoders(self)) {
999 if (!self->video_packet_type) {
1003 plm_frame_t *frame = plm_video_decode(self->video_decoder);
1005 self->time = frame->time;
1006 }
else if (plm_demux_has_ended(self->demux)) {
1007 plm_handle_end(self);
1012plm_samples_t *plm_decode_audio(plm_t *self) {
1013 if (!plm_init_decoders(self)) {
1017 if (!self->audio_packet_type) {
1021 plm_samples_t *samples = plm_audio_decode(self->audio_decoder);
1023 self->time = samples->time;
1024 }
else if (plm_demux_has_ended(self->demux)) {
1025 plm_handle_end(self);
1030void plm_handle_end(plm_t *self) {
1034 self->has_ended = TRUE;
1038void plm_read_video_packet(plm_buffer_t *buffer,
void *user) {
1040 plm_t *self = (plm_t *)user;
1041 plm_read_packets(self, self->video_packet_type);
1044void plm_read_audio_packet(plm_buffer_t *buffer,
void *user) {
1046 plm_t *self = (plm_t *)user;
1047 plm_read_packets(self, self->audio_packet_type);
1050void plm_read_packets(plm_t *self,
int requested_type) {
1051 plm_packet_t *packet;
1052 while ((packet = plm_demux_decode(self->demux))) {
1053 if (packet->type == self->video_packet_type) {
1054 plm_buffer_write(self->video_buffer, packet->data, packet->length);
1055 }
else if (packet->type == self->audio_packet_type) {
1056 plm_buffer_write(self->audio_buffer, packet->data, packet->length);
1059 if (packet->type == requested_type) {
1064 if (plm_demux_has_ended(self->demux)) {
1065 if (self->video_buffer) {
1066 plm_buffer_signal_end(self->video_buffer);
1068 if (self->audio_buffer) {
1069 plm_buffer_signal_end(self->audio_buffer);
1074plm_frame_t *plm_seek_frame(plm_t *self,
double time,
int seek_exact) {
1075 if (!plm_init_decoders(self)) {
1079 if (!self->video_packet_type) {
1083 int type = self->video_packet_type;
1085 double start_time = plm_demux_get_start_time(self->demux, type);
1086 double duration = plm_demux_get_duration(self->demux, type);
1090 }
else if (time > duration) {
1094 plm_packet_t *packet = plm_demux_seek(self->demux, time, type, TRUE);
1100 int previous_audio_packet_type = self->audio_packet_type;
1101 self->audio_packet_type = 0;
1104 plm_video_rewind(self->video_decoder);
1105 plm_video_set_time(self->video_decoder, packet->pts - start_time);
1106 plm_buffer_write(self->video_buffer, packet->data, packet->length);
1107 plm_frame_t *frame = plm_video_decode(self->video_decoder);
1112 while (frame && frame->time < time) {
1113 frame = plm_video_decode(self->video_decoder);
1118 self->audio_packet_type = previous_audio_packet_type;
1121 self->time = frame->time;
1124 self->has_ended = FALSE;
1128int plm_seek(plm_t *self,
double time,
int seek_exact) {
1129 plm_frame_t *frame = plm_seek_frame(self, time, seek_exact);
1135 if (self->video_decode_callback) {
1136 self->video_decode_callback(self, frame, self->video_decode_callback_user_data);
1140 if (!self->audio_packet_type) {
1148 double start_time = plm_demux_get_start_time(self->demux, self->video_packet_type);
1149 plm_audio_rewind(self->audio_decoder);
1151 plm_packet_t *packet = NULL;
1152 while ((packet = plm_demux_decode(self->demux))) {
1153 if (packet->type == self->video_packet_type) {
1154 plm_buffer_write(self->video_buffer, packet->data, packet->length);
1155 }
else if (packet->type == self->audio_packet_type && packet->pts - start_time > self->time) {
1156 plm_audio_set_time(self->audio_decoder, packet->pts - start_time);
1157 plm_buffer_write(self->audio_buffer, packet->data, packet->length);
1158 plm_decode(self, 0);
1169enum plm_buffer_mode { PLM_BUFFER_MODE_FILE, PLM_BUFFER_MODE_FIXED_MEM, PLM_BUFFER_MODE_RING, PLM_BUFFER_MODE_APPEND };
1171struct plm_buffer_t {
1176 int discard_read_bytes;
1179 int close_when_done;
1181 plm_buffer_load_callback load_callback;
1182 void *load_callback_user_data;
1184 enum plm_buffer_mode mode;
1197void plm_buffer_seek(plm_buffer_t *self,
size_t pos);
1198size_t plm_buffer_tell(plm_buffer_t *self);
1199void plm_buffer_discard_read_bytes(plm_buffer_t *self);
1200void plm_buffer_load_file_callback(plm_buffer_t *self,
void *user);
1202int plm_buffer_has(plm_buffer_t *self,
size_t count);
1203int plm_buffer_read(plm_buffer_t *self,
int count);
1204void plm_buffer_align(plm_buffer_t *self);
1205void plm_buffer_skip(plm_buffer_t *self,
size_t count);
1206int plm_buffer_skip_bytes(plm_buffer_t *self, uint8_t v);
1207int plm_buffer_next_start_code(plm_buffer_t *self);
1208int plm_buffer_find_start_code(plm_buffer_t *self,
int code);
1209int plm_buffer_no_start_code(plm_buffer_t *self);
1210int16_t plm_buffer_read_vlc(plm_buffer_t *self,
const plm_vlc_t *table);
1211uint16_t plm_buffer_read_vlc_uint(plm_buffer_t *self,
const plm_vlc_uint_t *table);
1213plm_buffer_t *plm_buffer_create_with_filename(
const char *filename) {
1214 FIL *fh = vexFileOpen(filename,
"rb");
1218 return plm_buffer_create_with_file(fh, TRUE);
1221plm_buffer_t *plm_buffer_create_with_file(FIL *fh,
int close_when_done) {
1222 plm_buffer_t *self = plm_buffer_create_with_capacity(PLM_BUFFER_DEFAULT_SIZE);
1224 self->close_when_done = close_when_done;
1225 self->mode = PLM_BUFFER_MODE_FILE;
1226 self->discard_read_bytes = TRUE;
1228 vexFileSeek(self->fh, 0, SEEK_END);
1229 self->total_size = vexFileTell(self->fh);
1230 vexFileSeek(self->fh, 0, SEEK_SET);
1232 plm_buffer_set_load_callback(self, plm_buffer_load_file_callback, NULL);
1236plm_buffer_t *plm_buffer_create_with_memory(uint8_t *bytes,
size_t length,
int free_when_done) {
1237 plm_buffer_t *self = (plm_buffer_t *)PLM_MALLOC(
sizeof(plm_buffer_t));
1238 memset(self, 0,
sizeof(plm_buffer_t));
1239 self->capacity = length;
1240 self->length = length;
1241 self->total_size = length;
1242 self->free_when_done = free_when_done;
1243 self->bytes = bytes;
1244 self->mode = PLM_BUFFER_MODE_FIXED_MEM;
1245 self->discard_read_bytes = FALSE;
1249plm_buffer_t *plm_buffer_create_with_capacity(
size_t capacity) {
1250 plm_buffer_t *self = (plm_buffer_t *)PLM_MALLOC(
sizeof(plm_buffer_t));
1251 memset(self, 0,
sizeof(plm_buffer_t));
1252 self->capacity = capacity;
1253 self->free_when_done = TRUE;
1254 self->bytes = (uint8_t *)PLM_MALLOC(capacity);
1255 self->mode = PLM_BUFFER_MODE_RING;
1256 self->discard_read_bytes = TRUE;
1260plm_buffer_t *plm_buffer_create_for_appending(
size_t initial_capacity) {
1261 plm_buffer_t *self = plm_buffer_create_with_capacity(initial_capacity);
1262 self->mode = PLM_BUFFER_MODE_APPEND;
1263 self->discard_read_bytes = FALSE;
1267void plm_buffer_destroy(plm_buffer_t *self) {
1268 if (self->fh && self->close_when_done) {
1269 vexFileClose(self->fh);
1271 if (self->free_when_done) {
1272 PLM_FREE(self->bytes);
1277size_t plm_buffer_get_size(plm_buffer_t *self) {
1278 return (self->mode == PLM_BUFFER_MODE_FILE) ? self->total_size : self->length;
1281size_t plm_buffer_get_remaining(plm_buffer_t *self) {
return self->length - (self->bit_index >> 3); }
1283size_t plm_buffer_write(plm_buffer_t *self, uint8_t *bytes,
size_t length) {
1284 if (self->mode == PLM_BUFFER_MODE_FIXED_MEM) {
1288 if (self->discard_read_bytes) {
1293 plm_buffer_discard_read_bytes(self);
1294 if (self->mode == PLM_BUFFER_MODE_RING) {
1295 self->total_size = 0;
1300 size_t bytes_available = self->capacity - self->length;
1301 if (bytes_available < length) {
1302 size_t new_size = self->capacity;
1305 }
while (new_size - self->length < length);
1306 self->bytes = (uint8_t *)PLM_REALLOC(self->bytes, new_size);
1307 self->capacity = new_size;
1310 memcpy(self->bytes + self->length, bytes, length);
1311 self->length += length;
1312 self->has_ended = FALSE;
1316void plm_buffer_signal_end(plm_buffer_t *self) { self->total_size = self->length; }
1318void plm_buffer_set_load_callback(plm_buffer_t *self, plm_buffer_load_callback fp,
void *user) {
1319 self->load_callback = fp;
1320 self->load_callback_user_data = user;
1323void plm_buffer_rewind(plm_buffer_t *self) { plm_buffer_seek(self, 0); }
1325void plm_buffer_seek(plm_buffer_t *self,
size_t pos) {
1326 self->has_ended = FALSE;
1328 if (self->mode == PLM_BUFFER_MODE_FILE) {
1329 vexFileSeek(self->fh, pos, SEEK_SET);
1330 self->bit_index = 0;
1332 }
else if (self->mode == PLM_BUFFER_MODE_RING) {
1337 self->bit_index = 0;
1339 self->total_size = 0;
1340 }
else if (pos < self->length) {
1341 self->bit_index = pos << 3;
1345size_t plm_buffer_tell(plm_buffer_t *self) {
1346 return self->mode == PLM_BUFFER_MODE_FILE ? vexFileTell(self->fh) + (self->bit_index >> 3) - self->length
1347 : self->bit_index >> 3;
1350void plm_buffer_discard_read_bytes(plm_buffer_t *self) {
1351 size_t byte_pos = self->bit_index >> 3;
1352 if (byte_pos == self->length) {
1353 self->bit_index = 0;
1355 }
else if (byte_pos > 0) {
1356 memmove(self->bytes, self->bytes + byte_pos, self->length - byte_pos);
1357 self->bit_index -= byte_pos << 3;
1358 self->length -= byte_pos;
1362void plm_buffer_load_file_callback(plm_buffer_t *self,
void *user) {
1365 if (self->discard_read_bytes) {
1366 plm_buffer_discard_read_bytes(self);
1369 size_t bytes_available = self->capacity - self->length;
1370 size_t bytes_read = vexFileRead((
char *)self->bytes + self->length, 1, bytes_available, self->fh);
1371 self->length += bytes_read;
1373 if (bytes_read == 0) {
1374 self->has_ended = TRUE;
1378int plm_buffer_has_ended(plm_buffer_t *self) {
return self->has_ended; }
1380int plm_buffer_has(plm_buffer_t *self,
size_t count) {
1381 if (((self->length << 3) - self->bit_index) >= count) {
1385 if (self->load_callback) {
1386 self->load_callback(self, self->load_callback_user_data);
1388 if (((self->length << 3) - self->bit_index) >= count) {
1393 if (self->total_size != 0 && self->length == self->total_size) {
1394 self->has_ended = TRUE;
1399int plm_buffer_read(plm_buffer_t *self,
int count) {
1400 if (!plm_buffer_has(self, count)) {
1406 int current_byte = self->bytes[self->bit_index >> 3];
1408 int remaining = 8 - (self->bit_index & 7);
1409 int read = remaining < count ? remaining : count;
1410 int shift = remaining - read;
1411 int mask = (0xff >> (8 - read));
1413 value = (value << read) | ((current_byte & (mask << shift)) >> shift);
1415 self->bit_index += read;
1422void plm_buffer_align(plm_buffer_t *self) {
1423 self->bit_index = ((self->bit_index + 7) >> 3) << 3;
1426void plm_buffer_skip(plm_buffer_t *self,
size_t count) {
1427 if (plm_buffer_has(self, count)) {
1428 self->bit_index += count;
1432int plm_buffer_skip_bytes(plm_buffer_t *self, uint8_t v) {
1433 plm_buffer_align(self);
1435 while (plm_buffer_has(self, 8) && self->bytes[self->bit_index >> 3] == v) {
1436 self->bit_index += 8;
1442int plm_buffer_next_start_code(plm_buffer_t *self) {
1443 plm_buffer_align(self);
1445 while (plm_buffer_has(self, (5 << 3))) {
1446 size_t byte_index = (self->bit_index) >> 3;
1447 if (self->bytes[byte_index] == 0x00 && self->bytes[byte_index + 1] == 0x00 && self->bytes[byte_index + 2] == 0x01) {
1448 self->bit_index = (byte_index + 4) << 3;
1449 return self->bytes[byte_index + 3];
1451 self->bit_index += 8;
1456int plm_buffer_find_start_code(plm_buffer_t *self,
int code) {
1459 current = plm_buffer_next_start_code(self);
1460 if (current == code || current == -1) {
1467int plm_buffer_has_start_code(plm_buffer_t *self,
int code) {
1468 size_t previous_bit_index = self->bit_index;
1469 int previous_discard_read_bytes = self->discard_read_bytes;
1471 self->discard_read_bytes = FALSE;
1472 int current = plm_buffer_find_start_code(self, code);
1474 self->bit_index = previous_bit_index;
1475 self->discard_read_bytes = previous_discard_read_bytes;
1479int plm_buffer_peek_non_zero(plm_buffer_t *self,
int bit_count) {
1480 if (!plm_buffer_has(self, bit_count)) {
1484 int val = plm_buffer_read(self, bit_count);
1485 self->bit_index -= bit_count;
1489int16_t plm_buffer_read_vlc(plm_buffer_t *self,
const plm_vlc_t *table) {
1490 plm_vlc_t state = {0, 0};
1492 state = table[state.index + plm_buffer_read(self, 1)];
1493 }
while (state.index > 0);
1497uint16_t plm_buffer_read_vlc_uint(plm_buffer_t *self,
const plm_vlc_uint_t *table) {
1498 return (uint16_t)plm_buffer_read_vlc(self, (
const plm_vlc_t *)table);
1504static const int PLM_START_PACK = 0xBA;
1505static const int PLM_START_END = 0xB9;
1506static const int PLM_START_SYSTEM = 0xBB;
1509 plm_buffer_t *buffer;
1510 int destroy_buffer_when_done;
1511 double system_clock_ref;
1513 size_t last_file_size;
1514 double last_decoded_pts;
1519 int has_pack_header;
1520 int has_system_header;
1523 int num_audio_streams;
1524 int num_video_streams;
1525 plm_packet_t current_packet;
1526 plm_packet_t next_packet;
1529void plm_demux_buffer_seek(plm_demux_t *self,
size_t pos);
1530double plm_demux_decode_time(plm_demux_t *self);
1531plm_packet_t *plm_demux_decode_packet(plm_demux_t *self,
int type);
1532plm_packet_t *plm_demux_get_packet(plm_demux_t *self);
1534plm_demux_t *plm_demux_create(plm_buffer_t *buffer,
int destroy_when_done) {
1535 plm_demux_t *self = (plm_demux_t *)PLM_MALLOC(
sizeof(plm_demux_t));
1536 memset(self, 0,
sizeof(plm_demux_t));
1538 self->buffer = buffer;
1539 self->destroy_buffer_when_done = destroy_when_done;
1541 self->start_time = PLM_PACKET_INVALID_TS;
1542 self->duration = PLM_PACKET_INVALID_TS;
1543 self->start_code = -1;
1545 plm_demux_has_headers(self);
1549void plm_demux_destroy(plm_demux_t *self) {
1550 if (self->destroy_buffer_when_done) {
1551 plm_buffer_destroy(self->buffer);
1556int plm_demux_has_headers(plm_demux_t *self) {
1557 if (self->has_headers) {
1562 if (!self->has_pack_header) {
1563 if (self->start_code != PLM_START_PACK && plm_buffer_find_start_code(self->buffer, PLM_START_PACK) == -1) {
1567 self->start_code = PLM_START_PACK;
1568 if (!plm_buffer_has(self->buffer, 64)) {
1571 self->start_code = -1;
1573 if (plm_buffer_read(self->buffer, 4) != 0x02) {
1577 self->system_clock_ref = plm_demux_decode_time(self);
1578 plm_buffer_skip(self->buffer, 1);
1579 plm_buffer_skip(self->buffer, 22);
1580 plm_buffer_skip(self->buffer, 1);
1582 self->has_pack_header = TRUE;
1586 if (!self->has_system_header) {
1587 if (self->start_code != PLM_START_SYSTEM && plm_buffer_find_start_code(self->buffer, PLM_START_SYSTEM) == -1) {
1591 self->start_code = PLM_START_SYSTEM;
1592 if (!plm_buffer_has(self->buffer, 56)) {
1595 self->start_code = -1;
1597 plm_buffer_skip(self->buffer, 16);
1598 plm_buffer_skip(self->buffer, 24);
1599 self->num_audio_streams = plm_buffer_read(self->buffer, 6);
1600 plm_buffer_skip(self->buffer, 5);
1601 self->num_video_streams = plm_buffer_read(self->buffer, 5);
1603 self->has_system_header = TRUE;
1606 self->has_headers = TRUE;
1610int plm_demux_get_num_video_streams(plm_demux_t *self) {
1611 return plm_demux_has_headers(self) ? self->num_video_streams : 0;
1614int plm_demux_get_num_audio_streams(plm_demux_t *self) {
1615 return plm_demux_has_headers(self) ? self->num_audio_streams : 0;
1618void plm_demux_rewind(plm_demux_t *self) {
1619 plm_buffer_rewind(self->buffer);
1620 self->current_packet.length = 0;
1621 self->next_packet.length = 0;
1622 self->start_code = -1;
1625int plm_demux_has_ended(plm_demux_t *self) {
return plm_buffer_has_ended(self->buffer); }
1627void plm_demux_buffer_seek(plm_demux_t *self,
size_t pos) {
1628 plm_buffer_seek(self->buffer, pos);
1629 self->current_packet.length = 0;
1630 self->next_packet.length = 0;
1631 self->start_code = -1;
1634double plm_demux_get_start_time(plm_demux_t *self,
int type) {
1635 if (self->start_time != PLM_PACKET_INVALID_TS) {
1636 return self->start_time;
1639 int previous_pos = plm_buffer_tell(self->buffer);
1640 int previous_start_code = self->start_code;
1643 plm_demux_rewind(self);
1645 plm_packet_t *packet = plm_demux_decode(self);
1649 if (packet->type == type) {
1650 self->start_time = packet->pts;
1652 }
while (self->start_time == PLM_PACKET_INVALID_TS);
1654 plm_demux_buffer_seek(self, previous_pos);
1655 self->start_code = previous_start_code;
1656 return self->start_time;
1659double plm_demux_get_duration(plm_demux_t *self,
int type) {
1660 size_t file_size = plm_buffer_get_size(self->buffer);
1662 if (self->duration != PLM_PACKET_INVALID_TS && self->last_file_size == file_size) {
1663 return self->duration;
1666 size_t previous_pos = plm_buffer_tell(self->buffer);
1667 int previous_start_code = self->start_code;
1671 long start_range = 64 * 1024;
1672 long max_range = 4096 * 1024;
1673 for (
long range = start_range; range <= max_range; range *= 2) {
1674 long seek_pos = file_size - range;
1679 plm_demux_buffer_seek(self, seek_pos);
1680 self->current_packet.length = 0;
1682 double last_pts = PLM_PACKET_INVALID_TS;
1683 plm_packet_t *packet = NULL;
1684 while ((packet = plm_demux_decode(self))) {
1685 if (packet->pts != PLM_PACKET_INVALID_TS && packet->type == type) {
1686 last_pts = packet->pts;
1689 if (last_pts != PLM_PACKET_INVALID_TS) {
1690 self->duration = last_pts - plm_demux_get_start_time(self, type);
1695 plm_demux_buffer_seek(self, previous_pos);
1696 self->start_code = previous_start_code;
1697 self->last_file_size = file_size;
1698 return self->duration;
1701plm_packet_t *plm_demux_seek(plm_demux_t *self,
double seek_time,
int type,
int force_intra) {
1702 if (!plm_demux_has_headers(self)) {
1722 double duration = plm_demux_get_duration(self, type);
1723 long file_size = plm_buffer_get_size(self->buffer);
1724 long byterate = file_size / duration;
1726 double cur_time = self->last_decoded_pts;
1727 double scan_span = 1;
1729 if (seek_time > duration) {
1730 seek_time = duration;
1731 }
else if (seek_time < 0) {
1734 seek_time += self->start_time;
1736 for (
int retry = 0; retry < 32; retry++) {
1737 int found_packet_with_pts = FALSE;
1738 int found_packet_in_range = FALSE;
1739 long last_valid_packet_start = -1;
1740 double first_packet_time = PLM_PACKET_INVALID_TS;
1742 long cur_pos = plm_buffer_tell(self->buffer);
1745 long offset = (seek_time - cur_time - scan_span) * byterate;
1746 long seek_pos = cur_pos + offset;
1749 }
else if (seek_pos > file_size - 256) {
1750 seek_pos = file_size - 256;
1753 plm_demux_buffer_seek(self, seek_pos);
1757 while (plm_buffer_find_start_code(self->buffer, type) != -1) {
1758 long packet_start = plm_buffer_tell(self->buffer);
1759 plm_packet_t *packet = plm_demux_decode_packet(self, type);
1762 if (!packet || packet->pts == PLM_PACKET_INVALID_TS) {
1770 if (packet->pts > seek_time || packet->pts < seek_time - scan_span) {
1771 found_packet_with_pts = TRUE;
1772 byterate = (seek_pos - cur_pos) / (packet->pts - cur_time);
1773 cur_time = packet->pts;
1782 if (!found_packet_in_range) {
1783 found_packet_in_range = TRUE;
1784 first_packet_time = packet->pts;
1792 for (
size_t i = 0; i < packet->length - 6; i++) {
1794 if (packet->data[i] == 0x00 && packet->data[i + 1] == 0x00 && packet->data[i + 2] == 0x01 &&
1795 packet->data[i + 3] == 0x00) {
1798 if ((packet->data[i + 5] & 0x38) == 8) {
1799 last_valid_packet_start = packet_start;
1808 last_valid_packet_start = packet_start;
1814 if (last_valid_packet_start != -1) {
1815 plm_demux_buffer_seek(self, last_valid_packet_start);
1816 return plm_demux_decode_packet(self, type);
1822 else if (found_packet_in_range) {
1824 seek_time = first_packet_time;
1829 else if (!found_packet_with_pts) {
1830 byterate = (seek_pos - cur_pos) / (duration - cur_time);
1831 cur_time = duration;
1838plm_packet_t *plm_demux_decode(plm_demux_t *self) {
1839 if (!plm_demux_has_headers(self)) {
1843 if (self->current_packet.length) {
1844 size_t bits_till_next_packet = self->current_packet.length << 3;
1845 if (!plm_buffer_has(self->buffer, bits_till_next_packet)) {
1848 plm_buffer_skip(self->buffer, bits_till_next_packet);
1849 self->current_packet.length = 0;
1853 if (self->next_packet.length) {
1854 return plm_demux_get_packet(self);
1858 if (self->start_code != -1) {
1859 return plm_demux_decode_packet(self, self->start_code);
1863 self->start_code = plm_buffer_next_start_code(self->buffer);
1864 if (self->start_code == PLM_DEMUX_PACKET_VIDEO_1 || self->start_code == PLM_DEMUX_PACKET_PRIVATE ||
1865 (self->start_code >= PLM_DEMUX_PACKET_AUDIO_1 && self->start_code <= PLM_DEMUX_PACKET_AUDIO_4)) {
1866 return plm_demux_decode_packet(self, self->start_code);
1868 }
while (self->start_code != -1);
1873double plm_demux_decode_time(plm_demux_t *self) {
1874 int64_t clock = plm_buffer_read(self->buffer, 3) << 30;
1875 plm_buffer_skip(self->buffer, 1);
1876 clock |= plm_buffer_read(self->buffer, 15) << 15;
1877 plm_buffer_skip(self->buffer, 1);
1878 clock |= plm_buffer_read(self->buffer, 15);
1879 plm_buffer_skip(self->buffer, 1);
1880 return (
double)clock / 90000.0;
1883plm_packet_t *plm_demux_decode_packet(plm_demux_t *self,
int type) {
1884 if (!plm_buffer_has(self->buffer, 16 << 3)) {
1888 self->start_code = -1;
1890 self->next_packet.type = type;
1891 self->next_packet.length = plm_buffer_read(self->buffer, 16);
1892 self->next_packet.length -= plm_buffer_skip_bytes(self->buffer, 0xff);
1895 if (plm_buffer_read(self->buffer, 2) == 0x01) {
1896 plm_buffer_skip(self->buffer, 16);
1897 self->next_packet.length -= 2;
1900 int pts_dts_marker = plm_buffer_read(self->buffer, 2);
1901 if (pts_dts_marker == 0x03) {
1902 self->next_packet.pts = plm_demux_decode_time(self);
1903 self->last_decoded_pts = self->next_packet.pts;
1904 plm_buffer_skip(self->buffer, 40);
1905 self->next_packet.length -= 10;
1906 }
else if (pts_dts_marker == 0x02) {
1907 self->next_packet.pts = plm_demux_decode_time(self);
1908 self->last_decoded_pts = self->next_packet.pts;
1909 self->next_packet.length -= 5;
1910 }
else if (pts_dts_marker == 0x00) {
1911 self->next_packet.pts = PLM_PACKET_INVALID_TS;
1912 plm_buffer_skip(self->buffer, 4);
1913 self->next_packet.length -= 1;
1918 return plm_demux_get_packet(self);
1921plm_packet_t *plm_demux_get_packet(plm_demux_t *self) {
1922 if (!plm_buffer_has(self->buffer, self->next_packet.length << 3)) {
1926 self->current_packet.data = self->buffer->bytes + (self->buffer->bit_index >> 3);
1927 self->current_packet.length = self->next_packet.length;
1928 self->current_packet.type = self->next_packet.type;
1929 self->current_packet.pts = self->next_packet.pts;
1931 self->next_packet.length = 0;
1932 return &self->current_packet;
1941static const int PLM_VIDEO_PICTURE_TYPE_INTRA = 1;
1942static const int PLM_VIDEO_PICTURE_TYPE_PREDICTIVE = 2;
1943static const int PLM_VIDEO_PICTURE_TYPE_B = 3;
1945static const int PLM_START_SEQUENCE = 0xB3;
1946static const int PLM_START_SLICE_FIRST = 0x01;
1947static const int PLM_START_SLICE_LAST = 0xAF;
1948static const int PLM_START_PICTURE = 0x00;
1949static const int PLM_START_EXTENSION = 0xB5;
1950static const int PLM_START_USER_DATA = 0xB2;
1952#define PLM_START_IS_SLICE(c) (c >= PLM_START_SLICE_FIRST && c <= PLM_START_SLICE_LAST)
1954static const double PLM_VIDEO_PICTURE_RATE[] = {0.000, 23.976, 24.000, 25.000, 29.970, 30.000, 50.000, 59.940,
1955 60.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000, 0.000};
1957static const uint8_t PLM_VIDEO_ZIG_ZAG[] = {0, 1, 8, 16, 9, 2, 3, 10, 17, 24, 32, 25, 18, 11, 4, 5,
1958 12, 19, 26, 33, 40, 48, 41, 34, 27, 20, 13, 6, 7, 14, 21, 28,
1959 35, 42, 49, 56, 57, 50, 43, 36, 29, 22, 15, 23, 30, 37, 44, 51,
1960 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63};
1962static const uint8_t PLM_VIDEO_INTRA_QUANT_MATRIX[] = {8, 16, 19, 22, 26, 27, 29, 34, 16, 16, 22, 24, 27, 29, 34, 37,
1963 19, 22, 26, 27, 29, 34, 34, 38, 22, 22, 26, 27, 29, 34, 37, 40,
1964 22, 26, 27, 29, 32, 35, 40, 48, 26, 27, 29, 32, 35, 40, 48, 58,
1965 26, 27, 29, 34, 38, 46, 56, 69, 27, 29, 35, 38, 46, 56, 69, 83};
1967static const uint8_t PLM_VIDEO_NON_INTRA_QUANT_MATRIX[] = {
1968 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
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};
1972static const uint8_t PLM_VIDEO_PREMULTIPLIER_MATRIX[] = {32, 44, 42, 38, 32, 25, 17, 9, 44, 62, 58, 52, 44, 35, 24, 12,
1973 42, 58, 55, 49, 42, 33, 23, 12, 38, 52, 49, 44, 38, 30, 20, 10,
1974 32, 44, 42, 38, 32, 25, 17, 9, 25, 35, 33, 30, 25, 20, 14, 7,
1975 17, 24, 23, 20, 17, 14, 9, 5, 9, 12, 12, 10, 9, 7, 5, 2};
1977static const plm_vlc_t PLM_VIDEO_MACROBLOCK_ADDRESS_INCREMENT[] = {
1978 {1 << 1, 0}, {0, 1},
1979 {2 << 1, 0}, {3 << 1, 0},
1980 {4 << 1, 0}, {5 << 1, 0},
1982 {6 << 1, 0}, {7 << 1, 0},
1984 {8 << 1, 0}, {9 << 1, 0},
1986 {10 << 1, 0}, {11 << 1, 0},
1987 {12 << 1, 0}, {13 << 1, 0},
1988 {14 << 1, 0}, {15 << 1, 0},
1989 {16 << 1, 0}, {17 << 1, 0},
1990 {18 << 1, 0}, {19 << 1, 0},
1992 {-1, 0}, {20 << 1, 0},
1993 {-1, 0}, {21 << 1, 0},
1994 {22 << 1, 0}, {23 << 1, 0},
1998 {24 << 1, 0}, {25 << 1, 0},
1999 {26 << 1, 0}, {27 << 1, 0},
2000 {28 << 1, 0}, {29 << 1, 0},
2001 {30 << 1, 0}, {31 << 1, 0},
2002 {32 << 1, 0}, {-1, 0},
2003 {-1, 0}, {33 << 1, 0},
2004 {34 << 1, 0}, {35 << 1, 0},
2005 {36 << 1, 0}, {37 << 1, 0},
2006 {38 << 1, 0}, {39 << 1, 0},
2020static const plm_vlc_t PLM_VIDEO_MACROBLOCK_TYPE_INTRA[] = {
2027static const plm_vlc_t PLM_VIDEO_MACROBLOCK_TYPE_PREDICTIVE[] = {
2028 {1 << 1, 0}, {0, 0x0a},
2029 {2 << 1, 0}, {0, 0x02},
2030 {3 << 1, 0}, {0, 0x08},
2031 {4 << 1, 0}, {5 << 1, 0},
2032 {6 << 1, 0}, {0, 0x12},
2033 {0, 0x1a}, {0, 0x01},
2037static const plm_vlc_t PLM_VIDEO_MACROBLOCK_TYPE_B[] = {
2038 {1 << 1, 0}, {2 << 1, 0},
2039 {3 << 1, 0}, {4 << 1, 0},
2040 {0, 0x0c}, {0, 0x0e},
2041 {5 << 1, 0}, {6 << 1, 0},
2042 {0, 0x04}, {0, 0x06},
2043 {7 << 1, 0}, {8 << 1, 0},
2044 {0, 0x08}, {0, 0x0a},
2045 {9 << 1, 0}, {10 << 1, 0},
2046 {0, 0x1e}, {0, 0x01},
2048 {0, 0x16}, {0, 0x1a},
2051static const plm_vlc_t *PLM_VIDEO_MACROBLOCK_TYPE[] = {
2052 NULL, PLM_VIDEO_MACROBLOCK_TYPE_INTRA, PLM_VIDEO_MACROBLOCK_TYPE_PREDICTIVE, PLM_VIDEO_MACROBLOCK_TYPE_B};
2054static const plm_vlc_t PLM_VIDEO_CODE_BLOCK_PATTERN[] = {
2055 {1 << 1, 0}, {2 << 1, 0},
2056 {3 << 1, 0}, {4 << 1, 0},
2057 {5 << 1, 0}, {6 << 1, 0},
2058 {7 << 1, 0}, {8 << 1, 0},
2059 {9 << 1, 0}, {10 << 1, 0},
2060 {11 << 1, 0}, {12 << 1, 0},
2061 {13 << 1, 0}, {0, 60},
2062 {14 << 1, 0}, {15 << 1, 0},
2063 {16 << 1, 0}, {17 << 1, 0},
2064 {18 << 1, 0}, {19 << 1, 0},
2065 {20 << 1, 0}, {21 << 1, 0},
2066 {22 << 1, 0}, {23 << 1, 0},
2069 {24 << 1, 0}, {25 << 1, 0},
2070 {26 << 1, 0}, {27 << 1, 0},
2071 {28 << 1, 0}, {29 << 1, 0},
2072 {30 << 1, 0}, {31 << 1, 0},
2079 {32 << 1, 0}, {33 << 1, 0},
2080 {34 << 1, 0}, {35 << 1, 0},
2081 {36 << 1, 0}, {37 << 1, 0},
2082 {38 << 1, 0}, {39 << 1, 0},
2083 {40 << 1, 0}, {41 << 1, 0},
2084 {42 << 1, 0}, {43 << 1, 0},
2087 {44 << 1, 0}, {45 << 1, 0},
2088 {46 << 1, 0}, {47 << 1, 0},
2089 {48 << 1, 0}, {49 << 1, 0},
2090 {50 << 1, 0}, {51 << 1, 0},
2091 {52 << 1, 0}, {53 << 1, 0},
2092 {54 << 1, 0}, {55 << 1, 0},
2093 {56 << 1, 0}, {57 << 1, 0},
2094 {58 << 1, 0}, {59 << 1, 0},
2099 {-1, 0}, {60 << 1, 0},
2100 {61 << 1, 0}, {62 << 1, 0},
2120static const plm_vlc_t PLM_VIDEO_MOTION[] = {
2121 {1 << 1, 0}, {0, 0},
2122 {2 << 1, 0}, {3 << 1, 0},
2123 {4 << 1, 0}, {5 << 1, 0},
2125 {6 << 1, 0}, {7 << 1, 0},
2127 {8 << 1, 0}, {9 << 1, 0},
2129 {10 << 1, 0}, {11 << 1, 0},
2130 {12 << 1, 0}, {13 << 1, 0},
2131 {-1, 0}, {14 << 1, 0},
2132 {15 << 1, 0}, {16 << 1, 0},
2133 {17 << 1, 0}, {18 << 1, 0},
2135 {-1, 0}, {19 << 1, 0},
2136 {20 << 1, 0}, {21 << 1, 0},
2140 {22 << 1, 0}, {23 << 1, 0},
2141 {24 << 1, 0}, {25 << 1, 0},
2142 {26 << 1, 0}, {27 << 1, 0},
2143 {28 << 1, 0}, {29 << 1, 0},
2144 {30 << 1, 0}, {31 << 1, 0},
2145 {32 << 1, 0}, {33 << 1, 0},
2157static const plm_vlc_t PLM_VIDEO_DCT_SIZE_LUMINANCE[] = {
2158 {1 << 1, 0}, {2 << 1, 0},
2160 {3 << 1, 0}, {4 << 1, 0},
2162 {0, 4}, {5 << 1, 0},
2163 {0, 5}, {6 << 1, 0},
2164 {0, 6}, {7 << 1, 0},
2165 {0, 7}, {8 << 1, 0},
2169static const plm_vlc_t PLM_VIDEO_DCT_SIZE_CHROMINANCE[] = {
2170 {1 << 1, 0}, {2 << 1, 0},
2172 {0, 2}, {3 << 1, 0},
2173 {0, 3}, {4 << 1, 0},
2174 {0, 4}, {5 << 1, 0},
2175 {0, 5}, {6 << 1, 0},
2176 {0, 6}, {7 << 1, 0},
2177 {0, 7}, {8 << 1, 0},
2181static const plm_vlc_t *PLM_VIDEO_DCT_SIZE[] = {PLM_VIDEO_DCT_SIZE_LUMINANCE, PLM_VIDEO_DCT_SIZE_CHROMINANCE,
2182 PLM_VIDEO_DCT_SIZE_CHROMINANCE};
2190static const plm_vlc_uint_t PLM_VIDEO_DCT_COEFF[] = {
2191 {1 << 1, 0}, {0, 0x0001},
2192 {2 << 1, 0}, {3 << 1, 0},
2193 {4 << 1, 0}, {5 << 1, 0},
2194 {6 << 1, 0}, {0, 0x0101},
2195 {7 << 1, 0}, {8 << 1, 0},
2196 {9 << 1, 0}, {10 << 1, 0},
2197 {0, 0x0002}, {0, 0x0201},
2198 {11 << 1, 0}, {12 << 1, 0},
2199 {13 << 1, 0}, {14 << 1, 0},
2200 {15 << 1, 0}, {0, 0x0003},
2201 {0, 0x0401}, {0, 0x0301},
2202 {16 << 1, 0}, {0, 0xffff},
2203 {17 << 1, 0}, {18 << 1, 0},
2204 {0, 0x0701}, {0, 0x0601},
2205 {0, 0x0102}, {0, 0x0501},
2206 {19 << 1, 0}, {20 << 1, 0},
2207 {21 << 1, 0}, {22 << 1, 0},
2208 {0, 0x0202}, {0, 0x0901},
2209 {0, 0x0004}, {0, 0x0801},
2210 {23 << 1, 0}, {24 << 1, 0},
2211 {25 << 1, 0}, {26 << 1, 0},
2212 {27 << 1, 0}, {28 << 1, 0},
2213 {29 << 1, 0}, {30 << 1, 0},
2214 {0, 0x0d01}, {0, 0x0006},
2215 {0, 0x0c01}, {0, 0x0b01},
2216 {0, 0x0302}, {0, 0x0103},
2217 {0, 0x0005}, {0, 0x0a01},
2218 {31 << 1, 0}, {32 << 1, 0},
2219 {33 << 1, 0}, {34 << 1, 0},
2220 {35 << 1, 0}, {36 << 1, 0},
2221 {37 << 1, 0}, {38 << 1, 0},
2222 {39 << 1, 0}, {40 << 1, 0},
2223 {41 << 1, 0}, {42 << 1, 0},
2224 {43 << 1, 0}, {44 << 1, 0},
2225 {45 << 1, 0}, {46 << 1, 0},
2226 {0, 0x1001}, {0, 0x0502},
2227 {0, 0x0007}, {0, 0x0203},
2228 {0, 0x0104}, {0, 0x0f01},
2229 {0, 0x0e01}, {0, 0x0402},
2230 {47 << 1, 0}, {48 << 1, 0},
2231 {49 << 1, 0}, {50 << 1, 0},
2232 {51 << 1, 0}, {52 << 1, 0},
2233 {53 << 1, 0}, {54 << 1, 0},
2234 {55 << 1, 0}, {56 << 1, 0},
2235 {57 << 1, 0}, {58 << 1, 0},
2236 {59 << 1, 0}, {60 << 1, 0},
2237 {61 << 1, 0}, {62 << 1, 0},
2238 {-1, 0}, {63 << 1, 0},
2239 {64 << 1, 0}, {65 << 1, 0},
2240 {66 << 1, 0}, {67 << 1, 0},
2241 {68 << 1, 0}, {69 << 1, 0},
2242 {70 << 1, 0}, {71 << 1, 0},
2243 {72 << 1, 0}, {73 << 1, 0},
2244 {74 << 1, 0}, {75 << 1, 0},
2245 {76 << 1, 0}, {77 << 1, 0},
2246 {0, 0x000b}, {0, 0x0802},
2247 {0, 0x0403}, {0, 0x000a},
2248 {0, 0x0204}, {0, 0x0702},
2249 {0, 0x1501}, {0, 0x1401},
2250 {0, 0x0009}, {0, 0x1301},
2251 {0, 0x1201}, {0, 0x0105},
2252 {0, 0x0303}, {0, 0x0008},
2253 {0, 0x0602}, {0, 0x1101},
2254 {78 << 1, 0}, {79 << 1, 0},
2255 {80 << 1, 0}, {81 << 1, 0},
2256 {82 << 1, 0}, {83 << 1, 0},
2257 {84 << 1, 0}, {85 << 1, 0},
2258 {86 << 1, 0}, {87 << 1, 0},
2259 {88 << 1, 0}, {89 << 1, 0},
2260 {90 << 1, 0}, {91 << 1, 0},
2261 {0, 0x0a02}, {0, 0x0902},
2262 {0, 0x0503}, {0, 0x0304},
2263 {0, 0x0205}, {0, 0x0107},
2264 {0, 0x0106}, {0, 0x000f},
2265 {0, 0x000e}, {0, 0x000d},
2266 {0, 0x000c}, {0, 0x1a01},
2267 {0, 0x1901}, {0, 0x1801},
2268 {0, 0x1701}, {0, 0x1601},
2269 {92 << 1, 0}, {93 << 1, 0},
2270 {94 << 1, 0}, {95 << 1, 0},
2271 {96 << 1, 0}, {97 << 1, 0},
2272 {98 << 1, 0}, {99 << 1, 0},
2273 {100 << 1, 0}, {101 << 1, 0},
2274 {102 << 1, 0}, {103 << 1, 0},
2275 {0, 0x001f}, {0, 0x001e},
2276 {0, 0x001d}, {0, 0x001c},
2277 {0, 0x001b}, {0, 0x001a},
2278 {0, 0x0019}, {0, 0x0018},
2279 {0, 0x0017}, {0, 0x0016},
2280 {0, 0x0015}, {0, 0x0014},
2281 {0, 0x0013}, {0, 0x0012},
2282 {0, 0x0011}, {0, 0x0010},
2283 {104 << 1, 0}, {105 << 1, 0},
2284 {106 << 1, 0}, {107 << 1, 0},
2285 {108 << 1, 0}, {109 << 1, 0},
2286 {110 << 1, 0}, {111 << 1, 0},
2287 {0, 0x0028}, {0, 0x0027},
2288 {0, 0x0026}, {0, 0x0025},
2289 {0, 0x0024}, {0, 0x0023},
2290 {0, 0x0022}, {0, 0x0021},
2291 {0, 0x0020}, {0, 0x010e},
2292 {0, 0x010d}, {0, 0x010c},
2293 {0, 0x010b}, {0, 0x010a},
2294 {0, 0x0109}, {0, 0x0108},
2295 {0, 0x0112}, {0, 0x0111},
2296 {0, 0x0110}, {0, 0x010f},
2297 {0, 0x0603}, {0, 0x1002},
2298 {0, 0x0f02}, {0, 0x0e02},
2299 {0, 0x0d02}, {0, 0x0c02},
2300 {0, 0x0b02}, {0, 0x1f01},
2301 {0, 0x1e01}, {0, 0x1d01},
2302 {0, 0x1c01}, {0, 0x1b01},
2311} plm_video_motion_t;
2332 plm_video_motion_t motion_forward;
2333 plm_video_motion_t motion_backward;
2335 int has_sequence_header;
2337 int quantizer_scale;
2339 int macroblock_address;
2344 int macroblock_type;
2345 int macroblock_intra;
2347 int dc_predictor[3];
2349 plm_buffer_t *buffer;
2350 int destroy_buffer_when_done;
2352 plm_frame_t frame_current;
2353 plm_frame_t frame_forward;
2354 plm_frame_t frame_backward;
2356 uint8_t *frames_data;
2359 uint8_t intra_quant_matrix[64];
2360 uint8_t non_intra_quant_matrix[64];
2362 int has_reference_frame;
2363 int assume_no_b_frames;
2366static inline uint8_t plm_clamp(
int n) {
2375int plm_video_decode_sequence_header(plm_video_t *self);
2376void plm_video_init_frame(plm_video_t *self, plm_frame_t *frame, uint8_t *base);
2377void plm_video_decode_picture(plm_video_t *self);
2378void plm_video_decode_slice(plm_video_t *self,
int slice);
2379void plm_video_decode_macroblock(plm_video_t *self);
2380void plm_video_decode_motion_vectors(plm_video_t *self);
2381int plm_video_decode_motion_vector(plm_video_t *self,
int r_size,
int motion);
2382void plm_video_predict_macroblock(plm_video_t *self);
2383void plm_video_copy_macroblock(plm_video_t *self, plm_frame_t *s,
int motion_h,
int motion_v);
2384void plm_video_interpolate_macroblock(plm_video_t *self, plm_frame_t *s,
int motion_h,
int motion_v);
2385void plm_video_process_macroblock(plm_video_t *self, uint8_t *s, uint8_t *d,
int mh,
int mb,
int bs,
int interp);
2386void plm_video_decode_block(plm_video_t *self,
int block);
2387void plm_video_idct(
int *block);
2389plm_video_t *plm_video_create_with_buffer(plm_buffer_t *buffer,
int destroy_when_done) {
2390 plm_video_t *self = (plm_video_t *)PLM_MALLOC(
sizeof(plm_video_t));
2391 memset(self, 0,
sizeof(plm_video_t));
2393 self->buffer = buffer;
2394 self->destroy_buffer_when_done = destroy_when_done;
2397 self->start_code = plm_buffer_find_start_code(self->buffer, PLM_START_SEQUENCE);
2398 if (self->start_code != -1) {
2399 plm_video_decode_sequence_header(self);
2404void plm_video_destroy(plm_video_t *self) {
2405 if (self->destroy_buffer_when_done) {
2406 plm_buffer_destroy(self->buffer);
2409 if (self->has_sequence_header) {
2410 PLM_FREE(self->frames_data);
2416double plm_video_get_framerate(plm_video_t *self) {
return plm_video_has_header(self) ? self->framerate : 0; }
2418int plm_video_get_width(plm_video_t *self) {
return plm_video_has_header(self) ? self->width : 0; }
2420int plm_video_get_height(plm_video_t *self) {
return plm_video_has_header(self) ? self->height : 0; }
2422void plm_video_set_no_delay(plm_video_t *self,
int no_delay) { self->assume_no_b_frames = no_delay; }
2424double plm_video_get_time(plm_video_t *self) {
return self->time; }
2426void plm_video_set_time(plm_video_t *self,
double time) {
2427 self->frames_decoded = self->framerate * time;
2431void plm_video_rewind(plm_video_t *self) {
2432 plm_buffer_rewind(self->buffer);
2434 self->frames_decoded = 0;
2435 self->has_reference_frame = FALSE;
2436 self->start_code = -1;
2439int plm_video_has_ended(plm_video_t *self) {
return plm_buffer_has_ended(self->buffer); }
2441plm_frame_t *plm_video_decode(plm_video_t *self) {
2442 if (!plm_video_has_header(self)) {
2446 plm_frame_t *frame = NULL;
2448 if (self->start_code != PLM_START_PICTURE) {
2449 self->start_code = plm_buffer_find_start_code(self->buffer, PLM_START_PICTURE);
2451 if (self->start_code == -1) {
2454 if (self->has_reference_frame && !self->assume_no_b_frames && plm_buffer_has_ended(self->buffer) &&
2455 (self->picture_type == PLM_VIDEO_PICTURE_TYPE_INTRA ||
2456 self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE)) {
2457 self->has_reference_frame = FALSE;
2458 frame = &self->frame_backward;
2471 if (plm_buffer_has_start_code(self->buffer, PLM_START_PICTURE) == -1 && !plm_buffer_has_ended(self->buffer)) {
2474 plm_buffer_discard_read_bytes(self->buffer);
2476 plm_video_decode_picture(self);
2478 if (self->assume_no_b_frames) {
2479 frame = &self->frame_backward;
2480 }
else if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_B) {
2481 frame = &self->frame_current;
2482 }
else if (self->has_reference_frame) {
2483 frame = &self->frame_forward;
2485 self->has_reference_frame = TRUE;
2489 frame->time = self->time;
2490 self->frames_decoded++;
2491 self->time = (double)self->frames_decoded / self->framerate;
2496int plm_video_has_header(plm_video_t *self) {
2497 if (self->has_sequence_header) {
2501 if (self->start_code != PLM_START_SEQUENCE) {
2502 self->start_code = plm_buffer_find_start_code(self->buffer, PLM_START_SEQUENCE);
2504 if (self->start_code == -1) {
2508 if (!plm_video_decode_sequence_header(self)) {
2515int plm_video_decode_sequence_header(plm_video_t *self) {
2516 int max_header_size = 64 + 2 * 64 * 8;
2517 if (!plm_buffer_has(self->buffer, max_header_size)) {
2521 self->width = plm_buffer_read(self->buffer, 12);
2522 self->height = plm_buffer_read(self->buffer, 12);
2524 if (self->width <= 0 || self->height <= 0) {
2529 plm_buffer_skip(self->buffer, 4);
2531 self->framerate = PLM_VIDEO_PICTURE_RATE[plm_buffer_read(self->buffer, 4)];
2534 plm_buffer_skip(self->buffer, 18 + 1 + 10 + 1);
2537 if (plm_buffer_read(self->buffer, 1)) {
2538 for (
int i = 0; i < 64; i++) {
2539 int idx = PLM_VIDEO_ZIG_ZAG[i];
2540 self->intra_quant_matrix[idx] = plm_buffer_read(self->buffer, 8);
2543 memcpy(self->intra_quant_matrix, PLM_VIDEO_INTRA_QUANT_MATRIX, 64);
2547 if (plm_buffer_read(self->buffer, 1)) {
2548 for (
int i = 0; i < 64; i++) {
2549 int idx = PLM_VIDEO_ZIG_ZAG[i];
2550 self->non_intra_quant_matrix[idx] = plm_buffer_read(self->buffer, 8);
2553 memcpy(self->non_intra_quant_matrix, PLM_VIDEO_NON_INTRA_QUANT_MATRIX, 64);
2556 self->mb_width = (self->width + 15) >> 4;
2557 self->mb_height = (self->height + 15) >> 4;
2558 self->mb_size = self->mb_width * self->mb_height;
2560 self->luma_width = self->mb_width << 4;
2561 self->luma_height = self->mb_height << 4;
2563 self->chroma_width = self->mb_width << 3;
2564 self->chroma_height = self->mb_height << 3;
2567 size_t luma_plane_size = self->luma_width * self->luma_height;
2568 size_t chroma_plane_size = self->chroma_width * self->chroma_height;
2569 size_t frame_data_size = (luma_plane_size + 2 * chroma_plane_size);
2571 self->frames_data = (uint8_t *)PLM_MALLOC(frame_data_size * 3);
2572 plm_video_init_frame(self, &self->frame_current, self->frames_data + frame_data_size * 0);
2573 plm_video_init_frame(self, &self->frame_forward, self->frames_data + frame_data_size * 1);
2574 plm_video_init_frame(self, &self->frame_backward, self->frames_data + frame_data_size * 2);
2576 self->has_sequence_header = TRUE;
2580void plm_video_init_frame(plm_video_t *self, plm_frame_t *frame, uint8_t *base) {
2581 size_t luma_plane_size = self->luma_width * self->luma_height;
2582 size_t chroma_plane_size = self->chroma_width * self->chroma_height;
2584 frame->width = self->width;
2585 frame->height = self->height;
2586 frame->y.width = self->luma_width;
2587 frame->y.height = self->luma_height;
2588 frame->y.data = base;
2590 frame->cr.width = self->chroma_width;
2591 frame->cr.height = self->chroma_height;
2592 frame->cr.data = base + luma_plane_size;
2594 frame->cb.width = self->chroma_width;
2595 frame->cb.height = self->chroma_height;
2596 frame->cb.data = base + luma_plane_size + chroma_plane_size;
2599void plm_video_decode_picture(plm_video_t *self) {
2600 plm_buffer_skip(self->buffer, 10);
2601 self->picture_type = plm_buffer_read(self->buffer, 3);
2602 plm_buffer_skip(self->buffer, 16);
2605 if (self->picture_type <= 0 || self->picture_type > PLM_VIDEO_PICTURE_TYPE_B) {
2610 if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE || self->picture_type == PLM_VIDEO_PICTURE_TYPE_B) {
2611 self->motion_forward.full_px = plm_buffer_read(self->buffer, 1);
2612 int f_code = plm_buffer_read(self->buffer, 3);
2617 self->motion_forward.r_size = f_code - 1;
2621 if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_B) {
2622 self->motion_backward.full_px = plm_buffer_read(self->buffer, 1);
2623 int f_code = plm_buffer_read(self->buffer, 3);
2628 self->motion_backward.r_size = f_code - 1;
2631 plm_frame_t frame_temp = self->frame_forward;
2632 if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_INTRA || self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE) {
2633 self->frame_forward = self->frame_backward;
2638 self->start_code = plm_buffer_next_start_code(self->buffer);
2639 }
while (self->start_code == PLM_START_EXTENSION || self->start_code == PLM_START_USER_DATA);
2642 while (PLM_START_IS_SLICE(self->start_code)) {
2643 plm_video_decode_slice(self, self->start_code & 0x000000FF);
2644 if (self->macroblock_address >= self->mb_size - 2) {
2647 self->start_code = plm_buffer_next_start_code(self->buffer);
2651 if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_INTRA || self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE) {
2652 self->frame_backward = self->frame_current;
2653 self->frame_current = frame_temp;
2657void plm_video_decode_slice(plm_video_t *self,
int slice) {
2658 self->slice_begin = TRUE;
2659 self->macroblock_address = (slice - 1) * self->mb_width - 1;
2662 self->motion_backward.h = self->motion_forward.h = 0;
2663 self->motion_backward.v = self->motion_forward.v = 0;
2664 self->dc_predictor[0] = 128;
2665 self->dc_predictor[1] = 128;
2666 self->dc_predictor[2] = 128;
2668 self->quantizer_scale = plm_buffer_read(self->buffer, 5);
2671 while (plm_buffer_read(self->buffer, 1)) {
2672 plm_buffer_skip(self->buffer, 8);
2676 plm_video_decode_macroblock(self);
2677 }
while (self->macroblock_address < self->mb_size - 1 && plm_buffer_peek_non_zero(self->buffer, 23));
2680void plm_video_decode_macroblock(plm_video_t *self) {
2683 int t = plm_buffer_read_vlc(self->buffer, PLM_VIDEO_MACROBLOCK_ADDRESS_INCREMENT);
2687 t = plm_buffer_read_vlc(self->buffer, PLM_VIDEO_MACROBLOCK_ADDRESS_INCREMENT);
2692 t = plm_buffer_read_vlc(self->buffer, PLM_VIDEO_MACROBLOCK_ADDRESS_INCREMENT);
2697 if (self->slice_begin) {
2700 self->slice_begin = FALSE;
2701 self->macroblock_address += increment;
2703 if (self->macroblock_address + increment >= self->mb_size) {
2706 if (increment > 1) {
2708 self->dc_predictor[0] = 128;
2709 self->dc_predictor[1] = 128;
2710 self->dc_predictor[2] = 128;
2713 if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE) {
2714 self->motion_forward.h = 0;
2715 self->motion_forward.v = 0;
2720 while (increment > 1) {
2721 self->macroblock_address++;
2722 self->mb_row = self->macroblock_address / self->mb_width;
2723 self->mb_col = self->macroblock_address % self->mb_width;
2725 plm_video_predict_macroblock(self);
2728 self->macroblock_address++;
2731 self->mb_row = self->macroblock_address / self->mb_width;
2732 self->mb_col = self->macroblock_address % self->mb_width;
2734 if (self->mb_col >= self->mb_width || self->mb_row >= self->mb_height) {
2739 const plm_vlc_t *table = PLM_VIDEO_MACROBLOCK_TYPE[self->picture_type];
2740 self->macroblock_type = plm_buffer_read_vlc(self->buffer, table);
2742 self->macroblock_intra = (self->macroblock_type & 0x01);
2743 self->motion_forward.is_set = (self->macroblock_type & 0x08);
2744 self->motion_backward.is_set = (self->macroblock_type & 0x04);
2747 if ((self->macroblock_type & 0x10) != 0) {
2748 self->quantizer_scale = plm_buffer_read(self->buffer, 5);
2751 if (self->macroblock_intra) {
2753 self->motion_backward.h = self->motion_forward.h = 0;
2754 self->motion_backward.v = self->motion_forward.v = 0;
2757 self->dc_predictor[0] = 128;
2758 self->dc_predictor[1] = 128;
2759 self->dc_predictor[2] = 128;
2761 plm_video_decode_motion_vectors(self);
2762 plm_video_predict_macroblock(self);
2766 int cbp = ((self->macroblock_type & 0x02) != 0) ? plm_buffer_read_vlc(self->buffer, PLM_VIDEO_CODE_BLOCK_PATTERN)
2767 : (self->macroblock_intra ? 0x3f : 0);
2769 for (
int block = 0, mask = 0x20; block < 6; block++) {
2770 if ((cbp & mask) != 0) {
2771 plm_video_decode_block(self, block);
2777void plm_video_decode_motion_vectors(plm_video_t *self) {
2780 if (self->motion_forward.is_set) {
2781 int r_size = self->motion_forward.r_size;
2782 self->motion_forward.h = plm_video_decode_motion_vector(self, r_size, self->motion_forward.h);
2783 self->motion_forward.v = plm_video_decode_motion_vector(self, r_size, self->motion_forward.v);
2784 }
else if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_PREDICTIVE) {
2786 self->motion_forward.h = 0;
2787 self->motion_forward.v = 0;
2790 if (self->motion_backward.is_set) {
2791 int r_size = self->motion_backward.r_size;
2792 self->motion_backward.h = plm_video_decode_motion_vector(self, r_size, self->motion_backward.h);
2793 self->motion_backward.v = plm_video_decode_motion_vector(self, r_size, self->motion_backward.v);
2797int plm_video_decode_motion_vector(plm_video_t *self,
int r_size,
int motion) {
2798 int fscale = 1 << r_size;
2799 int m_code = plm_buffer_read_vlc(self->buffer, PLM_VIDEO_MOTION);
2803 if ((m_code != 0) && (fscale != 1)) {
2804 r = plm_buffer_read(self->buffer, r_size);
2805 d = ((abs(m_code) - 1) << r_size) + r + 1;
2814 if (motion > (fscale << 4) - 1) {
2815 motion -= fscale << 5;
2816 }
else if (motion < ((-fscale) << 4)) {
2817 motion += fscale << 5;
2823void plm_video_predict_macroblock(plm_video_t *self) {
2824 int fw_h = self->motion_forward.h;
2825 int fw_v = self->motion_forward.v;
2827 if (self->motion_forward.full_px) {
2832 if (self->picture_type == PLM_VIDEO_PICTURE_TYPE_B) {
2833 int bw_h = self->motion_backward.h;
2834 int bw_v = self->motion_backward.v;
2836 if (self->motion_backward.full_px) {
2841 if (self->motion_forward.is_set) {
2842 plm_video_copy_macroblock(self, &self->frame_forward, fw_h, fw_v);
2843 if (self->motion_backward.is_set) {
2844 plm_video_interpolate_macroblock(self, &self->frame_backward, bw_h, bw_v);
2847 plm_video_copy_macroblock(self, &self->frame_backward, bw_h, bw_v);
2850 plm_video_copy_macroblock(self, &self->frame_forward, fw_h, fw_v);
2854void plm_video_copy_macroblock(plm_video_t *self, plm_frame_t *s,
int motion_h,
int motion_v) {
2855 plm_frame_t *d = &self->frame_current;
2856 plm_video_process_macroblock(self, s->y.data, d->y.data, motion_h, motion_v, 16, FALSE);
2857 plm_video_process_macroblock(self, s->cr.data, d->cr.data, motion_h / 2, motion_v / 2, 8, FALSE);
2858 plm_video_process_macroblock(self, s->cb.data, d->cb.data, motion_h / 2, motion_v / 2, 8, FALSE);
2861void plm_video_interpolate_macroblock(plm_video_t *self, plm_frame_t *s,
int motion_h,
int motion_v) {
2862 plm_frame_t *d = &self->frame_current;
2863 plm_video_process_macroblock(self, s->y.data, d->y.data, motion_h, motion_v, 16, TRUE);
2864 plm_video_process_macroblock(self, s->cr.data, d->cr.data, motion_h / 2, motion_v / 2, 8, TRUE);
2865 plm_video_process_macroblock(self, s->cb.data, d->cb.data, motion_h / 2, motion_v / 2, 8, TRUE);
2868#define PLM_BLOCK_SET(DEST, DEST_INDEX, DEST_WIDTH, SOURCE_INDEX, SOURCE_WIDTH, BLOCK_SIZE, OP) \
2870 int dest_scan = DEST_WIDTH - BLOCK_SIZE; \
2871 int source_scan = SOURCE_WIDTH - BLOCK_SIZE; \
2872 for (int y = 0; y < BLOCK_SIZE; y++) { \
2873 for (int x = 0; x < BLOCK_SIZE; x++) { \
2874 DEST[DEST_INDEX] = OP; \
2878 SOURCE_INDEX += source_scan; \
2879 DEST_INDEX += dest_scan; \
2883void plm_video_process_macroblock(plm_video_t *self, uint8_t *s, uint8_t *d,
int motion_h,
int motion_v,
int block_size,
2885 int dw = self->mb_width * block_size;
2887 int hp = motion_h >> 1;
2888 int vp = motion_v >> 1;
2889 int odd_h = (motion_h & 1) == 1;
2890 int odd_v = (motion_v & 1) == 1;
2892 unsigned int si = ((self->mb_row * block_size) + vp) * dw + (self->mb_col * block_size) + hp;
2893 unsigned int di = (self->mb_row * dw + self->mb_col) * block_size;
2895 unsigned int max_address = (dw * (self->mb_height * block_size - block_size + 1) - block_size);
2896 if (si > max_address || di > max_address) {
2900#define PLM_MB_CASE(INTERPOLATE, ODD_H, ODD_V, OP) \
2901 case ((INTERPOLATE << 2) | (ODD_H << 1) | (ODD_V)): \
2902 PLM_BLOCK_SET(d, di, dw, si, dw, block_size, OP); \
2905 switch ((interpolate << 2) | (odd_h << 1) | (odd_v)) {
2906 PLM_MB_CASE(0, 0, 0, (s[si]));
2907 PLM_MB_CASE(0, 0, 1, (s[si] + s[si + dw] + 1) >> 1);
2908 PLM_MB_CASE(0, 1, 0, (s[si] + s[si + 1] + 1) >> 1);
2909 PLM_MB_CASE(0, 1, 1, (s[si] + s[si + 1] + s[si + dw] + s[si + dw + 1] + 2) >> 2);
2911 PLM_MB_CASE(1, 0, 0, (d[di] + (s[si]) + 1) >> 1);
2912 PLM_MB_CASE(1, 0, 1, (d[di] + ((s[si] + s[si + dw] + 1) >> 1) + 1) >> 1);
2913 PLM_MB_CASE(1, 1, 0, (d[di] + ((s[si] + s[si + 1] + 1) >> 1) + 1) >> 1);
2914 PLM_MB_CASE(1, 1, 1, (d[di] + ((s[si] + s[si + 1] + s[si + dw] + s[si + dw + 1] + 2) >> 2) + 1) >> 1);
2920void plm_video_decode_block(plm_video_t *self,
int block) {
2923 uint8_t *quant_matrix;
2926 if (self->macroblock_intra) {
2931 int plane_index = block > 3 ? block - 3 : 0;
2932 predictor = self->dc_predictor[plane_index];
2933 dct_size = plm_buffer_read_vlc(self->buffer, PLM_VIDEO_DCT_SIZE[plane_index]);
2937 int differential = plm_buffer_read(self->buffer, dct_size);
2938 if ((differential & (1 << (dct_size - 1))) != 0) {
2939 self->block_data[0] = predictor + differential;
2941 self->block_data[0] = predictor + (-(1 << dct_size) | (differential + 1));
2944 self->block_data[0] = predictor;
2948 self->dc_predictor[plane_index] = self->block_data[0];
2951 self->block_data[0] <<= (3 + 5);
2953 quant_matrix = self->intra_quant_matrix;
2956 quant_matrix = self->non_intra_quant_matrix;
2963 uint16_t coeff = plm_buffer_read_vlc_uint(self->buffer, PLM_VIDEO_DCT_COEFF);
2965 if ((coeff == 0x0001) && (n > 0) && (plm_buffer_read(self->buffer, 1) == 0)) {
2969 if (coeff == 0xffff) {
2971 run = plm_buffer_read(self->buffer, 6);
2972 level = plm_buffer_read(self->buffer, 8);
2974 level = plm_buffer_read(self->buffer, 8);
2975 }
else if (level == 128) {
2976 level = plm_buffer_read(self->buffer, 8) - 256;
2977 }
else if (level > 128) {
2978 level = level - 256;
2982 level = coeff & 0xff;
2983 if (plm_buffer_read(self->buffer, 1)) {
2989 if (n < 0 || n >= 64) {
2993 int de_zig_zagged = PLM_VIDEO_ZIG_ZAG[n];
2998 if (!self->macroblock_intra) {
2999 level += (level < 0 ? -1 : 1);
3001 level = (level * self->quantizer_scale * quant_matrix[de_zig_zagged]) >> 4;
3002 if ((level & 1) == 0) {
3003 level -= level > 0 ? 1 : -1;
3007 }
else if (level < -2048) {
3012 self->block_data[de_zig_zagged] = level * PLM_VIDEO_PREMULTIPLIER_MATRIX[de_zig_zagged];
3021 d = self->frame_current.y.data;
3022 dw = self->luma_width;
3023 di = (self->mb_row * self->luma_width + self->mb_col) << 4;
3024 if ((block & 1) != 0) {
3027 if ((block & 2) != 0) {
3028 di += self->luma_width << 3;
3031 d = (block == 4) ? self->frame_current.cb.data : self->frame_current.cr.data;
3032 dw = self->chroma_width;
3033 di = ((self->mb_row * self->luma_width) << 2) + (self->mb_col << 3);
3036 int *s = self->block_data;
3038 if (self->macroblock_intra) {
3041 int clamped = plm_clamp((s[0] + 128) >> 8);
3042 PLM_BLOCK_SET(d, di, dw, si, 8, 8, clamped);
3046 PLM_BLOCK_SET(d, di, dw, si, 8, 8, plm_clamp(s[si]));
3047 memset(self->block_data, 0,
sizeof(self->block_data));
3052 int value = (s[0] + 128) >> 8;
3053 PLM_BLOCK_SET(d, di, dw, si, 8, 8, plm_clamp(d[di] + value));
3057 PLM_BLOCK_SET(d, di, dw, si, 8, 8, plm_clamp(d[di] + s[si]));
3058 memset(self->block_data, 0,
sizeof(self->block_data));
3063void plm_video_idct(
int *block) {
3064 int b1, b3, b4, b6, b7, tmp1, tmp2, m0, x0, x1, x2, x3, x4, y3, y4, y5, y6, y7;
3067 for (
int i = 0; i < 8; ++i) {
3068 b1 = block[4 * 8 + i];
3069 b3 = block[2 * 8 + i] + block[6 * 8 + i];
3070 b4 = block[5 * 8 + i] - block[3 * 8 + i];
3071 tmp1 = block[1 * 8 + i] + block[7 * 8 + i];
3072 tmp2 = block[3 * 8 + i] + block[5 * 8 + i];
3073 b6 = block[1 * 8 + i] - block[7 * 8 + i];
3075 m0 = block[0 * 8 + i];
3076 x4 = ((b6 * 473 - b4 * 196 + 128) >> 8) - b7;
3077 x0 = x4 - (((tmp1 - tmp2) * 362 + 128) >> 8);
3079 x2 = (((block[2 * 8 + i] - block[6 * 8 + i]) * 362 + 128) >> 8) - b3;
3085 y7 = -x0 - ((b4 * 473 + b6 * 196 + 128) >> 8);
3086 block[0 * 8 + i] = b7 + y4;
3087 block[1 * 8 + i] = x4 + y3;
3088 block[2 * 8 + i] = y5 - x0;
3089 block[3 * 8 + i] = y6 - y7;
3090 block[4 * 8 + i] = y6 + y7;
3091 block[5 * 8 + i] = x0 + y5;
3092 block[6 * 8 + i] = y3 - x4;
3093 block[7 * 8 + i] = y4 - b7;
3097 for (
int i = 0; i < 64; i += 8) {
3099 b3 = block[2 + i] + block[6 + i];
3100 b4 = block[5 + i] - block[3 + i];
3101 tmp1 = block[1 + i] + block[7 + i];
3102 tmp2 = block[3 + i] + block[5 + i];
3103 b6 = block[1 + i] - block[7 + i];
3106 x4 = ((b6 * 473 - b4 * 196 + 128) >> 8) - b7;
3107 x0 = x4 - (((tmp1 - tmp2) * 362 + 128) >> 8);
3109 x2 = (((block[2 + i] - block[6 + i]) * 362 + 128) >> 8) - b3;
3115 y7 = -x0 - ((b4 * 473 + b6 * 196 + 128) >> 8);
3116 block[0 + i] = (b7 + y4 + 128) >> 8;
3117 block[1 + i] = (x4 + y3 + 128) >> 8;
3118 block[2 + i] = (y5 - x0 + 128) >> 8;
3119 block[3 + i] = (y6 - y7 + 128) >> 8;
3120 block[4 + i] = (y6 + y7 + 128) >> 8;
3121 block[5 + i] = (x0 + y5 + 128) >> 8;
3122 block[6 + i] = (y3 - x4 + 128) >> 8;
3123 block[7 + i] = (y4 - b7 + 128) >> 8;
3130#define PLM_PUT_PIXEL(RI, GI, BI, Y_OFFSET, DEST_OFFSET) \
3131 y = ((frame->y.data[y_index + Y_OFFSET] - 16) * 76309) >> 16; \
3132 dest[d_index + DEST_OFFSET + RI] = plm_clamp(y + r); \
3133 dest[d_index + DEST_OFFSET + GI] = plm_clamp(y - g); \
3134 dest[d_index + DEST_OFFSET + BI] = plm_clamp(y + b);
3136#define PLM_DEFINE_FRAME_CONVERT_FUNCTION(NAME, BYTES_PER_PIXEL, RI, GI, BI) \
3137 void NAME(plm_frame_t *frame, uint8_t *dest, int stride) { \
3138 int cols = frame->width >> 1; \
3139 int rows = frame->height >> 1; \
3140 int yw = frame->y.width; \
3141 int cw = frame->cb.width; \
3142 for (int row = 0; row < rows; row++) { \
3143 int c_index = row * cw; \
3144 int y_index = row * 2 * yw; \
3145 int d_index = row * 2 * stride; \
3146 for (int col = 0; col < cols; col++) { \
3148 int cr = frame->cr.data[c_index] - 128; \
3149 int cb = frame->cb.data[c_index] - 128; \
3150 int r = (cr * 104597) >> 16; \
3151 int g = (cb * 25674 + cr * 53278) >> 16; \
3152 int b = (cb * 132201) >> 16; \
3153 PLM_PUT_PIXEL(RI, GI, BI, 0, 0); \
3154 PLM_PUT_PIXEL(RI, GI, BI, 1, BYTES_PER_PIXEL); \
3155 PLM_PUT_PIXEL(RI, GI, BI, yw, stride); \
3156 PLM_PUT_PIXEL(RI, GI, BI, yw + 1, stride + BYTES_PER_PIXEL); \
3159 d_index += 2 * BYTES_PER_PIXEL; \
3164PLM_DEFINE_FRAME_CONVERT_FUNCTION(plm_frame_to_rgb, 3, 0, 1, 2)
3165PLM_DEFINE_FRAME_CONVERT_FUNCTION(plm_frame_to_bgr, 3, 2, 1, 0)
3166PLM_DEFINE_FRAME_CONVERT_FUNCTION(plm_frame_to_rgba, 4, 0, 1, 2)
3167PLM_DEFINE_FRAME_CONVERT_FUNCTION(plm_frame_to_bgra, 4, 2, 1, 0)
3168PLM_DEFINE_FRAME_CONVERT_FUNCTION(plm_frame_to_argb, 4, 1, 2, 3)
3169PLM_DEFINE_FRAME_CONVERT_FUNCTION(plm_frame_to_abgr, 4, 3, 2, 1)
3172#undef PLM_DEFINE_FRAME_CONVERT_FUNCTION
3180static const int PLM_AUDIO_FRAME_SYNC = 0x7ff;
3182static const int PLM_AUDIO_MPEG_2_5 = 0x0;
3183static const int PLM_AUDIO_MPEG_2 = 0x2;
3184static const int PLM_AUDIO_MPEG_1 = 0x3;
3186static const int PLM_AUDIO_LAYER_III = 0x1;
3187static const int PLM_AUDIO_LAYER_II = 0x2;
3188static const int PLM_AUDIO_LAYER_I = 0x3;
3190static const int PLM_AUDIO_MODE_STEREO = 0x0;
3191static const int PLM_AUDIO_MODE_JOINT_STEREO = 0x1;
3192static const int PLM_AUDIO_MODE_DUAL_CHANNEL = 0x2;
3193static const int PLM_AUDIO_MODE_MONO = 0x3;
3195static const unsigned short PLM_AUDIO_SAMPLE_RATE[] = {
3196 44100, 48000, 32000, 0,
3197 22050, 24000, 16000, 0
3200static const short PLM_AUDIO_BIT_RATE[] = {
3201 32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384,
3202 8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160
3205static const int PLM_AUDIO_SCALEFACTOR_BASE[] = {0x02000000, 0x01965FEA, 0x01428A30};
3207static const float PLM_AUDIO_SYNTHESIS_WINDOW[] = {
3208 0.0, -0.5, -0.5, -0.5, -0.5, -0.5, -0.5, -1.0, -1.0, -1.0, -1.0,
3209 -1.5, -1.5, -2.0, -2.0, -2.5, -2.5, -3.0, -3.5, -3.5, -4.0, -4.5,
3210 -5.0, -5.5, -6.5, -7.0, -8.0, -8.5, -9.5, -10.5, -12.0, -13.0, -14.5,
3211 -15.5, -17.5, -19.0, -20.5, -22.5, -24.5, -26.5, -29.0, -31.5, -34.0, -36.5,
3212 -39.5, -42.5, -45.5, -48.5, -52.0, -55.5, -58.5, -62.5, -66.0, -69.5, -73.5,
3213 -77.0, -80.5, -84.5, -88.0, -91.5, -95.0, -98.0, -101.0, -104.0, 106.5, 109.0,
3214 111.0, 112.5, 113.5, 114.0, 114.0, 113.5, 112.0, 110.5, 107.5, 104.0, 100.0,
3215 94.5, 88.5, 81.5, 73.0, 63.5, 53.0, 41.5, 28.5, 14.5, -1.0, -18.0,
3216 -36.0, -55.5, -76.5, -98.5, -122.0, -147.0, -173.5, -200.5, -229.5, -259.5, -290.5,
3217 -322.5, -355.5, -389.5, -424.0, -459.5, -495.5, -532.0, -568.5, -605.0, -641.5, -678.0,
3218 -714.0, -749.0, -783.5, -817.0, -849.0, -879.5, -908.5, -935.0, -959.5, -981.0, -1000.5,
3219 -1016.0, -1028.5, -1037.5, -1042.5, -1043.5, -1040.0, -1031.5, 1018.5, 1000.0, 976.0, 946.5,
3220 911.0, 869.5, 822.0, 767.5, 707.0, 640.0, 565.5, 485.0, 397.0, 302.5, 201.0,
3221 92.5, -22.5, -144.0, -272.5, -407.0, -547.5, -694.0, -846.0, -1003.0, -1165.0, -1331.5,
3222 -1502.0, -1675.5, -1852.5, -2031.5, -2212.5, -2394.0, -2576.5, -2758.5, -2939.5, -3118.5, -3294.5,
3223 -3467.5, -3635.5, -3798.5, -3955.0, -4104.5, -4245.5, -4377.5, -4499.0, -4609.5, -4708.0, -4792.5,
3224 -4863.5, -4919.0, -4958.0, -4979.5, -4983.0, -4967.5, -4931.5, -4875.0, -4796.0, -4694.5, -4569.5,
3225 -4420.0, -4246.0, -4046.0, -3820.0, -3567.0, 3287.0, 2979.5, 2644.0, 2280.5, 1888.0, 1467.5,
3226 1018.5, 541.0, 35.0, -499.0, -1061.0, -1650.0, -2266.5, -2909.0, -3577.0, -4270.0, -4987.5,
3227 -5727.5, -6490.0, -7274.0, -8077.5, -8899.5, -9739.0, -10594.5, -11464.5, -12347.0, -13241.0, -14144.5,
3228 -15056.0, -15973.5, -16895.5, -17820.0, -18744.5, -19668.0, -20588.0, -21503.0, -22410.5, -23308.5, -24195.0,
3229 -25068.5, -25926.5, -26767.0, -27589.0, -28389.0, -29166.5, -29919.0, -30644.5, -31342.0, -32009.5, -32645.0,
3230 -33247.0, -33814.5, -34346.0, -34839.5, -35295.0, -35710.0, -36084.5, -36417.5, -36707.5, -36954.0, -37156.5,
3231 -37315.0, -37428.0, -37496.0, 37519.0, 37496.0, 37428.0, 37315.0, 37156.5, 36954.0, 36707.5, 36417.5,
3232 36084.5, 35710.0, 35295.0, 34839.5, 34346.0, 33814.5, 33247.0, 32645.0, 32009.5, 31342.0, 30644.5,
3233 29919.0, 29166.5, 28389.0, 27589.0, 26767.0, 25926.5, 25068.5, 24195.0, 23308.5, 22410.5, 21503.0,
3234 20588.0, 19668.0, 18744.5, 17820.0, 16895.5, 15973.5, 15056.0, 14144.5, 13241.0, 12347.0, 11464.5,
3235 10594.5, 9739.0, 8899.5, 8077.5, 7274.0, 6490.0, 5727.5, 4987.5, 4270.0, 3577.0, 2909.0,
3236 2266.5, 1650.0, 1061.0, 499.0, -35.0, -541.0, -1018.5, -1467.5, -1888.0, -2280.5, -2644.0,
3237 -2979.5, 3287.0, 3567.0, 3820.0, 4046.0, 4246.0, 4420.0, 4569.5, 4694.5, 4796.0, 4875.0,
3238 4931.5, 4967.5, 4983.0, 4979.5, 4958.0, 4919.0, 4863.5, 4792.5, 4708.0, 4609.5, 4499.0,
3239 4377.5, 4245.5, 4104.5, 3955.0, 3798.5, 3635.5, 3467.5, 3294.5, 3118.5, 2939.5, 2758.5,
3240 2576.5, 2394.0, 2212.5, 2031.5, 1852.5, 1675.5, 1502.0, 1331.5, 1165.0, 1003.0, 846.0,
3241 694.0, 547.5, 407.0, 272.5, 144.0, 22.5, -92.5, -201.0, -302.5, -397.0, -485.0,
3242 -565.5, -640.0, -707.0, -767.5, -822.0, -869.5, -911.0, -946.5, -976.0, -1000.0, 1018.5,
3243 1031.5, 1040.0, 1043.5, 1042.5, 1037.5, 1028.5, 1016.0, 1000.5, 981.0, 959.5, 935.0,
3244 908.5, 879.5, 849.0, 817.0, 783.5, 749.0, 714.0, 678.0, 641.5, 605.0, 568.5,
3245 532.0, 495.5, 459.5, 424.0, 389.5, 355.5, 322.5, 290.5, 259.5, 229.5, 200.5,
3246 173.5, 147.0, 122.0, 98.5, 76.5, 55.5, 36.0, 18.0, 1.0, -14.5, -28.5,
3247 -41.5, -53.0, -63.5, -73.0, -81.5, -88.5, -94.5, -100.0, -104.0, -107.5, -110.5,
3248 -112.0, -113.5, -114.0, -114.0, -113.5, -112.5, -111.0, -109.0, 106.5, 104.0, 101.0,
3249 98.0, 95.0, 91.5, 88.0, 84.5, 80.5, 77.0, 73.5, 69.5, 66.0, 62.5,
3250 58.5, 55.5, 52.0, 48.5, 45.5, 42.5, 39.5, 36.5, 34.0, 31.5, 29.0,
3251 26.5, 24.5, 22.5, 20.5, 19.0, 17.5, 15.5, 14.5, 13.0, 12.0, 10.5,
3252 9.5, 8.5, 8.0, 7.0, 6.5, 5.5, 5.0, 4.5, 4.0, 3.5, 3.5,
3253 3.0, 2.5, 2.5, 2.0, 2.0, 1.5, 1.5, 1.0, 1.0, 1.0, 1.0,
3254 0.5, 0.5, 0.5, 0.5, 0.5, 0.5};
3257static const uint8_t PLM_AUDIO_QUANT_LUT_STEP_1[2][16] = {
3259 {0, 0, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2},
3261 {0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2, 2, 2, 2}
3265#define PLM_AUDIO_QUANT_TAB_A (27 | 64)
3266#define PLM_AUDIO_QUANT_TAB_B (30 | 64)
3267#define PLM_AUDIO_QUANT_TAB_C 8
3268#define PLM_AUDIO_QUANT_TAB_D 12
3270static const uint8_t QUANT_LUT_STEP_2[3][3] = {
3272 {PLM_AUDIO_QUANT_TAB_C, PLM_AUDIO_QUANT_TAB_C, PLM_AUDIO_QUANT_TAB_D},
3273 {PLM_AUDIO_QUANT_TAB_A, PLM_AUDIO_QUANT_TAB_A, PLM_AUDIO_QUANT_TAB_A},
3274 {PLM_AUDIO_QUANT_TAB_B, PLM_AUDIO_QUANT_TAB_A, PLM_AUDIO_QUANT_TAB_B}
3279static const uint8_t PLM_AUDIO_QUANT_LUT_STEP_3[3][32] = {
3281 {0x44, 0x44, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34},
3283 {0x43, 0x43, 0x43, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x42, 0x31, 0x31, 0x31, 0x31,
3284 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x31, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20},
3286 {0x45, 0x45, 0x45, 0x45, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x34, 0x24, 0x24, 0x24, 0x24,
3287 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24, 0x24}};
3290static const uint8_t PLM_AUDIO_QUANT_LUT_STEP_4[6][16] = {{0, 1, 2, 17},
3291 {0, 1, 2, 3, 4, 5, 6, 17},
3292 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17},
3293 {0, 1, 3, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17},
3294 {0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 17},
3295 {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}};
3297typedef struct plm_quantizer_spec_t {
3298 unsigned short levels;
3299 unsigned char group;
3301} plm_quantizer_spec_t;
3303static const plm_quantizer_spec_t PLM_AUDIO_QUANT_TAB[] = {
3325 int samples_decoded;
3326 int samplerate_index;
3333 int next_frame_data_size;
3336 plm_buffer_t *buffer;
3337 int destroy_buffer_when_done;
3339 const plm_quantizer_spec_t *allocation[2][32];
3340 uint8_t scale_factor_info[2][32];
3341 int scale_factor[2][32][3];
3342 int sample[2][32][3];
3344 plm_samples_t samples;
3350int plm_audio_find_frame_sync(plm_audio_t *self);
3351int plm_audio_decode_header(plm_audio_t *self);
3352void plm_audio_decode_frame(plm_audio_t *self);
3353const plm_quantizer_spec_t *plm_audio_read_allocation(plm_audio_t *self,
int sb,
int tab3);
3354void plm_audio_read_samples(plm_audio_t *self,
int ch,
int sb,
int part);
3355void plm_audio_idct36(
int s[32][3],
int ss,
float *d,
int dp);
3357plm_audio_t *plm_audio_create_with_buffer(plm_buffer_t *buffer,
int destroy_when_done) {
3358 plm_audio_t *self = (plm_audio_t *)PLM_MALLOC(
sizeof(plm_audio_t));
3359 memset(self, 0,
sizeof(plm_audio_t));
3361 self->samples.count = PLM_AUDIO_SAMPLES_PER_FRAME;
3362 self->buffer = buffer;
3363 self->destroy_buffer_when_done = destroy_when_done;
3364 self->samplerate_index = 3;
3366 memcpy(self->D, PLM_AUDIO_SYNTHESIS_WINDOW, 512 *
sizeof(
float));
3367 memcpy(self->D + 512, PLM_AUDIO_SYNTHESIS_WINDOW, 512 *
sizeof(
float));
3370 self->next_frame_data_size = plm_audio_decode_header(self);
3375void plm_audio_destroy(plm_audio_t *self) {
3376 if (self->destroy_buffer_when_done) {
3377 plm_buffer_destroy(self->buffer);
3382int plm_audio_has_header(plm_audio_t *self) {
3383 if (self->has_header) {
3387 self->next_frame_data_size = plm_audio_decode_header(self);
3388 return self->has_header;
3391int plm_audio_get_samplerate(plm_audio_t *self) {
3392 return plm_audio_has_header(self) ? PLM_AUDIO_SAMPLE_RATE[self->samplerate_index] : 0;
3395double plm_audio_get_time(plm_audio_t *self) {
return self->time; }
3397void plm_audio_set_time(plm_audio_t *self,
double time) {
3398 self->samples_decoded = time * (double)PLM_AUDIO_SAMPLE_RATE[self->samplerate_index];
3402void plm_audio_rewind(plm_audio_t *self) {
3403 plm_buffer_rewind(self->buffer);
3405 self->samples_decoded = 0;
3406 self->next_frame_data_size = 0;
3409int plm_audio_has_ended(plm_audio_t *self) {
return plm_buffer_has_ended(self->buffer); }
3411plm_samples_t *plm_audio_decode(plm_audio_t *self) {
3413 if (!self->next_frame_data_size) {
3414 if (!plm_buffer_has(self->buffer, 48)) {
3417 self->next_frame_data_size = plm_audio_decode_header(self);
3420 if (self->next_frame_data_size == 0 || !plm_buffer_has(self->buffer, self->next_frame_data_size << 3)) {
3424 plm_audio_decode_frame(self);
3425 self->next_frame_data_size = 0;
3427 self->samples.time = self->time;
3429 self->samples_decoded += PLM_AUDIO_SAMPLES_PER_FRAME;
3430 self->time = (double)self->samples_decoded / (
double)PLM_AUDIO_SAMPLE_RATE[self->samplerate_index];
3432 return &self->samples;
3435int plm_audio_find_frame_sync(plm_audio_t *self) {
3437 for (i = self->buffer->bit_index >> 3; i < self->buffer->length - 1; i++) {
3438 if (self->buffer->bytes[i] == 0xFF && (self->buffer->bytes[i + 1] & 0xFE) == 0xFC) {
3439 self->buffer->bit_index = ((i + 1) << 3) + 3;
3443 self->buffer->bit_index = (i + 1) << 3;
3447int plm_audio_decode_header(plm_audio_t *self) {
3448 if (!plm_buffer_has(self->buffer, 48)) {
3452 plm_buffer_skip_bytes(self->buffer, 0x00);
3453 int sync = plm_buffer_read(self->buffer, 11);
3462 if (sync != PLM_AUDIO_FRAME_SYNC && !plm_audio_find_frame_sync(self)) {
3466 self->version = plm_buffer_read(self->buffer, 2);
3467 self->layer = plm_buffer_read(self->buffer, 2);
3468 int hasCRC = !plm_buffer_read(self->buffer, 1);
3470 if (self->version != PLM_AUDIO_MPEG_1 || self->layer != PLM_AUDIO_LAYER_II) {
3474 int bitrate_index = plm_buffer_read(self->buffer, 4) - 1;
3475 if (bitrate_index > 13) {
3479 int samplerate_index = plm_buffer_read(self->buffer, 2);
3480 if (samplerate_index == 3) {
3484 int padding = plm_buffer_read(self->buffer, 1);
3485 plm_buffer_skip(self->buffer, 1);
3486 int mode = plm_buffer_read(self->buffer, 2);
3490 if (self->has_header &&
3491 (self->bitrate_index != bitrate_index || self->samplerate_index != samplerate_index || self->mode != mode)) {
3495 self->bitrate_index = bitrate_index;
3496 self->samplerate_index = samplerate_index;
3498 self->has_header = TRUE;
3501 if (mode == PLM_AUDIO_MODE_JOINT_STEREO) {
3502 self->bound = (plm_buffer_read(self->buffer, 2) + 1) << 2;
3504 plm_buffer_skip(self->buffer, 2);
3505 self->bound = (mode == PLM_AUDIO_MODE_MONO) ? 0 : 32;
3509 plm_buffer_skip(self->buffer, 4);
3511 plm_buffer_skip(self->buffer, 16);
3516 int bitrate = PLM_AUDIO_BIT_RATE[self->bitrate_index];
3517 int samplerate = PLM_AUDIO_SAMPLE_RATE[self->samplerate_index];
3518 int frame_size = (144000 * bitrate / samplerate) + padding;
3519 return frame_size - (hasCRC ? 6 : 4);
3522void plm_audio_decode_frame(plm_audio_t *self) {
3527 int tab1 = (self->mode == PLM_AUDIO_MODE_MONO) ? 0 : 1;
3528 int tab2 = PLM_AUDIO_QUANT_LUT_STEP_1[tab1][self->bitrate_index];
3529 tab3 = QUANT_LUT_STEP_2[tab2][self->samplerate_index];
3530 sblimit = tab3 & 63;
3533 if (self->bound > sblimit) {
3534 self->bound = sblimit;
3538 for (
int sb = 0; sb < self->bound; sb++) {
3539 self->allocation[0][sb] = plm_audio_read_allocation(self, sb, tab3);
3540 self->allocation[1][sb] = plm_audio_read_allocation(self, sb, tab3);
3543 for (
int sb = self->bound; sb < sblimit; sb++) {
3544 self->allocation[0][sb] = self->allocation[1][sb] = plm_audio_read_allocation(self, sb, tab3);
3548 int channels = (self->mode == PLM_AUDIO_MODE_MONO) ? 1 : 2;
3549 for (
int sb = 0; sb < sblimit; sb++) {
3550 for (
int ch = 0; ch < channels; ch++) {
3551 if (self->allocation[ch][sb]) {
3552 self->scale_factor_info[ch][sb] = plm_buffer_read(self->buffer, 2);
3555 if (self->mode == PLM_AUDIO_MODE_MONO) {
3556 self->scale_factor_info[1][sb] = self->scale_factor_info[0][sb];
3561 for (
int sb = 0; sb < sblimit; sb++) {
3562 for (
int ch = 0; ch < channels; ch++) {
3563 if (self->allocation[ch][sb]) {
3564 int *sf = self->scale_factor[ch][sb];
3565 switch (self->scale_factor_info[ch][sb]) {
3567 sf[0] = plm_buffer_read(self->buffer, 6);
3568 sf[1] = plm_buffer_read(self->buffer, 6);
3569 sf[2] = plm_buffer_read(self->buffer, 6);
3572 sf[0] = sf[1] = plm_buffer_read(self->buffer, 6);
3573 sf[2] = plm_buffer_read(self->buffer, 6);
3576 sf[0] = sf[1] = sf[2] = plm_buffer_read(self->buffer, 6);
3579 sf[0] = plm_buffer_read(self->buffer, 6);
3580 sf[1] = sf[2] = plm_buffer_read(self->buffer, 6);
3585 if (self->mode == PLM_AUDIO_MODE_MONO) {
3586 self->scale_factor[1][sb][0] = self->scale_factor[0][sb][0];
3587 self->scale_factor[1][sb][1] = self->scale_factor[0][sb][1];
3588 self->scale_factor[1][sb][2] = self->scale_factor[0][sb][2];
3594 for (
int part = 0; part < 3; part++) {
3595 for (
int granule = 0; granule < 4; granule++) {
3598 for (
int sb = 0; sb < self->bound; sb++) {
3599 plm_audio_read_samples(self, 0, sb, part);
3600 plm_audio_read_samples(self, 1, sb, part);
3602 for (
int sb = self->bound; sb < sblimit; sb++) {
3603 plm_audio_read_samples(self, 0, sb, part);
3604 self->sample[1][sb][0] = self->sample[0][sb][0];
3605 self->sample[1][sb][1] = self->sample[0][sb][1];
3606 self->sample[1][sb][2] = self->sample[0][sb][2];
3608 for (
int sb = sblimit; sb < 32; sb++) {
3609 self->sample[0][sb][0] = 0;
3610 self->sample[0][sb][1] = 0;
3611 self->sample[0][sb][2] = 0;
3612 self->sample[1][sb][0] = 0;
3613 self->sample[1][sb][1] = 0;
3614 self->sample[1][sb][2] = 0;
3618 for (
int p = 0; p < 3; p++) {
3620 self->v_pos = (self->v_pos - 64) & 1023;
3622 for (
int ch = 0; ch < 2; ch++) {
3623 plm_audio_idct36(self->sample[ch], p, self->V[ch], self->v_pos);
3626 memset(self->U, 0,
sizeof(self->U));
3628 int d_index = 512 - (self->v_pos >> 1);
3629 int v_index = (self->v_pos % 128) >> 1;
3630 while (v_index < 1024) {
3631 for (
int i = 0; i < 32; ++i) {
3632 self->U[i] += self->D[d_index++] * self->V[ch][v_index++];
3635 v_index += 128 - 32;
3639 d_index -= (512 - 32);
3640 v_index = (128 - 32 + 1024) - v_index;
3641 while (v_index < 1024) {
3642 for (
int i = 0; i < 32; ++i) {
3643 self->U[i] += self->D[d_index++] * self->V[ch][v_index++];
3646 v_index += 128 - 32;
3651#ifdef PLM_AUDIO_SEPARATE_CHANNELS
3652 float *out_channel = ch == 0 ? self->samples.left : self->samples.right;
3653 for (
int j = 0; j < 32; j++) {
3654 out_channel[out_pos + j] = self->U[j] / 2147418112.0f;
3657 for (
int j = 0; j < 32; j++) {
3658 self->samples.interleaved[((out_pos + j) << 1) + ch] = self->U[j] / 2147418112.0f;
3668 plm_buffer_align(self->buffer);
3671const plm_quantizer_spec_t *plm_audio_read_allocation(plm_audio_t *self,
int sb,
int tab3) {
3672 int tab4 = PLM_AUDIO_QUANT_LUT_STEP_3[tab3][sb];
3673 int qtab = PLM_AUDIO_QUANT_LUT_STEP_4[tab4 & 15][plm_buffer_read(self->buffer, tab4 >> 4)];
3674 return qtab ? (&PLM_AUDIO_QUANT_TAB[qtab - 1]) : 0;
3677void plm_audio_read_samples(plm_audio_t *self,
int ch,
int sb,
int part) {
3678 const plm_quantizer_spec_t *q = self->allocation[ch][sb];
3679 int sf = self->scale_factor[ch][sb][part];
3680 int *sample = self->sample[ch][sb];
3685 sample[0] = sample[1] = sample[2] = 0;
3693 int shift = (sf / 3) | 0;
3694 sf = (PLM_AUDIO_SCALEFACTOR_BASE[sf % 3] + ((1 << shift) >> 1)) >> shift;
3698 int adj = q->levels;
3701 val = plm_buffer_read(self->buffer, q->bits);
3702 sample[0] = val % adj;
3704 sample[1] = val % adj;
3705 sample[2] = val / adj;
3708 sample[0] = plm_buffer_read(self->buffer, q->bits);
3709 sample[1] = plm_buffer_read(self->buffer, q->bits);
3710 sample[2] = plm_buffer_read(self->buffer, q->bits);
3714 int scale = 65536 / (adj + 1);
3715 adj = ((adj + 1) >> 1) - 1;
3717 val = (adj - sample[0]) * scale;
3718 sample[0] = (val * (sf >> 12) + ((val * (sf & 4095) + 2048) >> 12)) >> 12;
3720 val = (adj - sample[1]) * scale;
3721 sample[1] = (val * (sf >> 12) + ((val * (sf & 4095) + 2048) >> 12)) >> 12;
3723 val = (adj - sample[2]) * scale;
3724 sample[2] = (val * (sf >> 12) + ((val * (sf & 4095) + 2048) >> 12)) >> 12;
3727void plm_audio_idct36(
int s[32][3],
int ss,
float *d,
int dp) {
3728 float t01, t02, t03, t04, t05, t06, t07, t08, t09, t10, t11, t12, t13, t14, t15, t16, t17, t18, t19, t20, t21, t22,
3729 t23, t24, t25, t26, t27, t28, t29, t30, t31, t32, t33;
3731 t01 = (float)(s[0][ss] + s[31][ss]);
3732 t02 = (float)(s[0][ss] - s[31][ss]) * 0.500602998235f;
3733 t03 = (float)(s[1][ss] + s[30][ss]);
3734 t04 = (float)(s[1][ss] - s[30][ss]) * 0.505470959898f;
3735 t05 = (float)(s[2][ss] + s[29][ss]);
3736 t06 = (float)(s[2][ss] - s[29][ss]) * 0.515447309923f;
3737 t07 = (float)(s[3][ss] + s[28][ss]);
3738 t08 = (float)(s[3][ss] - s[28][ss]) * 0.53104259109f;
3739 t09 = (float)(s[4][ss] + s[27][ss]);
3740 t10 = (float)(s[4][ss] - s[27][ss]) * 0.553103896034f;
3741 t11 = (float)(s[5][ss] + s[26][ss]);
3742 t12 = (float)(s[5][ss] - s[26][ss]) * 0.582934968206f;
3743 t13 = (float)(s[6][ss] + s[25][ss]);
3744 t14 = (float)(s[6][ss] - s[25][ss]) * 0.622504123036f;
3745 t15 = (float)(s[7][ss] + s[24][ss]);
3746 t16 = (float)(s[7][ss] - s[24][ss]) * 0.674808341455f;
3747 t17 = (float)(s[8][ss] + s[23][ss]);
3748 t18 = (float)(s[8][ss] - s[23][ss]) * 0.744536271002f;
3749 t19 = (float)(s[9][ss] + s[22][ss]);
3750 t20 = (float)(s[9][ss] - s[22][ss]) * 0.839349645416f;
3751 t21 = (float)(s[10][ss] + s[21][ss]);
3752 t22 = (float)(s[10][ss] - s[21][ss]) * 0.972568237862f;
3753 t23 = (float)(s[11][ss] + s[20][ss]);
3754 t24 = (float)(s[11][ss] - s[20][ss]) * 1.16943993343f;
3755 t25 = (float)(s[12][ss] + s[19][ss]);
3756 t26 = (float)(s[12][ss] - s[19][ss]) * 1.48416461631f;
3757 t27 = (float)(s[13][ss] + s[18][ss]);
3758 t28 = (float)(s[13][ss] - s[18][ss]) * 2.05778100995f;
3759 t29 = (float)(s[14][ss] + s[17][ss]);
3760 t30 = (float)(s[14][ss] - s[17][ss]) * 3.40760841847f;
3761 t31 = (float)(s[15][ss] + s[16][ss]);
3762 t32 = (float)(s[15][ss] - s[16][ss]) * 10.1900081235f;
3765 t31 = (t01 - t31) * 0.502419286188f;
3767 t29 = (t03 - t29) * 0.52249861494f;
3769 t27 = (t05 - t27) * 0.566944034816f;
3771 t25 = (t07 - t25) * 0.64682178336f;
3773 t23 = (t09 - t23) * 0.788154623451f;
3775 t21 = (t11 - t21) * 1.06067768599f;
3777 t19 = (t13 - t19) * 1.72244709824f;
3779 t17 = (t15 - t17) * 5.10114861869f;
3781 t13 = (t33 - t13) * 0.509795579104f;
3783 t01 = (t01 - t11) * 0.601344886935f;
3785 t09 = (t03 - t09) * 0.899976223136f;
3787 t07 = (t05 - t07) * 2.56291544774f;
3789 t15 = (t15 - t03) * 0.541196100146f;
3791 t11 = (t33 - t11) * 1.30656296488f;
3793 t05 = (t05 - t03) * 0.707106781187f;
3795 t15 = (t15 - t11) * 0.707106781187f;
3798 t13 = (t13 - t07) * 0.541196100146f;
3800 t09 = (t01 - t09) * 1.30656296488f;
3802 t07 = (t11 - t07) * 0.707106781187f;
3804 t13 = (t13 - t09) * 0.707106781187f;
3810 t31 = (t31 - t17) * 0.509795579104f;
3812 t29 = (t29 - t19) * 0.601344886935f;
3814 t21 = (t27 - t21) * 0.899976223136f;
3816 t23 = (t25 - t23) * 2.56291544774f;
3818 t09 = (t09 - t27) * 0.541196100146f;
3820 t19 = (t17 - t19) * 1.30656296488f;
3822 t27 = (t25 - t27) * 0.707106781187f;
3824 t19 = (t09 - t19) * 0.707106781187f;
3827 t31 = (t31 - t23) * 0.541196100146f;
3829 t21 = (t29 - t21) * 1.30656296488f;
3831 t23 = (t09 - t23) * 0.707106781187f;
3833 t31 = (t31 - t21) * 0.707106781187f;
3846 t02 = (t02 - t32) * 0.502419286188f;
3848 t04 = (t04 - t30) * 0.52249861494f;
3850 t28 = (t06 - t28) * 0.566944034816f;
3852 t08 = (t08 - t26) * 0.64682178336f;
3854 t10 = (t10 - t24) * 0.788154623451f;
3856 t22 = (t12 - t22) * 1.06067768599f;
3858 t20 = (t14 - t20) * 1.72244709824f;
3860 t16 = (t16 - t18) * 5.10114861869f;
3862 t14 = (t21 - t14) * 0.509795579104f;
3864 t32 = (t32 - t12) * 0.601344886935f;
3866 t24 = (t30 - t24) * 0.899976223136f;
3868 t26 = (t06 - t26) * 2.56291544774f;
3870 t18 = (t18 - t30) * 0.541196100146f;
3872 t12 = (t21 - t12) * 1.30656296488f;
3874 t30 = (t06 - t30) * 0.707106781187f;
3876 t12 = (t18 - t12) * 0.707106781187f;
3879 t26 = (t14 - t26) * 0.541196100146f;
3881 t24 = (t32 - t24) * 1.30656296488f;
3883 t14 = (t18 - t14) * 0.707106781187f;
3885 t24 = (t26 - t24) * 0.707106781187f;
3891 t02 = (t02 - t16) * 0.509795579104f;
3893 t04 = (t04 - t20) * 0.601344886935f;
3895 t22 = (t28 - t22) * 0.899976223136f;
3897 t10 = (t08 - t10) * 2.56291544774f;
3899 t14 = (t14 - t28) * 0.541196100146f;
3901 t20 = (t16 - t20) * 1.30656296488f;
3903 t28 = (t08 - t28) * 0.707106781187f;
3905 t20 = (t14 - t20) * 0.707106781187f;
3908 t02 = (t02 - t10) * 0.541196100146f;
3910 t22 = (t04 - t22) * 1.30656296488f;
3912 t10 = (t14 - t10) * 0.707106781187f;
3914 t02 = (t02 - t22) * 0.707106781187f;
3943 d[dp + 49] = d[dp + 47] = -t21;
3944 d[dp + 50] = d[dp + 46] = -t17;
3945 d[dp + 51] = d[dp + 45] = -t16;
3946 d[dp + 52] = d[dp + 44] = -t01;
3947 d[dp + 53] = d[dp + 43] = -t32;
3948 d[dp + 54] = d[dp + 42] = -t29;
3949 d[dp + 55] = d[dp + 41] = -t04;
3950 d[dp + 56] = d[dp + 40] = -t03;
3951 d[dp + 57] = d[dp + 39] = -t06;
3952 d[dp + 58] = d[dp + 38] = -t25;
3953 d[dp + 59] = d[dp + 37] = -t08;
3954 d[dp + 60] = d[dp + 36] = -t11;
3955 d[dp + 61] = d[dp + 35] = -t18;
3956 d[dp + 62] = d[dp + 34] = -t09;
3957 d[dp + 63] = d[dp + 33] = -t14;