1 /* General codec for all MPEG-4 derived encoding. */
2 /* Uses ffmpeg and encore50. */
3 /* Encore50 still seemed to provide better results than ffmpeg for encoding */
4 /* so it does all the generic MPEG-4 encoding. */
11 #include "colormodels.h"
12 #include "funcprotos.h"
13 #include "quicktime.h"
14 #include "workarounds.h"
15 #include ENCORE_INCLUDE
16 //#include DECORE_INCLUDE
25 #define FRAME_RATE_BASE 10000
31 int decode_initialized
[FIELDS
];
35 AVCodec
*decoder
[FIELDS
];
36 AVCodecContext
*decoder_context
[FIELDS
];
37 AVFrame picture
[FIELDS
];
41 // DEC_PARAM dec_param[FIELDS];
42 // int decode_handle[FIELDS];
45 long last_frame
[FIELDS
];
58 int encode_initialized
[FIELDS
];
59 // Information for picking the right library routines.
60 // ID out of avcodec.h for the codec used.
61 // Invalid if encore50 is used.
63 // True if encore50 is being used.
67 AVCodec
*encoder
[FIELDS
];
68 AVCodecContext
*encoder_context
[FIELDS
];
72 int encode_handle
[FIELDS
];
73 ENC_PARAM enc_param
[FIELDS
];
74 // Must count pframes in VBR
78 // Encoding parameters
80 // For heroine 60 encoding, we want different streams for each field.
82 long rc_period
; // the intended rate control averaging period
83 long rc_reaction_period
; // the reation period for rate control
84 long rc_reaction_ratio
; // the ratio for down/up rate control
85 long max_key_interval
; // the maximum interval between key frames
86 int bitrate_tolerance
;
89 int max_quantizer
; // the upper limit of the quantizer
90 int min_quantizer
; // the lower limit of the quantizer
91 int quantizer
; // For vbr
92 int quality
; // the forward search range for motion estimation
97 // Temporary storage for color conversions
99 // Storage of compressed data
100 unsigned char *work_buffer
;
101 // Allocation of work_buffer
103 } quicktime_mpeg4_codec_t
;
107 // Decore needs the user to specify handles
108 static int decode_handle
= 1;
109 static int encode_handle
= 0;
119 // Direct copy routines
122 // Determine of the compressed frame is a keyframe for direct copy
123 int quicktime_mpeg4_is_key(unsigned char *data
, long size
, char *codec_id
)
128 if(quicktime_match_32(codec_id
, QUICKTIME_DIVX
) ||
129 quicktime_match_32(codec_id
, QUICKTIME_MP4V
) ||
130 quicktime_match_32(codec_id
, QUICKTIME_HV60
))
132 for(i
= 0; i
< size
- 5; i
++)
134 if( data
[i
] == 0x00 &&
135 data
[i
+ 1] == 0x00 &&
136 data
[i
+ 2] == 0x01 &&
139 if((data
[i
+ 4] & 0xc0) == 0x0)
150 // Test for VOL header in frame
151 int quicktime_mpeg4_has_vol(unsigned char *data
)
153 if( data
[0] == 0x00 &&
169 static void putbits(unsigned char **data
,
176 value
&= 0xffffffffffffffffLL
>> (64 - count
);
178 while(64 - *bit_pos
< count
)
180 *(*data
)++ = (*bit_store
) >> 56;
185 (*bit_store
) |= value
<< (64 - count
- *bit_pos
);
191 static void flushbits(unsigned char **data
,
195 //printf("flushbits %llx\n", (*bit_store));
196 while((*bit_pos
) > 0)
198 *(*data
)++ = (*bit_store
) >> 56;
207 #define VO_START_CODE 0x8
208 #define VO_START_CODE_LENGTH 27
209 #define VOL_START_CODE 0x12 /* 25-MAR-97 JDL : according to WD2 */
210 #define VOL_START_CODE_LENGTH 28
214 int quicktime_mpeg4_write_vol(unsigned char *data_start
,
217 int time_increment_resolution
,
221 int bits
, fixed_vop_time_increment
;
222 unsigned char *data
= data_start
;
229 vol_width
= quicktime_quantize16(vol_width
);
230 vol_height
= quicktime_quantize16(vol_height
);
237 VO_START_CODE_LENGTH
, VO_START_CODE
);
242 5, 0); /* vo_id = 0 */
248 VOL_START_CODE_LENGTH
, VOL_START_CODE
);
256 4, 0); /* vol_id = 0 */
262 1, 0); /* random_accessible_vol = 0 */
267 8, 1); /* video_object_type_indication = 1 video */
272 1, 1); /* is_object_layer_identifier = 1 */
277 4, 2); /* visual_object_layer_ver_id = 2 */
282 3, 1); /* visual_object_layer_priority = 1 */
287 4, 1); /* aspect_ratio_info = 1 */
299 1, 0); /* vol_control_parameter = 0 */
304 2, 0); /* vol_shape = 0 rectangular */
321 16, time_increment_resolution
);
331 1, 1); /* fixed_vop_rate = 1 */
335 while((1 << bits
) < time_increment_resolution
) bits
++;
337 // Log calculation fails for some reason
338 // bits = (int)ceil(log((double)time_increment_resolution) / log(2.0));
339 // if (bits < 1) bits=1;
341 fixed_vop_time_increment
=
342 (int)(time_increment_resolution
/ frame_rate
+ 0.1);
348 bits
, fixed_vop_time_increment
);
381 1, 0); /* interlaced = 0 */
386 1, 1); /* OBMC_disabled = 1 */
391 2, 0); /* vol_sprite_usage = 0 */
396 1, 0); /* not_8_bit = 0 */
402 1, 0); /* vol_quant_type = 0 */
407 1, 0); /* vol_quarter_pixel = 0 */
412 1, 1); /* complexity_estimation_disabled = 1 */
417 1, 1); /* resync_marker_disabled = 1 */
422 1, 0); /* data_partitioning_enabled = 0 */
427 1, 0); /* scalability = 0 */
435 * for(i = 0; i < data - data_start; i++)
436 * for(j = 0x80; j >= 1; j /= 2)
437 * printf("%d", (data_start[i] & j) ? 1 : 0);
443 return data
- data_start
;
448 // Create the header for the esds block which is used in mp4v.
449 // Taken from libavcodec
451 static int write_mp4v_header(unsigned char *data
,
456 unsigned char *start
= data
;
460 * static unsigned char test[] =
463 * 0x00, 0x00, 0x01, 0xb0, 0x01, 0x00, 0x00, 0x01, 0xb5, 0x89, 0x13,
464 * 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x20, 0x00, 0xc4, 0x8d,
465 * 0x8a, 0xee, 0x05, 0x28, 0x04, 0x5a, 0x14, 0x63, 0x00, 0x00, 0x01, 0xb2,
466 * 0x46, 0x46, 0x6d, 0x70, 0x65, 0x67, 0x43, 0x56, 0x53, 0x62, 0x34, 0x37,
470 * memcpy(data, test, sizeof(test));
472 * return sizeof(test);
476 // Advanced simple level 1
477 // int profile_level = 0xf3;
479 int profile_level
= 0x1;
480 // int vo_version_id = 5;
481 int vo_version_id
= 1;
492 *data
++ = profile_level
;
494 // Visual object startcode
499 *data
++ = ((unsigned char)0x1 << 7) |
500 ((unsigned char)vo_version_id
<< 3) |
503 // visual object type video
504 *data
++ = (0x1 << 4) |
515 int vol_size
= quicktime_mpeg4_write_vol(data
,
533 static int reads_colormodel(quicktime_t
*file
,
537 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
538 quicktime_codec_t
*codec
= (quicktime_codec_t
*)vtrack
->codec
;
539 return (colormodel
== BC_YUV420P
&&
540 !quicktime_match_32(QUICKTIME_SVQ1
, codec
->fourcc
));
543 static int writes_colormodel(quicktime_t
*file
,
547 return colormodel
== BC_YUV420P
;
551 static int delete_decoder(quicktime_mpeg4_codec_t
*codec
, int field
)
553 if(codec
->decode_initialized
[field
])
555 pthread_mutex_lock(&ffmpeg_lock
);
557 avcodec_close(codec
->decoder_context
[field
]);
558 free(codec
->decoder_context
[field
]);
560 pthread_mutex_unlock(&ffmpeg_lock
);
561 codec
->decode_initialized
[field
] = 0;
566 static int init_decode(quicktime_t
*file
,
567 quicktime_mpeg4_codec_t
*codec
,
568 quicktime_trak_t
*trak
,
573 quicktime_stsd_table_t
*stsd_table
= &trak
->mdia
.minf
.stbl
.stsd
.table
[0];
574 quicktime_esds_t
*esds
= &stsd_table
->esds
;
576 if(!ffmpeg_initialized
)
578 ffmpeg_initialized
= 1;
580 avcodec_register_all();
584 codec
->decoder
[current_field
] = avcodec_find_decoder(codec
->ffmpeg_id
);
585 if(!codec
->decoder
[current_field
])
587 printf("init_decode: avcodec_find_decoder returned NULL.\n");
591 AVCodecContext
*context
=
592 codec
->decoder_context
[current_field
] =
593 avcodec_alloc_context();
594 context
->width
= width_i
;
595 context
->height
= height_i
;
598 if(esds
->mpeg4_header
&& esds
->mpeg4_header_size
)
600 context
->extradata
= esds
->mpeg4_header
;
601 context
->extradata_size
= esds
->mpeg4_header_size
;
606 avcodec_thread_init(context
, file
->cpus
);
607 context
->thread_count
= file
->cpus
;
610 if(avcodec_open(context
,
611 codec
->decoder
[current_field
]) < 0)
613 printf("init_decode: avcodec_open failed.\n");
619 static int decode_wrapper(quicktime_t
*file
,
620 quicktime_video_map_t
*vtrack
,
621 quicktime_mpeg4_codec_t
*codec
,
631 int header_bytes
= 0;
632 char *compressor
= vtrack
->track
->mdia
.minf
.stbl
.stsd
.table
[0].format
;
633 quicktime_trak_t
*trak
= vtrack
->track
;
634 quicktime_stsd_table_t
*stsd_table
= &trak
->mdia
.minf
.stbl
.stsd
.table
[0];
635 int width
= trak
->tkhd
.track_width
;
636 int height
= trak
->tkhd
.track_height
;
640 if(codec
->ffmpeg_id
== CODEC_ID_SVQ1
)
642 width_i
= quicktime_quantize32(width
);
643 height_i
= quicktime_quantize32(height
);
647 width_i
= quicktime_quantize16(width
);
648 height_i
= quicktime_quantize16(height
);
652 quicktime_set_video_position(file
, frame_number
, track
);
654 bytes
= quicktime_frame_size(file
, frame_number
, track
);
655 if(frame_number
== 0 && codec
->ffmpeg_id
== CODEC_ID_SVQ3
&& stsd_table
->extradata
)
657 codec
->decoder_context
[current_field
]->extradata_size
= stsd_table
->extradata_size
;
658 codec
->decoder_context
[current_field
]->extradata
= stsd_table
->extradata
;
660 if(frame_number
== 0)
662 header_bytes
= stsd_table
->esds
.mpeg4_header_size
;
665 if(!codec
->work_buffer
|| codec
->buffer_size
< bytes
+ header_bytes
)
667 if(codec
->work_buffer
) free(codec
->work_buffer
);
668 codec
->buffer_size
= bytes
+ header_bytes
;
669 codec
->work_buffer
= calloc(1, codec
->buffer_size
+ 100);
672 // Special handling of SVQ3 codec (some others might be alike)
675 memcpy(codec
->work_buffer
, stsd_table
->esds
.mpeg4_header
, header_bytes
);
677 if(!quicktime_read_data(file
,
678 codec
->work_buffer
+ header_bytes
,
686 * if(!codec->got_key[current_field])
688 * if(!quicktime_mpeg4_is_key(codec->work_buffer, bytes, compressor))
692 * codec->got_key[current_field] = 1;
698 // No way to determine if there was an error based on nonzero status.
699 // Need to test row pointers to determine if an error occurred.
701 codec
->decoder_context
[current_field
]->skip_frame
= AVDISCARD_NONREF
;
703 codec
->decoder_context
[current_field
]->skip_frame
= AVDISCARD_DEFAULT
;
704 result
= avcodec_decode_video(codec
->decoder_context
[current_field
],
705 &codec
->picture
[current_field
],
708 bytes
+ header_bytes
);
712 if(codec
->picture
[current_field
].data
[0])
714 if(!codec
->got_key
[current_field
])
716 codec
->got_key
[current_field
] = 1;
722 // ffmpeg can't recover if the first frame errored out, like in a direct copy
725 * delete_decoder(codec, current_field);
726 * init_decode(codec, current_field, width_i, height_i);
739 static int decode(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
743 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
744 quicktime_trak_t
*trak
= vtrack
->track
;
745 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
746 int width
= trak
->tkhd
.track_width
;
747 int height
= trak
->tkhd
.track_height
;
752 int current_field
= vtrack
->current_position
% codec
->total_fields
;
753 unsigned char **input_rows
;
754 int seeking_done
= 0;
756 if(codec
->ffmpeg_id
== CODEC_ID_SVQ1
)
758 width_i
= quicktime_quantize32(width
);
759 height_i
= quicktime_quantize32(height
);
763 width_i
= quicktime_quantize16(width
);
764 height_i
= quicktime_quantize16(height
);
767 pthread_mutex_lock(&ffmpeg_lock
);
770 if(!codec
->decode_initialized
[current_field
])
772 int current_frame
= vtrack
->current_position
;
773 init_decode(file
, codec
, trak
, current_field
, width_i
, height_i
);
774 // Must decode frame with stream header first but only the first frame in the
775 // field sequence has a stream header.
776 result
= decode_wrapper(file
,
783 // Reset position because decode wrapper set it
784 quicktime_set_video_position(file
, current_frame
, track
);
785 codec
->decode_initialized
[current_field
] = 1;
789 if(quicktime_has_keyframes(file
, track
) &&
790 vtrack
->current_position
!= codec
->last_frame
[current_field
] + codec
->total_fields
)
792 int frame1
, frame2
= vtrack
->current_position
, current_frame
= frame2
;
795 // Get first keyframe of same field
798 frame1
= quicktime_get_keyframe_before(file
,
801 }while(frame1
> 0 && (frame1
% codec
->total_fields
) != current_field
);
803 // Keyframe is before last decoded frame and current frame is after last decoded
804 // frame, so instead of rerendering from the last keyframe we can rerender from
805 // the last decoded frame.
806 if(frame1
< codec
->last_frame
[current_field
] &&
807 frame2
> codec
->last_frame
[current_field
])
809 frame1
= codec
->last_frame
[current_field
] + codec
->total_fields
;
813 while(frame1
<= frame2
)
815 result
= decode_wrapper(file
,
824 // May need to do the first I frame twice.
827 result
= decode_wrapper(file
,
836 frame1
+= codec
->total_fields
;
839 vtrack
->current_position
= frame2
;
846 result
= decode_wrapper(file
,
849 vtrack
->current_position
,
854 pthread_mutex_unlock(&ffmpeg_lock
);
858 codec
->last_frame
[current_field
] = vtrack
->current_position
;
868 // result = (result != 0);
869 switch(codec
->decoder_context
[current_field
]->pix_fmt
)
871 case PIX_FMT_YUV420P
:
872 input_cmodel
= BC_YUV420P
;
875 input_cmodel
= BC_YUV422
;
877 case PIX_FMT_YUV422P
:
878 input_cmodel
= BC_YUV422P
;
880 case PIX_FMT_YUV410P
:
881 input_cmodel
= BC_YUV9P
;
885 "mpeg4 decode: unrecognized color model %d\n",
886 codec
->decoder_context
[current_field
]->pix_fmt
);
887 input_cmodel
= BC_YUV420P
;
895 if(codec
->picture
[current_field
].data
[0])
899 malloc(sizeof(unsigned char*) *
900 codec
->decoder_context
[current_field
]->height
);
903 for(i
= 0; i
< codec
->decoder_context
[current_field
]->height
; i
++)
904 input_rows
[i
] = codec
->picture
[current_field
].data
[0] +
906 codec
->decoder_context
[current_field
]->width
*
907 cmodel_calculate_pixelsize(input_cmodel
);
910 cmodel_transfer(row_pointers
, /* Leave NULL if non existent */
912 row_pointers
[0], /* Leave NULL if non existent */
915 codec
->picture
[current_field
].data
[0], /* Leave NULL if non existent */
916 codec
->picture
[current_field
].data
[1],
917 codec
->picture
[current_field
].data
[2],
918 file
->in_x
, /* Dimensions to capture from input frame */
922 0, /* Dimensions to project on output frame */
928 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
929 codec
->picture
[current_field
].linesize
[0], /* For planar use the luma rowspan */
941 static int encode(quicktime_t
*file
, unsigned char **row_pointers
, int track
)
943 int64_t offset
= quicktime_position(file
);
944 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
945 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
946 quicktime_trak_t
*trak
= vtrack
->track
;
947 int width
= trak
->tkhd
.track_width
;
948 int height
= trak
->tkhd
.track_height
;
949 int width_i
= quicktime_quantize16(width
);
950 int height_i
= quicktime_quantize16(height
);
955 int current_field
= vtrack
->current_position
% codec
->total_fields
;
956 quicktime_atom_t chunk_atom
;
962 pthread_mutex_lock(&ffmpeg_lock
);
966 if(!codec
->encode_initialized
[current_field
])
969 if(codec
->ffmpeg_id
== CODEC_ID_MPEG4
&& codec
->use_encore
)
971 codec
->encode_initialized
[current_field
] = 1;
972 codec
->encode_handle
[current_field
] = encode_handle
++;
973 codec
->enc_param
[current_field
].x_dim
= width_i
;
974 codec
->enc_param
[current_field
].y_dim
= height_i
;
975 codec
->enc_param
[current_field
].framerate
=
976 quicktime_frame_rate(file
, track
) / codec
->total_fields
;
977 codec
->enc_param
[current_field
].bitrate
=
978 codec
->bitrate
/ codec
->total_fields
;
979 codec
->enc_param
[current_field
].rc_period
= codec
->rc_period
;
980 codec
->enc_param
[current_field
].rc_reaction_period
= codec
->rc_reaction_period
;
981 codec
->enc_param
[current_field
].rc_reaction_ratio
= codec
->rc_reaction_ratio
;
982 codec
->enc_param
[current_field
].max_quantizer
= codec
->max_quantizer
;
983 codec
->enc_param
[current_field
].min_quantizer
= codec
->min_quantizer
;
984 codec
->enc_param
[current_field
].max_key_interval
= codec
->max_key_interval
;
986 codec
->enc_param
[current_field
].search_range
= codec
->quality
* 3;
987 if(codec
->enc_param
[current_field
].search_range
> 15)
988 codec
->enc_param
[current_field
].search_range
= 15;
990 encore(codec
->encode_handle
[current_field
],
992 &codec
->enc_param
[current_field
], NULL
);
998 static char *video_rc_eq
="tex^qComp";
999 codec
->encode_initialized
[current_field
] = 1;
1000 if(!ffmpeg_initialized
)
1002 ffmpeg_initialized
= 1;
1004 avcodec_register_all();
1007 codec
->encoder
[current_field
] = avcodec_find_encoder(codec
->ffmpeg_id
);
1008 if(!codec
->encoder
[current_field
])
1010 printf("encode: avcodec_find_encoder returned NULL.\n");
1011 pthread_mutex_unlock(&ffmpeg_lock
);
1015 codec
->encoder_context
[current_field
] = avcodec_alloc_context();
1016 AVCodecContext
*context
= codec
->encoder_context
[current_field
];
1018 context
->width
= width_i
;
1019 context
->height
= height_i
;
1020 context
->gop_size
= codec
->gop_size
;
1021 context
->pix_fmt
= PIX_FMT_YUV420P
;
1022 context
->bit_rate
= codec
->bitrate
/ codec
->total_fields
;
1023 context
->bit_rate_tolerance
= codec
->bitrate_tolerance
;
1024 context
->rc_eq
= video_rc_eq
;
1025 context
->rc_max_rate
= 0;
1026 context
->rc_min_rate
= 0;
1027 context
->rc_buffer_size
= 0;
1029 (!codec
->fix_bitrate
? codec
->quantizer
: 2);
1031 (!codec
->fix_bitrate
? codec
->quantizer
: 31);
1032 context
->lmin
= 2 * FF_QP2LAMBDA
;
1033 context
->lmax
= 31 * FF_QP2LAMBDA
;
1034 context
->mb_lmin
= 2 * FF_QP2LAMBDA
;
1035 context
->mb_lmax
= 31 * FF_QP2LAMBDA
;
1036 context
->max_qdiff
= 3;
1037 context
->qblur
= 0.5;
1038 context
->qcompress
= 0.5;
1039 // It needs the time per frame, not the frame rate.
1040 context
->time_base
.den
= quicktime_frame_rate_n(file
, track
);
1041 context
->time_base
.num
= quicktime_frame_rate_d(file
, track
);
1043 context
->b_quant_factor
= 1.25;
1044 context
->b_quant_offset
= 1.25;
1045 context
->error_resilience
= FF_ER_CAREFULL
;
1046 context
->error_concealment
= 3;
1047 context
->frame_skip_cmp
= FF_CMP_DCTMAX
;
1048 context
->ildct_cmp
= FF_CMP_VSAD
;
1049 context
->intra_dc_precision
= 0;
1050 context
->intra_quant_bias
= FF_DEFAULT_QUANT_BIAS
;
1051 context
->inter_quant_bias
= FF_DEFAULT_QUANT_BIAS
;
1052 context
->i_quant_factor
= -0.8;
1053 context
->i_quant_offset
= 0.0;
1054 context
->mb_decision
= FF_MB_DECISION_SIMPLE
;
1055 context
->mb_cmp
= FF_CMP_SAD
;
1056 context
->me_sub_cmp
= FF_CMP_SAD
;
1057 context
->me_cmp
= FF_CMP_SAD
;
1058 context
->me_pre_cmp
= FF_CMP_SAD
;
1059 context
->me_method
= ME_EPZS
;
1060 context
->me_subpel_quality
= 8;
1061 context
->me_penalty_compensation
= 256;
1062 context
->me_range
= 0;
1063 context
->me_threshold
= 0;
1064 context
->mb_threshold
= 0;
1065 context
->nsse_weight
= 8;
1066 context
->profile
= FF_PROFILE_UNKNOWN
;
1067 context
->rc_buffer_aggressivity
= 1.0;
1068 context
->level
= FF_LEVEL_UNKNOWN
;
1069 context
->flags
|= CODEC_FLAG_H263P_UMV
;
1070 context
->flags
|= CODEC_FLAG_AC_PRED
;
1071 context
->flags
|= CODEC_FLAG_4MV
;
1072 // Not compatible with Win
1073 // context->flags |= CODEC_FLAG_QPEL;
1077 avcodec_thread_init(context
, file
->cpus
);
1078 context
->thread_count
= file
->cpus
;
1081 if(!codec
->fix_bitrate
)
1082 context
->flags
|= CODEC_FLAG_QSCALE
;
1084 if(codec
->interlaced
)
1086 context
->flags
|= CODEC_FLAG_INTERLACED_DCT
;
1087 context
->flags
|= CODEC_FLAG_INTERLACED_ME
;
1092 * printf("encode gop_size=%d fix_bitrate=%d quantizer=%d\n",
1094 * codec->fix_bitrate,
1095 * codec->quantizer);
1097 avcodec_open(context
, codec
->encoder
[current_field
]);
1099 avcodec_get_frame_defaults(&codec
->picture
[current_field
]);
1105 if(!codec
->work_buffer
)
1107 codec
->buffer_size
= width_i
* height_i
;
1108 codec
->work_buffer
= malloc(codec
->buffer_size
);
1114 if(codec
->use_encore
)
1117 ENC_FRAME encore_input
;
1118 ENC_RESULT encore_result
;
1121 // Assume planes are contiguous.
1122 // Encode directly from function arguments
1123 if(file
->color_model
== BC_YUV420P
&&
1127 encore_input
.image
= row_pointers
[0];
1129 // Convert to YUV420P
1130 // Encode from temporary.
1133 if(!codec
->temp_frame
)
1135 codec
->temp_frame
= malloc(width_i
* height_i
* 3 / 2);
1138 cmodel_transfer(0, /* Leave NULL if non existent */
1140 codec
->temp_frame
, /* Leave NULL if non existent */
1141 codec
->temp_frame
+ width_i
* height_i
,
1142 codec
->temp_frame
+ width_i
* height_i
+ width_i
* height_i
/ 4,
1143 row_pointers
[0], /* Leave NULL if non existent */
1146 0, /* Dimensions to capture from input frame */
1150 0, /* Dimensions to project on output frame */
1156 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
1157 width
, /* For planar use the luma rowspan */
1161 encore_input
.image
= codec
->temp_frame
;
1166 bzero(codec
->work_buffer
, codec
->buffer_size
);
1167 encore_input
.bitstream
= codec
->work_buffer
;
1168 encore_input
.length
= 0;
1169 encore_input
.quant
= !codec
->fix_bitrate
? codec
->quantizer
: 0;
1171 if(codec
->p_count
== 0)
1173 codec
->p_count
[current_field
]++;
1177 codec
->p_count
[current_field
]++;
1178 if(codec
->p_count
[current_field
] >= codec
->max_key_interval
)
1179 codec
->p_count
[current_field
] = 0;
1183 encore(codec
->encode_handle
[current_field
],
1188 bytes
= encore_input
.length
;
1189 is_keyframe
= encore_result
.isKeyFrame
;
1194 AVCodecContext
*context
= codec
->encoder_context
[current_field
];
1195 AVFrame
*picture
= &codec
->picture
[current_field
];
1197 if(width_i
== width
&&
1198 height_i
== height
&&
1199 file
->color_model
== BC_YUV420P
)
1201 picture
->data
[0] = row_pointers
[0];
1202 picture
->data
[1] = row_pointers
[1];
1203 picture
->data
[2] = row_pointers
[2];
1204 picture
->linesize
[0] = width_i
;
1205 picture
->linesize
[1] = width_i
/ 2;
1206 picture
->linesize
[2] = width_i
/ 2;
1210 if(!codec
->temp_frame
)
1212 codec
->temp_frame
= malloc(width_i
* height_i
* 3 / 2);
1215 cmodel_transfer(0, /* Leave NULL if non existent */
1217 codec
->temp_frame
, /* Leave NULL if non existent */
1218 codec
->temp_frame
+ width_i
* height_i
,
1219 codec
->temp_frame
+ width_i
* height_i
+ width_i
* height_i
/ 4,
1220 row_pointers
[0], /* Leave NULL if non existent */
1223 0, /* Dimensions to capture from input frame */
1227 0, /* Dimensions to project on output frame */
1233 0, /* When transfering BC_RGBA8888 to non-alpha this is the background color in 0xRRGGBB hex */
1234 width
, /* For planar use the luma rowspan */
1237 picture
->data
[0] = codec
->temp_frame
;
1238 picture
->data
[1] = codec
->temp_frame
+ width_i
* height_i
;
1239 picture
->data
[2] = codec
->temp_frame
+ width_i
* height_i
+ width_i
* height_i
/ 4;
1240 picture
->linesize
[0] = width_i
;
1241 picture
->linesize
[1] = width_i
/ 2;
1242 picture
->linesize
[2] = width_i
/ 2;
1246 picture
->pict_type
= 0;
1247 picture
->quality
= 0;
1248 picture
->pts
= vtrack
->current_position
* quicktime_frame_rate_d(file
, track
);
1249 picture
->key_frame
= 0;
1250 bytes
= avcodec_encode_video(context
,
1254 is_keyframe
= context
->coded_frame
&& context
->coded_frame
->key_frame
;
1256 * printf("encode current_position=%d is_keyframe=%d\n",
1257 * vtrack->current_position,
1261 if(!trak
->mdia
.minf
.stbl
.stsd
.table
[0].esds
.mpeg4_header_size
&&
1262 !strcmp(((quicktime_codec_t
*)vtrack
->codec
)->fourcc
, QUICKTIME_MP4V
))
1264 unsigned char temp
[1024];
1265 unsigned char *ptr
= temp
;
1266 for(i
= 0; i
< bytes
- 4; i
++)
1268 if(!(codec
->work_buffer
[i
] == 0x00 &&
1269 codec
->work_buffer
[i
+ 1] == 0x00 &&
1270 codec
->work_buffer
[i
+ 2] == 0x01 &&
1271 codec
->work_buffer
[i
+ 3] == 0xb3))
1273 *ptr
++ = codec
->work_buffer
[i
];
1278 quicktime_set_mpeg4_header(&trak
->mdia
.minf
.stbl
.stsd
.table
[0],
1281 trak
->mdia
.minf
.stbl
.stsd
.table
[0].version
= 0;
1290 pthread_mutex_unlock(&ffmpeg_lock
);
1291 quicktime_write_chunk_header(file
, trak
, &chunk_atom
);
1292 result
= !quicktime_write_data(file
,
1295 quicktime_write_chunk_footer(file
,
1297 vtrack
->current_chunk
,
1300 if(is_keyframe
|| vtrack
->current_position
== 0)
1301 quicktime_insert_keyframe(file
,
1302 vtrack
->current_position
,
1305 vtrack
->current_chunk
++;
1314 static void flush(quicktime_t
*file
, int track
)
1316 quicktime_video_map_t
*track_map
= &(file
->vtracks
[track
]);
1317 quicktime_trak_t
*trak
= track_map
->track
;
1318 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)track_map
->codec
)->priv
;
1321 if(!trak
->mdia
.minf
.stbl
.stsd
.table
[0].esds
.mpeg4_header_size
&&
1322 !strcmp(((quicktime_codec_t
*)track_map
->codec
)->fourcc
, QUICKTIME_MP4V
))
1324 int width
= trak
->tkhd
.track_width
;
1325 int height
= trak
->tkhd
.track_height
;
1326 int width_i
= quicktime_quantize16(width
);
1327 int height_i
= quicktime_quantize16(height
);
1329 unsigned char temp
[1024];
1330 int size
= write_mp4v_header(temp
,
1333 quicktime_frame_rate(file
, track
));
1334 quicktime_set_mpeg4_header(&trak
->mdia
.minf
.stbl
.stsd
.table
[0],
1340 file
->moov
.udta
.require
= strdup("QuickTime 6.0 or greater");
1341 file
->moov
.udta
.require_len
= strlen(file
->moov
.udta
.require
);
1351 static int set_parameter(quicktime_t
*file
,
1356 quicktime_video_map_t
*vtrack
= &(file
->vtracks
[track
]);
1357 char *compressor
= vtrack
->track
->mdia
.minf
.stbl
.stsd
.table
[0].format
;
1359 if(quicktime_match_32(compressor
, QUICKTIME_DIVX
) ||
1360 quicktime_match_32(compressor
, QUICKTIME_MP42
) ||
1361 quicktime_match_32(compressor
, QUICKTIME_MPG4
) ||
1362 quicktime_match_32(compressor
, QUICKTIME_DX50
) ||
1363 quicktime_match_32(compressor
, QUICKTIME_HV60
))
1365 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
1367 if(!strcasecmp(key
, "divx_bitrate"))
1368 codec
->bitrate
= *(int*)value
;
1370 if(!strcasecmp(key
, "divx_rc_period"))
1371 codec
->rc_period
= *(int*)value
;
1373 if(!strcasecmp(key
, "divx_rc_reaction_ratio"))
1374 codec
->rc_reaction_ratio
= *(int*)value
;
1376 if(!strcasecmp(key
, "divx_rc_reaction_period"))
1377 codec
->rc_reaction_period
= *(int*)value
;
1379 if(!strcasecmp(key
, "divx_max_key_interval"))
1380 codec
->max_key_interval
= *(int*)value
;
1382 if(!strcasecmp(key
, "divx_max_quantizer"))
1383 codec
->max_quantizer
= *(int*)value
;
1385 if(!strcasecmp(key
, "divx_min_quantizer"))
1386 codec
->min_quantizer
= *(int*)value
;
1388 if(!strcasecmp(key
, "divx_quantizer"))
1389 codec
->quantizer
= *(int*)value
;
1391 if(!strcasecmp(key
, "divx_quality"))
1392 codec
->quality
= *(int*)value
;
1394 if(!strcasecmp(key
, "divx_fix_bitrate"))
1395 codec
->fix_bitrate
= *(int*)value
;
1397 if(!strcasecmp(key
, "divx_use_deblocking"))
1398 codec
->use_deblocking
= *(int*)value
;
1401 if(quicktime_match_32(compressor
, QUICKTIME_DIV3
) ||
1402 quicktime_match_32(compressor
, QUICKTIME_MP4V
))
1404 quicktime_mpeg4_codec_t
*codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
1405 if(!strcasecmp(key
, "ffmpeg_bitrate"))
1406 codec
->bitrate
= *(int*)value
;
1408 if(!strcasecmp(key
, "ffmpeg_bitrate_tolerance"))
1409 codec
->bitrate_tolerance
= *(int*)value
;
1411 if(!strcasecmp(key
, "ffmpeg_interlaced"))
1412 codec
->interlaced
= *(int*)value
;
1414 if(!strcasecmp(key
, "ffmpeg_gop_size"))
1415 codec
->gop_size
= *(int*)value
;
1417 if(!strcasecmp(key
, "ffmpeg_quantizer"))
1418 codec
->quantizer
= *(int*)value
;
1420 if(!strcasecmp(key
, "ffmpeg_fix_bitrate"))
1421 codec
->fix_bitrate
= *(int*)value
;
1428 static int delete_codec(quicktime_video_map_t
*vtrack
)
1430 quicktime_mpeg4_codec_t
*codec
;
1434 codec
= ((quicktime_codec_t
*)vtrack
->codec
)->priv
;
1435 for(i
= 0; i
< codec
->total_fields
; i
++)
1437 if(codec
->encode_initialized
[i
])
1439 pthread_mutex_lock(&ffmpeg_lock
);
1440 if(codec
->use_encore
)
1442 encore(codec
->encode_handle
[i
],
1449 avcodec_close(codec
->encoder_context
[i
]);
1450 free(codec
->encoder_context
[i
]);
1452 pthread_mutex_unlock(&ffmpeg_lock
);
1454 delete_decoder(codec
, i
);
1458 if(codec
->temp_frame
) free(codec
->temp_frame
);
1459 if(codec
->work_buffer
) free(codec
->work_buffer
);
1469 static quicktime_mpeg4_codec_t
* init_common(quicktime_video_map_t
*vtrack
,
1474 quicktime_codec_t
*codec_base
= (quicktime_codec_t
*)vtrack
->codec
;
1475 quicktime_mpeg4_codec_t
*codec
;
1477 codec_base
->priv
= calloc(1, sizeof(quicktime_mpeg4_codec_t
));
1478 codec_base
->delete_vcodec
= delete_codec
;
1479 codec_base
->decode_video
= decode
;
1480 codec_base
->encode_video
= encode
;
1481 codec_base
->flush
= flush
;
1482 codec_base
->reads_colormodel
= reads_colormodel
;
1483 codec_base
->writes_colormodel
= writes_colormodel
;
1484 codec_base
->set_parameter
= set_parameter
;
1485 codec_base
->fourcc
= compressor
;
1486 codec_base
->title
= title
;
1487 codec_base
->desc
= description
;
1489 codec
= (quicktime_mpeg4_codec_t
*)codec_base
->priv
;
1494 codec
->bitrate
= 1000000;
1495 codec
->rc_period
= 50;
1496 codec
->rc_reaction_ratio
= 45;
1497 codec
->rc_reaction_period
= 10;
1498 codec
->max_key_interval
= 45;
1499 codec
->max_quantizer
= 31;
1500 codec
->min_quantizer
= 1;
1501 codec
->quantizer
= 10;
1503 codec
->fix_bitrate
= 1;
1504 codec
->total_fields
= 1;
1514 // Mike Rowe Soft MPEG-4
1515 void quicktime_init_codec_div3(quicktime_video_map_t
*vtrack
)
1517 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1520 "Mike Row Soft MPEG4 Version 3");
1521 result
->ffmpeg_id
= CODEC_ID_MSMPEG4V3
;
1524 void quicktime_init_codec_div5(quicktime_video_map_t
*vtrack
)
1526 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1529 "Mike Row Soft MPEG4 Version 5");
1530 result
->ffmpeg_id
= CODEC_ID_MPEG4
;
1533 // Mike Rowe Soft MPEG-4
1534 void quicktime_init_codec_div3lower(quicktime_video_map_t
*vtrack
)
1536 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1537 QUICKTIME_DIV3_LOWER
,
1539 "Mike Row Soft MPEG4 Version 3");
1540 result
->ffmpeg_id
= CODEC_ID_MSMPEG4V3
;
1543 void quicktime_init_codec_div3v2(quicktime_video_map_t
*vtrack
)
1545 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1548 "Mike Row Soft MPEG4 Version 2");
1549 result
->ffmpeg_id
= CODEC_ID_MSMPEG4V2
;
1553 void quicktime_init_codec_divx(quicktime_video_map_t
*vtrack
)
1555 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1558 "Generic MPEG Four");
1559 result
->ffmpeg_id
= CODEC_ID_MPEG4
;
1560 result
->use_encore
= 1;
1563 void quicktime_init_codec_mpg4(quicktime_video_map_t
*vtrack
)
1565 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1568 "FFMPEG (msmpeg4)");
1569 result
->ffmpeg_id
= CODEC_ID_MSMPEG4V1
;
1572 void quicktime_init_codec_dx50(quicktime_video_map_t
*vtrack
)
1574 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1578 result
->ffmpeg_id
= CODEC_ID_MPEG4
;
1582 void quicktime_init_codec_mp4v(quicktime_video_map_t
*vtrack
)
1584 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1587 "Generic MPEG Four");
1588 result
->ffmpeg_id
= CODEC_ID_MPEG4
;
1589 // result->use_encore = 1;
1594 void quicktime_init_codec_svq1(quicktime_video_map_t
*vtrack
)
1596 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1598 "Sorenson Version 1",
1599 "From the chearch of codecs of yesterday's sights");
1600 result
->ffmpeg_id
= CODEC_ID_SVQ1
;
1603 void quicktime_init_codec_svq3(quicktime_video_map_t
*vtrack
)
1605 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1607 "Sorenson Version 3",
1608 "From the chearch of codecs of yesterday's sights");
1609 result
->ffmpeg_id
= CODEC_ID_SVQ3
;
1612 void quicktime_init_codec_h263(quicktime_video_map_t
*vtrack
)
1614 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1618 result
->ffmpeg_id
= CODEC_ID_H263
;
1621 void quicktime_init_codec_xvid(quicktime_video_map_t
*vtrack
)
1623 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1627 result
->ffmpeg_id
= CODEC_ID_MPEG4
;
1630 // field based MPEG-4
1631 void quicktime_init_codec_hv60(quicktime_video_map_t
*vtrack
)
1633 quicktime_mpeg4_codec_t
*result
= init_common(vtrack
,
1636 "MPEG 4 with alternating streams every other frame. (Not standardized)");
1637 result
->total_fields
= 2;
1638 result
->ffmpeg_id
= CODEC_ID_MPEG4
;