Search code examples
c++ffmpegvideo-streamingvlc

how to output a media stream using ffmpeg?


I am reading a mpeg4 video stream using ffmpeg. I use some of its properties and do some processes using those properties. What I want is to play the opened video using a player like vlc. And then consequently I need to play the output video after processing in order to check whether there is a latency. Is it possible to give the video to a port. So that I can get the video as a input to the vlc player from the specific port.

This is my code up to now. I use MV_generation method to extract features from it and to do a comparison from it.

static int MV_generation(const AVPacket *pkt)
{
    std::vector<unsigned long long> vl = File_read();
    std::hash<string> hash1;
    std::ios_base::app);
    double x_src_val = 0;
    double y_src_val = 0;
    double x_dst_val = 0;
    double y_dst_val = 0;

    int ret = avcodec_send_packet(video_dec_ctx, pkt);
    if (ret < 0) {
        //fprintf(stderr, "Error while sending a packet to the decoder: %s\n", av_err2str(ret));
        return ret;
    }
    video_frame_count++;
    while (ret >= 0){

        ret = avcodec_receive_frame(video_dec_ctx, frame);
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
            break;
        }
        else if (ret < 0) {
            return ret;
        }
        if (ret >= 0) {
            AVFrameSideData *sd;
            sd = av_frame_get_side_data(frame, AV_FRAME_DATA_MOTION_VECTORS);

            if (sd) {

                const AVMotionVector *mvs = (const AVMotionVector *)sd->data;

                int size_sd = sd->size;
                //outData << size_sd << endl;

                string str = "", str1, str2, str3, str4;
                for (int i = 0; i < size_sd / sizeof(*mvs); i++) {
                    const AVMotionVector *mv = &mvs[i];

                    int x_src = mv->src_x;
                    int y_src = mv->src_y;
                    int x_dst = mv->dst_x;
                    int y_dst = mv->dst_y;


                    if (x_src != x_dst || y_src != y_dst || x_src > 100 || y_src > 100 || x_dst > 100 || y_dst > 100){
                        str1 = to_string(x_src);
                        str2 = to_string(y_src);
                        str3 = to_string(x_dst);
                        str4 = to_string(y_dst);

                        str = str.append(str1).append(str2).append(str3).append(str4);
                    }
                }

                for (unsigned long long y : vl)
                {
                    // Check if any of the numbers are equal to x
                    if (hash1(str) == y)
                    {
                        cout << "matched frame_no : " << video_frame_count << endl;
                    }
                }
            }
            av_frame_unref(frame);
        }
    }
    outData.close();
    return 0;
}

Solution

  • This method can also used once the frame is converted to a mat

    int ShowVideo(Mat mRGB, string textOnVideo, string windowName){
        namedWindow(windowName, 1);
    
    
    Pict_type = frame->pict_type;
    //cout << av_get_picture_type_char(Pict_type); //I P or B frame 
    
    if (AV_PICTURE_TYPE_NONE != Pict_type)
    {
        namedWindow(windowName, 1);
        mRGB = Mat(dec_ctx->height, dec_ctx->width, CV_8UC3);
        Mat mYUV(dec_ctx->height + dec_ctx->height / 2, dec_ctx->width, CV_8UC1, (void*)buff);
        cvtColor(mYUV, mRGB, CV_YUV2RGB_YV12, 3);
    
        putText(mRGB, textOnVideo,
            Point(100, 100), FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 255, 255));
    
    
        imshow(windowName, mRGB);
        waitKey(1);
    }
    return 0;
    }