--- On Wed, 10/20/10, John Gladman <[email protected]> wrote:
> From: John Gladman <[email protected]>
> Subject: Re: [libav-user] Using FFmpeg in iPhone Project
> To: "Libav* user questions and discussions" <[email protected]>
> Date: Wednesday, October 20, 2010, 1:56 PM
> Hi
>
> What would it cost to provide a sample iPhone APP. I want
> to convert a video file from AVI to an MP4 file that will
> play on the iPhone.
>
> My problem is that I am currently creating an AVI file
> within my APP but AVI files won't play on the iPhone. Thats
> why I want to be able to convert it to
> a format that will play on the iPhone.
>
> John G
>
> On 20 Oct 2010, at 18:50, Igor R wrote:
>
> >> Does anyone have a simple sample iPhone project
> that allows video to be converted from one format to
> another
> >
> > I don't have such a sample project, but I do develop
> projects for
> > iPhone with ffmpeg libs (libavcodec etc), and it
> doesn't differ from
> > using ffmpeg on Windows. Actually, we compile on
> multiple platforms
> > the same portable c++ code, which uses ffmpeg.
> > _______________________________________________
> > libav-user mailing list
> > [email protected]
> > https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>
> _______________________________________________
> libav-user mailing list
> [email protected]
> https://lists.mplayerhq.hu/mailman/listinfo/libav-user
>
As Igor mentioned the code is the same as on other platforms, but here's a
sample (from what I remember it was working correctly, I haven't used/tested it
much though). To convert to mpeg4 you'll need to make some changes (it requires
some strict parameters from what I recall).
I hope it helps.
int Convert(const char *inputVideoPath, const char *outputPath){
if(inputVideoPath == NULL || outputPath == NULL){
fprintf(stderr, "Video path or image path aren't set!\n");
return -1;
}
av_register_all();
AVFormatContext *ic;
AVInputFormat *ifmt;
ifmt = av_find_input_format("mov");
if(!ifmt){
fprintf(stderr, "Nu gaseste demuxer pt mov\n");
return -1;
}
if(av_open_input_file(&ic, inputVideoPath, ifmt, 0, NULL) != 0){
fprintf(stderr, "Nu poate deschide fisierul de intrare! %s\n",
inputVideoPath);
return -1;
}
if(av_find_stream_info(ic) < 0){
fprintf(stderr, "Nu s-a gasit un stream pt fisierul de
intrare\n");
return -1;
}
ic->flags |= AVFMT_FLAG_NONBLOCK;
ic->loop_input = 0;
AVFormatContext *oc;
AVOutputFormat *ofmt;
ofmt = av_guess_format("mov", NULL, NULL);
if(!ofmt){
fprintf(stderr, "Nu s-a gasit muxer pt mov (output)\n");
return -1;
}
oc = avformat_alloc_context();
if(!oc){
fprintf(stderr, "nu s-a putut aloca contextul de iesire\n");
return -1;
}
oc->oformat = ofmt;
strcpy(oc->filename, outputPath);
int video_index = -1, audio_index = -1;
AVStream *video_st, *audio_st;
AVCodecContext *video_enc;
for(int i=0; i<ic->nb_streams; i++){
if(ic->streams[i]->codec->codec_type==CODEC_TYPE_VIDEO){
video_index = i;
ic->streams[i]->discard = AVDISCARD_NONE;
video_st = av_new_stream(oc, oc->nb_streams);
if (!video_st) {
fprintf(stderr, "Could not alloc stream\n");
return -1;
}
avcodec_get_context_defaults2(video_st->codec,
CODEC_TYPE_VIDEO);
for(int i=0; i<3; i++){
video_st->auxMatrix[i][0] =
ic->streams[video_index]->auxMatrix[i][0];
video_st->auxMatrix[i][1] =
ic->streams[video_index]->auxMatrix[i][1];
}
video_enc = video_st->codec;
video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
video_enc->width =
ic->streams[video_index]->codec->width;
video_enc->height =
ic->streams[video_index]->codec->height;
video_enc->pix_fmt = PIX_FMT_YUV420P;
video_enc->flags |= CODEC_FLAG_QSCALE;
video_enc->global_quality = video_st->quality = 0;
video_enc->time_base.den =
ic->streams[video_index]->time_base.den;
video_enc->time_base.num =
ic->streams[video_index]->time_base.num;
video_enc->sample_aspect_ratio =
av_d2q(video_enc->height/video_enc->width, 255);
video_st->sample_aspect_ratio =
video_enc->sample_aspect_ratio;
{
video_enc->thread_count=1;
video_enc->rc_override_count=0;
video_enc->rc_initial_buffer_occupancy =
video_enc->rc_buffer_size*3/4; //0
video_enc->me_threshold = 0;
video_enc->intra_dc_precision = 0;
}
oc->streams[video_index]->codec->bits_per_raw_sample=
ic->streams[video_index]->codec->bits_per_raw_sample;
oc->streams[video_index]->codec->chroma_sample_location
= ic->streams[video_index]->codec->chroma_sample_location;
}
else if(ic->streams[i]->codec->codec_type==CODEC_TYPE_AUDIO){
audio_index = i;
audio_st = add_output_stream(oc,
ic->streams[audio_index]);
audio_st->stream_copy = 1;
ic->streams[i]->discard = AVDISCARD_NONE;
audio_st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
else{
ic->streams[i]->discard = AVDISCARD_ALL;
}
}
if(video_index<0){
fprintf(stderr, "Can't find any video stream! %s:%d\n",
__FILE__, __LINE__);
return -1;
}
if(audio_index<0){
fprintf(stderr, "Can't find any audio stream! %s:%d\n",
__FILE__, __LINE__);
goto fail;
}
dump_format(ic, 1, inputVideoPath, 0);
if(url_fopen(&oc->pb, outputPath, URL_WRONLY)<0){
fprintf(stderr, "Nu s-a putut deschide fisierul de iesire
%s:%d\n", __FILE__, __LINE__);
goto fail;
}
uint8_t *bit_buffer = NULL;
int bit_buffer_size =1024*256;
int size = video_enc->width*video_enc->height;
bit_buffer_size = FFMAX(bit_buffer_size, 6*size+200);
bit_buffer = av_malloc(bit_buffer_size);
if(!bit_buffer){
fprintf(stderr, "Could not allocate buffer\n");
}
enum CodecID codec_id;
AVCodec *codec;
codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL,
CODEC_TYPE_VIDEO);
codec = avcodec_find_encoder(codec_id);
video_enc->codec_id = codec_id;
if(!codec){
fprintf(stderr, "Unsupported coder! %s:%d", __FILE__, __LINE__);
goto fail;
}
if (avcodec_open(video_enc, codec) < 0) {
fprintf(stderr, "Could not open codec for encoding! %s:%d\n",
__FILE__, __LINE__);
goto fail;
}
AVCodec *pCodec;
pCodec=avcodec_find_decoder(ic->streams[video_index]->codec->codec_id);
if(!pCodec) {
fprintf(stderr, "Unsupported decoder! %s:%d\n", __FILE__,
__LINE__);
avcodec_close(video_enc);
goto fail;
}
if (avcodec_open(ic->streams[video_index]->codec, pCodec) < 0) {
fprintf(stderr, "Could not open codec for decoding! %s:%d\n",
__FILE__, __LINE__);
avcodec_close(video_enc);
goto fail;
}
if(av_write_header(oc)<0){
fprintf(stderr, "Could not write header for output file!
%s:%d\n", __FILE__, __LINE__);
avcodec_close(ic->streams[video_index]->codec);
avcodec_close(video_enc);
goto fail;
}
int decode_done = 0, got_picture=0;
do {
AVPacket packet;
decode_done = av_read_frame(ic, &packet);
if(decode_done<0){
fprintf(stdin, "Decodare terminata");
break;
}
if(ic->streams[packet.stream_index]->codec->codec_type ==
CODEC_TYPE_VIDEO){
AVFrame picture;
avcodec_get_frame_defaults(&picture);
int ret =
avcodec_decode_video2(ic->streams[video_index]->codec, &picture, &got_picture,
&packet);
ic->streams[video_index]->quality= picture.quality;
if(ret<0){
av_free_packet(&packet);
fprintf(stderr, "Could not decode packet!
%s:%d\n", __FILE__, __LINE__);
break;
}
if(!got_picture){
fprintf(stderr, "Didn't get picture! %s:%d\n",
__FILE__, __LINE__);
av_free_packet(&packet);
av_free(&picture);
continue;
}
packet.size = 0;
picture.pict_type=0;
ret = avcodec_encode_video(video_enc, bit_buffer,
bit_buffer_size, &picture);
//av_free(picture);
if(ret<0){
fprintf(stderr, "Video encoding failed!
%s:%d\n", __FILE__, __LINE__);
continue;
}
if(ret>0){
AVPacket opacket;
av_init_packet(&opacket);
opacket.pts = opacket.dts = packet.pts;
opacket.stream_index = video_index;
opacket.data = bit_buffer;
opacket.size = ret;
if(video_enc->coded_frame &&
video_enc->coded_frame->key_frame)
opacket.flags |= PKT_FLAG_KEY;
ret = av_interleaved_write_frame(oc, &opacket);
if(ret<0){
fprintf(stderr, "Error writing frame!
%s:%d\n", __FILE__, __LINE__);
}
av_free_packet(&opacket);
}
}
else if(ic->streams[packet.stream_index]->codec->codec_type ==
CODEC_TYPE_AUDIO){
packet.stream_index = audio_index;
int ret = av_interleaved_write_frame(oc, &packet);
if(ret<0){
fprintf(stderr, "Error writing frame! %s:%d\n",
__FILE__, __LINE__);
}
}
else{
av_free_packet(&packet);
continue;
}
av_free_packet(&packet);
} while(!decode_done);
av_free(bit_buffer);
av_write_trailer(oc);
av_freep(&ic->streams[video_index]->codec->stats_in);
avcodec_close(ic->streams[video_index]->codec);
avcodec_close(video_enc);
dump_format(oc, 0, outputPath, 1);
for(int i = 0; i < oc->nb_streams; i++) {
av_freep(&oc->streams[i]->codec);
av_freep(&oc->streams[i]);
}
url_fclose(oc->pb);
av_free(oc);
av_close_input_file(ic);
return 0;
fail:
dump_format(oc, 0, outputPath, 1);
for(int i = 0; i < oc->nb_streams; i++) {
av_freep(&oc->streams[i]->codec);
av_freep(&oc->streams[i]);
}
url_fclose(oc->pb);
av_free(oc);
av_close_input_file(ic);
return -1;
}_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user