Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- bool VideoDecoder::decodeFrame(int width, int height, int maxTextureSize, const boost::shared_ptr<CodedFrame>& frame) {
- if (!width || !height) {
- //LOGDEBUG("zero width or height for decoding %s frame", getDecoderStream()->streamDescription());
- return false;
- }
- AVFormatContext* formatContext = avformat_alloc_context();
- const double current_time = now_ms();
- boost::mutex::scoped_lock frame_lock(frame_guard);
- if (needDecoding() && pFrame == NULL) {
- //LOGDEBUG("New decoding %s", getDecoderStream()->streamDescription());
- if (MPEG4_CODEC == frame->codec_type)
- codec = avcodec_find_decoder(AV_CODEC_ID_MPEG4);
- else if (H264_CODEC == frame->codec_type)
- codec = avcodec_find_decoder(AV_CODEC_ID_H264);
- else if (MJPEG_CODEC == frame->codec_type)
- codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);
- if (codec == NULL) {
- LOGDEBUG("Codec was not found. Codec = %d", frame->codec_type);
- return false;
- }
- //LOGDEBUG("Finish avcodec_find_decoder");
- codec_context = avcodec_alloc_context3(codec);
- if (codec_context == NULL) {
- LOGDEBUG("avcodec_alloc_context fault");
- return false;
- }
- codec_context->flags2 |= CODEC_FLAG2_CHUNKS;
- //LOGDEBUG("Finish avcodec_alloc_context3");
- if (codec->capabilities & CODEC_CAP_TRUNCATED) {
- codec_context->flags |= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
- LOGDEBUG("CODEC_FLAG_TRUNCATED");
- }
- int r = avcodec_open2(codec_context, codec, 0);
- if (r < 0) {
- LOGDEBUG("Codec was not open");
- if (codec_context != NULL) {
- if (avcodec_is_open(codec_context)) {
- avcodec_close(codec_context);
- }
- av_free(codec_context);
- }
- codec_context = NULL;
- decoded_frame_number = 0;
- return false;
- }
- LOGDEBUG("Finish avcodec_open2");
- pFrame = avcodec_alloc_frame();
- }
- if (!frame) {
- LOGDEBUG("Coded frame is null");
- return false;
- }
- AVPacket packet;
- av_init_packet(&packet);
- packet.data = (uint8_t*) frame->data;
- packet.size = frame->size;
- int decode_count = 0;
- bool pushed = false;
- // while(av_read_frame(formatContext, &packet) >= 0) {
- //decode_ret = avcodec_decode_video2(codec_context, pFrame, &got_picture, &packet);
- //}
- LOGDEBUG("Frame len: %d", packet.size);
- while (packet.size > 0) {
- decode_count++;
- int got_picture;
- int decode_ret = 0;
- // LOGDEBUG("Decoding [%d] (%d/%d, %d/%d) %d", getDecoderId(), codec_context->width, width, codec_context->height, height, packet.size);
- try {
- decode_ret = avcodec_decode_video2(codec_context, pFrame, &got_picture, &packet);
- LOGDEBUG("Decoding frame size decode_ret: %d, got_picture: %d, width: %d, height: %d", decode_ret, got_picture, codec_context->width, codec_context->height);
- decoded_frame_number = frame->index;
- if (decode_ret < 0) {
- LOGDEBUG("Decoding error %d", decode_ret);
- return false;
- }
- } catch (...) {
- LOGDEBUG("Error decoding");
- return false;
- }
- if (packet.data) {
- packet.size -= decode_ret;
- packet.data += decode_ret;
- }
- if (!got_picture) {
- LOGDEBUG("Waiting for full picture");
- std::string packet_flags = "";
- if (packet.flags & AV_PKT_FLAG_KEY) {
- packet_flags += "AV_PKT_FLAG_KEY";
- }
- if (packet.flags & AV_PKT_FLAG_CORRUPT) {
- packet_flags += " | AV_PKT_FLAG_CORRUPT";
- }
- // LOGDEBUG("Decoding %d frame[%ld] not complete (%d, %d) flags %s packetsize %d/%d keyframe %d for %d",
- // decode_ret, frame->index, codec_context->width,
- // codec_context->height, packet_flags.c_str(), packet.size, frame->size,
- // pFrame->key_frame, decode_count);
- continue;
- }
- {
- const bool is_frame_size_changed = (coded_frame_w && coded_frame_h) && (coded_frame_w != codec_context->width || coded_frame_h != codec_context->height);
- if (is_frame_size_changed) {
- LOGDEBUG("Detect frame size changed and ignore one frame.\n"
- "Old frame(%d,%d) was ignore by new frame(%d, %d)", coded_frame_w, coded_frame_h, codec_context->width, codec_context->height);
- }
- coded_frame_w = codec_context->width;
- coded_frame_h = codec_context->height;
- if (is_frame_size_changed) {
- if (img_preview_ctx != NULL)
- sws_freeContext(img_preview_ctx);
- img_preview_ctx = NULL;
- if (pFramePreview != NULL)
- av_free(pFramePreview);
- pFramePreview = NULL;
- //break;
- }
- if (!pFrame->linesize[0]) {
- LOGDEBUG("Decoding linesize 0");
- return false;
- }
- bool need_fix2cif = false;
- if ((codec_context->width == 704 && codec_context->height == 288)
- || (codec_context->width == 720
- && codec_context->height == 288)
- || (codec_context->width == 640
- && codec_context->height == 240)) {
- need_fix2cif = true;
- }
- if (pFrame->linesize[0] > maxTextureSize || need_fix2cif) {
- float ratio = (float) codec_context->width / (float) codec_context->height;
- height = width / ratio;
- if (need_fix2cif) {
- height *= 2;
- }
- if (img_resize_ctx == NULL) {
- LOGDEBUG("Resize frame(%d, %d) to screen(%d, %d)",
- codec_context->width, codec_context->height,
- width, height);
- img_resize_ctx = sws_getContext(codec_context->width,
- codec_context->height, codec_context->pix_fmt,
- width, height, codec_context->pix_fmt,
- SWS_FAST_BILINEAR, NULL, NULL, NULL);
- if (img_resize_ctx == NULL) {
- LOGDEBUG(
- "could not initialize conversion context");
- return false;
- }
- pFrameResized = avcodec_alloc_frame();
- //int numBytes = avpicture_get_size(codec_context->pix_fmt, width, height);
- //LOGDEBUG("av_malloc[%d] %d", getDecoderId(), numBytes);
- //uint8_t *buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
- //avpicture_fill((AVPicture *)pFrameResized, buffer, codec_context->pix_fmt,
- // width, height);
- avpicture_alloc((AVPicture *) pFrameResized, codec_context->pix_fmt, width, height);
- }
- int scale_ret = sws_scale(img_resize_ctx, pFrame->data,
- pFrame->linesize, 0, codec_context->height,
- pFrameResized->data, pFrameResized->linesize);
- // LOGDEBUG("Scale ret = %d linesize %d", scale_ret, pFrameResized->linesize[0]);
- pushDecodedFrame(pFrameResized, width, height, frame->index);
- pushed = true;
- } else {
- // LOGDEBUG("Without scale %d", frame->index);
- pushDecodedFrame(pFrame, codec_context->width,
- codec_context->height, frame->index);
- pushed = true;
- }
- }
- }
- // if (!pushed) {
- // pushDecodedFrame(pFrame, codec_context->width,
- // codec_context->height, frame->index);
- // }
- LOGDEBUG("Decoding frame out");
- calculateFps(current_time);
- decoding_per_sec_time += long(now_ms() - current_time);
- decoding_per_sec_counter++;
- decode_frame_counter++;
- return true;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement