Example #1
0
void grabber::loop()
{
	
	while(!b_stop)
	{
		AVPacket packet;
		av_init_packet( &packet );
		int ret = 0;
		int got_picture = 0;
		
		
		if(av_read_frame(pFormatCtx, &packet)>=0)
		{
			if(packet.stream_index==videoindex)
			{
				AVPacket* pkt = new AVPacket;
				av_new_packet(pkt, packet.size);
				
				av_copy_packet(pkt, &packet);
				decFifo.push(pkt);
			}
		}
		av_free_packet(&packet);
		
	}
}
Example #2
0
    int Read(int stream, int sampNum, char*** data, int* channels) {
	CheckStream(stream);
	TFFmpegStream& Stream = Streams[stream];
	*channels = 1;
	if(Stream.Type == EFF_AUDIO_STREAM)
	    *channels = Stream.CodecCtx->channels;
	int BufSize = Stream.SampleSize * sampNum;
	*data = new char*[*channels];
	for(int i = 0; i < *channels; ++i)
	    (*data)[i] = new char[BufSize];

	int ToRead = sampNum;
	while(ToRead > 0) {
	    if(Stream.Cache.size()) {
		ToRead -= Stream.Read(ToRead, *data, sampNum);
	    } else {
		if(av_read_frame(FormatCtx, Packet) < 0)
		    break;
		if(Packet->buf == NULL) {
		    // Make copy for longer lifetime
		    AVPacket Dup;
		    av_copy_packet(&Dup, Packet);
		    av_free_packet(Packet);
		    *Packet = Dup;
		}
		Streams[Packet->stream_index].Cache.push_back(*Packet);
	    }
	}
	int PerChannelBytes = Stream.SampleSize * (sampNum - ToRead);
	return PerChannelBytes;
    }
Example #3
0
File: wtvenc.c Project: 1c0n/xbmc
static int write_packet(AVFormatContext *s, AVPacket *pkt)
{
    AVIOContext *pb = s->pb;
    WtvContext  *wctx = s->priv_data;

    if (s->streams[pkt->stream_index]->codec->codec_id == AV_CODEC_ID_MJPEG && !wctx->thumbnail.size) {
        av_copy_packet(&wctx->thumbnail, pkt);
        return 0;
    }

    /* emit sync chunk and 'timeline.table.0.entries.Event' record every 50 frames */
    if (wctx->serial - (wctx->nb_sp_pairs ? wctx->sp_pairs[wctx->nb_sp_pairs - 1].serial : 0) >= 50)
        write_sync(s);

    /* emit 'table.0.entries.time' record every 500ms */
    if (pkt->pts != AV_NOPTS_VALUE && pkt->pts - (wctx->nb_st_pairs ? wctx->st_pairs[wctx->nb_st_pairs - 1].value : 0) >= 5000000)
        add_serial_pair(&wctx->st_pairs, &wctx->nb_st_pairs, wctx->serial, pkt->pts);

    if (pkt->pts != AV_NOPTS_VALUE && pkt->pts > wctx->last_pts) {
        wctx->last_pts = pkt->pts;
        wctx->last_serial = wctx->serial;
    }

    // write timestamp chunk
    write_timestamp(s, pkt);

    write_chunk_header(s, &ff_data_guid, pkt->size, INDEX_BASE + pkt->stream_index);
    avio_write(pb, pkt->data, pkt->size);
    write_pad(pb, WTV_PAD8(pkt->size) - pkt->size);

    wctx->serial++;
    avio_flush(pb);
    return 0;
}
Example #4
0
int CVideoDecoder2::Put(const uint8_t* buf, int len)
{
    if(!bInit){
        return -1;
    }

    int ret = -1;
    const uint8_t *curBuf = buf;
    int      curLen = len;
    bool     bPushed = false;
    
    if(!buf && len == 0){ // done, there are no more data put in
        AVPacket *pkt = (AVPacket*)av_malloc(sizeof(AVPacket));
        if(!pkt){
            ret = -1;
            return ret;
        }
        av_init_packet(pkt);
        pkt->data = const_cast<uint8_t*>(buf);
        pkt->size = len;

        uv_mutex_lock(pQueueMutex);
        packetQueue.push_back(pkt);
        uv_mutex_unlock(pQueueMutex);
        uv_cond_signal(pQueueNotEmpty);
        return 0;
    }
    uv_mutex_lock(pQueueMutex);
    while(curLen > 0){
        AVPacket *pkt = (AVPacket*)av_malloc(sizeof(AVPacket));
        if(!pkt){
            ret = -1;
            break;
        }
        av_init_packet(pkt);
        int parserLen = av_parser_parse2(pCodecParserCtx, pCodecCtx, 
                                         &pkt->data, &pkt->size, 
                                         curBuf, curLen, 
                                         AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE);
        curBuf += parserLen;
        curLen -= parserLen;
        if(pkt->size == 0){
            av_freep(pkt);
            continue;
        }
        AVPacket *pkt2 = (AVPacket*)av_malloc(sizeof(AVPacket));
        ret = av_copy_packet(pkt2, pkt);
        packetQueue.push_back(pkt2);
        bPushed = true;
        av_free_packet(pkt);
        av_freep(pkt);
        ret = 0;
    }
    uv_mutex_unlock(pQueueMutex);
    if(ret >= 0 && bPushed){
        uv_cond_signal(pQueueNotEmpty);
    }
    return ret;
}
Example #5
0
int ff_subtitles_queue_read_packet(FFDemuxSubtitlesQueue *q, AVPacket *pkt)
{
    AVPacket *sub = q->subs + q->current_sub_idx;

    if (q->current_sub_idx == q->nb_subs)
        return AVERROR_EOF;
    av_copy_packet(pkt, sub);

    pkt->dts = pkt->pts;
    q->current_sub_idx++;
    return 0;
}
Example #6
0
static int aiff_write_packet(AVFormatContext *s, AVPacket *pkt)
{
    AIFFOutputContext *aiff = s->priv_data;
    AVIOContext *pb = s->pb;
    if (pkt->stream_index == aiff->audio_stream_idx)
        avio_write(pb, pkt->data, pkt->size);
    else {
        int ret;
        AVPacketList *pict_list, *last;

        if (s->streams[pkt->stream_index]->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
            return 0;

        /* warn only once for each stream */
        if (s->streams[pkt->stream_index]->nb_frames == 1) {
            av_log(s, AV_LOG_WARNING, "Got more than one picture in stream %d,"
                   " ignoring.\n", pkt->stream_index);
        }
        if (s->streams[pkt->stream_index]->nb_frames >= 1)
            return 0;

        pict_list = av_mallocz(sizeof(AVPacketList));
        if (!pict_list)
            return AVERROR(ENOMEM);

        if ((ret = av_copy_packet(&pict_list->pkt, pkt)) < 0) {
            av_freep(&pict_list);
            return ret;
        }

        if (!aiff->pict_list)
            aiff->pict_list = pict_list;
        else {
            last = aiff->pict_list;
            while (last->next)
                last = last->next;
            last->next = pict_list;
        }
    }

    return 0;
}
int lw_copy_av_packet
(
    AVPacket *dst,
    AVPacket *src
)
{
#if LIBAVUTIL_VERSION_MICRO >= 100
    return av_copy_packet( dst, src );
#else
    int ret;
    if( (ret = av_new_packet( dst, src->size )) != 0
     || (ret = av_packet_copy_props( dst, src )) != 0 )
    {
        av_packet_unref( dst );
        return ret;
    }
    memcpy( dst->data, src->data, src->size );
    return 0;
#endif
}
Example #8
0
static int filter_packet(void *log_ctx, AVPacket *pkt,
                         AVFormatContext *fmt_ctx, AVBitStreamFilterContext *bsf_ctx)
{
    AVCodecContext *enc_ctx = fmt_ctx->streams[pkt->stream_index]->codec;
    int ret = 0;

    while (bsf_ctx) {
        AVPacket new_pkt = *pkt;
        ret = av_bitstream_filter_filter(bsf_ctx, enc_ctx, NULL,
                                             &new_pkt.data, &new_pkt.size,
                                             pkt->data, pkt->size,
                                             pkt->flags & AV_PKT_FLAG_KEY);
        if (ret == 0 && new_pkt.data != pkt->data && new_pkt.destruct) {
            if ((ret = av_copy_packet(&new_pkt, pkt)) < 0)
                break;
            ret = 1;
        }

        if (ret > 0) {
            av_free_packet(pkt);
            new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size,
                                           av_buffer_default_free, NULL, 0);
            if (!new_pkt.buf)
                break;
        }
        *pkt = new_pkt;

        bsf_ctx = bsf_ctx->next;
    }

    if (ret < 0) {
        av_log(log_ctx, AV_LOG_ERROR,
               "Failed to filter bitstream with filter %s for stream %d in file '%s' with codec %s\n",
               bsf_ctx->filter->name, pkt->stream_index, fmt_ctx->filename,
               avcodec_get_name(enc_ctx->codec_id));
    }

    return ret;
}
Example #9
0
File: tee.c Project: 26mansi/FFmpeg
static int tee_write_packet(AVFormatContext *avf, AVPacket *pkt)
{
    TeeContext *tee = avf->priv_data;
    AVFormatContext *avf2;
    AVPacket pkt2;
    int ret_all = 0, ret;
    unsigned i, s;
    int s2;
    AVRational tb, tb2;

    for (i = 0; i < tee->nb_slaves; i++) {
        avf2 = tee->slaves[i].avf;
        s = pkt->stream_index;
        s2 = tee->slaves[i].stream_map[s];
        if (s2 < 0)
            continue;

        if ((ret = av_copy_packet(&pkt2, pkt)) < 0 ||
            (ret = av_dup_packet(&pkt2))< 0)
            if (!ret_all) {
                ret_all = ret;
                continue;
            }
        tb  = avf ->streams[s ]->time_base;
        tb2 = avf2->streams[s2]->time_base;
        pkt2.pts      = av_rescale_q(pkt->pts,      tb, tb2);
        pkt2.dts      = av_rescale_q(pkt->dts,      tb, tb2);
        pkt2.duration = av_rescale_q(pkt->duration, tb, tb2);
        pkt2.stream_index = s2;

        filter_packet(avf2, &pkt2, avf2, tee->slaves[i].bsfs[s2]);
        if ((ret = av_interleaved_write_frame(avf2, &pkt2)) < 0)
            if (!ret_all)
                ret_all = ret;
    }
    return ret_all;
}
int AvFormatDecoderDVD::ReadPacket(AVFormatContext *ctx, AVPacket* pkt)
{
    int result = 0;

    if (m_framesReq > 0)
    {
        m_framesReq--;

        if (m_lastVideoPkt)
        {
            av_copy_packet(pkt, m_lastVideoPkt);

            if (m_lastVideoPkt->pts != AV_NOPTS_VALUE)
                m_lastVideoPkt->pts += pkt->duration;

            if (m_lastVideoPkt->dts != AV_NOPTS_VALUE)
                m_lastVideoPkt->dts += pkt->duration;
        }
        else
        {
            LOG(VB_GENERAL, LOG_ERR, LOC + QString( "Need to generate frame @ %1 - %2 but no frame available!")
                .arg(pkt->pts)
                .arg(m_framesReq));
        }
    }
    else
    {
        bool gotPacket;

        do
        {
            gotPacket = true;

            result = av_read_frame(ctx, pkt);

            while (result == AVERROR_EOF && errno == EAGAIN)
            {
                if (ringBuffer->DVD()->IsReadingBlocked())
                {
                    if (ringBuffer->DVD()->GetLastEvent() == DVDNAV_HOP_CHANNEL)
                    {
                        // Non-seamless jump - clear all buffers
                        m_framesReq = 0;
                        ReleaseContext(m_curContext);

                        while (m_contextList.size() > 0)
                            m_contextList.takeFirst()->DecrRef();

                        Reset(true, false, false);
                        m_audio->Reset();
                        m_parent->DiscardVideoFrames(false);
                    }
                    ringBuffer->DVD()->UnblockReading();
                    result = av_read_frame(ctx, pkt);
                }
                else
                {
                    break;
                }
            }

            if (result >= 0)
            {
                pkt->dts = ringBuffer->DVD()->AdjustTimestamp(pkt->dts);
                pkt->pts = ringBuffer->DVD()->AdjustTimestamp(pkt->pts);

                if (m_returnContext)
                {
                    // We've jumped in a slideshow and have had to jump again
                    // to find the right video packet to show so only allow
                    // the packets through that let us find it.
                    gotPacket = false;

                    AVStream *curstream = ic->streams[pkt->stream_index];

                    if ((curstream->codec->codec_type == AVMEDIA_TYPE_VIDEO) ||
                        (curstream->codec->codec_id == AV_CODEC_ID_DVD_NAV))
                    {
                        // Allow video or NAV packets through
                        gotPacket = true;
                    }
                }
            }
        }while(!gotPacket);
    }

    return result;
}
bool AvFormatDecoderDVD::ProcessVideoPacket(AVStream *stream, AVPacket *pkt)
{
    int64_t pts = pkt->pts;

    if (pts == AV_NOPTS_VALUE)
        pts = pkt->dts;

    CheckContext(pts);

    bool ret = AvFormatDecoder::ProcessVideoPacket(stream, pkt);
        
    if( ret &&
        m_curContext &&
        pts != AV_NOPTS_VALUE &&
        pts + pkt->duration == m_curContext->GetSeqEndPTS())
    {
        // If this video frame is the last in the sequence,
        // make a copy of it so we can 'generate' more
        // to fill in the gaps (e.g. when a single frame
        // should be displayed with audio)
        if (!m_lastVideoPkt)
        {
            m_lastVideoPkt = new AVPacket;
            memset(m_lastVideoPkt, 0, sizeof(AVPacket));
        }
        else
        {
            av_free_packet(m_lastVideoPkt);
        }

        av_init_packet(m_lastVideoPkt);
        av_copy_packet(m_lastVideoPkt, pkt);
        m_lbaLastVideoPkt = m_curContext->GetLBA();

        if (m_returnContext)
        {
            // After seeking in a slideshow, we needed to find
            // the previous video frame to display.
            // We've found it now, so we need to jump back to
            // where we originally wanted to be.
            LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString( "Found video packet, jumping back to sector %1")
                .arg(m_returnContext->GetLBA()));

            ringBuffer->DVD()->SectorSeek(m_returnContext->GetLBA());
            ReleaseContext(m_returnContext);
        }
        else
        {
            if (m_lastVideoPkt->pts != AV_NOPTS_VALUE)
                m_lastVideoPkt->pts += pkt->duration;

            if (m_lastVideoPkt->dts != AV_NOPTS_VALUE)
                m_lastVideoPkt->dts += pkt->duration;

            m_framesReq = m_curContext->GetNumFrames() - m_curContext->GetNumFramesPresent();

            LOG(VB_PLAYBACK, LOG_DEBUG, LOC + QString( "SeqEnd @ %1 - require %2 frame(s)")
                .arg(pkt->pts)
                .arg(m_framesReq));
        }
    }

    return ret;
}
Example #12
0
static int write_packet(AVFormatContext *s, AVPacket *pkt)
{
    VideoMuxData *img = s->priv_data;
    AVIOContext *pb[4];
    char filename[1024];
    AVCodecContext *codec = s->streams[pkt->stream_index]->codec;
    const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(codec->pix_fmt);
    int i;
    int nb_renames = 0;

    if (!img->is_pipe) {
        if (img->update) {
            av_strlcpy(filename, img->path, sizeof(filename));
        } else if (img->use_strftime) {
            time_t now0;
            struct tm *tm, tmpbuf;
            time(&now0);
            tm = localtime_r(&now0, &tmpbuf);
            if (!strftime(filename, sizeof(filename), img->path, tm)) {
                av_log(s, AV_LOG_ERROR, "Could not get frame filename with strftime\n");
                return AVERROR(EINVAL);
            }
        } else if (av_get_frame_filename(filename, sizeof(filename), img->path, img->img_number) < 0 &&
                   img->img_number > 1) {
            av_log(s, AV_LOG_ERROR,
                   "Could not get frame filename number %d from pattern '%s' (either set updatefirst or use a pattern like %%03d within the filename pattern)\n",
                   img->img_number, img->path);
            return AVERROR(EINVAL);
        }
        for (i = 0; i < 4; i++) {
            snprintf(img->tmp[i], sizeof(img->tmp[i]), "%s.tmp", filename);
            av_strlcpy(img->target[i], filename, sizeof(img->target[i]));
            if (avio_open2(&pb[i], img->use_rename ? img->tmp[i] : filename, AVIO_FLAG_WRITE,
                           &s->interrupt_callback, NULL) < 0) {
                av_log(s, AV_LOG_ERROR, "Could not open file : %s\n", img->use_rename ? img->tmp[i] : filename);
                return AVERROR(EIO);
            }

            if (!img->split_planes || i+1 >= desc->nb_components)
                break;
            filename[strlen(filename) - 1] = "UVAx"[i];
        }
        if (img->use_rename)
            nb_renames = i + 1;
    } else {
        pb[0] = s->pb;
    }

    if (img->split_planes) {
        int ysize = codec->width * codec->height;
        int usize = AV_CEIL_RSHIFT(codec->width, desc->log2_chroma_w) * AV_CEIL_RSHIFT(codec->height, desc->log2_chroma_h);
        if (desc->comp[0].depth >= 9) {
            ysize *= 2;
            usize *= 2;
        }
        avio_write(pb[0], pkt->data                , ysize);
        avio_write(pb[1], pkt->data + ysize        , usize);
        avio_write(pb[2], pkt->data + ysize + usize, usize);
        avio_closep(&pb[1]);
        avio_closep(&pb[2]);
        if (desc->nb_components > 3) {
            avio_write(pb[3], pkt->data + ysize + 2*usize, ysize);
            avio_closep(&pb[3]);
        }
    } else if (img->muxer) {
        int ret;
        AVStream *st;
        AVPacket pkt2 = {0};
        AVFormatContext *fmt = NULL;

        av_assert0(!img->split_planes);

        ret = avformat_alloc_output_context2(&fmt, NULL, img->muxer, s->filename);
        if (ret < 0)
            return ret;
        st = avformat_new_stream(fmt, NULL);
        if (!st) {
            avformat_free_context(fmt);
            return AVERROR(ENOMEM);
        }
        st->id = pkt->stream_index;

        fmt->pb = pb[0];
        if ((ret = av_copy_packet(&pkt2, pkt))                            < 0 ||
            (ret = av_dup_packet(&pkt2))                                  < 0 ||
            (ret = avcodec_copy_context(st->codec, s->streams[0]->codec)) < 0 ||
            (ret = avformat_write_header(fmt, NULL))                      < 0 ||
            (ret = av_interleaved_write_frame(fmt, &pkt2))                < 0 ||
            (ret = av_write_trailer(fmt))                                 < 0) {
            av_packet_unref(&pkt2);
            avformat_free_context(fmt);
            return ret;
        }
        av_packet_unref(&pkt2);
        avformat_free_context(fmt);
    } else {
        avio_write(pb[0], pkt->data, pkt->size);
    }
    avio_flush(pb[0]);
    if (!img->is_pipe) {
        avio_closep(&pb[0]);
        for (i = 0; i < nb_renames; i++) {
            ff_rename(img->tmp[i], img->target[i], s);
        }
    }

    img->img_number++;
    return 0;
}
int get_embedded_picture(State **ps, AVPacket *pkt) {
	printf("get_embedded_picture\n");
	int i = 0;
	int got_packet = 0;
	AVFrame *frame = NULL;
	
	State *state = *ps;

	if (!state || !state->pFormatCtx) {
		return FAILURE;
	}

    // TODO commented out 5/31/16, do we actully need this since the context
    // has been initialized
    // read the format headers
    /*if (state->pFormatCtx->iformat->read_header(state->pFormatCtx) < 0) {
    	printf("Could not read the format header\n");
    	return FAILURE;
    }*/

    // find the first attached picture, if available
    for (i = 0; i < state->pFormatCtx->nb_streams; i++) {
        if (state->pFormatCtx->streams[i]->disposition & AV_DISPOSITION_ATTACHED_PIC) {
        	printf("Found album art\n");
        	if (pkt) {
        		av_packet_unref(pkt);
        		av_init_packet(pkt);
        	}
            av_copy_packet(pkt, &state->pFormatCtx->streams[i]->attached_pic);
			// TODO is this right
			got_packet = 1;
        	
        	// Is this a packet from the video stream?
        	if (pkt->stream_index == state->video_stream) {
        		int codec_id = state->video_st->codec->codec_id;
				int pix_fmt = state->video_st->codec->pix_fmt;

        		// If the image isn't already in a supported format convert it to one
        		if (!is_supported_format(codec_id, pix_fmt)) {
        			int got_frame = 0;
        			
   			        frame = av_frame_alloc();
        			    	
   			        if (!frame) {
   			        	break;
        			}
   			        
        			if (avcodec_decode_video2(state->video_st->codec, frame, &got_frame, pkt) <= 0) {
        				break;
        			}

        			// Did we get a video frame?
        			if (got_frame) {
        				AVPacket convertedPkt;
        	            av_init_packet(&convertedPkt);
        	            convertedPkt.size = 0;
        	            convertedPkt.data = NULL;

        	            convert_image(state, state->video_st->codec, frame, &convertedPkt, &got_packet, -1, -1);

        				av_packet_unref(pkt);
        				av_init_packet(pkt);
        				av_copy_packet(pkt, &convertedPkt);

        				av_packet_unref(&convertedPkt);

        				break;
        			}
        		} else {
        			av_packet_unref(pkt);
                	av_init_packet(pkt);
                    av_copy_packet(pkt, &state->pFormatCtx->streams[i]->attached_pic);
        			
        			got_packet = 1;
        			break;
        		}
        	}
        }
    }

	av_frame_free(&frame);

	if (got_packet) {
		return SUCCESS;
	} else {
		return FAILURE;
	}
}
Example #14
0
int main(int argc, char* argv[]) {
    if (argc < 2) {
        printf("Usage: %s filename\n", argv[0]);
        return 0;
    }
    f = fopen("002.avi", "wb");
    if (signal(SIGINT, mysigint) == SIG_ERR)
       printf("Cannot handle SIGINT!\n");
    //if (signal(SIGHUP, mysighup) == SIG_ERR)
    //   printf("Cannot handle SIGHUP!\n");
    //if (signal(SIGTERM, mysigterm) == SIG_ERR)
    //   printf("Cannot handle SIGTERM!\n");

    /* can SIGKILL be handled by our own function? */
    //if (signal(SIGKILL, mysigkill) == SIG_ERR)
    //   printf("Cannot handle SIGKILL!\n");

    // Register all available file formats and codecs
    av_register_all();

    int err;
    // Init SDL with video support
    err = SDL_Init(SDL_INIT_VIDEO);
    if (err < 0) {
        fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
        return -1;
    }

    // Open video file
    const char* filename = argv[1];
    AVFormatContext* format_context = NULL;
    err = avformat_open_input(&format_context, filename, NULL, NULL);
    if (err < 0) {
        fprintf(stderr, "ffmpeg: Unable to open input file\n");
        return -1;
    }

    // Retrieve stream information
    err = avformat_find_stream_info(format_context, NULL);
    if (err < 0) {
        fprintf(stderr, "ffmpeg: Unable to find stream info\n");
        return -1;
    }

    // Dump information about file onto standard error
    av_dump_format(format_context, 0, argv[1], 0);

    // Find the first video stream
    int video_stream;
    for (video_stream = 0; video_stream < format_context->nb_streams; ++video_stream) {
        if (format_context->streams[video_stream]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
            break;
        }
    }
    if (video_stream == format_context->nb_streams) {
        fprintf(stderr, "ffmpeg: Unable to find video stream\n");
        return -1;
    }

    AVCodecContext* codec_context = format_context->streams[video_stream]->codec;
    AVCodec* codec = avcodec_find_decoder(codec_context->codec_id);
    err = avcodec_open2(codec_context, codec, NULL);
    if (err < 0) {
        fprintf(stderr, "ffmpeg: Unable to open codec\n");
        return -1;
    }

    SDL_Surface* screen = SDL_SetVideoMode(codec_context->width, codec_context->height, 0, 0);
    if (screen == NULL) {
        fprintf(stderr, "Couldn't set video mode\n");
        return -1;
    }

    SDL_Overlay* bmp = SDL_CreateYUVOverlay(codec_context->width, codec_context->height,
                                            SDL_YV12_OVERLAY, screen);

    struct SwsContext* img_convert_context;
    img_convert_context = sws_getCachedContext(NULL,
                                                codec_context->width, codec_context->height,
                                                codec_context->pix_fmt,
                                                codec_context->width, codec_context->height,
                                                PIX_FMT_YUV420P, SWS_BICUBIC,
                                                NULL, NULL, NULL);
    if (img_convert_context == NULL) {
        fprintf(stderr, "Cannot initialize the conversion context\n");
        return -1;
    }


    AVFrame* frame = avcodec_alloc_frame();
    AVPacket packet;
    AVPacket packet_copy;

    // preparing output ...
    int i, ret;
    char * outputfile = "test.mpg";
    AVFormatContext * oformat_context = NULL;
    AVOutputFormat *ofmt = NULL;
    avformat_alloc_output_context2(&oformat_context, NULL, NULL, outputfile);
    if (!oformat_context) {
        fprintf(stderr, "Could not create output context\n");
        ret = AVERROR_UNKNOWN;
        return (-1);
    };
    ofmt = oformat_context->oformat;

    for (i = 0; i < format_context->nb_streams; i++) {
        AVStream *in_stream = format_context->streams[i];
        AVStream *out_stream = avformat_new_stream(oformat_context, in_stream->codec->codec);
        if (!out_stream) {
            fprintf(stderr, "Failed allocating output stream\n");
            ret = AVERROR_UNKNOWN;
            return (-1);
        }
        ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
        if (ret < 0) {
            fprintf(stderr, "Failed to copy context from input to output stream codec context\n");
            return (-1);
        }
        out_stream->codec->codec_tag = 0;
        if (oformat_context->oformat->flags & AVFMT_GLOBALHEADER)
            out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
    }
    av_dump_format(oformat_context, 0, outputfile, 1);
    if (!(ofmt->flags & AVFMT_NOFILE)) {
        ret = avio_open(&oformat_context->pb, outputfile, AVIO_FLAG_WRITE);
        if (ret < 0) {
            fprintf(stderr, "Could not open output file '%s'", outputfile);
            return (-1);
        }
    }
    ret = avformat_write_header(oformat_context, NULL);
    if (ret < 0) {
        fprintf(stderr, "Error occurred when opening output file\n");
        return (-1);
    };
    AVStream *in_stream, *out_stream;


    while (av_read_frame(format_context, &packet) >= 0) {
        av_copy_packet(&packet_copy, &packet);
        // in_stream  = format_context->streams[packet_copy.stream_index];
        // out_stream = oformat_context->streams[packet_copy.stream_index];

        // packet_copy.pts = av_rescale_q_rnd(packet_copy.pts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
        // packet_copy.dts = av_rescale_q_rnd(packet_copy.dts, in_stream->time_base, out_stream->time_base, AV_ROUND_NEAR_INF|AV_ROUND_PASS_MINMAX);
        // packet_copy.duration = av_rescale_q(packet_copy.duration, in_stream->time_base, out_stream->time_base);
        // packet_copy.pos = -1;
        ret = av_interleaved_write_frame(oformat_context, &packet_copy);
        if (ret < 0) {
            fprintf(stderr, "Error muxing packet\n");
        };

        if (packet.stream_index == video_stream) {
            // Video stream packet
            int frame_finished;

            avcodec_decode_video2(codec_context, frame, &frame_finished, &packet);

            if (frame_finished) {
                SDL_LockYUVOverlay(bmp);

                // Convert frame to YV12 pixel format for display in SDL overlay

                AVPicture pict;
                pict.data[0] = bmp->pixels[0];
                pict.data[1] = bmp->pixels[2];  // it's because YV12
                pict.data[2] = bmp->pixels[1];

                pict.linesize[0] = bmp->pitches[0];
                pict.linesize[1] = bmp->pitches[2];
                pict.linesize[2] = bmp->pitches[1];

                sws_scale(img_convert_context,
                            frame->data, frame->linesize,
                            0, codec_context->height,
                            pict.data, pict.linesize);

                SDL_UnlockYUVOverlay(bmp);

                SDL_Rect rect;
                rect.x = 0;
                rect.y = 0;
                rect.w = codec_context->width;
                rect.h = codec_context->height;
                SDL_DisplayYUVOverlay(bmp, &rect);

                printf("%d\n", packet.size);
                fwrite(packet.data, 1, packet.size, f);

            }
        }

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

        // Handling SDL events there
        SDL_Event event;
        if (SDL_PollEvent(&event)) {
            if (event.type == SDL_QUIT) {
                break;
            }
        }
    }

    fclose(f);

    av_write_trailer(oformat_context);

    if (oformat_context && !(ofmt->flags & AVFMT_NOFILE))
        avio_closep(&oformat_context->pb);
    avformat_free_context(oformat_context);

    sws_freeContext(img_convert_context);

    // Free the YUV frame
    av_free(frame);

    // Close the codec
    avcodec_close(codec_context);

    // Close the video file
    avformat_close_input(&format_context);

    // Quit SDL
    SDL_Quit();
    return 0;
}