4 #include "colormodels.h"
5 #include "funcprotos.h"
7 #include "workarounds.h"
8 #include ENCORE_INCLUDE
9 #include DECORE_INCLUDE
18 unsigned char *work_buffer;
21 int decode_initialized;
22 int encode_initialized;
24 long rc_period; // the intended rate control averaging period
25 long rc_reaction_period; // the reation period for rate control
26 long rc_reaction_ratio; // the ratio for down/up rate control
27 long max_key_interval; // the maximum interval between key frames
28 int max_quantizer; // the upper limit of the quantizer
29 int min_quantizer; // the lower limit of the quantizer
30 int quantizer; // For vbr
31 int quality; // the forward search range for motion estimation
41 // Must count pframes in VBR
43 } quicktime_divx_codec_t;
45 static pthread_mutex_t encode_mutex;
46 static pthread_mutex_t decode_mutex;
47 static int mutex_initialized = 0;
48 static int decode_handle = 1;
49 static int encode_handle = 0;
51 static int delete_codec(quicktime_video_map_t *vtrack)
53 quicktime_divx_codec_t *codec;
55 codec = ((quicktime_codec_t*)vtrack->codec)->priv;
56 if(codec->encode_initialized)
58 pthread_mutex_lock(&encode_mutex);
59 encore(codec->encode_handle,
63 pthread_mutex_unlock(&encode_mutex);
65 if(codec->decode_initialized)
67 pthread_mutex_lock(&decode_mutex);
74 * decore(codec->handle,
82 decore(codec->decode_handle,
89 pthread_mutex_unlock(&decode_mutex);
91 if(codec->temp_frame) free(codec->temp_frame);
92 if(codec->work_buffer) free(codec->work_buffer);
97 static int reads_colormodel(quicktime_t *file,
101 return (colormodel == BC_YUV420P);
104 static int writes_colormodel(quicktime_t *file,
108 return (colormodel == BC_RGB888 ||
109 colormodel == BC_RGBA8888 ||
110 colormodel == BC_RGB161616 ||
111 colormodel == BC_RGBA16161616 ||
112 colormodel == BC_YUV888 ||
113 colormodel == BC_YUVA8888 ||
114 colormodel == BC_YUV161616 ||
115 colormodel == BC_YUVA16161616 ||
116 colormodel == BC_YUV420P ||
117 colormodel == BC_YUV422 ||
118 colormodel == BC_COMPRESSED);
128 static void init_mutex()
130 if(!mutex_initialized)
132 pthread_mutexattr_t attr;
133 mutex_initialized = 1;
134 pthread_mutexattr_init(&attr);
135 pthread_mutex_init(&decode_mutex, &attr);
136 pthread_mutex_init(&encode_mutex, &attr);
143 // Determine of the compressed frame is a keyframe for direct copy
144 int quicktime_divx_is_key(unsigned char *data, long size)
149 for(i = 0; i < size - 5; i++)
151 if( data[i] == 0x00 &&
152 data[i + 1] == 0x00 &&
153 data[i + 2] == 0x01 &&
156 if((data[i + 4] & 0xc0) == 0x0)
167 // Test for VOL header in frame
168 int quicktime_divx_has_vol(unsigned char *data)
170 if( data[0] == 0x00 &&
186 static void putbits(unsigned char **data,
193 value &= 0xffffffffffffffff >> (64 - count);
195 while(64 - *bit_pos < count)
197 *(*data)++ = (*bit_store) >> 56;
202 (*bit_store) |= value << (64 - count - *bit_pos);
208 static void flushbits(unsigned char **data,
212 //printf("flushbits %llx\n", (*bit_store));
213 while((*bit_pos) > 0)
215 *(*data)++ = (*bit_store) >> 56;
224 #define VO_START_CODE 0x8
225 #define VO_START_CODE_LENGTH 27
226 #define VOL_START_CODE 0x12 /* 25-MAR-97 JDL : according to WD2 */
227 #define VOL_START_CODE_LENGTH 28
231 int quicktime_divx_write_vol(unsigned char *data_start,
234 int time_increment_resolution,
238 int bits, fixed_vop_time_increment;
239 unsigned char *data = data_start;
246 vol_width = (int)((float)vol_width / 16 + 0.5) * 16;
247 vol_height = (int)((float)vol_height / 16 + 0.5) * 16;
254 VO_START_CODE_LENGTH, VO_START_CODE);
259 5, 0); /* vo_id = 0 */
265 VOL_START_CODE_LENGTH, VOL_START_CODE);
274 4, 0); /* vol_id = 0 */
280 1, 0); /* random_accessible_vol = 0 */
285 8, 1); /* video_object_type_indication = 1 video */
290 1, 1); /* is_object_layer_identifier = 1 */
295 4, 2); /* visual_object_layer_ver_id = 2 */
300 3, 1); /* visual_object_layer_priority = 1 */
305 4, 1); /* aspect_ratio_info = 1 */
317 1, 0); /* vol_control_parameter = 0 */
322 2, 0); /* vol_shape = 0 rectangular */
339 16, time_increment_resolution);
349 1, 1); /* fixed_vop_rate = 1 */
353 while((1 << bits) < time_increment_resolution) bits++;
355 // Log calculation fails for some reason
356 // bits = (int)ceil(log((double)time_increment_resolution) / log(2.0));
357 // if (bits < 1) bits=1;
359 fixed_vop_time_increment =
360 (int)(time_increment_resolution / frame_rate + 0.1);
366 bits, fixed_vop_time_increment);
399 1, 0); /* interlaced = 0 */
404 1, 1); /* OBMC_disabled = 1 */
409 2, 0); /* vol_sprite_usage = 0 */
414 1, 0); /* not_8_bit = 0 */
420 1, 0); /* vol_quant_type = 0 */
425 1, 0); /* vol_quarter_pixel = 0 */
430 1, 1); /* complexity_estimation_disabled = 1 */
435 1, 1); /* resync_marker_disabled = 1 */
440 1, 0); /* data_partitioning_enabled = 0 */
445 1, 0); /* scalability = 0 */
454 * for(i = 0; i < data - data_start; i++)
455 * for(j = 0x80; j >= 1; j /= 2)
456 * printf("%d", (data_start[i] & j) ? 1 : 0);
462 return data - data_start;
469 #define READ_RAW(framenum) \
471 quicktime_set_video_position(file, framenum, track); \
472 bytes = quicktime_frame_size(file, framenum, track); \
473 if(!codec->work_buffer || codec->buffer_size < bytes) \
475 if(codec->work_buffer) free(codec->work_buffer); \
476 codec->buffer_size = bytes; \
477 codec->work_buffer = calloc(1, codec->buffer_size + 100); \
479 result = !quicktime_read_data(file, codec->work_buffer, bytes); \
486 static int decode(quicktime_t *file, unsigned char **row_pointers, int track)
491 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
492 quicktime_trak_t *trak = vtrack->track;
493 quicktime_divx_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
494 int width = trak->tkhd.track_width;
495 int height = trak->tkhd.track_height;
496 int width_i = (int)((float)width / 16 + 0.5) * 16;
497 int height_i = (int)((float)height / 16 + 0.5) * 16;
501 char *bmp_pointers[3];
507 //printf("decode 1 %d\n", file->color_model);
510 pthread_mutex_lock(&decode_mutex);
523 if(!codec->decode_initialized)
525 DEC_MEM_REQS dec_mem_reqs;
527 // decore requires handle to be > 1
528 codec->decode_handle = decode_handle++;
529 codec->last_frame = -1;
530 codec->dec_param.x_dim = width_i;
531 codec->dec_param.y_dim = height_i;
532 codec->dec_param.output_format = DEC_420;
533 codec->dec_param.time_incr = 0;
535 decore(codec->decode_handle, DEC_OPT_MEMORY_REQS, &codec->dec_param, &dec_mem_reqs);
536 codec->dec_param.buffers.mp4_edged_ref_buffers = calloc(1, dec_mem_reqs.mp4_edged_ref_buffers_size);
537 codec->dec_param.buffers.mp4_edged_for_buffers = calloc(1, dec_mem_reqs.mp4_edged_for_buffers_size);
538 codec->dec_param.buffers.mp4_display_buffers = calloc(1, dec_mem_reqs.mp4_display_buffers_size);
539 codec->dec_param.buffers.mp4_state = calloc(1, dec_mem_reqs.mp4_state_size);
540 codec->dec_param.buffers.mp4_tables = calloc(1, dec_mem_reqs.mp4_tables_size);
541 codec->dec_param.buffers.mp4_stream = calloc(1, dec_mem_reqs.mp4_stream_size);
542 decore(codec->decode_handle, DEC_OPT_INIT, &codec->dec_param, NULL);
544 codec->temp_frame = malloc(width_i * height_i * 3 / 2);
548 * codec->dec_param.width = width_i;
549 * codec->dec_param.height = height_i;
550 * decore(0, DEC_OPT_CREATE, &codec->dec_param, NULL);
556 // Must decode frame with VOL header first but only the first frame in the
557 // sequence has a VOL header.
558 temp_position = vtrack->current_position;
560 vtrack->current_position = temp_position;
561 dec_frame.bitstream = codec->work_buffer;
562 dec_frame.length = bytes;
563 dec_frame.stride = width_i;
564 dec_frame.render_flag = 0;
565 dec_frame.bmp[0] = codec->temp_frame;
566 dec_frame.bmp[1] = codec->temp_frame + width_i * height_i;
567 dec_frame.bmp[2] = codec->temp_frame + width_i * height_i * 5 / 4;
568 decore(codec->decode_handle, 0, &dec_frame, NULL);
572 codec->decode_initialized = 1;
575 //printf("decode 1\n");
580 input_cmodel = BC_YUV420P;
581 if(file->color_model == input_cmodel &&
582 file->out_w == width_i &&
583 file->out_h == height_i &&
586 file->in_w == width_i &&
587 file->in_h == height_i)
589 // dec_frame.dst = row_pointers[0];
590 dec_frame.bmp[0] = row_pointers[0];
591 dec_frame.bmp[1] = row_pointers[1];
592 dec_frame.bmp[2] = row_pointers[2];
597 // dec_frame.dst = codec->temp_frame;
598 dec_frame.bmp[0] = codec->temp_frame;
599 dec_frame.bmp[1] = codec->temp_frame + width_i * height_i;
600 dec_frame.bmp[2] = codec->temp_frame + width_i * height_i * 5 / 4;
611 dec_frame.stride = width_i;
613 // dec_frame.render = 1;
614 // dec_frame.colorspace = DEC_CSP_YV12;
627 //printf("decode 1 %d %d\n", codec->last_frame, vtrack->current_position);
629 if(quicktime_has_keyframes(file, track) &&
630 vtrack->current_position != codec->last_frame + 1)
632 int frame1, frame2 = vtrack->current_position;
634 frame1 = quicktime_get_keyframe_before(file, vtrack->current_position, track);
636 if(frame1 < codec->last_frame &&
637 frame2 > codec->last_frame) frame1 = codec->last_frame + 1;
640 while(frame1 < frame2)
642 quicktime_set_video_position(file, frame1, track);
643 bytes = quicktime_frame_size(file, frame1, track);
646 if(!codec->work_buffer || codec->buffer_size < bytes)
648 if(codec->work_buffer) free(codec->work_buffer);
649 codec->buffer_size = bytes;
650 codec->work_buffer = calloc(1, codec->buffer_size + 100);
653 quicktime_read_data(file, codec->work_buffer, bytes);
655 //printf("decode 2 %d %d\n", frame1, frame2);
656 dec_frame.bitstream = codec->work_buffer;
657 dec_frame.length = bytes;
658 dec_frame.render_flag = 0;
659 decore(codec->decode_handle, 0, &dec_frame, NULL);
664 vtrack->current_position = frame2;
680 codec->last_frame = vtrack->current_position;
681 //printf("decode 1\n");
684 READ_RAW(vtrack->current_position);
688 //printf("decode 1\n");
690 //printf("decode 1\n");
693 dec_frame.bitstream = codec->work_buffer;
694 dec_frame.length = bytes;
695 dec_frame.render_flag = 1;
697 //printf("decode 1\n");
698 // decore(codec->dec_param.handle, DEC_OPT_DECODE, &dec_frame, NULL);
699 decore(codec->decode_handle, 0, &dec_frame, NULL);
700 //printf("decode 2\n");
703 pthread_mutex_unlock(&decode_mutex);
704 //printf("decode 1 %d %d\n", use_temp, file->color_model);
708 unsigned char **input_rows = malloc(sizeof(unsigned char*) * height_i);
709 for(i = 0; i < height_i; i++)
710 input_rows[i] = codec->temp_frame + width_i * 3;
713 cmodel_transfer(row_pointers, /* Leave NULL if non existent */
715 row_pointers[0], /* Leave NULL if non existent */
718 codec->temp_frame, /* Leave NULL if non existent */
719 codec->temp_frame + width_i * height_i,
720 codec->temp_frame + width_i * height_i + width_i * height_i / 4,
721 file->in_x, /* Dimensions to capture from input frame */
725 0, /* Dimensions to project on output frame */
731 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
732 width_i, /* For planar use the luma rowspan */
741 //printf("decode 2\n");
748 static int encode(quicktime_t *file, unsigned char **row_pointers, int track)
750 //printf("encode 1\n");
751 longest offset = quicktime_position(file);
752 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
753 quicktime_divx_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
754 quicktime_trak_t *trak = vtrack->track;
755 int width = trak->tkhd.track_width;
756 int height = trak->tkhd.track_height;
757 int width_i = (int)((float)width / 16 + 0.5) * 16;
758 int height_i = (int)((float)height / 16 + 0.5) * 16;
761 ENC_FRAME encore_input;
762 ENC_RESULT encore_result;
763 //printf("encode 1 %d %d\n", width_i, height_i);
766 pthread_mutex_lock(&encode_mutex);
768 if(!codec->encode_initialized)
770 codec->encode_initialized = 1;
771 codec->enc_param.x_dim = width_i;
772 codec->enc_param.y_dim = height_i;
773 codec->enc_param.framerate = quicktime_frame_rate(file, track);
774 codec->enc_param.bitrate = codec->bitrate;
775 codec->enc_param.rc_period = codec->rc_period;
776 codec->enc_param.rc_reaction_period = codec->rc_reaction_period;
777 codec->enc_param.rc_reaction_ratio = codec->rc_reaction_ratio;
778 codec->enc_param.max_quantizer = codec->max_quantizer;
779 codec->enc_param.min_quantizer = codec->min_quantizer;
780 codec->enc_param.max_key_interval = codec->max_key_interval;
781 codec->enc_param.use_bidirect = 0;
782 codec->enc_param.deinterlace = 0;
783 codec->enc_param.quality = codec->quality;
784 codec->enc_param.obmc = 0;
788 encore(0, ENC_OPT_INIT, &codec->enc_param, NULL);
791 //printf("encode 1\n");
793 // Assume planes are contiguous
794 if(file->color_model == BC_YUV420P &&
798 //printf("encode 1.1\n");
799 encore_input.image = row_pointers[0];
801 // Convert to YUV420P
804 if(!codec->temp_frame)
806 codec->temp_frame = malloc(width_i * height_i * 3 / 2);
808 //printf("encode 2 %d %d %d %d %d %d\n", file->color_model, width, height, width_i, height_i);
810 //printf("encode 1.5\n");
811 cmodel_transfer(0, /* Leave NULL if non existent */
813 codec->temp_frame, /* Leave NULL if non existent */
814 codec->temp_frame + width_i * height_i,
815 codec->temp_frame + width_i * height_i + width_i * height_i / 4,
816 row_pointers[0], /* Leave NULL if non existent */
819 0, /* Dimensions to capture from input frame */
823 0, /* Dimensions to project on output frame */
829 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
830 width, /* For planar use the luma rowspan */
833 //printf("encode 2\n");
835 encore_input.image = codec->temp_frame;
837 //printf("encode 3\n");
839 if(!codec->work_buffer)
841 codec->buffer_size = width * height;
842 // codec->buffer_size = 0x1000000;
843 codec->work_buffer = malloc(codec->buffer_size);
846 //printf("encode 4\n");
848 bzero(codec->work_buffer, codec->buffer_size);
849 encore_input.bitstream = codec->work_buffer;
850 encore_input.length = 0;
851 encore_input.colorspace = ENC_CSP_YV12;
852 encore_input.quant = codec->quantizer;
854 if(codec->p_count == 0)
856 encore_input.intra = 1;
861 encore_input.intra = 0;
863 if(codec->p_count >= codec->max_key_interval)
867 //printf("encode 5 %d\n", encore_input.quant);
868 if(codec->fix_bitrate)
869 encore(codec->enc_param.handle,
874 encore(codec->enc_param.handle,
878 pthread_mutex_unlock(&encode_mutex);
879 //printf("encode 6\n");
881 result = !quicktime_write_data(file, codec->work_buffer, encore_input.length);
882 quicktime_update_tables(file,
883 file->vtracks[track].track,
885 file->vtracks[track].current_chunk,
886 file->vtracks[track].current_position,
888 encore_input.length);
890 file->vtracks[track].current_chunk++;
892 if(encore_result.is_key_frame)
893 quicktime_insert_keyframe(file, file->vtracks[track].current_position, track);
895 //printf("encode 7\n");
897 //printf("encode 8\n");
902 static int set_parameter(quicktime_t *file,
907 quicktime_video_map_t *vtrack = &(file->vtracks[track]);
908 quicktime_divx_codec_t *codec = ((quicktime_codec_t*)vtrack->codec)->priv;
910 if(!strcasecmp(key, "divx_bitrate"))
911 codec->bitrate = *(int*)value;
913 if(!strcasecmp(key, "divx_rc_period"))
914 codec->rc_period = *(int*)value;
916 if(!strcasecmp(key, "divx_rc_reaction_ratio"))
917 codec->rc_reaction_ratio = *(int*)value;
919 if(!strcasecmp(key, "divx_rc_reaction_period"))
920 codec->rc_reaction_period = *(int*)value;
922 if(!strcasecmp(key, "divx_max_key_interval"))
923 codec->max_key_interval = *(int*)value;
925 if(!strcasecmp(key, "divx_max_quantizer"))
926 codec->max_quantizer = *(int*)value;
928 if(!strcasecmp(key, "divx_min_quantizer"))
929 codec->min_quantizer = *(int*)value;
931 if(!strcasecmp(key, "divx_quantizer"))
932 codec->quantizer = *(int*)value;
934 if(!strcasecmp(key, "divx_quality"))
935 codec->quality = *(int*)value;
937 if(!strcasecmp(key, "divx_fix_bitrate"))
938 codec->fix_bitrate = *(int*)value;
943 void quicktime_init_codec_divx(quicktime_video_map_t *vtrack)
946 quicktime_divx_codec_t *codec;
948 /* Init public items */
949 ((quicktime_codec_t*)vtrack->codec)->priv = calloc(1, sizeof(quicktime_divx_codec_t));
950 ((quicktime_codec_t*)vtrack->codec)->delete_vcodec = delete_codec;
951 ((quicktime_codec_t*)vtrack->codec)->decode_video = decode;
952 ((quicktime_codec_t*)vtrack->codec)->encode_video = encode;
953 ((quicktime_codec_t*)vtrack->codec)->reads_colormodel = reads_colormodel;
954 ((quicktime_codec_t*)vtrack->codec)->writes_colormodel = writes_colormodel;
955 ((quicktime_codec_t*)vtrack->codec)->set_parameter = set_parameter;
957 codec = ((quicktime_codec_t*)vtrack->codec)->priv;
959 codec->bitrate = 1000000;
960 codec->rc_period = 50;
961 codec->rc_reaction_ratio = 45;
962 codec->rc_reaction_period = 10;
963 codec->max_key_interval = 45;
964 codec->max_quantizer = 31;
965 codec->min_quantizer = 1;
966 codec->quantizer = 10;
968 codec->fix_bitrate = 1;