I am writing a simple C program to accept video input decode it encode it into
flv and then save output video file. I have looked at danger's tutorials,
output-example.c,api-example.c and such. But i seem to be missing something very
essential. And always end up encountering , segmentation faults, ( sometimes
buffer under flows or warning max analysis time reached.  The below is the
program. I would very much appreciate for a clear solution to this problem. I
have spend to many days trying to figure this out already.
I understand process might be called trans coding. If any one can
provide a link to a working c transcode_sample using libavi api
it would be very much helpful.The only thing i have come across close
in this regard is this
http://ffmpeg.arrozcru.org/forum/viewtopic.php?f=8&t=1456
but this breaks with different formats other than mpg input and breaks
on trying to output an flv file.

I have not found any clear solution on buffer under flow errors and
segmentation faults  while using avcodec_encode_video() ..



#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

static void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame);
AVFormatContext *pFormatCtx;
static int i, videoStream;
AVCodecContext *pCodecCtx;
AVCodec *pCodec;
AVFrame *pFrame;
AVFrame *pFrameRGB;
AVPacket packet;
static int frameFinished;
static int numBytes;
static uint8_t *buffer;
AVCodec *codec;
AVCodecContext *c = NULL;
int out_size, size, outbuf_size;
uint8_t *outbuf;
FILE *f;

int init_video_file(char *inputFileName) {
        // Register all formats and codecs
        av_register_all();

        // Open video file
        if (av_open_input_file(&pFormatCtx, inputFileName, NULL, 0, NULL) != 0)
                return -1; // Couldn't open file

        // Retrieve stream information
        if (av_find_stream_info(pFormatCtx) < 0)
                return -1; // Couldn't find stream information

        // Dump information about file onto standard error
        dump_format(pFormatCtx, 0, inputFileName, false);

        // Find the first video stream
        videoStream = -1;
        for (i = 0; i < pFormatCtx->nb_streams; i++)
                if (pFormatCtx->streams[i]->codec->codec_type == 
CODEC_TYPE_VIDEO) {
                        videoStream = i;
                        break;
                }
        if (videoStream == -1)
                return -1; // Didn't find a video stream

        return 0;
}
int init_video_codec() {

        // Get a pointer to the codec context for the video stream
        pCodecCtx = pFormatCtx->streams[videoStream]->codec;

        // Find the decoder for the video stream
        pCodec = avcodec_find_decoder(pCodecCtx->codec_id);
        if (pCodec == NULL)
                return -1; // Codec not found

        // Open codec
        if (avcodec_open(pCodecCtx, pCodec) < 0)
                return -1; // Could not open codec

        return 0;
}
int set_frame_data() {
        // Hack to correct wrong frame rates that seem to be generated by some 
codecs
        if (pCodecCtx->time_base.num > 1000 && pCodecCtx->time_base.den == 1)
                pCodecCtx->time_base.den = 1000;

        // Allocate video frame
        pFrame = avcodec_alloc_frame();

        // Allocate an AVFrame structure
        pFrameRGB = avcodec_alloc_frame();
        if (pFrameRGB == NULL)
                return -1;

        // Determine required buffer size and allocate buffer
        numBytes = avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width,
                        pCodecCtx->height);

        buffer = malloc(numBytes);

        // Assign appropriate parts of buffer to image planes in pFrameRGB
        avpicture_fill((AVPicture *) pFrameRGB, buffer, PIX_FMT_RGB24,
                        pCodecCtx->width, pCodecCtx->height);

        return 0;
}

void process_packet_data(char *outFileName) {
        // Read frames and save first five frames to disk
        i = 0;
        while (av_read_frame(pFormatCtx, &packet) >= 0) {
                // Is this a packet from the video stream?
                if (packet.stream_index == videoStream) {
                        // Decode video frame
                        avcodec_decode_video(pCodecCtx, pFrame, &frameFinished,
                                        packet.data, packet.size);

                        // Did we get a video frame?
                        if (frameFinished) {
                                //printf("\n packet size= %d \t  pframe 
number=n%d ", packet.size,
                                        //      pFrame->coded_picture_number);

                                 // Insane segmentation faults when encoding 
the got frame.. !!Help.
                                //out_size = avcodec_encode_video(c, outbuf, 
outbuf_size, pFrame);

                                save_frame_as_image();

                        }
                }

                // Free the packet that was allocated by av_read_frame
                av_free_packet(&packet);
        }

}

void set_encoder_for_output(const char *filename) {

        uint8_t *outbuf;

        printf("Video encoding\n");

        /* find the mpeg1 video encoder */
        codec = avcodec_find_encoder(CODEC_ID_FLASHSV);
        if (!codec) {
                fprintf(stderr, "codec not found\n");
                exit(1);
        }

        c = avcodec_alloc_context();
        pFrame = avcodec_alloc_frame();

        /* put sample parameters */
        c->bit_rate = 128000;
        /* resolution must be a multiple of two */
        c->width = 320;
        c->height = 240;
        /* frames per second */
        c->time_base = (AVRational) {1,25};
                        c->gop_size = 10; /* emit one intra frame every ten 
frames */
                        c->max_b_frames=1;
                        c->pix_fmt = PIX_FMT_YUV420P;

                        /* open it */
                        if (avcodec_open(c, codec) < 0) {
                                fprintf(stderr, "could not open codec\n");
                                exit(1);
                        }

                        f = fopen(filename, "wb");
                        if (!f) {
                                fprintf(stderr, "could not open ______::: 
%s\n", filename);
                                exit(1);
                        }

                        /* alloc image and output buffer */
                        outbuf_size = 230400;
                        outbuf = malloc(outbuf_size);
                        size = c->width * c->height;

                        //out_size = avcodec_encode_video(c, outbuf, 
outbuf_size, picture);
                }
void cleanup() {
        // Free the RGB image'

        free(outbuf);
        avcodec_close(c);
        av_free(c);
        printf("\n");

        free(buffer);
        av_free(pFrameRGB);

        // Free the YUV frame
        av_free(pFrame);

        // Close the codec
        avcodec_close(pCodecCtx);

        // Close the video file
        av_close_input_file(pFormatCtx);

}
void encode_frames_to_video() {

}
void save_frame_as_image() {
        static struct SwsContext *img_convert_ctx;

         // Convert the image into YUV format that SDL uses
         if (img_convert_ctx == NULL) {
         int w = pCodecCtx->width;
         int h = pCodecCtx->height;

         img_convert_ctx = sws_getContext(w, h, pCodecCtx->pix_fmt, w, h,
         PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);

         if (img_convert_ctx == NULL) {
         fprintf(stderr, "Cannot initialize the conversion context!\n");
         exit(1);
         }
         }
         int ret = sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0,
         pCodecCtx->height, pFrameRGB->data, pFrameRGB->linesize);

         // Save the frame to disk
         if (i++ <= 5)
         SaveFrame(pFrameRGB, pCodecCtx->width, pCodecCtx->height, i);

}
int main(int argc, char * argv[]) {

        init_video_file(argv[1]);
        init_video_codec();
        set_frame_data();
        set_encoder_for_output(argv[2]);
        process_packet_data(argv[2]);
        cleanup();
        return 0;
}

static void SaveFrame(AVFrame *pFrame, int width, int height, int iFrame) {
        FILE *pFile;
        char szFilename[32];
        int y;

        // Open file
        sprintf(szFilename, "frame%d.ppm", iFrame);
        pFile = fopen(szFilename, "wb");
        if (pFile == NULL)
                return;

        // Write header
        fprintf(pFile, "P6\n%d %d\n255\n", width, height);

        // Write pixel data
        for (y = 0; y < height; y++)
                fwrite(pFrame->data[0] + y * pFrame->linesize[0], 1, width * 3, 
pFile);

        // Close file
        fclose(pFile);
}


[b] Kindly help in resolving the segmentation faults in the above program [/b]

I have been unable to find any straight forward example on how to do this.

Thanks



-- 
Aditya
_______________________________________________
libav-api mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-api

Reply via email to