--- 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

Reply via email to