It is .mkv. Sent from my iPhone
On 28.07.2013, at 23:08, Alex Cohn <[email protected]> wrote: > On Jul 23, 2013 11:54 AM, "Marika Marszalkowski" <[email protected]> wrote: > > > > I should have added that oformat->video_codec is AV_CODEC_ID_H264, of > > course. > > > > Best, > > Marika > > > > > > On Mon, Jul 22, 2013 at 8:00 PM, Marika Marszalkowski <[email protected]> > > wrote: > >> > >> Hello everyone, > >> > >> I have been trying to create an encoded h264 Video from multiple images > >> (QImage), but I can't really achieve this. > >> > >> This list is my last resort and I totally hope there is someone out there > >> who can help me with this not as complicated problem. I am not sure what > >> the exact problem is - the video is created, but it is kind of jumpy, so > >> that an image is shown and it stays there for two second and then there is > >> a very short sequence (like half a second) and it's not moving again. Also > >> the first 40 encoded frames, return 0 (SUCCESS) but got_packet_ptr is 0. > >> > >> So this is how I create the video with its header: > >> > >> AVCodec *codec = avcodec_find_encoder(oformat->video_codec); > >> > >> > >> m_codecContext = avcodec_alloc_context3(codec); > >> > >> m_codecContext->gop_size = 30; > >> > >> m_codecContext->sample_fmt = AV_SAMPLE_FMT_NONE; > >> > >> m_codecContext->bit_rate = width * height; > >> > >> m_codecContext->width = width; > >> > >> m_codecContext->height = height; > >> > >> m_codecContext->time_base = (AVRational){1,frameRate}; > >> > >> m_codecContext->pix_fmt = AV_PIX_FMT_YUV420P; > >> > >> > >> formatCtx = avformat_alloc_context(); > >> > >> if(!formatCtx) > >> > >> { > >> > >> printf("Error allocating format context\n"); > >> > >> } > >> > >> formatCtx->oformat = oformat; > >> > >> formatCtx->video_codec_id = oformat->video_codec; > >> > >> snprintf(formatCtx->filename, sizeof(formatCtx->filename), "%s", > >> outputFileName.toStdString().c_str()); > >> > >> > >> AVStream *videoStream = av_new_stream(formatCtx, 0); > >> > >> if(!videoStream) > >> > >> { > >> > >> printf("Could not allocate stream\n"); > >> > >> } > >> > >> videoStream->codec = m_codecContext; > >> > >> > >> if(formatCtx->oformat->flags & AVFMT_GLOBALHEADER) > >> > >> { > >> > >> m_codecContext->flags |= CODEC_FLAG_GLOBAL_HEADER; > >> > >> } > >> > >> > >> avcodec_open2(m_codecContext, codec, NULL); > >> > >> avio_open(&formatCtx->pb, outputFileName.toStdString().c_str(), > >> AVIO_FLAG_WRITE); > >> > >> avformat_write_header(formatCtx, NULL); > >> > >> > >> > >> and this is how I add the frames: > >> > >> > >> > >> > >> AVFrame *frame = avcodec_alloc_frame(); > >> > >> int size = m_codecContext->width * m_codecContext->height; > >> > >> int numBytes = avpicture_get_size(m_codecContext->pix_fmt, > >> m_codecContext->width, m_codecContext->height); > >> > >> > >> QSharedPointer<BlendImage> img = imageData; > >> > >> > >> uint8_t *outbuf = (uint8_t *)malloc(numBytes); > >> > >> uint8_t *picture_buf = (uint8_t *)av_malloc(numBytes); > >> > >> > >> if (true) > >> > >> { > >> > >> int ret = av_image_fill_arrays(frame->data, frame->linesize, > >> picture_buf, m_codecContext->pix_fmt, m_codecContext->width, > >> m_codecContext->height, 1); > >> > >> > >> frame->data[0] = picture_buf; > >> > >> frame->data[1] = frame->data[0] + size; > >> > >> frame->data[2] = frame->data[1] + size/4; > >> > >> frame->linesize[0] = m_codecContext->width; > >> > >> frame->linesize[1] = m_codecContext->width/2; > >> > >> frame->linesize[2] = m_codecContext->width/2; > >> > >> > >> fflush(stdout); > >> > >> for (int y = 0; y < m_codecContext->height; y++) > >> > >> { > >> > >> for (int x = 0; x < m_codecContext->width; x++) > >> > >> { > >> > >> unsigned char b = img->bits()[(y * > >> m_codecContext->width + x) * 4 + 0]; > >> > >> unsigned char g = img->bits()[(y * > >> m_codecContext->width + x) * 4 + 1]; > >> > >> unsigned char r = img->bits()[(y * > >> m_codecContext->width + x) * 4 + 2]; > >> > >> > >> unsigned char Y = (0.257 * r) + (0.504 * g) + (0.098 * > >> b) + 16; > >> > >> > >> frame->data[0][y * frame->linesize[0] + x] = Y; > >> > >> > >> if (y % 2 == 0 && x % 2 == 0) > >> > >> { > >> > >> unsigned char V = (0.439 * r) - (0.368 * g) - > >> (0.071 * b) + 128; > >> > >> unsigned char U = -(0.148 * r) - (0.291 * g) + > >> (0.439 * b) + 128; > >> > >> > >> frame->data[1][y/2 * frame->linesize[1] + x/2] = U; > >> > >> frame->data[2][y/2 * frame->linesize[2] + x/2] = V; > >> > >> } > >> > >> } > >> > >> } > >> > >> int pts = (1.0 / 30.0) * 9000.0 * frameIndex; > >> > >> frame->pts = pts; > >> > >> > >> int got_packet_ptr; > >> > >> > >> AVPacket packet; > >> > >> av_init_packet(&packet); > >> > >> packet.data = outbuf; > >> > >> packet.size = numBytes; > >> > >> packet.stream_index = formatCtx->streams[0]->index; > >> > >> packet.flags |= AV_PKT_FLAG_KEY; > >> > >> packet.pts = packet.dts = pts; > >> > >> > >> m_codecContext->coded_frame->pts = pts; > >> > >> > >> ret = avcodec_encode_video2(m_codecContext, &packet, frame, > >> &got_packet_ptr); > >> > >> > >> > >> if (got_packet_ptr != 0) > >> > >> { > >> > >> m_codecContext->coded_frame->pts = pts; > >> > >> > >> if (m_codecContext->coded_frame->pts != > >> (0x8000000000000000LL)) > >> > >> pts = av_rescale_q(m_codecContext->coded_frame->pts, > >> m_codecContext->time_base, formatCtx->streams[0]->time_base); > >> > >> > >> packet.pts = pts; > >> > >> > >> if(m_codecContext->coded_frame->key_frame) > >> > >> { > >> > >> packet.flags |= AV_PKT_FLAG_KEY; > >> > >> } > >> > >> > >> > >> std::cout << "pts: " << packet.pts << ", dts: " << > >> packet.dts << std::endl; > >> > >> > >> av_interleaved_write_frame(formatCtx, &packet); > >> > >> av_free_packet(&packet); > >> > >> } > >> > >> } > >> > >> > >> free(picture_buf); > >> > >> free(outbuf); > >> > >> av_free(frame); > >> > >> > >> > >> and of course in the end: > >> > >> > >> av_write_trailer(formatCtx); > >> > >> fclose(m_file); > >> > >> avcodec_close(m_codecContext); > >> > >> av_free(m_codecContext); > >> > >> > >> > >> I think this has something to do with the PTS/DTS values. PTS values start > >> at 120 (as the first 40 frames are omitted) and are increased by 3 ((1.0 / > >> 30.0) * 9000.0 * frameIndex) and the DTS values start at -6 also being > >> increased by 3 per frame. But it might also be the settings or anything > >> else. I feel like I have tried everything I was able to find on the > >> internet and it's still wrong. I am desperate, help would be soooo > >> appreciated! > >> > >> > >> Cheers, > >> > >> Marika > > What is your output format? > Alex > _______________________________________________ > Libav-user mailing list > [email protected] > http://ffmpeg.org/mailman/listinfo/libav-user
_______________________________________________ Libav-user mailing list [email protected] http://ffmpeg.org/mailman/listinfo/libav-user
