Exemple #1
0
static int
scanVolData(afs_int32 taskId, struct butm_tapeInfo *curTapePtr,
            afs_int32 tapeVersion, struct volumeHeader *volumeHeader,
            struct volumeHeader *volumeTrailer, afs_uint32 *bytesRead)
{
    afs_int32 headBytes, tailBytes;
    char *block = NULL;
    char *buffer[2];
    int hasdata[2], curr, prev;
    afs_uint32 chunkSize = 0;
    afs_int32 nbytes;
    afs_int32 code = 0;
    afs_int32 rcode, tcode;

    memset(volumeHeader, 0, sizeof(struct volumeHeader));

    block = (char *)malloc(2 * BUTM_BLOCKSIZE);
    if (!block)
        return (TC_NOMEMORY);
    buffer[0] = &block[sizeof(struct blockMark)];
    buffer[1] = &block[BUTM_BLOCKSIZE + sizeof(struct blockMark)];
    hasdata[0] = hasdata[1] = 0;
    curr = 0;

    tcode = NextFile(curTapePtr);	/* guarantees we are at a filemark */
    if (tcode)
        ERROR_EXIT(tcode)

        /* Read the FileBegin FileMark */
        code = butm_ReadFileBegin(curTapePtr);
    if (code) {
        /*
         * Tapes made with 3.0 have no software EOT markers. Therefore
         * at this point, we will most likely get a read error, indicating
         * the end of this dump
         */
        if ((tapeVersion == TAPE_VERSION_0)
                || (tapeVersion == TAPE_VERSION_1)) {
            /*
             * then a tape error is possible at this point, and it
             * signals the end of the dump. Tapes that are continued
             * have an EOT marker.
             */
            TapeLog(0, taskId, code, curTapePtr->error,
                    "Read error - end-of-dump inferred\n");
            code = BUTM_EOD;
        }

        if (code != BUTM_EOD)
            ErrorLog(0, taskId, code, curTapePtr->error,
                     "Can't read FileBegin on tape\n");
        ERROR_EXIT(code);
    }

    /* now read the volume header */
    code = ReadVolHeader(taskId, curTapePtr, volumeHeader);
    if (code)
        ERROR_EXIT(code);

    *bytesRead = 0;
    while (1) {			/*w */

        /* Check for abort in the middle of scanning data */
        if (*bytesRead >= chunkSize) {
            if (checkAbortByTaskId(taskId))
                ERROR_EXIT(TC_ABORTEDBYREQUEST);
            chunkSize += BIGCHUNK;
        }

        /*
         * Read volume date - If prematurely hit the HW EOF
         * marker, check to see if data contains a volumetrailer.
         */
        rcode =
            butm_ReadFileData(curTapePtr, buffer[curr], BUTM_BLKSIZE,
                              &nbytes);
        if (rcode) {
            hasdata[curr] = 0;
            if ((rcode == BUTM_EOF) || (rcode == BUTM_ENDVOLUME))
                break;

            ErrorLog(0, taskId, rcode, curTapePtr->error,
                     "Can't read FileData on tape\n");
            ERROR_EXIT(rcode)
        }
        hasdata[curr] = 1;
        *bytesRead += nbytes;

        if ((nbytes != BUTM_BLKSIZE)
                ||
                (FindVolTrailer(buffer[curr], nbytes, &tailBytes, volumeTrailer)))
            break;

        curr = ((curr == 0) ? 1 : 0);	/* Switch buffers */
    }				/*w */

    /* Now verify that there is a volume trailer and its valid and copy it */
    prev = ((curr == 0) ? 1 : 0);
    if (!FindVolTrailer2
            (buffer[prev], (hasdata[prev] ? BUTM_BLKSIZE : 0), &headBytes,
             buffer[curr], nbytes, &tailBytes, volumeTrailer)) {
        code = TC_MISSINGTRAILER;
        ErrorLog(0, taskId, code, 0, "Missing volume trailer on tape\n");
    } else {
        /* subtract size of the volume trailer from data read */
        *bytesRead -= sizeof(struct volumeHeader);
    }

    /*
     * If we didn't hit the EOF while reading data, read FileEnd marker
     * or EOF marker.
     */
    if (!rcode) {
        tcode = butm_ReadFileEnd(curTapePtr);
        if (tcode) {
            ErrorLog(0, taskId, tcode, curTapePtr->error,
                     "Can't read EOF on tape\n");
            ERROR_EXIT(tcode);
        }
    }

error_exit:
    if (block)
        free(block);
    return (code);
}
FrameParserStatus_t   FrameParser_VideoDivxHd_c::ReadHeaders( void )
{
		unsigned int  Code;

		ParsedFrameParameters->NewStreamParameters = false;
		ParsedFrameParameters->NewFrameParameters = false;
		ParsedFrameParameters->DataOffset = 0xafff0000;

/*
	report (severity_info, "Start Code List ");
	for (unsigned int j = 0 ; j < StartCodeList->NumberOfStartCodes; ++j)
		report(severity_info,"%x ",ExtractStartCodeCode(StartCodeList->StartCodes[j]));
	report (severity_info,"\n");
*/

#ifdef DUMP_HEADERS
		++inputCount;
#endif

		//      report( severity_error, "%d start codes found\n",StartCodeList->NumberOfStartCodes);
		for(unsigned int i=0; i< StartCodeList->NumberOfStartCodes; ++i)
		{

				Code = ExtractStartCodeCode(StartCodeList->StartCodes[i]);
				//report ( severity_info, "Processing code: %x (%d of %d)\n",Code,i+1, StartCodeList->NumberOfStartCodes);
				Bits.SetPointer( BufferData + ExtractStartCodeOffset(StartCodeList->StartCodes[i]) +4);

				if ( Code == 0x31 )
				{
						// Magic to pass version number around
						DivXVersion = Bits.Get(8);
						switch (DivXVersion)
						{
						        case 3:
								        DivXVersion = 311;
								        break;
						        case 4:
								        DivXVersion = 412;
								        break;
						        case 5:
								        DivXVersion = 500;
								        break;
						        default:
								        DivXVersion = 100;
						}

						//report (severity_info, "DivX Version Number %d\n",DivXVersion);
				}
				else if (Code == DROPPED_FRAME_CODE)
				{
						// magic to work around avi's with skipped 0 byte frames inside them
						DroppedFrame = true;
						report (severity_info,"Seen AVI Dropped Frame\n");
				}
				else if( (Code & VOL_START_CODE_MASK) == VOL_START_CODE )
				{
						FrameParserStatus_t     Status = FrameParserNoError;
						// report (severity_error,"%x VOL_START_CODE\n",VOL_START_CODE);
						if( StreamParameters == NULL)
						{
								StreamParameters = new Mpeg4VideoStreamParameters_t;
								ParsedFrameParameters->StreamParameterStructure = StreamParameters;
								ParsedFrameParameters->SizeofStreamParameterStructure = sizeof(Mpeg4VideoStreamParameters_t);
								ParsedFrameParameters->NewStreamParameters = true;
						}

						Status  = ReadVolHeader( &StreamParameters->VolHeader );
						if( Status != FrameParserNoError )
						{
								ParsedFrameParameters->NewStreamParameters = false;
								StreamParametersSet = false;
								return Status;
						}

						// take some state which affects the decoding of VOP headers
						QuantPrecision = StreamParameters->VolHeader.quant_precision;
						Interlaced = StreamParameters->VolHeader.interlaced;
						StreamParameters->MicroSecondsPerFrame = CurrentMicroSecondsPerFrame;
						StreamParametersSet = true;
						//report (severity_error,"Stream is %s\n",Interlaced?"Interlaced":"Progressive");

						if (DivXVersion != 311)
								ParsedFrameParameters->DataOffset =  ExtractStartCodeOffset(StartCodeList->StartCodes[i]);

				}
				else if( (Code & VOP_START_CODE_MASK) == VOP_START_CODE )
				{
						// report (severity_error,"%x VOP_START_CODE\n",VOP_START_CODE);
						// NOTE the vop reading depends on a valid Vol having been aquired
						if( StreamParametersSet )
						{
								Mpeg4VopHeader_t Vop;
								FrameParserStatus_t     Status = FrameParserNoError;

								if (DivXVersion == 311)
								{
										unsigned char* ptr;
										Vop.prediction_type = Bits.Get(2);
										Vop.quantizer       = Bits.Get(5);
										Bits.GetPosition(&ptr,&bit_skip_no);
										ParsedFrameParameters->DataOffset = (unsigned int)(ptr - BufferData);

								}
								else
								{
										if (DivXVersion != 311 && (ParsedFrameParameters->DataOffset == 0xafff0000))
												ParsedFrameParameters->DataOffset =  ExtractStartCodeOffset(StartCodeList->StartCodes[i]);

										Status  = ReadVopHeader( &Vop );
										if( Status != FrameParserNoError )
												return Status;
								}

								if( FrameParameters == NULL )
								{
										FrameParserStatus_t status  = GetNewFrameParameters( (void **)&FrameParameters );
										if( status != FrameParserNoError )
										{
												report (severity_error,"Failed to get new FrameParameters\n");
												return status;
										}
								}

								FrameParameters->VopHeader = Vop;
								FrameParameters->bit_skip_no = bit_skip_no;
								ParsedFrameParameters->FrameParameterStructure = FrameParameters;
								ParsedFrameParameters->SizeofFrameParameterStructure = sizeof(Mpeg4VideoFrameParameters_t);
								ParsedFrameParameters->NewFrameParameters = true;
								Buffer->AttachBuffer( FrameParametersBuffer );
#ifdef DUMP_HEADERS
								++vopCount;
#endif

								CommitFrameForDecode();

						}
						else
						{
								report( severity_error, "Have Frame without Stream Parameters\n");
								//                              Code = INVALID_START_CODE;
						}
				}
				else if( Code == VSOS_START_CODE )
				{
						// report (severity_error,"%x VSOS_START_CODE\n",VSOS_START_CODE);
						//
						// NOTE this could be my AVI header added to send the MS per frame from the
						// AVI file
						// some avi files have real ones which upset things.... if it returns back 0
						// which is from an unknown profile then use the last one, otherwise pick 25fps
						unsigned int cnpf =  ReadVosHeader( );

						if ( cnpf != 0 )
								CurrentMicroSecondsPerFrame = cnpf;

						// Nick changed this to sanitize the frame rate (4..120)
						if ( (CurrentMicroSecondsPerFrame == 0) || !inrange(Rational_t(1000000,CurrentMicroSecondsPerFrame), 4, 120) )
						{
								report(severity_error,"Current ms per frame not valid (%d) defaulting to 25fps\n");
								CurrentMicroSecondsPerFrame = 40000;
						}
						//report (severity_error,"CurrentMicroSecondsPerFrame %d\n",CurrentMicroSecondsPerFrame);
				}
				else if( (Code & VO_START_CODE_MASK) == VO_START_CODE )
				{
						report (severity_info,"%x VO_START_CODE\n",VO_START_CODE);
						ReadVoHeader();
				}
/*
				else if( (Code & USER_DATA_START_CODE_MASK) == USER_DATA_START_CODE )
				{
						report (severity_info,"%x USER_DATA_START_CODE\n",USER_DATA_START_CODE);
				} // No action
				else if( Code == VSOS_END_CODE )
				{
                      report (severity_info,"%x VSOS_END_CODE\n",VSOS_END_CODE);
				} // No action
				else if( Code == VSO_START_CODE )
				{
						report (severity_info,"%x VSO_START_CODE\n",VSO_START_CODE);
				} // No action
				else if( Code == GOV_START_CODE )
				{
						report (severity_info,"%x GOV_START_CODE\n",GOV_START_CODE);
				} // No action
				else if( Code == END_OF_START_CODE_LIST )
				{
						report (severity_error,"%x END_OF_START_CODE_LIST\n",END_OF_START_CODE_LIST);
				} // No action
				else
				{
						report( severity_error, "ReadHeaders - Unknown/Unsupported header 0x%02x\n", Code );
				}
*/
		}

		return FrameParserNoError;
}